diff --git a/Kavita.Server/Controllers/PersonController.cs b/Kavita.Server/Controllers/PersonController.cs
index 4209be842..88245491a 100644
--- a/Kavita.Server/Controllers/PersonController.cs
+++ b/Kavita.Server/Controllers/PersonController.cs
@@ -221,19 +221,6 @@ public class PersonController(
return Ok(await unitOfWork.PersonRepository.GetSeriesKnownFor(personId, UserId));
}
- ///
- /// Return external Series the person is an artist/author of. Requires Admin due to age rating restrictions.
- ///
- ///
- ///
- [PersonAccess]
- [KPlus]
- [Authorize(PolicyGroups.AdminPolicy)]
- [HttpGet("external-series")]
- public async Task>> GetExternalSeries(int personId)
- {
- return Ok(await unitOfWork.ExternalSeriesMetadataRepository.GetExternalSeriesForPerson(personId, UserId));
- }
///
/// Returns all individual chapters by role. Limited to 20 results.
diff --git a/UI/Web/src/app/_services/account.service.ts b/UI/Web/src/app/_services/account.service.ts
index 49bcaded1..e4a7358da 100644
--- a/UI/Web/src/app/_services/account.service.ts
+++ b/UI/Web/src/app/_services/account.service.ts
@@ -272,15 +272,14 @@ export class AccountService {
this.stopRefreshTokenTimer();
- if (user) {
- if (!isSameUser) {
- this.messageHub.stopHubConnection();
- this.messageHub.createHubConnection(user);
- this.licenseService.checkForValidLicense().subscribe();
- }
- if (user.token) {
- this.startRefreshTokenTimer();
- }
+ if (user && !isSameUser) {
+ this.messageHub.stopHubConnection();
+ this.messageHub.createHubConnection(user);
+ this.licenseService.checkForValidLicense().subscribe();
+ }
+
+ if (user?.token) {
+ this.startRefreshTokenTimer();
}
}
@@ -447,7 +446,10 @@ export class AccountService {
refreshAccount(): Observable {
if (!this._currentUser()) return of(null);
return this.httpClient.get(this.baseUrl + 'account/refresh-account').pipe(map((user: User) => {
- if (user) this.setCurrentUser({ ...user });
+ if (user) {
+ this.setCurrentUser({...user});
+ this.licenseService.checkForValidLicense().subscribe();
+ }
return user;
}));
}
diff --git a/UI/Web/src/app/dashboard/_components/dashboard.component.ts b/UI/Web/src/app/dashboard/_components/dashboard.component.ts
index 05e96a2f5..d0c58cfc9 100644
--- a/UI/Web/src/app/dashboard/_components/dashboard.component.ts
+++ b/UI/Web/src/app/dashboard/_components/dashboard.component.ts
@@ -134,7 +134,7 @@ export class DashboardComponent {
}
});
- this.licenseService.checkForValidLicense()
+ this.licenseService.hasAnyLicense()
.pipe(
filter((hasLic: boolean) => hasLic),
switchMap(_ => this.scrobblingService.hasTokenExpired(ScrobbleProvider.AniList)),
diff --git a/UI/Web/src/app/shared/_services/download.service.ts b/UI/Web/src/app/shared/_services/download.service.ts
index 7cf480235..0457f2e34 100644
--- a/UI/Web/src/app/shared/_services/download.service.ts
+++ b/UI/Web/src/app/shared/_services/download.service.ts
@@ -249,7 +249,7 @@ export class DownloadService {
this.downloadSeries(entity as Series);
break;
case 'volume':
- this.enqueueSingle(entity as Volume, 'volume', '', libraryId, seriesId);
+ this.downloadVolume(entity as Volume, libraryId, seriesId);
break;
case 'chapter':
this.enqueueSingle(entity as Chapter, 'chapter', '', libraryId, seriesId);
@@ -489,6 +489,41 @@ export class DownloadService {
return this.httpClient.post>(this.baseUrl + 'download/bulk-series-size', seriesIds);
}
+ private downloadVolumeSize(volumeId: number) {
+ return this.httpClient.get(this.baseUrl + 'download/volume-size?volumeId=' + volumeId);
+ }
+
+ private downloadChapterSize(chapterId: number) {
+ return this.httpClient.get(this.baseUrl + 'download/chapter-size?chapterId=' + chapterId);
+ }
+
+ private downloadVolume(volume: Volume, libraryId: number, seriesId: number) {
+ this.debugLog('downloadVolume()', volume.minNumber);
+
+ // Volumes can be either a bunch of chapters or just 1
+ if (volume.chapters.length === 1) {
+ this.enqueueSingle(volume, 'volume', '', libraryId, seriesId);
+ return;
+ }
+ this.debugLog(`downloadVolume() decomposed into ${volume.chapters.length} items`);
+
+ const items = volume.chapters.map(c => ({ entity: c as Chapter, entityType: 'chapter' as const }));
+
+ const userPrefs = this.accountService.userPreferences();
+ if (userPrefs?.promptForDownloadSize && items.length > 0) {
+ // Single size call for the whole series, single confirm dialog
+ this.downloadVolumeSize(volume.id).pipe(
+ switchMap(async size => this.confirmSize(size, 'volume')),
+ filter(confirmed => confirmed),
+ takeUntilDestroyed(this.destroyRef)
+ ).subscribe(() => this.enqueueItems(items, '', libraryId, seriesId));
+ } else {
+ this.enqueueItems(items, '', libraryId, seriesId);
+ }
+
+
+ }
+
private downloadSeries(series: Series) {
this.debugLog('downloadSeries()', series.name);
this.seriesService.getSeriesDetail(series.id).pipe(