From 176748d0267ade7b5358605b89fbb23ab84896c2 Mon Sep 17 00:00:00 2001 From: James Chien Date: Wed, 13 Jan 2021 12:39:59 +0800 Subject: [PATCH 01/19] Add diaBackendAssetId field to Proof class This is a quick implementation but might be suboptimal depends on how we want to design the data abstraction. Signed-off-by: James Chien --- src/app/shared/services/repositories/proof/proof.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/shared/services/repositories/proof/proof.ts b/src/app/shared/services/repositories/proof/proof.ts index 8bc4857ef..250b791e4 100644 --- a/src/app/shared/services/repositories/proof/proof.ts +++ b/src/app/shared/services/repositories/proof/proof.ts @@ -7,6 +7,7 @@ import { ImageStore } from '../../image-store/image-store.service'; export class Proof { willCollectTruth = false; + diaBackendAssetId = ''; get timestamp() { return this.truth.timestamp; @@ -122,6 +123,7 @@ export class Proof { truth: this.truth, signatures: this.signatures, willCollectTruth: this.willCollectTruth, + diaBackendAssetId: this.diaBackendAssetId, }; } @@ -164,6 +166,7 @@ export class Proof { ); proof.setIndexedAssets(indexedProofView.indexedAssets); proof.willCollectTruth = indexedProofView.willCollectTruth ?? false; + proof.diaBackendAssetId = indexedProofView.diaBackendAssetId ?? ''; return proof; } @@ -281,4 +284,5 @@ export interface IndexedProofView extends Tuple { readonly truth: Truth; readonly signatures: Signatures; readonly willCollectTruth?: boolean; + readonly diaBackendAssetId?: string; } From 0347b47f30439be63e442561f780876f408160ed Mon Sep 17 00:00:00 2001 From: James Chien Date: Wed, 13 Jan 2021 12:42:10 +0800 Subject: [PATCH 02/19] Remove unused add method and expose createAsset$ to public. DiaAssetRepository no longer serves as a local repository, so add instead of createAsset$ is removed to prevent confusion since it does not really store any data now. The notification functionality is removed by request. Signed-off-by: James Chien --- .../dia-backend-asset-repository.service.ts | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/app/shared/services/dia-backend/asset/dia-backend-asset-repository.service.ts b/src/app/shared/services/dia-backend/asset/dia-backend-asset-repository.service.ts index 1f1a7409c..a4a71ed5c 100644 --- a/src/app/shared/services/dia-backend/asset/dia-backend-asset-repository.service.ts +++ b/src/app/shared/services/dia-backend/asset/dia-backend-asset-repository.service.ts @@ -6,6 +6,7 @@ import { concatMap, concatMapTo, distinctUntilChanged, + map, pluck, single, tap, @@ -15,6 +16,7 @@ import { toExtension } from '../../../../utils/mime-type'; import { Tuple } from '../../database/table/table'; import { NotificationService } from '../../notification/notification.service'; import { + getOldProof, getOldSignatures, getSortedProofInformation, OldSignature, @@ -55,6 +57,18 @@ export class DiaBackendAssetRepository { ); } + fetchByProof$(proof: Proof) { + return defer(() => this.authService.getAuthHeaders()).pipe( + concatMap(headers => + this.httpClient.get(`${BASE_URL}/api/v2/assets/`, { + headers, + params: { proof_hash: getOldProof(proof).hash }, + }) + ), + map(listAssetResponse => listAssetResponse.results[0]) + ); + } + private fetchAll$() { return defer(async () => this._isFetching$.next(true)).pipe( concatMapTo(defer(() => this.authService.getAuthHeaders())), @@ -68,15 +82,7 @@ export class DiaBackendAssetRepository { ); } - async add(proof: Proof) { - return this.notificationService.notifyOnGoing( - this.createAsset$(proof), - this.translocoService.translate('registeringProof'), - this.translocoService.translate('message.registeringProof') - ); - } - - private createAsset$(proof: Proof) { + createAsset$(proof: Proof) { return forkJoin([ defer(() => this.authService.getAuthHeaders()), defer(() => buildFormDataToCreateAsset(proof)), From ce68f42c7c17cff01e63b60e42d3137c36811142 Mon Sep 17 00:00:00 2001 From: James Chien Date: Wed, 13 Jan 2021 12:44:44 +0800 Subject: [PATCH 03/19] Add upload service. Signed-off-by: James Chien --- .../services/upload/upload.service.spec.ts | 18 +++ .../shared/services/upload/upload.service.ts | 141 ++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 src/app/shared/services/upload/upload.service.spec.ts create mode 100644 src/app/shared/services/upload/upload.service.ts diff --git a/src/app/shared/services/upload/upload.service.spec.ts b/src/app/shared/services/upload/upload.service.spec.ts new file mode 100644 index 000000000..66fff3140 --- /dev/null +++ b/src/app/shared/services/upload/upload.service.spec.ts @@ -0,0 +1,18 @@ +import { TestBed } from '@angular/core/testing'; +import { SharedTestingModule } from '../../shared-testing.module'; +import { UploadService } from './upload.service'; + +describe('UploadService', () => { + let service: UploadService; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [SharedTestingModule], + }); + service = TestBed.inject(UploadService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/shared/services/upload/upload.service.ts b/src/app/shared/services/upload/upload.service.ts new file mode 100644 index 000000000..ad534575a --- /dev/null +++ b/src/app/shared/services/upload/upload.service.ts @@ -0,0 +1,141 @@ +import { HttpErrorResponse } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { + BehaviorSubject, + combineLatest, + EMPTY, + from, + of, + Subject, + throwError, + timer, +} from 'rxjs'; +import { + catchError, + concatMap, + debounceTime, + distinctUntilChanged, + filter, + map, + mergeMap, + retryWhen, + switchMap, + tap, +} from 'rxjs/operators'; +import { DiaBackendAssetRepository } from '../dia-backend/asset/dia-backend-asset-repository.service'; +import { getOldProof } from '../repositories/proof/old-proof-adapter'; +import { Proof } from '../repositories/proof/proof'; +import { ProofRepository } from '../repositories/proof/proof-repository.service'; + +@Injectable({ + providedIn: 'root', +}) +export class UploadService { + private readonly _isPaused$ = new BehaviorSubject(false); + private readonly _isPausedByFailure$ = new BehaviorSubject(false); + private readonly _taskQueue$ = new Subject(); + private readonly _currentUploadingCount$ = new BehaviorSubject(0); + readonly isPaused$ = this._isPaused$ + .asObservable() + .pipe(distinctUntilChanged()); + readonly isPausedByFailure$ = this._isPausedByFailure$ + .asObservable() + .pipe(distinctUntilChanged()); + readonly currentUploadingCount$ = this._currentUploadingCount$ + .asObservable() + .pipe(distinctUntilChanged()); + + constructor( + private readonly diaBackendAssetRepository: DiaBackendAssetRepository, + private readonly proofRepository: ProofRepository + ) {} + + initialize$() { + return combineLatest([ + this.uploadTaskDispatcher$(), + this.uploadTaskWorker$(), + ]); + } + + pause() { + this._isPaused$.next(true); + } + + resume() { + this._isPaused$.next(false); + } + + private uploadTaskDispatcher$() { + const taskDebounceTime = 50; + return combineLatest([ + this.proofRepository.getAll$().pipe(debounceTime(taskDebounceTime)), + this.isPaused$.pipe(filter(isPaused => !isPaused)), + ]).pipe( + map(([proofs, _]) => + proofs.filter( + proof => !proof.diaBackendAssetId && !proof.willCollectTruth + ) + ), + tap(proofs => this._currentUploadingCount$.next(proofs.length)), + tap(proofs => this.updateTaskQueue(proofs)) + ); + } + + private uploadTaskWorker$() { + const cleanTasks$ = EMPTY.pipe(tap(() => this.updateTaskQueue([]))); + const runTasks$ = this._taskQueue$.pipe( + filter(proofs => proofs.length > 0), + concatMap(proofs => + from(proofs).pipe( + concatMap(proof => this.uploadProof$(proof)), + concatMap(proof => + this.proofRepository.update( + proof, + (x, y) => getOldProof(x).hash === getOldProof(y).hash + ) + ) + ) + ) + ); + return this.isPaused$.pipe( + switchMap(isPaused => (isPaused ? cleanTasks$ : runTasks$)) + ); + } + + private updateTaskQueue(proofs: Proof[]) { + this._taskQueue$.next(proofs); + } + + private uploadProof$(proof: Proof) { + const retryDelay = 500; + const retryLimit = 3; + return this.diaBackendAssetRepository.createAsset$(proof).pipe( + catchError((err: HttpErrorResponse) => { + if (err.error?.error.type === 'duplicate_asset_not_allowed') { + return this.diaBackendAssetRepository.fetchByProof$(proof); + } + return throwError(err); + }), + map(diaBackendAsset => { + proof.diaBackendAssetId = diaBackendAsset.id; + return proof; + }), + retryWhen(err$ => + err$.pipe( + mergeMap((error, i) => { + const retryAttempt = i + 1; + if (retryAttempt > retryLimit) { + return throwError(error); + } + return timer(retryDelay); + }) + ) + ), + catchError(_ => { + this._isPausedByFailure$.next(true); + this._isPaused$.next(true); + return of(proof); + }) + ); + } +} From 8ab8c0ba0e7170cbc2f86beb489c6d361546f23e Mon Sep 17 00:00:00 2001 From: James Chien Date: Wed, 13 Jan 2021 12:45:11 +0800 Subject: [PATCH 04/19] Add upload-bar component. Signed-off-by: James Chien --- .../upload-bar/upload-bar.component.html | 44 +++++++++++++++++++ .../upload-bar/upload-bar.component.scss | 28 ++++++++++++ .../upload-bar/upload-bar.component.spec.ts | 23 ++++++++++ .../upload-bar/upload-bar.component.ts | 23 ++++++++++ .../upload-bar/upload-bar.module.ts | 10 +++++ 5 files changed, 128 insertions(+) create mode 100644 src/app/features/home/capture-tab/upload-bar/upload-bar.component.html create mode 100644 src/app/features/home/capture-tab/upload-bar/upload-bar.component.scss create mode 100644 src/app/features/home/capture-tab/upload-bar/upload-bar.component.spec.ts create mode 100644 src/app/features/home/capture-tab/upload-bar/upload-bar.component.ts create mode 100644 src/app/features/home/capture-tab/upload-bar/upload-bar.module.ts diff --git a/src/app/features/home/capture-tab/upload-bar/upload-bar.component.html b/src/app/features/home/capture-tab/upload-bar/upload-bar.component.html new file mode 100644 index 000000000..3fe0efe7a --- /dev/null +++ b/src/app/features/home/capture-tab/upload-bar/upload-bar.component.html @@ -0,0 +1,44 @@ + + + + Registering {{ uploadState.currentUploadingCount }} photos on + blockchain. + Registering {{ uploadState.currentUploadingCount }} photos on + blockchain paused. + Server connection lost. Registering paused. + + + + pause + publish + + + All photos registered on blockchain successfully + + + diff --git a/src/app/features/home/capture-tab/upload-bar/upload-bar.component.scss b/src/app/features/home/capture-tab/upload-bar/upload-bar.component.scss new file mode 100644 index 000000000..f71c101d6 --- /dev/null +++ b/src/app/features/home/capture-tab/upload-bar/upload-bar.component.scss @@ -0,0 +1,28 @@ +.thin-upload-bar { + min-height: 32px; + height: 32px; + justify-content: stretch; + transition: all 1s; + .upload-text { + flex-grow: 0; + font-size: 0.7em; + margin-left: 10px; + margin-right: 10px; + color: darkgray; + } + .complete-text { + flex-grow: 1; + font-size: 0.7em; + margin-left: 10px; + margin-right: 10px; + color: darkgray; + } + mat-icon { + margin-left: 10px; + margin-right: 10px; + } +} + +.spacer { + flex: 1 1 auto; +} diff --git a/src/app/features/home/capture-tab/upload-bar/upload-bar.component.spec.ts b/src/app/features/home/capture-tab/upload-bar/upload-bar.component.spec.ts new file mode 100644 index 000000000..6d8b6373c --- /dev/null +++ b/src/app/features/home/capture-tab/upload-bar/upload-bar.component.spec.ts @@ -0,0 +1,23 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { SharedTestingModule } from '../../../../shared/shared-testing.module'; +import { UploadBarComponent } from './upload-bar.component'; + +describe('UploadBarComponent', () => { + let component: UploadBarComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [UploadBarComponent], + imports: [SharedTestingModule], + }).compileComponents(); + + fixture = TestBed.createComponent(UploadBarComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + })); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/features/home/capture-tab/upload-bar/upload-bar.component.ts b/src/app/features/home/capture-tab/upload-bar/upload-bar.component.ts new file mode 100644 index 000000000..d83cdd685 --- /dev/null +++ b/src/app/features/home/capture-tab/upload-bar/upload-bar.component.ts @@ -0,0 +1,23 @@ +import { Component } from '@angular/core'; +import { UploadService } from '../../../../shared/services/upload/upload.service'; + +@Component({ + selector: 'app-upload-bar', + templateUrl: './upload-bar.component.html', + styleUrls: ['./upload-bar.component.scss'], +}) +export class UploadBarComponent { + currentUploadingCount$ = this.uploadService.currentUploadingCount$; + isPaused$ = this.uploadService.isPaused$; + isPausedByFailure$ = this.uploadService.isPausedByFailure$; + + constructor(private readonly uploadService: UploadService) {} + + pause() { + this.uploadService.pause(); + } + + resume() { + this.uploadService.resume(); + } +} diff --git a/src/app/features/home/capture-tab/upload-bar/upload-bar.module.ts b/src/app/features/home/capture-tab/upload-bar/upload-bar.module.ts new file mode 100644 index 000000000..27025b538 --- /dev/null +++ b/src/app/features/home/capture-tab/upload-bar/upload-bar.module.ts @@ -0,0 +1,10 @@ +import { NgModule } from '@angular/core'; +import { SharedModule } from '../../../../shared/shared.module'; +import { UploadBarComponent } from './upload-bar.component'; + +@NgModule({ + declarations: [UploadBarComponent], + imports: [SharedModule], + exports: [UploadBarComponent], +}) +export class UploadBarModule {} From 017019b5ed647dd2c2ad7d2843d0ab522e05863d Mon Sep 17 00:00:00 2001 From: James Chien Date: Wed, 13 Jan 2021 12:45:57 +0800 Subject: [PATCH 05/19] Display diaBackendAssetId on capture-details page. Signed-off-by: James Chien --- .../capture-details/capture-details.page.html | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/app/features/home/capture-tab/capture-details/capture-details.page.html b/src/app/features/home/capture-tab/capture-details/capture-details.page.html index c7ab8edc1..dcf202762 100644 --- a/src/app/features/home/capture-tab/capture-details/capture-details.page.html +++ b/src/app/features/home/capture-tab/capture-details/capture-details.page.html @@ -24,16 +24,23 @@ {{ location$ | async }} - - access_time -
- {{ (proof$ | async)?.truth.timestamp | date: 'long' }} -
-
- - -
{{ '' }}
-
+ + + access_time +
+ {{ proof?.truth.timestamp | date: 'long' }} +
+
+ + +
+ {{ proof.diaBackendAssetId }} +
+
+ {{ 'Not Registered' }} +
+
+
- + From 4c4e7e9066d53abc066af9374723708c75a269b9 Mon Sep 17 00:00:00 2001 From: James Chien Date: Wed, 13 Jan 2021 12:51:28 +0800 Subject: [PATCH 08/19] Fix styelint Signed-off-by: James Chien --- .../home/capture-tab/upload-bar/upload-bar.component.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/app/features/home/capture-tab/upload-bar/upload-bar.component.scss b/src/app/features/home/capture-tab/upload-bar/upload-bar.component.scss index f71c101d6..51297ba5a 100644 --- a/src/app/features/home/capture-tab/upload-bar/upload-bar.component.scss +++ b/src/app/features/home/capture-tab/upload-bar/upload-bar.component.scss @@ -3,6 +3,7 @@ height: 32px; justify-content: stretch; transition: all 1s; + .upload-text { flex-grow: 0; font-size: 0.7em; @@ -10,6 +11,7 @@ margin-right: 10px; color: darkgray; } + .complete-text { flex-grow: 1; font-size: 0.7em; @@ -17,6 +19,7 @@ margin-right: 10px; color: darkgray; } + mat-icon { margin-left: 10px; margin-right: 10px; From f5feeb1c4c880ffc8d8630976be5ebdb9ac44ee8 Mon Sep 17 00:00:00 2001 From: James Chien Date: Wed, 13 Jan 2021 13:26:13 +0800 Subject: [PATCH 09/19] Fix resume does not trigger task queue update if task queue not changed Signed-off-by: James Chien --- .../shared/services/upload/upload.service.ts | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/app/shared/services/upload/upload.service.ts b/src/app/shared/services/upload/upload.service.ts index ad534575a..ff7165ba1 100644 --- a/src/app/shared/services/upload/upload.service.ts +++ b/src/app/shared/services/upload/upload.service.ts @@ -44,6 +44,10 @@ export class UploadService { readonly currentUploadingCount$ = this._currentUploadingCount$ .asObservable() .pipe(distinctUntilChanged()); + private readonly taskQueue$ = combineLatest([ + this._taskQueue$.asObservable().pipe(distinctUntilChanged()), + this.isPaused$, + ]).pipe(map(([t, _]) => t)); constructor( private readonly diaBackendAssetRepository: DiaBackendAssetRepository, @@ -69,21 +73,20 @@ export class UploadService { const taskDebounceTime = 50; return combineLatest([ this.proofRepository.getAll$().pipe(debounceTime(taskDebounceTime)), - this.isPaused$.pipe(filter(isPaused => !isPaused)), + this.isPaused$, ]).pipe( - map(([proofs, _]) => - proofs.filter( + tap(([proofs, isPaused]) => { + const tasks = proofs.filter( proof => !proof.diaBackendAssetId && !proof.willCollectTruth - ) - ), - tap(proofs => this._currentUploadingCount$.next(proofs.length)), - tap(proofs => this.updateTaskQueue(proofs)) + ); + this._currentUploadingCount$.next(tasks.length); + this.updateTaskQueue(isPaused ? [] : tasks); + }) ); } private uploadTaskWorker$() { - const cleanTasks$ = EMPTY.pipe(tap(() => this.updateTaskQueue([]))); - const runTasks$ = this._taskQueue$.pipe( + const runTasks$ = this.taskQueue$.pipe( filter(proofs => proofs.length > 0), concatMap(proofs => from(proofs).pipe( @@ -98,7 +101,7 @@ export class UploadService { ) ); return this.isPaused$.pipe( - switchMap(isPaused => (isPaused ? cleanTasks$ : runTasks$)) + switchMap(isPaused => (isPaused ? EMPTY : runTasks$)) ); } From 321570ba0699707bf09a766c317867885d50dd1d Mon Sep 17 00:00:00 2001 From: James Chien Date: Wed, 13 Jan 2021 13:35:05 +0800 Subject: [PATCH 10/19] Use BehaviorSubject for taskqueue Signed-off-by: James Chien --- src/app/shared/services/upload/upload.service.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/app/shared/services/upload/upload.service.ts b/src/app/shared/services/upload/upload.service.ts index ff7165ba1..e3196d5ee 100644 --- a/src/app/shared/services/upload/upload.service.ts +++ b/src/app/shared/services/upload/upload.service.ts @@ -6,7 +6,6 @@ import { EMPTY, from, of, - Subject, throwError, timer, } from 'rxjs'; @@ -33,7 +32,7 @@ import { ProofRepository } from '../repositories/proof/proof-repository.service' export class UploadService { private readonly _isPaused$ = new BehaviorSubject(false); private readonly _isPausedByFailure$ = new BehaviorSubject(false); - private readonly _taskQueue$ = new Subject(); + private readonly _taskQueue$ = new BehaviorSubject([]); private readonly _currentUploadingCount$ = new BehaviorSubject(0); readonly isPaused$ = this._isPaused$ .asObservable() From 0a3a14897d62c9981874892a98f6d9028f559f7b Mon Sep 17 00:00:00 2001 From: James Chien Date: Wed, 13 Jan 2021 15:43:36 +0800 Subject: [PATCH 11/19] Use undefined as default value for diaBackendAssetId Signed-off-by: James Chien --- src/app/shared/services/repositories/proof/proof.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/shared/services/repositories/proof/proof.ts b/src/app/shared/services/repositories/proof/proof.ts index 250b791e4..681727abd 100644 --- a/src/app/shared/services/repositories/proof/proof.ts +++ b/src/app/shared/services/repositories/proof/proof.ts @@ -7,7 +7,7 @@ import { ImageStore } from '../../image-store/image-store.service'; export class Proof { willCollectTruth = false; - diaBackendAssetId = ''; + diaBackendAssetId: string | undefined = undefined; get timestamp() { return this.truth.timestamp; From de5a7cac3dba49f1de2d6904273d85a8fd27c6ea Mon Sep 17 00:00:00 2001 From: James Chien Date: Wed, 13 Jan 2021 15:54:40 +0800 Subject: [PATCH 12/19] Add i18n Signed-off-by: James Chien --- .../capture-details/capture-details.page.html | 2 +- .../upload-bar/upload-bar.component.html | 22 +++++++++++-------- src/assets/i18n/en-us.json | 7 +++++- src/assets/i18n/zh-tw.json | 7 +++++- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/app/features/home/capture-tab/capture-details/capture-details.page.html b/src/app/features/home/capture-tab/capture-details/capture-details.page.html index dcf202762..3d56442ee 100644 --- a/src/app/features/home/capture-tab/capture-details/capture-details.page.html +++ b/src/app/features/home/capture-tab/capture-details/capture-details.page.html @@ -37,7 +37,7 @@ {{ proof.diaBackendAssetId }}
- {{ 'Not Registered' }} + {{ t('notRegistered') }}
diff --git a/src/app/features/home/capture-tab/upload-bar/upload-bar.component.html b/src/app/features/home/capture-tab/upload-bar/upload-bar.component.html index 3fe0efe7a..1390b5e13 100644 --- a/src/app/features/home/capture-tab/upload-bar/upload-bar.component.html +++ b/src/app/features/home/capture-tab/upload-bar/upload-bar.component.html @@ -5,22 +5,26 @@ isPausedByFailure: isPausedByFailure$ | async } as uploadState" > - + - Registering {{ uploadState.currentUploadingCount }} photos on - blockchain. + {{ + t('message.registeringPhotos', { + photos: uploadState.currentUploadingCount + }) + }} Registering {{ uploadState.currentUploadingCount }} photos on - blockchain paused.{{ + t('message.registeringPhotosPaused', { + photos: uploadState.currentUploadingCount + }) + }} Server connection lost. Registering paused.{{ t('message.serverConnectionLost') }} All photos registered on blockchain successfully{{ t('message.allPhotosRegistered') }} diff --git a/src/assets/i18n/en-us.json b/src/assets/i18n/en-us.json index 5a66d2681..fdc592ee9 100644 --- a/src/assets/i18n/en-us.json +++ b/src/assets/i18n/en-us.json @@ -84,6 +84,7 @@ ".message": "Message", "next": "Next", "start": "Start", + "notRegistered": "Not Registered", "message": { "areYouSure": "This action cannot be undone.", "verificationEmailSent": "A verification email has been sent to your email address.", @@ -106,7 +107,11 @@ "transactionExpired": "A PostCapture you delivered has been returned.", "viewAll": "open more...", "postCaptureLimitation": "The current Beta version of Capture only displays the 10 newest PostCaptures.", - "syncingAssets": "Syncing of your photo assets is in progress, this might take a few minutes. Please keep the app open and connected online." + "syncingAssets": "Syncing of your photo assets is in progress, this might take a few minutes. Please keep the app open and connected online.", + "registeringPhotos": "Registering {{ photos }} photos on blockchain.", + "registeringPhotosPaused": "Registering {{ photos }} photos on blockchain paused.", + "serverConnectionLost": "Server connection lost. Registration paused.", + "allPhotosRegistered": "All photos registered on blockchain successfully" }, "error": { "loginTimeoutError": "Connection timeout. Please try again later.", diff --git a/src/assets/i18n/zh-tw.json b/src/assets/i18n/zh-tw.json index d5d0e4816..496c1cd79 100644 --- a/src/assets/i18n/zh-tw.json +++ b/src/assets/i18n/zh-tw.json @@ -83,6 +83,7 @@ "sendToFriends": "送給朋友", "next": "下一頁", "start": "開始使用", + "notRegistered": "未註冊", ".message": "訊息", "message": { "areYouSure": "此操作不可撤銷。", @@ -106,7 +107,11 @@ "transactionExpired": "您寄出的 PostCapture 已被退回。", "viewAll": "檢視全部", "postCaptureLimitation": "目前的 Beta 版本 Capture 只會顯示 10 張最新的 PostCapture 。", - "syncingAssets": "正在同步您的影像資產至手機,這個步驟會執行數分鐘,請保持 app 開啟並且連線至網路。" + "syncingAssets": "正在同步您的影像資產至手機,這個步驟會執行數分鐘,請保持 app 開啟並且連線至網路。", + "registeringPhotos": "正在註冊 {{ photos }} 張相片到區塊鏈上", + "registeringPhotosPaused": "暫停註冊 {{ photos }} 張相片到區塊鏈上", + "serverConnectionLost": "伺服器斷線,暫停註冊", + "allPhotosRegistered": "所有照片都已被成功註冊" }, "error": { "loginTimeoutError": "連線逾時。請稍候再試。", From 733d6fa990060b46a3b09523c50bba50dcf84ad5 Mon Sep 17 00:00:00 2001 From: James Chien Date: Wed, 13 Jan 2021 16:09:31 +0800 Subject: [PATCH 13/19] Do not set diaBackendAssetId in fromIndexedProofView Signed-off-by: James Chien --- src/app/shared/services/repositories/proof/proof.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/shared/services/repositories/proof/proof.ts b/src/app/shared/services/repositories/proof/proof.ts index 681727abd..a48bb880f 100644 --- a/src/app/shared/services/repositories/proof/proof.ts +++ b/src/app/shared/services/repositories/proof/proof.ts @@ -166,7 +166,7 @@ export class Proof { ); proof.setIndexedAssets(indexedProofView.indexedAssets); proof.willCollectTruth = indexedProofView.willCollectTruth ?? false; - proof.diaBackendAssetId = indexedProofView.diaBackendAssetId ?? ''; + proof.diaBackendAssetId = indexedProofView.diaBackendAssetId; return proof; } From 7e2d43b16f17f01152264cd11faa058342aec4c5 Mon Sep 17 00:00:00 2001 From: Sean Wu Date: Wed, 13 Jan 2021 17:15:21 +0800 Subject: [PATCH 14/19] Move and rename uploading units. --- src/app/app.component.ts | 4 +-- .../upload-bar/upload-bar.component.ts | 23 ----------------- .../upload-bar/upload-bar.module.ts | 10 -------- .../uploading-bar.component.html} | 0 .../uploading-bar.component.scss} | 0 .../uploading-bar.component.spec.ts} | 12 ++++----- .../uploading-bar/uploading-bar.component.ts | 25 +++++++++++++++++++ src/app/features/home/home.module.ts | 14 +++++------ src/app/features/home/home.page.html | 2 +- src/app/features/home/home.page.spec.ts | 3 ++- ...ia-backend-asset-uploading.service.spec.ts | 18 +++++++++++++ .../dia-backend-asset-uploading.service.ts} | 10 ++++---- .../services/upload/upload.service.spec.ts | 18 ------------- 13 files changed, 66 insertions(+), 73 deletions(-) delete mode 100644 src/app/features/home/capture-tab/upload-bar/upload-bar.component.ts delete mode 100644 src/app/features/home/capture-tab/upload-bar/upload-bar.module.ts rename src/app/features/home/capture-tab/{upload-bar/upload-bar.component.html => uploading-bar/uploading-bar.component.html} (100%) rename src/app/features/home/capture-tab/{upload-bar/upload-bar.component.scss => uploading-bar/uploading-bar.component.scss} (100%) rename src/app/features/home/capture-tab/{upload-bar/upload-bar.component.spec.ts => uploading-bar/uploading-bar.component.spec.ts} (58%) create mode 100644 src/app/features/home/capture-tab/uploading-bar/uploading-bar.component.ts create mode 100644 src/app/shared/services/dia-backend/asset/uploading/dia-backend-asset-uploading.service.spec.ts rename src/app/shared/services/{upload/upload.service.ts => dia-backend/asset/uploading/dia-backend-asset-uploading.service.ts} (91%) delete mode 100644 src/app/shared/services/upload/upload.service.spec.ts diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 2c621b34b..df9ad8ac3 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -10,6 +10,7 @@ import { CaptureService } from './shared/services/capture/capture.service'; import { CollectorService } from './shared/services/collector/collector.service'; import { CapacitorFactsProvider } from './shared/services/collector/facts/capacitor-facts-provider/capacitor-facts-provider.service'; import { WebCryptoApiSignatureProvider } from './shared/services/collector/signature/web-crypto-api-signature-provider/web-crypto-api-signature-provider.service'; +import { DiaBackendAssetUploadingService } from './shared/services/dia-backend/asset/uploading/dia-backend-asset-uploading.service'; import { DiaBackendAuthService } from './shared/services/dia-backend/auth/dia-backend-auth.service'; import { DiaBackendNotificationService } from './shared/services/dia-backend/notification/dia-backend-notification.service'; import { LanguageService } from './shared/services/language/language.service'; @@ -17,7 +18,6 @@ import { NotificationService } from './shared/services/notification/notification import { PushNotificationService } from './shared/services/push-notification/push-notification.service'; import { getOldProof } from './shared/services/repositories/proof/old-proof-adapter'; import { ProofRepository } from './shared/services/repositories/proof/proof-repository.service'; -import { UploadService } from './shared/services/upload/upload.service'; const { SplashScreen } = Plugins; @@ -43,7 +43,7 @@ export class AppComponent { langaugeService: LanguageService, diaBackendAuthService: DiaBackendAuthService, diaBackendNotificationService: DiaBackendNotificationService, - uploadService: UploadService + uploadService: DiaBackendAssetUploadingService ) { notificationService.requestPermission(); pushNotificationService.register(); diff --git a/src/app/features/home/capture-tab/upload-bar/upload-bar.component.ts b/src/app/features/home/capture-tab/upload-bar/upload-bar.component.ts deleted file mode 100644 index d83cdd685..000000000 --- a/src/app/features/home/capture-tab/upload-bar/upload-bar.component.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Component } from '@angular/core'; -import { UploadService } from '../../../../shared/services/upload/upload.service'; - -@Component({ - selector: 'app-upload-bar', - templateUrl: './upload-bar.component.html', - styleUrls: ['./upload-bar.component.scss'], -}) -export class UploadBarComponent { - currentUploadingCount$ = this.uploadService.currentUploadingCount$; - isPaused$ = this.uploadService.isPaused$; - isPausedByFailure$ = this.uploadService.isPausedByFailure$; - - constructor(private readonly uploadService: UploadService) {} - - pause() { - this.uploadService.pause(); - } - - resume() { - this.uploadService.resume(); - } -} diff --git a/src/app/features/home/capture-tab/upload-bar/upload-bar.module.ts b/src/app/features/home/capture-tab/upload-bar/upload-bar.module.ts deleted file mode 100644 index 27025b538..000000000 --- a/src/app/features/home/capture-tab/upload-bar/upload-bar.module.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { NgModule } from '@angular/core'; -import { SharedModule } from '../../../../shared/shared.module'; -import { UploadBarComponent } from './upload-bar.component'; - -@NgModule({ - declarations: [UploadBarComponent], - imports: [SharedModule], - exports: [UploadBarComponent], -}) -export class UploadBarModule {} diff --git a/src/app/features/home/capture-tab/upload-bar/upload-bar.component.html b/src/app/features/home/capture-tab/uploading-bar/uploading-bar.component.html similarity index 100% rename from src/app/features/home/capture-tab/upload-bar/upload-bar.component.html rename to src/app/features/home/capture-tab/uploading-bar/uploading-bar.component.html diff --git a/src/app/features/home/capture-tab/upload-bar/upload-bar.component.scss b/src/app/features/home/capture-tab/uploading-bar/uploading-bar.component.scss similarity index 100% rename from src/app/features/home/capture-tab/upload-bar/upload-bar.component.scss rename to src/app/features/home/capture-tab/uploading-bar/uploading-bar.component.scss diff --git a/src/app/features/home/capture-tab/upload-bar/upload-bar.component.spec.ts b/src/app/features/home/capture-tab/uploading-bar/uploading-bar.component.spec.ts similarity index 58% rename from src/app/features/home/capture-tab/upload-bar/upload-bar.component.spec.ts rename to src/app/features/home/capture-tab/uploading-bar/uploading-bar.component.spec.ts index 6d8b6373c..a951025eb 100644 --- a/src/app/features/home/capture-tab/upload-bar/upload-bar.component.spec.ts +++ b/src/app/features/home/capture-tab/uploading-bar/uploading-bar.component.spec.ts @@ -1,18 +1,18 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { SharedTestingModule } from '../../../../shared/shared-testing.module'; -import { UploadBarComponent } from './upload-bar.component'; +import { UploadingBarComponent } from './uploading-bar.component'; -describe('UploadBarComponent', () => { - let component: UploadBarComponent; - let fixture: ComponentFixture; +describe('UploadingBarComponent', () => { + let component: UploadingBarComponent; + let fixture: ComponentFixture; beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [UploadBarComponent], + declarations: [UploadingBarComponent], imports: [SharedTestingModule], }).compileComponents(); - fixture = TestBed.createComponent(UploadBarComponent); + fixture = TestBed.createComponent(UploadingBarComponent); component = fixture.componentInstance; fixture.detectChanges(); })); diff --git a/src/app/features/home/capture-tab/uploading-bar/uploading-bar.component.ts b/src/app/features/home/capture-tab/uploading-bar/uploading-bar.component.ts new file mode 100644 index 000000000..8426ae3d4 --- /dev/null +++ b/src/app/features/home/capture-tab/uploading-bar/uploading-bar.component.ts @@ -0,0 +1,25 @@ +import { Component } from '@angular/core'; +import { DiaBackendAssetUploadingService } from '../../../../shared/services/dia-backend/asset/uploading/dia-backend-asset-uploading.service'; + +@Component({ + selector: 'app-uploading-bar', + templateUrl: './uploading-bar.component.html', + styleUrls: ['./uploading-bar.component.scss'], +}) +export class UploadingBarComponent { + currentUploadingCount$ = this.uploadService.currentUploadingCount$; + isPaused$ = this.uploadService.isPaused$; + isPausedByFailure$ = this.uploadService.isPausedByFailure$; + + constructor( + private readonly uploadService: DiaBackendAssetUploadingService + ) {} + + pause() { + this.uploadService.pause(); + } + + resume() { + this.uploadService.resume(); + } +} diff --git a/src/app/features/home/home.module.ts b/src/app/features/home/home.module.ts index 092f92de8..0d69a86fe 100644 --- a/src/app/features/home/home.module.ts +++ b/src/app/features/home/home.module.ts @@ -3,17 +3,17 @@ import { PostCaptureCardModule } from '../../shared/core/post-capture-card/post- import { SharedModule } from '../../shared/shared.module'; import { CaptureItemComponent } from './capture-tab/capture-item/capture-item.component'; import { CaptureTabComponent } from './capture-tab/capture-tab.component'; -import { UploadBarModule } from './capture-tab/upload-bar/upload-bar.module'; +import { UploadingBarComponent } from './capture-tab/uploading-bar/uploading-bar.component'; import { HomePageRoutingModule } from './home-routing.module'; import { HomePage } from './home.page'; @NgModule({ - imports: [ - SharedModule, - HomePageRoutingModule, - PostCaptureCardModule, - UploadBarModule, + imports: [SharedModule, HomePageRoutingModule, PostCaptureCardModule], + declarations: [ + HomePage, + CaptureTabComponent, + CaptureItemComponent, + UploadingBarComponent, ], - declarations: [HomePage, CaptureTabComponent, CaptureItemComponent], }) export class HomePageModule {} diff --git a/src/app/features/home/home.page.html b/src/app/features/home/home.page.html index 6d6b58b04..56317ef4d 100644 --- a/src/app/features/home/home.page.html +++ b/src/app/features/home/home.page.html @@ -59,7 +59,7 @@ backgroundColor="primary" > - + diff --git a/src/app/features/home/home.page.spec.ts b/src/app/features/home/home.page.spec.ts index 8b29f16d0..439e0825d 100644 --- a/src/app/features/home/home.page.spec.ts +++ b/src/app/features/home/home.page.spec.ts @@ -2,6 +2,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { Router } from '@angular/router'; import { SharedTestingModule } from '../../shared/shared-testing.module'; import { CaptureTabComponent } from './capture-tab/capture-tab.component'; +import { UploadingBarComponent } from './capture-tab/uploading-bar/uploading-bar.component'; import { HomePage } from './home.page'; describe('HomePage', () => { @@ -10,7 +11,7 @@ describe('HomePage', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [HomePage, CaptureTabComponent], + declarations: [HomePage, CaptureTabComponent, UploadingBarComponent], imports: [SharedTestingModule], }).compileComponents(); diff --git a/src/app/shared/services/dia-backend/asset/uploading/dia-backend-asset-uploading.service.spec.ts b/src/app/shared/services/dia-backend/asset/uploading/dia-backend-asset-uploading.service.spec.ts new file mode 100644 index 000000000..ef1572b72 --- /dev/null +++ b/src/app/shared/services/dia-backend/asset/uploading/dia-backend-asset-uploading.service.spec.ts @@ -0,0 +1,18 @@ +import { TestBed } from '@angular/core/testing'; +import { SharedTestingModule } from '../../../../shared-testing.module'; +import { DiaBackendAssetUploadingService } from './dia-backend-asset-uploading.service'; + +describe('DiaBackendAssetUploadingService', () => { + let service: DiaBackendAssetUploadingService; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [SharedTestingModule], + }); + service = TestBed.inject(DiaBackendAssetUploadingService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/shared/services/upload/upload.service.ts b/src/app/shared/services/dia-backend/asset/uploading/dia-backend-asset-uploading.service.ts similarity index 91% rename from src/app/shared/services/upload/upload.service.ts rename to src/app/shared/services/dia-backend/asset/uploading/dia-backend-asset-uploading.service.ts index 76fcf4ec3..a6043506f 100644 --- a/src/app/shared/services/upload/upload.service.ts +++ b/src/app/shared/services/dia-backend/asset/uploading/dia-backend-asset-uploading.service.ts @@ -21,15 +21,15 @@ import { switchMap, tap, } from 'rxjs/operators'; -import { DiaBackendAssetRepository } from '../dia-backend/asset/dia-backend-asset-repository.service'; -import { getOldProof } from '../repositories/proof/old-proof-adapter'; -import { Proof } from '../repositories/proof/proof'; -import { ProofRepository } from '../repositories/proof/proof-repository.service'; +import { getOldProof } from '../../../repositories/proof/old-proof-adapter'; +import { Proof } from '../../../repositories/proof/proof'; +import { ProofRepository } from '../../../repositories/proof/proof-repository.service'; +import { DiaBackendAssetRepository } from '../dia-backend-asset-repository.service'; @Injectable({ providedIn: 'root', }) -export class UploadService { +export class DiaBackendAssetUploadingService { private readonly _isPaused$ = new BehaviorSubject(false); private readonly _isPausedByFailure$ = new BehaviorSubject(false); private readonly _taskQueue$ = new BehaviorSubject([]); diff --git a/src/app/shared/services/upload/upload.service.spec.ts b/src/app/shared/services/upload/upload.service.spec.ts deleted file mode 100644 index 66fff3140..000000000 --- a/src/app/shared/services/upload/upload.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { SharedTestingModule } from '../../shared-testing.module'; -import { UploadService } from './upload.service'; - -describe('UploadService', () => { - let service: UploadService; - - beforeEach(() => { - TestBed.configureTestingModule({ - imports: [SharedTestingModule], - }); - service = TestBed.inject(UploadService); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); From f456638b671f3ffc5966e2f6f88c8624761ebe2b Mon Sep 17 00:00:00 2001 From: Sean Wu Date: Wed, 13 Jan 2021 17:23:56 +0800 Subject: [PATCH 15/19] Revert D1 merge. --- .../capture-item/capture-item.component.html | 11 ---- .../capture-item/capture-item.component.scss | 46 -------------- .../capture-item.component.spec.ts | 23 ------- .../capture-item/capture-item.component.ts | 63 ------------------- .../capture-tab/capture-tab.component.html | 21 ++++--- .../capture-tab/capture-tab.component.scss | 43 +++++++++++++ .../home/capture-tab/capture-tab.component.ts | 29 ++++----- src/app/features/home/home.module.ts | 8 +-- 8 files changed, 68 insertions(+), 176 deletions(-) delete mode 100644 src/app/features/home/capture-tab/capture-item/capture-item.component.html delete mode 100644 src/app/features/home/capture-tab/capture-item/capture-item.component.scss delete mode 100644 src/app/features/home/capture-tab/capture-item/capture-item.component.spec.ts delete mode 100644 src/app/features/home/capture-tab/capture-item/capture-item.component.ts diff --git a/src/app/features/home/capture-tab/capture-item/capture-item.component.html b/src/app/features/home/capture-tab/capture-item/capture-item.component.html deleted file mode 100644 index b72448ec5..000000000 --- a/src/app/features/home/capture-tab/capture-item/capture-item.component.html +++ /dev/null @@ -1,11 +0,0 @@ -
- -
- - - diff --git a/src/app/features/home/capture-tab/capture-item/capture-item.component.scss b/src/app/features/home/capture-tab/capture-item/capture-item.component.scss deleted file mode 100644 index fc66c5c56..000000000 --- a/src/app/features/home/capture-tab/capture-item/capture-item.component.scss +++ /dev/null @@ -1,46 +0,0 @@ -:host { - display: block; - position: relative; - width: 100%; - height: 100%; - overflow: hidden; - border-radius: 4px; - background-color: whitesmoke; -} - -ion-icon { - position: absolute; - top: 50%; - left: 50%; - margin-right: -50%; - transform: translate(-50%, -50%); - z-index: 10; - opacity: 50%; - font-size: 24px; - color: white; -} - -.spinner-container { - position: absolute; - top: 50%; - left: 50%; - margin-right: -50%; - transform: translate(-50%, -50%); - z-index: 9; - - ion-spinner { - width: 48px; - height: 48px; - opacity: 50%; - - --color: white; - } -} - -img { - width: 100%; - height: 100%; - object-fit: cover; - object-position: center; - background-color: whitesmoke; -} diff --git a/src/app/features/home/capture-tab/capture-item/capture-item.component.spec.ts b/src/app/features/home/capture-tab/capture-item/capture-item.component.spec.ts deleted file mode 100644 index 17af03712..000000000 --- a/src/app/features/home/capture-tab/capture-item/capture-item.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { SharedTestingModule } from '../../../../shared/shared-testing.module'; -import { CaptureItemComponent } from './capture-item.component'; - -describe('CaptureItemComponent', () => { - let component: CaptureItemComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [CaptureItemComponent], - imports: [SharedTestingModule], - }).compileComponents(); - - fixture = TestBed.createComponent(CaptureItemComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - })); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/features/home/capture-tab/capture-item/capture-item.component.ts b/src/app/features/home/capture-tab/capture-item/capture-item.component.ts deleted file mode 100644 index 2608ba4f2..000000000 --- a/src/app/features/home/capture-tab/capture-item/capture-item.component.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { Component, Input } from '@angular/core'; -import { UntilDestroy } from '@ngneat/until-destroy'; -import { BehaviorSubject } from 'rxjs'; -import { map, switchMap } from 'rxjs/operators'; -import { getOldProof } from '../../../../shared/services/repositories/proof/old-proof-adapter'; -import { Proof } from '../../../../shared/services/repositories/proof/proof'; -import { isNonNullable } from '../../../../utils/rx-operators/rx-operators'; - -@UntilDestroy({ checkProperties: true }) -@Component({ - selector: 'app-capture-item', - templateUrl: './capture-item.component.html', - styleUrls: ['./capture-item.component.scss'], -}) -export class CaptureItemComponent { - // Use setter to make sure the item is updated even if the component is - // recycled and redrawed (e.g. virtual scroll). - @Input() - set item(value: CaptureItem) { - this._item$.next(value); - } - - // tslint:disable-next-line: rxjs-no-explicit-generics - private readonly _item$ = new BehaviorSubject( - undefined - ); - readonly item$ = this._item$.asObservable().pipe(isNonNullable()); - readonly thumbnailUrl$ = this.item$.pipe( - switchMap(item => item.getThumbnailUrl()) - ); - readonly willCollectTruth$ = this.item$.pipe( - map(item => item.proof?.willCollectTruth === true) - ); -} - -export class CaptureItem { - proof?: Proof; - private readonly createdTimestamp: number; - - get oldProofHash() { - if (this.proof) { - return getOldProof(this.proof).hash; - } - } - - get timestamp() { - if (this.proof) { - return this.proof.timestamp; - } - return this.createdTimestamp; - } - - constructor({ proof }: { proof?: Proof }) { - this.proof = proof; - this.createdTimestamp = Date.now(); - } - - async getThumbnailUrl() { - if (this.proof) { - return this.proof.getThumbnailUrl(); - } - } -} diff --git a/src/app/features/home/capture-tab/capture-tab.component.html b/src/app/features/home/capture-tab/capture-tab.component.html index 092c4b0d1..656ce31c0 100644 --- a/src/app/features/home/capture-tab/capture-tab.component.html +++ b/src/app/features/home/capture-tab/capture-tab.component.html @@ -1,20 +1,25 @@
{{ group.key }}
- +
+ +
+ +
diff --git a/src/app/features/home/capture-tab/capture-tab.component.scss b/src/app/features/home/capture-tab/capture-tab.component.scss index f803369be..c327d6a3c 100644 --- a/src/app/features/home/capture-tab/capture-tab.component.scss +++ b/src/app/features/home/capture-tab/capture-tab.component.scss @@ -9,3 +9,46 @@ div.mat-title { margin: 26px 0 0; font-size: large; } + +.capture-item { + height: 30vw; + overflow: hidden; + object-fit: cover; + border-radius: 4px; + + .spinner-container { + position: absolute; + top: 50%; + left: 50%; + margin-right: -50%; + transform: translate(-50%, -50%); + z-index: 9; + + ion-spinner { + width: 48px; + height: 48px; + opacity: 50%; + + --color: white; + } + } + + ion-icon { + position: absolute; + top: 50%; + left: 50%; + margin-right: -50%; + transform: translate(-50%, -50%); + z-index: 10; + opacity: 30%; + color: white; + font-size: 24px; + } + + img { + width: 100%; + height: 100%; + object-fit: cover; + object-position: inherit; + } +} diff --git a/src/app/features/home/capture-tab/capture-tab.component.ts b/src/app/features/home/capture-tab/capture-tab.component.ts index dd548c245..2f093fa7f 100644 --- a/src/app/features/home/capture-tab/capture-tab.component.ts +++ b/src/app/features/home/capture-tab/capture-tab.component.ts @@ -2,8 +2,8 @@ import { formatDate, KeyValue } from '@angular/common'; import { Component } from '@angular/core'; import { groupBy } from 'lodash'; import { concatMap, map } from 'rxjs/operators'; +import { getOldProof } from '../../../shared/services/repositories/proof/old-proof-adapter'; import { ProofRepository } from '../../../shared/services/repositories/proof/proof-repository.service'; -import { CaptureItem } from './capture-item/capture-item.component'; @Component({ selector: 'app-capture-tab', @@ -15,11 +15,17 @@ export class CaptureTabComponent { readonly capturesByDate$ = this.proofs$.pipe( map(proofs => proofs.sort((a, b) => b.timestamp - a.timestamp)), concatMap(proofs => - Promise.all(proofs.map(async proof => new CaptureItem({ proof }))) + Promise.all( + proofs.map(async proof => ({ + proof, + thumbnailUrl: await proof.getThumbnailUrl(), + oldProofHash: getOldProof(proof).hash, + })) + ) ), - map(captureItems => - groupBy(captureItems, item => - formatDate(item.timestamp, 'yyyy/MM/dd', 'en-US') + map(captures => + groupBy(captures, capture => + formatDate(capture.proof.timestamp, 'yyyy/MM/dd', 'en-US') ) ) ); @@ -33,17 +39,4 @@ export class CaptureTabComponent { ): number { return a.key > b.key ? -1 : b.key > a.key ? 1 : 0; } - - // tslint:disable-next-line: prefer-function-over-method - trackCaptureGroupByDate( - _: number, - item: { key: string; value: CaptureItem[] } - ) { - return item.key; - } - - // tslint:disable-next-line: prefer-function-over-method - trackCaptureItem(_: number, item: CaptureItem) { - return item.oldProofHash; - } } diff --git a/src/app/features/home/home.module.ts b/src/app/features/home/home.module.ts index 0d69a86fe..64b9e6af3 100644 --- a/src/app/features/home/home.module.ts +++ b/src/app/features/home/home.module.ts @@ -1,7 +1,6 @@ import { NgModule } from '@angular/core'; import { PostCaptureCardModule } from '../../shared/core/post-capture-card/post-capture-card.module'; import { SharedModule } from '../../shared/shared.module'; -import { CaptureItemComponent } from './capture-tab/capture-item/capture-item.component'; import { CaptureTabComponent } from './capture-tab/capture-tab.component'; import { UploadingBarComponent } from './capture-tab/uploading-bar/uploading-bar.component'; import { HomePageRoutingModule } from './home-routing.module'; @@ -9,11 +8,6 @@ import { HomePage } from './home.page'; @NgModule({ imports: [SharedModule, HomePageRoutingModule, PostCaptureCardModule], - declarations: [ - HomePage, - CaptureTabComponent, - CaptureItemComponent, - UploadingBarComponent, - ], + declarations: [HomePage, CaptureTabComponent, UploadingBarComponent], }) export class HomePageModule {} From 610ed9dea41a53d02d164526af751693cc9f493a Mon Sep 17 00:00:00 2001 From: James Chien Date: Fri, 15 Jan 2021 12:24:36 +0800 Subject: [PATCH 16/19] Store isCollected property in Proof Signed-off-by: James Chien --- src/app/shared/services/collector/collector.service.ts | 4 +++- .../asset/uploading/dia-backend-asset-uploading.service.ts | 2 +- src/app/shared/services/repositories/proof/proof.ts | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/app/shared/services/collector/collector.service.ts b/src/app/shared/services/collector/collector.service.ts index 662f7bf9b..8c9843687 100644 --- a/src/app/shared/services/collector/collector.service.ts +++ b/src/app/shared/services/collector/collector.service.ts @@ -23,7 +23,9 @@ export class CollectorService { async run(assets: Assets) { const truth = await this.collectTruth(assets); const signatures = await this.signTargets({ assets, truth }); - return Proof.from(this.imageStore, assets, truth, signatures); + const proof = await Proof.from(this.imageStore, assets, truth, signatures); + proof.isCollected = true; + return proof; } private async collectTruth(assets: Assets): Promise { diff --git a/src/app/shared/services/dia-backend/asset/uploading/dia-backend-asset-uploading.service.ts b/src/app/shared/services/dia-backend/asset/uploading/dia-backend-asset-uploading.service.ts index a6043506f..53f6de583 100644 --- a/src/app/shared/services/dia-backend/asset/uploading/dia-backend-asset-uploading.service.ts +++ b/src/app/shared/services/dia-backend/asset/uploading/dia-backend-asset-uploading.service.ts @@ -76,7 +76,7 @@ export class DiaBackendAssetUploadingService { ]).pipe( tap(([proofs, isPaused]) => { const tasks = proofs.filter( - proof => !proof.diaBackendAssetId && !proof.willCollectTruth + proof => !proof.diaBackendAssetId && proof.isCollected ); this._currentUploadingCount$.next(tasks.length); this.updateTaskQueue(isPaused ? [] : tasks); diff --git a/src/app/shared/services/repositories/proof/proof.ts b/src/app/shared/services/repositories/proof/proof.ts index b7b9bfb4c..be02c2111 100644 --- a/src/app/shared/services/repositories/proof/proof.ts +++ b/src/app/shared/services/repositories/proof/proof.ts @@ -7,6 +7,7 @@ import { ImageStore } from '../../image-store/image-store.service'; export class Proof { diaBackendAssetId: string | undefined = undefined; + isCollected = false; get timestamp() { return this.truth.timestamp; @@ -122,6 +123,7 @@ export class Proof { truth: this.truth, signatures: this.signatures, diaBackendAssetId: this.diaBackendAssetId, + isCollected: this.isCollected, }; } @@ -164,6 +166,7 @@ export class Proof { ); proof.setIndexedAssets(indexedProofView.indexedAssets); proof.diaBackendAssetId = indexedProofView.diaBackendAssetId; + proof.isCollected = indexedProofView.isCollected ?? false; return proof; } @@ -281,4 +284,5 @@ export interface IndexedProofView extends Tuple { readonly truth: Truth; readonly signatures: Signatures; readonly diaBackendAssetId?: string; + readonly isCollected?: boolean; } From d50ae25c14956295a887d789f3bdf584fb485cf7 Mon Sep 17 00:00:00 2001 From: James Chien Date: Fri, 15 Jan 2021 12:45:50 +0800 Subject: [PATCH 17/19] Add back mistakenly removed code when merging Signed-off-by: James Chien --- .../home/capture-tab/capture-tab.component.html | 7 +++++-- .../home/capture-tab/capture-tab.component.ts | 13 +++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/app/features/home/capture-tab/capture-tab.component.html b/src/app/features/home/capture-tab/capture-tab.component.html index 8ce2e7a3e..d29125d8f 100644 --- a/src/app/features/home/capture-tab/capture-tab.component.html +++ b/src/app/features/home/capture-tab/capture-tab.component.html @@ -1,10 +1,13 @@
{{ group.key }}