diff --git a/API.Tests/API.Tests.csproj b/API.Tests/API.Tests.csproj index 052226f56..44df6ff83 100644 --- a/API.Tests/API.Tests.csproj +++ b/API.Tests/API.Tests.csproj @@ -6,7 +6,7 @@ - + diff --git a/API/API.csproj b/API/API.csproj index c045d6981..2ab6842ce 100644 --- a/API/API.csproj +++ b/API/API.csproj @@ -53,9 +53,9 @@ - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -65,18 +65,18 @@ - + - + - - - - + + + + @@ -95,15 +95,15 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + diff --git a/API/Services/Plus/LicenseService.cs b/API/Services/Plus/LicenseService.cs index 0ed50c791..5a12f7c0b 100644 --- a/API/Services/Plus/LicenseService.cs +++ b/API/Services/Plus/LicenseService.cs @@ -205,14 +205,12 @@ public class LicenseService( InstallId = HashUtil.ServerToken() }) .ReceiveString(); + var result = bool.Parse(response); - if (!result) - { - var provider = cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.License); - await provider.FlushAsync(); - await provider.SetAsync(CacheKey, result, _licenseCacheTimeout); - } + var provider = cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.License); + await provider.FlushAsync(); + await provider.SetAsync(CacheKey, result, _licenseCacheTimeout); return result; } @@ -229,6 +227,7 @@ public class LicenseService( serverSetting.Value = string.Empty; unitOfWork.SettingsRepository.Update(serverSetting); await unitOfWork.CommitAsync(); + var provider = cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.License); await provider.RemoveAsync(CacheKey); } diff --git a/API/Services/TaskScheduler.cs b/API/Services/TaskScheduler.cs index c9ae918ec..53004b803 100644 --- a/API/Services/TaskScheduler.cs +++ b/API/Services/TaskScheduler.cs @@ -169,12 +169,12 @@ public class TaskScheduler : ITaskScheduler { return; } + RecurringJob.AddOrUpdate(CheckScrobblingTokensId, () => _scrobblingService.CheckExternalAccessTokens(), Cron.Daily, RecurringJobOptions); BackgroundJob.Enqueue(() => _scrobblingService.CheckExternalAccessTokens()); // We also kick off an immediate check on startup RecurringJob.AddOrUpdate(LicenseCheckId, () => _licenseService.HasActiveLicense(true), LicenseService.Cron, RecurringJobOptions); - BackgroundJob.Enqueue(() => _licenseService.HasActiveLicense(true)); // KavitaPlus Scrobbling (every 4 hours) RecurringJob.AddOrUpdate(ProcessScrobblingEventsId, () => _scrobblingService.ProcessUpdatesSinceLastSync(), diff --git a/API/Services/Tasks/ScannerService.cs b/API/Services/Tasks/ScannerService.cs index ddc319e70..ca71acd3f 100644 --- a/API/Services/Tasks/ScannerService.cs +++ b/API/Services/Tasks/ScannerService.cs @@ -254,7 +254,7 @@ public class ScannerService : IScannerService // Transform seen series into the parsedSeries (I think we can actually just have processedSeries be used instead TrackFoundSeriesAndFiles(parsedSeries, processedSeries); - _logger.LogInformation("ScanFiles for {Series} took {Time}", series.Name, scanElapsedTime); + _logger.LogInformation("ScanFiles for {Series} took {Time} milliseconds", series.Name, scanElapsedTime); // We now technically have all scannedSeries, we could invoke each Series to be scanned diff --git a/API/Services/TokenService.cs b/API/Services/TokenService.cs index 069b28403..c03c7724a 100644 --- a/API/Services/TokenService.cs +++ b/API/Services/TokenService.cs @@ -147,6 +147,6 @@ public class TokenService : ITokenService if (string.IsNullOrEmpty(token)) return true; var tokenHandler = new JwtSecurityTokenHandler(); var tokenContent = tokenHandler.ReadJwtToken(token); - return tokenContent.ValidTo <= DateTime.UtcNow; + return tokenContent.ValidTo >= DateTime.UtcNow; } } diff --git a/Kavita.Common/Kavita.Common.csproj b/Kavita.Common/Kavita.Common.csproj index c7dcd4438..970d94602 100644 --- a/Kavita.Common/Kavita.Common.csproj +++ b/Kavita.Common/Kavita.Common.csproj @@ -15,7 +15,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/UI/Web/src/app/_services/account.service.ts b/UI/Web/src/app/_services/account.service.ts index 00ed8f817..31d61353c 100644 --- a/UI/Web/src/app/_services/account.service.ts +++ b/UI/Web/src/app/_services/account.service.ts @@ -115,6 +115,7 @@ export class AccountService { } hasValidLicense(forceCheck: boolean = false) { + console.log('hasValidLicense being called: ', forceCheck); return this.httpClient.get(this.baseUrl + 'license/valid-license?forceCheck=' + forceCheck, TextResonse) .pipe( map(res => res === "true"), diff --git a/UI/Web/src/app/admin/license/license.component.ts b/UI/Web/src/app/admin/license/license.component.ts index 8155c4d0f..0e1c520a4 100644 --- a/UI/Web/src/app/admin/license/license.component.ts +++ b/UI/Web/src/app/admin/license/license.component.ts @@ -49,16 +49,21 @@ export class LicenseComponent implements OnInit { this.formGroup.addControl('licenseKey', new FormControl('', [Validators.required])); this.formGroup.addControl('email', new FormControl('', [Validators.required])); this.formGroup.addControl('discordId', new FormControl('', [Validators.pattern(/\d+/)])); + + this.isChecking = true; + this.cdRef.markForCheck(); + this.accountService.hasAnyLicense().subscribe(res => { this.hasLicense = res; this.cdRef.markForCheck(); - }); - this.isChecking = true; - this.cdRef.markForCheck(); - this.accountService.hasValidLicense().subscribe(res => { - this.hasValidLicense = res; - this.isChecking = false; - this.cdRef.markForCheck(); + + if (this.hasLicense) { + this.accountService.hasValidLicense().subscribe(res => { + this.hasValidLicense = res; + this.isChecking = false; + this.cdRef.markForCheck(); + }); + } }); } diff --git a/UI/Web/src/app/cards/_modals/bulk-add-to-collection/bulk-add-to-collection.component.html b/UI/Web/src/app/cards/_modals/bulk-add-to-collection/bulk-add-to-collection.component.html index 4778f47f2..fad45f7c3 100644 --- a/UI/Web/src/app/cards/_modals/bulk-add-to-collection/bulk-add-to-collection.component.html +++ b/UI/Web/src/app/cards/_modals/bulk-add-to-collection/bulk-add-to-collection.component.html @@ -47,7 +47,7 @@
- +
diff --git a/UI/Web/src/app/cards/_modals/bulk-add-to-collection/bulk-add-to-collection.component.ts b/UI/Web/src/app/cards/_modals/bulk-add-to-collection/bulk-add-to-collection.component.ts index c0fd745a6..c83fbdf3d 100644 --- a/UI/Web/src/app/cards/_modals/bulk-add-to-collection/bulk-add-to-collection.component.ts +++ b/UI/Web/src/app/cards/_modals/bulk-add-to-collection/bulk-add-to-collection.component.ts @@ -48,6 +48,7 @@ export class BulkAddToCollectionComponent implements OnInit, AfterViewInit { */ lists: Array = []; loading: boolean = false; + isCreating: boolean = false; listForm: FormGroup = new FormGroup({}); ngOnInit(): void { @@ -77,9 +78,13 @@ export class BulkAddToCollectionComponent implements OnInit, AfterViewInit { } create() { + if (this.isCreating) return; const tagName = this.listForm.value.title; + this.isCreating = true; + this.cdRef.markForCheck(); this.collectionService.addByMultiple(0, this.seriesIds, tagName).subscribe(() => { this.toastr.success(translate('toasts.series-added-to-collection', {collectionName: tagName})); + this.isCreating = false; this.modal.close(); }); } diff --git a/UI/Web/src/app/metadata-filter/_components/metadata-filter-row/metadata-filter-row.component.ts b/UI/Web/src/app/metadata-filter/_components/metadata-filter-row/metadata-filter-row.component.ts index c897a5bf2..3969bbd89 100644 --- a/UI/Web/src/app/metadata-filter/_components/metadata-filter-row/metadata-filter-row.component.ts +++ b/UI/Web/src/app/metadata-filter/_components/metadata-filter-row/metadata-filter-row.component.ts @@ -299,8 +299,8 @@ export class MetadataFilterRowComponent implements OnInit { case FilterField.Penciller: return this.getPersonOptions(PersonRole.Penciller); case FilterField.Publisher: return this.getPersonOptions(PersonRole.Publisher); case FilterField.Imprint: return this.getPersonOptions(PersonRole.Imprint); - case FilterField.Team: return this.getPersonOptions(PersonRole.Imprint); - case FilterField.Location: return this.getPersonOptions(PersonRole.Imprint); + case FilterField.Team: return this.getPersonOptions(PersonRole.Team); + case FilterField.Location: return this.getPersonOptions(PersonRole.Location); case FilterField.Translators: return this.getPersonOptions(PersonRole.Translator); case FilterField.Writers: return this.getPersonOptions(PersonRole.Writer); } diff --git a/UI/Web/src/app/statistics/_components/kavitaplus-metadata-breakdown-stats/kavitaplus-metadata-breakdown-stats.component.html b/UI/Web/src/app/statistics/_components/kavitaplus-metadata-breakdown-stats/kavitaplus-metadata-breakdown-stats.component.html index cf74d396b..678e20445 100644 --- a/UI/Web/src/app/statistics/_components/kavitaplus-metadata-breakdown-stats/kavitaplus-metadata-breakdown-stats.component.html +++ b/UI/Web/src/app/statistics/_components/kavitaplus-metadata-breakdown-stats/kavitaplus-metadata-breakdown-stats.component.html @@ -8,8 +8,8 @@
{{t('no-data')}}
} @else { - - + + @if (breakdown.seriesCompleted >= breakdown.totalSeries) {

{{t('complete') }} diff --git a/UI/Web/src/app/user-settings/manage-scrobbling-providers/manage-scrobbling-providers.component.ts b/UI/Web/src/app/user-settings/manage-scrobbling-providers/manage-scrobbling-providers.component.ts index ece423c71..a09e213ad 100644 --- a/UI/Web/src/app/user-settings/manage-scrobbling-providers/manage-scrobbling-providers.component.ts +++ b/UI/Web/src/app/user-settings/manage-scrobbling-providers/manage-scrobbling-providers.component.ts @@ -60,7 +60,7 @@ export class ManageScrobblingProvidersComponent implements OnInit { loaded: boolean = false; constructor() { - this.accountService.hasValidLicense().subscribe(res => { + this.accountService.hasValidLicense$.subscribe(res => { this.hasValidLicense = res; this.cdRef.markForCheck(); if (this.hasValidLicense) { diff --git a/openapi.json b/openapi.json index 509a147ba..7c8ee793a 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.14.13" + "version": "0.7.14.14" }, "servers": [ {