diff --git a/API/Controllers/LibraryController.cs b/API/Controllers/LibraryController.cs index ae569f272..878681738 100644 --- a/API/Controllers/LibraryController.cs +++ b/API/Controllers/LibraryController.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -12,6 +13,7 @@ using API.Entities; using API.Entities.Enums; using API.Entities.Metadata; using API.Extensions; +using API.Helpers.Builders; using API.Services; using API.Services.Tasks.Scanner; using API.SignalR; @@ -112,7 +114,7 @@ public class LibraryController : BaseApiController })); } - if (!Directory.Exists(path)) return BadRequest("This is not a valid path"); + if (!Directory.Exists(path)) return Ok(_directoryService.ListDirectory(Path.GetDirectoryName(path))); return Ok(_directoryService.ListDirectory(path)); } diff --git a/API/Data/DataContext.cs b/API/Data/DataContext.cs index 6482b42b6..f6c91aa42 100644 --- a/API/Data/DataContext.cs +++ b/API/Data/DataContext.cs @@ -95,26 +95,6 @@ public sealed class DataContext : IdentityDbContext b.BookReaderWritingStyle) .HasDefaultValue(WritingStyle.Horizontal); - - builder.Entity() - .Property(b => b.FolderWatching) - .HasDefaultValue(true); - builder.Entity() - .Property(b => b.IncludeInDashboard) - .HasDefaultValue(true); - builder.Entity() - .Property(b => b.IncludeInRecommended) - .HasDefaultValue(true); - builder.Entity() - .Property(b => b.IncludeInSearch) - .HasDefaultValue(true); - builder.Entity() - .Property(b => b.ManageCollections) - .HasDefaultValue(true); - builder.Entity() - .Property(b => b.ManageReadingLists) - .HasDefaultValue(true); - builder.Entity() .Property(b => b.WebLinks) .HasDefaultValue(string.Empty); diff --git a/API/Extensions/SeriesExtensions.cs b/API/Extensions/SeriesExtensions.cs index 42b428579..8d0c0b3e1 100644 --- a/API/Extensions/SeriesExtensions.cs +++ b/API/Extensions/SeriesExtensions.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +#nullable enable +using System.Collections.Generic; using System.Linq; using API.Comparators; using API.Entities; @@ -20,13 +21,30 @@ public static class SeriesExtensions if (firstVolume == null) return null; string? coverImage = null; - var chapters = firstVolume.Chapters.OrderBy(c => double.Parse(c.Number), ChapterSortComparerZeroFirst.Default).ToList(); + var chapters = firstVolume.Chapters + .OrderBy(c => double.Parse(c.Number), ChapterSortComparerZeroFirst.Default).ToList(); if (chapters.Count > 1 && chapters.Any(c => c.IsSpecial)) { coverImage = chapters.FirstOrDefault(c => !c.IsSpecial)?.CoverImage ?? chapters.First().CoverImage; firstVolume = null; } + else + { + var allChapters = volumes + .SelectMany(v => v.Chapters) + .OrderBy(c => double.Parse(c.Number), ChapterSortComparerZeroFirst.Default) + .Where(c => !c.IsSpecial) + .ToList(); - return firstVolume?.CoverImage ?? coverImage; + var num = allChapters.FirstOrDefault()?.Number ?? $"{int.MaxValue}"; + + if (double.Parse(num) < firstVolume.Number && double.Parse(num) < double.Parse(chapters.First().Number)) + { + coverImage = allChapters.First().CoverImage; + } + } + + + return coverImage ?? firstVolume?.CoverImage; } } diff --git a/API/Services/DirectoryService.cs b/API/Services/DirectoryService.cs index 64c196ded..0053dbe2f 100644 --- a/API/Services/DirectoryService.cs +++ b/API/Services/DirectoryService.cs @@ -518,7 +518,9 @@ public class DirectoryService : IDirectoryService { Name = d.Name, FullPath = d.FullName, - }).ToImmutableList(); + }) + .OrderBy(s => s.Name) + .ToImmutableList(); return dirs; } diff --git a/UI/Web/.editorconfig b/UI/Web/.editorconfig index 59d9a3a3e..300add175 100644 --- a/UI/Web/.editorconfig +++ b/UI/Web/.editorconfig @@ -11,6 +11,9 @@ trim_trailing_whitespace = true [*.ts] quote_type = single +[*.scss] +indent_size = 4 + [*.md] max_line_length = off trim_trailing_whitespace = false diff --git a/UI/Web/src/_manga-reader-common.scss b/UI/Web/src/_manga-reader-common.scss index 123b925a6..2dc2e9c1e 100644 --- a/UI/Web/src/_manga-reader-common.scss +++ b/UI/Web/src/_manga-reader-common.scss @@ -42,6 +42,7 @@ img { } .full-width { + width: 100%; margin: 0 auto; vertical-align: top; max-width: fit-content; diff --git a/UI/Web/src/app/admin/manage-library/manage-library.component.ts b/UI/Web/src/app/admin/manage-library/manage-library.component.ts index 28565633a..0b6cf321c 100644 --- a/UI/Web/src/app/admin/manage-library/manage-library.component.ts +++ b/UI/Web/src/app/admin/manage-library/manage-library.component.ts @@ -4,13 +4,11 @@ import { Component, DestroyRef, inject, - OnDestroy, OnInit } from '@angular/core'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ToastrService } from 'ngx-toastr'; -import { Subject } from 'rxjs'; -import { distinctUntilChanged, filter, take, takeUntil } from 'rxjs/operators'; +import { distinctUntilChanged, filter, take } from 'rxjs/operators'; import { ConfirmService } from 'src/app/shared/confirm.service'; import { LibrarySettingsModalComponent } from 'src/app/sidenav/_modals/library-settings-modal/library-settings-modal.component'; import { NotificationProgressEvent } from 'src/app/_models/events/notification-progress-event'; @@ -85,7 +83,7 @@ export class ManageLibraryComponent implements OnInit { this.loading = true; this.cdRef.markForCheck(); this.libraryService.getLibraries().pipe(take(1)).subscribe(libraries => { - this.libraries = libraries; + this.libraries = [...libraries]; this.loading = false; this.cdRef.markForCheck(); }); @@ -111,13 +109,13 @@ export class ManageLibraryComponent implements OnInit { } async deleteLibrary(library: Library) { - if (await this.confirmService.confirm('Are you sure you want to delete this library? You cannot undo this action.')) { + if (await this.confirmService.confirm('Are you sure you want to delete the ' + library.name + ' library? You cannot undo this action.')) { this.deletionInProgress = true; this.libraryService.delete(library.id).pipe(take(1)).subscribe(() => { this.deletionInProgress = false; this.cdRef.markForCheck(); this.getLibraries(); - this.toastr.success('Library has been removed'); + this.toastr.success('Library ' + library.name + ' has been removed'); }); } } diff --git a/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.scss b/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.scss index 976a3134f..a36290820 100644 --- a/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.scss +++ b/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.scss @@ -336,7 +336,6 @@ $action-bar-height: 38px; top: $action-bar-height; width: 20vw; z-index: 3; - cursor: pointer; background: transparent; border-color: transparent; border: none !important; @@ -346,6 +345,10 @@ $action-bar-height: 38px; &.immersive { top: 0px; } + + &:hover { + cursor: pointer; + } } // This class pushes the click area to the left a bit to let users click the scrollbar @@ -355,7 +358,6 @@ $action-bar-height: 38px; top: $action-bar-height; width: 18%; z-index: 3; - cursor: pointer; background: transparent; border-color: transparent; border: none !important; @@ -365,6 +367,9 @@ $action-bar-height: 38px; &.immersive { top: 0px; } + &:hover { + cursor: pointer; + } } .left { @@ -376,7 +381,6 @@ $action-bar-height: 38px; border-color: transparent; border: none !important; z-index: 3; - cursor: pointer; opacity: 0; outline: none; @@ -384,6 +388,9 @@ $action-bar-height: 38px; top: 0px; } + &:hover { + cursor: pointer; + } } diff --git a/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.ts b/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.ts index 48f67c6f0..dec6e0e77 100644 --- a/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.ts +++ b/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.ts @@ -474,6 +474,9 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy { this.handleScrollEvent(); }); + + // TODO: In order to allow people to highlight content under pagination overlays, apply pointer-events: none while + // a highlight operation is in effect } handleScrollEvent() { diff --git a/UI/Web/src/app/book-reader/_models/book-paper-theme.ts b/UI/Web/src/app/book-reader/_models/book-paper-theme.ts index 129a5df13..98c4375f3 100644 --- a/UI/Web/src/app/book-reader/_models/book-paper-theme.ts +++ b/UI/Web/src/app/book-reader/_models/book-paper-theme.ts @@ -80,30 +80,36 @@ export const BookPaperTheme = ` --nav-link-active-text-color: white; --nav-link-text-color: white; - - /* Reading Bar */ --br-actionbar-button-hover-border-color: #6c757d; --br-actionbar-bg-color: #F1E4D5; /* Drawer */ --drawer-pagination-horizontal-rule: inset 0 -1px 0 rgb(0 0 0 / 13%); + + /* Custom variables */ + --theme-bg-color: #fff3c9; } .reader-container { color: black !important; - background-color: #fff3c9 !important; + background-color: var(--theme-bg-color) !important; background: url("/assets/images/paper-bg.png"); } .book-content *:not(input), .book-content *:not(select), .book-content *:not(code), .book-content *:not(:link), .book-content *:not(.ngx-toastr) { - color: black !important; + color: var(--bs-body-color) !important; } .book-content code { color: #e83e8c !important; } +// KDB has a reboot style so for lighter themes, this is needed +.book-content kbd { + background-color: transparent; +} + .book-content :link, .book-content a { color: #8db2e5 !important; } @@ -115,7 +121,7 @@ background-color: initial !important; } -.book-content *:not(code), .book-content *:not(a) { +.book-content *:not(code), .book-content *:not(a), .book-content *:not(kbd) { //background-color: #F1E4D5; box-shadow: none; text-shadow: none; diff --git a/openapi.json b/openapi.json index 3e41b1384..b14e94e6c 100644 --- a/openapi.json +++ b/openapi.json @@ -7,7 +7,7 @@ "name": "GPL-3.0", "url": "https://github.com/Kareadita/Kavita/blob/develop/LICENSE" }, - "version": "0.7.2.31" + "version": "0.7.3.1" }, "servers": [ {