diff --git a/API.Tests/Services/ReaderServiceTests.cs b/API.Tests/Services/ReaderServiceTests.cs index 6f9d71126..3134997ff 100644 --- a/API.Tests/Services/ReaderServiceTests.cs +++ b/API.Tests/Services/ReaderServiceTests.cs @@ -1687,6 +1687,35 @@ public class ReaderServiceTests } + + [Fact] + public async Task GetContinuePoint_ShouldReturnFirstChapter_WhenHasSpecial() + { + await ResetDb(); + var series = new SeriesBuilder("Test") + // Loose chapters + .WithVolume(new VolumeBuilder("0") + .WithChapter(new ChapterBuilder("1").WithPages(1).Build()) + .WithChapter(new ChapterBuilder("2").WithPages(1).Build()) + .WithChapter(new ChapterBuilder("Prologue").WithIsSpecial(true).WithPages(1).Build()) + .Build()) + .Build(); + series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build(); + + _context.Series.Add(series); + + _context.AppUser.Add(new AppUser() + { + UserName = "majora2007" + }); + + await _context.SaveChangesAsync(); + + var nextChapter = await _readerService.GetContinuePoint(1, 1); + + Assert.Equal("1", nextChapter.Range); + } + [Fact] public async Task GetContinuePoint_ShouldReturnFirstSpecial() { diff --git a/API/Controllers/LicenseController.cs b/API/Controllers/LicenseController.cs index 195610f06..30c85d22c 100644 --- a/API/Controllers/LicenseController.cs +++ b/API/Controllers/LicenseController.cs @@ -31,7 +31,9 @@ public class LicenseController( [ResponseCache(CacheProfileName = ResponseCacheProfiles.LicenseCache)] public async Task> HasValidLicense(bool forceCheck = false) { - return Ok(await licenseService.HasActiveLicense(forceCheck)); + var result = await licenseService.HasActiveLicense(forceCheck); + await taskScheduler.ScheduleKavitaPlusTasks(); + return Ok(result); } /// @@ -66,7 +68,11 @@ public class LicenseController( public async Task ResetLicense(UpdateLicenseDto dto) { logger.LogInformation("Resetting license on file for Server"); - if (await licenseService.ResetLicense(dto.License, dto.Email)) return Ok(); + if (await licenseService.ResetLicense(dto.License, dto.Email)) + { + await taskScheduler.ScheduleKavitaPlusTasks(); + return Ok(); + } return BadRequest(localizationService.Translate(User.GetUserId(), "unable-to-reset-k+")); } diff --git a/API/EmailTemplates/EmailChange.html b/API/EmailTemplates/EmailChange.html index 6db4552e0..c7e0447ed 100644 --- a/API/EmailTemplates/EmailChange.html +++ b/API/EmailTemplates/EmailChange.html @@ -1,36 +1,33 @@ - - - - - - - - - - - - - - - - -
-

Email Change Update

-

Your account's email has been updated on {{InvitingUser}}'s Kavita instance.

-
-

Please click the following link to validate your email change. The email is not changed until you complete validation.

-
- -
- - - - - -
- -
-

If the button above does not work, please find the link here: {{Link}}

-
+ + + +

Email Change Update

+

Your account's email has been updated on {{InvitingUser}}'s Kavita instance.

+

Please click the following link to validate your email change. The email is not changed until you complete validation.

+ + + + + + + + + + +

If the button above does not work, please find the link here: {{Link}}

+ + + diff --git a/API/EmailTemplates/EmailConfirm.html b/API/EmailTemplates/EmailConfirm.html index 6c65b5477..40e60f185 100644 --- a/API/EmailTemplates/EmailConfirm.html +++ b/API/EmailTemplates/EmailConfirm.html @@ -1,36 +1,32 @@ - - - - - - - - - - - - - - - - -
-

You've Been Invited

-

You have been invited to {{InvitingUser}}'s Kavita instance.

-
-

Please click the following link to setup an account for yourself and start reading.

-
- -
- - - - - -
- -
-

If the button above does not work, please find the link here: {{Link}}

-
+ + + +

You've Been Invited!

+

You have been invited to {{InvitingUser}}'s Kavita instance.

+

Please click the following link to setup an account for yourself and start reading.

+ + + + + + + + + +

If the button above does not work, please find the link here: {{Link}}

+ + + diff --git a/API/EmailTemplates/EmailPasswordReset.html b/API/EmailTemplates/EmailPasswordReset.html index f8b785f97..afcc2866d 100644 --- a/API/EmailTemplates/EmailPasswordReset.html +++ b/API/EmailTemplates/EmailPasswordReset.html @@ -1,36 +1,33 @@ - - - - - - - - - - - - - - - - -
-

Forgot your password?

-

That's okay, it happens! Click on the button below to reset your password.

-
- -
- - - - - -
- -
-

If you did not perform this action, ignore this email.

-
-

If the button above does not work, please find the link here: {{Link}}

-
+ + + +

Forgot your password?

+

That's okay, it happens! Click on the button below to reset your password.

+ +

If you did not perform this action, ignore this email. Your account is safe.

+ + + + + + + + + +

If the button above does not work, please find the link here: {{Link}}

+ + + diff --git a/API/EmailTemplates/EmailTest.html b/API/EmailTemplates/EmailTest.html index 6acef1371..ae00e4889 100644 --- a/API/EmailTemplates/EmailTest.html +++ b/API/EmailTemplates/EmailTest.html @@ -1,11 +1,8 @@ - - - - - - - -
-

This is a Test Email

-

If you've received this email, your KavitaEmail is setup

-
+ + +

This is a Test Email

+

Congrats! Your instance of Kavita is setup to email correctly!

+ +

If you did not perform this action, ignore this email. Your account is safe.

+ + diff --git a/API/EmailTemplates/SendToDevice.html b/API/EmailTemplates/SendToDevice.html index 325736992..673d773c5 100644 --- a/API/EmailTemplates/SendToDevice.html +++ b/API/EmailTemplates/SendToDevice.html @@ -1,11 +1,6 @@ - - - - - - - -
-

You sent a file from Kavita

-

Please find attached the file(s) you've sent.

-
+ + +

You sent file(s) from Kavita

+

Please find attached the file(s) you've sent.

+ + diff --git a/API/EmailTemplates/base.html b/API/EmailTemplates/base.html index 9151cc62b..267e678d0 100644 --- a/API/EmailTemplates/base.html +++ b/API/EmailTemplates/base.html @@ -1,320 +1,523 @@ - + - - - - - - - - + + + + + + + - Kavita - [Plain HTML] - - - - - - - - - - + + + + + + - - - + Kavita - {{Preheader}} - - - - + - -
- -
Your account's email has been updated on {{InvitingUser}}'s Kavita instance. Click the button to validate your email.
- - - -
+ - diff --git a/API/Services/EmailService.cs b/API/Services/EmailService.cs index dccf5d8a3..731578421 100644 --- a/API/Services/EmailService.cs +++ b/API/Services/EmailService.cs @@ -20,10 +20,11 @@ namespace API.Services; internal class EmailOptionsDto { - public IList ToEmails { get; set; } - public string Subject { get; set; } - public string Body { get; set; } - public IList> PlaceHolders { get; set; } + public required IList ToEmails { get; set; } + public required string Subject { get; set; } + public required string Body { get; set; } + public required string Preheader { get; set; } + public IList>? PlaceHolders { get; set; } /// /// Filenames to attach /// @@ -81,7 +82,6 @@ public class EmailService : IEmailService return result; } - // TODO: Come back and update the template. We can't do it with the v0.8.0 release var placeholders = new List> { new ("{{Host}}", settings.HostName), @@ -91,8 +91,9 @@ public class EmailService : IEmailService { var emailOptions = new EmailOptionsDto() { - Subject = "KavitaEmail Test", + Subject = "Kavita - Email Test", Body = UpdatePlaceHolders(await GetEmailBody("EmailTest"), placeholders), + Preheader = "Kavita - Email Test", ToEmails = new List() { adminEmail @@ -127,6 +128,7 @@ public class EmailService : IEmailService { Subject = UpdatePlaceHolders("Your email has been changed on {{InvitingUser}}'s Server", placeholders), Body = UpdatePlaceHolders(await GetEmailBody("EmailChange"), placeholders), + Preheader = UpdatePlaceHolders("Your email has been changed on {{InvitingUser}}'s Server", placeholders), ToEmails = new List() { data.EmailAddress @@ -182,6 +184,7 @@ public class EmailService : IEmailService { Subject = UpdatePlaceHolders("You've been invited to join {{InvitingUser}}'s Server", placeholders), Body = UpdatePlaceHolders(await GetEmailBody("EmailConfirm"), placeholders), + Preheader = UpdatePlaceHolders("You've been invited to join {{InvitingUser}}'s Server", placeholders), ToEmails = new List() { data.EmailAddress @@ -207,6 +210,7 @@ public class EmailService : IEmailService { Subject = UpdatePlaceHolders("A password reset has been requested", placeholders), Body = UpdatePlaceHolders(await GetEmailBody("EmailPasswordReset"), placeholders), + Preheader = "A password reset has been requested", ToEmails = new List() { dto.EmailAddress @@ -225,6 +229,7 @@ public class EmailService : IEmailService var emailOptions = new EmailOptionsDto() { Subject = "Send file from Kavita", + Preheader = "File(s) sent from Kavita", ToEmails = new List() { data.DestinationEmail @@ -249,7 +254,8 @@ public class EmailService : IEmailService // Inject the body into the base template var fullBody = UpdatePlaceHolders(await GetEmailBody("base"), new List>() { - new ("{{Body}}", userEmailOptions.Body) + new ("{{Body}}", userEmailOptions.Body), + new ("{{Preheader}}", userEmailOptions.Preheader), }); var body = new BodyBuilder @@ -320,7 +326,7 @@ public class EmailService : IEmailService return body; } - private static string UpdatePlaceHolders(string text, IList> keyValuePairs) + private static string UpdatePlaceHolders(string text, IList>? keyValuePairs) { if (string.IsNullOrEmpty(text) || keyValuePairs == null) return text; diff --git a/API/Services/ReaderService.cs b/API/Services/ReaderService.cs index 29cf756c5..693c7667b 100644 --- a/API/Services/ReaderService.cs +++ b/API/Services/ReaderService.cs @@ -531,8 +531,24 @@ public class ReaderService : IReaderService if (!await _unitOfWork.AppUserProgressRepository.AnyUserProgressForSeriesAsync(seriesId, userId)) { // I think i need a way to sort volumes last - return volumes.OrderBy(v => v.MinNumber.ToString(CultureInfo.InvariantCulture).AsDouble(), _chapterSortComparer).First().Chapters - .OrderBy(c => c.Number.AsFloat()).First(); + var chapters = volumes.OrderBy(v => v.MinNumber, _chapterSortComparer).First().Chapters + .OrderBy(c => c.Number.AsFloat()) + .ToList(); + + // If there are specials, then return the first Non-special + if (chapters.Exists(c => c.IsSpecial)) + { + var firstChapter = chapters.FirstOrDefault(c => !c.IsSpecial); + if (firstChapter == null) + { + // If there is no non-special chapter, then return first chapter + return chapters[0]; + } + + return firstChapter; + } + // Else use normal logic + return chapters[0]; } // Loop through all chapters that are not in volume 0 diff --git a/API/Services/Tasks/VersionUpdaterService.cs b/API/Services/Tasks/VersionUpdaterService.cs index c20cadfad..2591fdbba 100644 --- a/API/Services/Tasks/VersionUpdaterService.cs +++ b/API/Services/Tasks/VersionUpdaterService.cs @@ -130,7 +130,7 @@ public class VersionUpdaterService : IVersionUpdaterService { if (update == null) return; - var updateVersion = new Version(update.CurrentVersion); + var updateVersion = new Version(update.UpdateVersion); if (BuildInfo.Version < updateVersion) { @@ -138,12 +138,6 @@ public class VersionUpdaterService : IVersionUpdaterService await _eventHub.SendMessageAsync(MessageFactory.UpdateAvailable, MessageFactory.UpdateVersionEvent(update), true); } - else if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == Environments.Development) - { - _logger.LogWarning("Server is up to date. Current: {CurrentVersion}", BuildInfo.Version); - await _eventHub.SendMessageAsync(MessageFactory.UpdateAvailable, MessageFactory.UpdateVersionEvent(update), - true); - } } diff --git a/UI/Web/package-lock.json b/UI/Web/package-lock.json index 4f9313bf9..fa6b9d010 100644 --- a/UI/Web/package-lock.json +++ b/UI/Web/package-lock.json @@ -615,6 +615,7 @@ "version": "17.1.0", "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-17.1.0.tgz", "integrity": "sha512-WDpO4WvC5ItjaRexnpFpKPpT+cu+5GYkWF8h74iHhfxOgU+gaQiMWERHylWCqF25AzmhKu0iI3ZZtaIJ6qqwog==", + "dev": true, "dependencies": { "@babel/core": "7.23.2", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -5542,6 +5543,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -5787,6 +5789,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, "engines": { "node": ">=8" } @@ -6092,6 +6095,7 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, "funding": [ { "type": "individual", @@ -6340,7 +6344,8 @@ "node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true }, "node_modules/cookie": { "version": "0.5.0", @@ -7230,6 +7235,7 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, "optional": true, "dependencies": { "iconv-lite": "^0.6.2" @@ -7239,6 +7245,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, "optional": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -8318,6 +8325,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -9092,6 +9100,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -10868,6 +10877,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -12258,6 +12268,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -12268,7 +12279,8 @@ "node_modules/reflect-metadata": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", + "dev": true }, "node_modules/regenerate": { "version": "1.4.2", @@ -12720,7 +12732,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "devOptional": true + "dev": true }, "node_modules/sass": { "version": "1.69.7", @@ -12836,6 +12848,7 @@ "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -12850,6 +12863,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -12860,7 +12874,8 @@ "node_modules/semver/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/send": { "version": "0.18.0", @@ -13967,6 +13982,7 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/UI/Web/src/app/manga-reader/_components/manga-reader/manga-reader.component.ts b/UI/Web/src/app/manga-reader/_components/manga-reader/manga-reader.component.ts index 81c90cf0b..9fe413cb2 100644 --- a/UI/Web/src/app/manga-reader/_components/manga-reader/manga-reader.component.ts +++ b/UI/Web/src/app/manga-reader/_components/manga-reader/manga-reader.component.ts @@ -13,7 +13,7 @@ import { OnInit, ViewChild } from '@angular/core'; -import {DOCUMENT, NgStyle, NgIf, NgFor, NgSwitch, NgSwitchCase, PercentPipe, NgClass, AsyncPipe} from '@angular/common'; +import {AsyncPipe, DOCUMENT, NgClass, NgFor, NgIf, NgStyle, NgSwitch, NgSwitchCase, PercentPipe} from '@angular/common'; import {ActivatedRoute, Router} from '@angular/router'; import { BehaviorSubject, @@ -29,9 +29,9 @@ import { take, tap } from 'rxjs'; -import { ChangeContext, LabelType, Options, NgxSliderModule } from 'ngx-slider-v2'; +import {ChangeContext, LabelType, NgxSliderModule, Options} from 'ngx-slider-v2'; import {animate, state, style, transition, trigger} from '@angular/animations'; -import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; +import {FormBuilder, FormControl, FormGroup, ReactiveFormsModule} from '@angular/forms'; import {NgbModal, NgbProgressbar} from '@ng-bootstrap/ng-bootstrap'; import {ToastrService} from 'ngx-toastr'; import {ShortcutsModalComponent} from 'src/app/reader-shared/_modals/shortcuts-modal/shortcuts-modal.component'; @@ -61,12 +61,12 @@ import {ChapterInfo} from '../../_models/chapter-info'; import {DoubleNoCoverRendererComponent} from '../double-renderer-no-cover/double-no-cover-renderer.component'; import {SwipeEvent} from 'src/app/ng-swipe/ag-swipe.core'; import {takeUntilDestroyed} from "@angular/core/rxjs-interop"; -import { FullscreenIconPipe } from '../../../_pipes/fullscreen-icon.pipe'; -import { ReaderModeIconPipe } from '../../../_pipes/reader-mode-icon.pipe'; -import { FittingIconPipe } from '../../../_pipes/fitting-icon.pipe'; -import { InfiniteScrollerComponent } from '../infinite-scroller/infinite-scroller.component'; -import { SwipeDirective } from '../../../ng-swipe/ng-swipe.directive'; -import { LoadingComponent } from '../../../shared/loading/loading.component'; +import {FullscreenIconPipe} from '../../../_pipes/fullscreen-icon.pipe'; +import {ReaderModeIconPipe} from '../../../_pipes/reader-mode-icon.pipe'; +import {FittingIconPipe} from '../../../_pipes/fitting-icon.pipe'; +import {InfiniteScrollerComponent} from '../infinite-scroller/infinite-scroller.component'; +import {SwipeDirective} from '../../../ng-swipe/ng-swipe.directive'; +import {LoadingComponent} from '../../../shared/loading/loading.component'; import {translate, TranslocoDirective} from "@ngneat/transloco"; import {shareReplay} from "rxjs/operators"; @@ -676,11 +676,6 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy { } break; case ReaderMode.Webtoon: - if (event.key === KEY_CODES.DOWN_ARROW) { - this.nextPage() - } else if (event.key === KEY_CODES.UP_ARROW) { - this.prevPage() - } break; } @@ -1220,14 +1215,14 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy { this.pagingDirectionSubject.next(PAGING_DIRECTION.BACKWARDS); - const pageAmount = Math.max(this.canvasRenderer.getPageAmount(PAGING_DIRECTION.BACKWARDS), + const pageAmount = this.readerMode === ReaderMode.Webtoon ? 1 : Math.max(this.canvasRenderer.getPageAmount(PAGING_DIRECTION.BACKWARDS), this.singleRenderer.getPageAmount(PAGING_DIRECTION.BACKWARDS), this.doubleRenderer.getPageAmount(PAGING_DIRECTION.BACKWARDS), this.doubleNoCoverRenderer.getPageAmount(PAGING_DIRECTION.BACKWARDS), this.doubleReverseRenderer.getPageAmount(PAGING_DIRECTION.BACKWARDS) ); - const notInSplit = this.canvasRenderer.shouldMovePrev(); + const notInSplit = this.readerMode === ReaderMode.Webtoon ? true : this.canvasRenderer.shouldMovePrev(); if ((this.pageNum - 1 < 0 && notInSplit)) { // Move to next volume/chapter automatically diff --git a/UI/Web/src/app/sidenav/_modals/library-settings-modal/library-settings-modal.component.html b/UI/Web/src/app/sidenav/_modals/library-settings-modal/library-settings-modal.component.html index f1442cf91..492e36aca 100644 --- a/UI/Web/src/app/sidenav/_modals/library-settings-modal/library-settings-modal.component.html +++ b/UI/Web/src/app/sidenav/_modals/library-settings-modal/library-settings-modal.component.html @@ -32,7 +32,8 @@
- + + {{t('type-tooltip')}} @@ -233,7 +234,7 @@