Download Refactor (#483)

# Added
- New: Cards when processing a download shows a spinner for the progress of the download

# Changed
- Changed: Downloads now always take the backend filename and are streamed in a more optimal manner, reducing the javascript processing that was needed previously.
==================================

* Started refactor of downloader to be more UX friendly and much faster.

* Completed refactor of Volume download to use a new mechanism. Downloads are streamed over and filename used exclusively from header. Backend has additional DB calls to get the Series Name information to make filenames nice.

* download service has been updated so all download functions use new event based observable. Duplicates code for downloading, but much cleaner and faster.

* Small code cleanup
This commit is contained in:
Joseph Milazzo 2021-08-11 16:01:44 -05:00 committed by GitHub
parent 855f452d14
commit 89b68bc301
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 439 additions and 92 deletions

View file

@ -3,7 +3,8 @@ import { Title } from '@angular/platform-browser';
import { ActivatedRoute, Router } from '@angular/router';
import { NgbModal, NgbRatingConfig } from '@ng-bootstrap/ng-bootstrap';
import { ToastrService } from 'ngx-toastr';
import { take } from 'rxjs/operators';
import { asyncScheduler } from 'rxjs';
import { finalize, take, takeWhile, throttleTime } from 'rxjs/operators';
import { ConfirmConfig } from '../shared/confirm-dialog/_models/confirm-config';
import { ConfirmService } from '../shared/confirm.service';
import { TagBadgeCursor } from '../shared/tag-badge/tag-badge.component';
@ -61,6 +62,8 @@ export class SeriesDetailComponent implements OnInit {
libraryType: LibraryType = LibraryType.Manga;
seriesMetadata: SeriesMetadata | null = null;
downloadInProgress: boolean = false;
/**
* If an action is currently being done, don't let the user kick off another action
*/
@ -142,16 +145,16 @@ export class SeriesDetailComponent implements OnInit {
});
break;
case(Action.ScanLibrary):
this.actionService.scanSeries(series, (series) => this.actionInProgress = false);
this.actionService.scanSeries(series, () => this.actionInProgress = false);
break;
case(Action.RefreshMetadata):
this.actionService.refreshMetdata(series, (series) => this.actionInProgress = false);
this.actionService.refreshMetdata(series, () => this.actionInProgress = false);
break;
case(Action.Delete):
this.deleteSeries(series);
break;
case(Action.Bookmarks):
this.actionService.openBookmarkModal(series, (series) => this.actionInProgress = false);
this.actionService.openBookmarkModal(series, () => this.actionInProgress = false);
break;
default:
break;
@ -169,9 +172,6 @@ export class SeriesDetailComponent implements OnInit {
case(Action.Info):
this.openViewInfo(volume);
break;
case(Action.Download):
this.downloadService.downloadVolume(volume, this.series.name);
break;
default:
break;
}
@ -188,9 +188,6 @@ export class SeriesDetailComponent implements OnInit {
case(Action.Info):
this.openViewInfo(chapter);
break;
case(Action.Download):
this.downloadService.downloadChapter(chapter, this.series.name);
break;
default:
break;
}
@ -285,7 +282,7 @@ export class SeriesDetailComponent implements OnInit {
}
const seriesId = this.series.id;
this.actionService.markVolumeAsRead(seriesId, vol, (volume) => {
this.actionService.markVolumeAsRead(seriesId, vol, () => {
this.setContinuePoint();
this.actionInProgress = false;
});
@ -297,7 +294,7 @@ export class SeriesDetailComponent implements OnInit {
}
const seriesId = this.series.id;
this.actionService.markVolumeAsUnread(seriesId, vol, (volume) => {
this.actionService.markVolumeAsUnread(seriesId, vol, () => {
this.setContinuePoint();
this.actionInProgress = false;
});
@ -309,7 +306,7 @@ export class SeriesDetailComponent implements OnInit {
}
const seriesId = this.series.id;
this.actionService.markChapterAsRead(seriesId, chapter, (chapter) => {
this.actionService.markChapterAsRead(seriesId, chapter, () => {
this.setContinuePoint();
this.actionInProgress = false;
});
@ -321,7 +318,7 @@ export class SeriesDetailComponent implements OnInit {
}
const seriesId = this.series.id;
this.actionService.markChapterAsUnread(seriesId, chapter, (chapter) => {
this.actionService.markChapterAsUnread(seriesId, chapter, () => {
this.setContinuePoint();
this.actionInProgress = false;
});
@ -433,6 +430,19 @@ export class SeriesDetailComponent implements OnInit {
}
downloadSeries() {
this.downloadService.downloadSeries(this.series);
this.downloadService.downloadSeriesSize(this.series.id).pipe(take(1)).subscribe(async (size) => {
const wantToDownload = await this.downloadService.confirmSize(size, 'series');
if (!wantToDownload) { return; }
this.downloadInProgress = true;
this.downloadService.downloadSeries(this.series).pipe(
throttleTime(100, asyncScheduler, { leading: true, trailing: true }),
takeWhile(val => {
return val.state != 'DONE';
}),
finalize(() => {
this.downloadInProgress = false;
}));
});
}
}