-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #265 from e-picsa/ft-download
feat(resources-tool): multiple file download and size display
- Loading branch information
Showing
18 changed files
with
325 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
...l/src/app/components/resource-download-multiple/resource-download-multiple.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
@switch (downloadStatus) { | ||
|
||
<!-- Ready --> | ||
@case ('ready') { | ||
<button mat-stroked-button color="primary" class="downloads-button" (click)="downloadAllResources()"> | ||
<mat-icon>download</mat-icon> | ||
{{ 'Download All' | translate }} | ||
{{ totalSize | sizeMB }} MB | ||
</button> | ||
} | ||
|
||
<!-- Pending --> | ||
@case ('pending') { | ||
<button mat-stroked-button (click)="cancelDownload()"> | ||
<div class="download-progress"> | ||
<mat-progress-spinner | ||
color="primary" | ||
[mode]="downloadProgress > 0 ? 'determinate' : 'indeterminate'" | ||
[value]="downloadProgress" | ||
[diameter]="16" | ||
> | ||
</mat-progress-spinner> | ||
<span>{{ downloadCount }} / {{ totalCount }}</span> | ||
|
||
<mat-icon>close</mat-icon> | ||
</div> | ||
</button> | ||
} | ||
|
||
<!-- Complete --> | ||
@case ('complete') { | ||
<button mat-stroked-button disabled color="primary" class="downloads-button"> | ||
<mat-icon>download_done</mat-icon> | ||
{{ 'Downloaded' | translate }} | ||
</button> | ||
} } |
10 changes: 10 additions & 0 deletions
10
...l/src/app/components/resource-download-multiple/resource-download-multiple.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
.downloads-button { | ||
display: flex; | ||
align-items: center; | ||
margin-left: auto; | ||
} | ||
.download-progress { | ||
display: flex; | ||
align-items: center; | ||
gap: 16px; | ||
} |
21 changes: 21 additions & 0 deletions
21
...rc/app/components/resource-download-multiple/resource-download-multiple.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
import { ResourceDownloadMultipleComponent } from './resource-download-multiple.component'; | ||
|
||
describe('ResourceDownloadMultipleComponent', () => { | ||
let component: ResourceDownloadMultipleComponent; | ||
let fixture: ComponentFixture<ResourceDownloadMultipleComponent>; | ||
|
||
beforeEach(async () => { | ||
await TestBed.configureTestingModule({ | ||
imports: [ResourceDownloadMultipleComponent], | ||
}).compileComponents(); | ||
|
||
fixture = TestBed.createComponent(ResourceDownloadMultipleComponent); | ||
component = fixture.componentInstance; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
}); |
115 changes: 115 additions & 0 deletions
115
...ool/src/app/components/resource-download-multiple/resource-download-multiple.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import { Component, Input, OnDestroy } from '@angular/core'; | ||
import { RxDocument } from 'rxdb'; | ||
import { lastValueFrom, Subject, Subscription } from 'rxjs'; | ||
|
||
import { IResourceFile } from '../../schemas'; | ||
import { IDownloadStatus, ResourcesToolService } from '../../services/resources-tool.service'; | ||
|
||
@Component({ | ||
selector: 'resource-download-multiple', | ||
templateUrl: './resource-download-multiple.component.html', | ||
styleUrl: './resource-download-multiple.component.scss', | ||
}) | ||
export class ResourceDownloadMultipleComponent implements OnDestroy { | ||
private _resources: IResourceFile[]; | ||
private pendingDocs: RxDocument<IResourceFile>[] = []; | ||
|
||
downloadStatus: IDownloadStatus; | ||
downloadProgress = 0; | ||
downloadCount = 0; | ||
totalSize = 0; | ||
totalCount = 0; | ||
|
||
private componentDestroyed$ = new Subject(); | ||
private downloadSubscription?: Subscription; | ||
|
||
@Input() hideOnComplete = false; | ||
|
||
@Input() set resources(resources: IResourceFile[]) { | ||
this._resources = resources; | ||
this.totalCount = resources.length; | ||
this.getPendingDownloads(); | ||
} | ||
|
||
constructor(private service: ResourcesToolService) {} | ||
|
||
ngOnDestroy(): void { | ||
this.componentDestroyed$.next(true); | ||
this.componentDestroyed$.complete(); | ||
} | ||
|
||
/** | ||
* Iterate over list of input resources, checking which already have attachments downloaded | ||
* and generating summary of pending downloads with total size | ||
*/ | ||
public async getPendingDownloads() { | ||
let totalSize = 0; | ||
let totalCount = 0; | ||
let downloadCount = 0; | ||
const pendingDocs: RxDocument<IResourceFile>[] = []; | ||
for (const resource of this._resources) { | ||
const dbDoc = await this.service.dbFiles.findOne(resource.id).exec(); | ||
if (dbDoc) { | ||
totalCount++; | ||
// check | ||
const attachment = dbDoc.getAttachment(dbDoc.filename); | ||
if (attachment) { | ||
downloadCount++; | ||
} else { | ||
pendingDocs.push(dbDoc); | ||
totalSize += dbDoc.size_kb; | ||
} | ||
} | ||
} | ||
this.totalCount = totalCount; | ||
this.totalSize = totalSize; | ||
this.downloadCount = downloadCount; | ||
this.pendingDocs = pendingDocs; | ||
this.downloadStatus = totalSize > 0 ? 'ready' : 'complete'; | ||
console.log('pending', { totalCount, totalSize, downloadCount, pendingDocs }); | ||
} | ||
|
||
public async downloadAllResources() { | ||
// recalc sizes to ensure pending docs correct (in case of single file download) | ||
await this.getPendingDownloads(); | ||
|
||
// handle all downloads | ||
this.downloadStatus = 'pending'; | ||
|
||
for (const doc of this.pendingDocs) { | ||
await this.downloadNextResource(doc); | ||
} | ||
// refresh UI | ||
await this.getPendingDownloads(); | ||
this.downloadStatus = 'complete'; | ||
return; | ||
} | ||
|
||
/** | ||
* Trigger next download | ||
* Updates download progress and waits until download complete | ||
*/ | ||
private async downloadNextResource(doc: RxDocument<IResourceFile>) { | ||
// Only download if pending status given (will be set to 'ready' if cancelled) | ||
if (this.downloadStatus === 'pending') { | ||
const { download$, progress$, status$ } = this.service.triggerResourceDownload(doc); | ||
this.downloadSubscription = download$; | ||
progress$.subscribe((progress) => (this.downloadProgress = progress)); | ||
const endStatus = await lastValueFrom(status$); | ||
if (endStatus === 'complete') { | ||
this.downloadCount++; | ||
} | ||
} | ||
} | ||
public async cancelDownload() { | ||
// cancel active download | ||
if (this.downloadSubscription) { | ||
this.downloadSubscription.unsubscribe(); | ||
this.downloadSubscription = undefined; | ||
} | ||
// change the download status which will prevent nextResourceDownload trigger | ||
this.downloadStatus = 'ready'; | ||
this.downloadProgress = 0; | ||
await this.getPendingDownloads(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.