diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 18842859a..eac61a305 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -63,7 +63,11 @@ export class AppComponent { this.registerIcon(); } - static setDarkMode() { + static setDarkMode(forceDarkMode = false) { + if (forceDarkMode) { + document.body.classList.toggle('dark', true); + return; + } const dark = window.navigator.userAgent.includes('AndroidDarkMode') || window.matchMedia('(prefers-color-scheme: dark)').matches; @@ -72,7 +76,7 @@ export class AppComponent { async initializeApp() { await this.platform.ready(); - AppComponent.setDarkMode(); + AppComponent.setDarkMode(true); await SplashScreen.hide(); } 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 36825e681..0a1d4f166 100644 --- a/src/app/features/home/capture-tab/capture-tab.component.html +++ b/src/app/features/home/capture-tab/capture-tab.component.html @@ -2,43 +2,87 @@ + - - - {{ username$ | ngrxPush }} - - + {{ username$ | ngrxPush }} +
{{ email$ | ngrxPush }}
-
- -
{{ group.key | date: 'longDate' }}
+ +
+ + + {{ 'home.profileTab.captured' | transloco }} + + + {{ 'home.profileTab.collected' | transloco }} + + + +

+ {{ 'message.networkNotConnected' | transloco }} +

+ +
+
+ +
{{ group.key | date: 'longDate' }}
+ + + + + +
+
+
+ +
- + + + + + - +
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 f360f8b7c..6dd56b1de 100644 --- a/src/app/features/home/capture-tab/capture-tab.component.scss +++ b/src/app/features/home/capture-tab/capture-tab.component.scss @@ -8,6 +8,22 @@ div.mat-title { font-size: medium; } +mat-card { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +mat-card-title { + text-align: center; + margin-top: 32px; +} + +mat-card-subtitle { + margin-top: 12px !important; /* stylelint-disable-line declaration-no-important */ +} + .user-card { width: 100%; padding-left: 16px; @@ -34,6 +50,16 @@ app-avatar { height: 64px; } +.network-status { + margin: 0; + padding: 8px; + text-align: center; + color: darkgray; + font-weight: 500; + font-size: 0.9em; + background-color: var(--ion-color-light); +} + .capture-container { padding-left: 16px; padding-right: 16px; @@ -45,3 +71,37 @@ app-capture-item { overflow: hidden; border-radius: 4px; } + +.post-captures { + overflow: auto; + padding: 16px; + + mat-grid-tile { + ion-img { + width: 100%; + height: 100%; + object-fit: cover; + object-position: center; + overflow: hidden; + border-radius: 4px; + } + + ion-icon { + color: white; + z-index: 10; + position: absolute; + opacity: 0.3; + font-size: 16px; + } + + ion-icon.is-video { + top: 8px; + right: 8px; + } + + ion-icon.is-from-store { + top: 8px; + left: 8px; + } + } +} 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 104d75d4a..9b4f9c0d1 100644 --- a/src/app/features/home/capture-tab/capture-tab.component.ts +++ b/src/app/features/home/capture-tab/capture-tab.component.ts @@ -4,11 +4,17 @@ import { AlertController } from '@ionic/angular'; import { TranslocoService } from '@ngneat/transloco'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { groupBy } from 'lodash-es'; -import { catchError, finalize, map } from 'rxjs/operators'; +import { iif } from 'rxjs'; +import { catchError, finalize, map, pluck, switchMap } from 'rxjs/operators'; import { BlockingActionService } from '../../../shared/blocking-action/blocking-action.service'; +import { + DiaBackendAsset, + DiaBackendAssetRepository, +} from '../../../shared/dia-backend/asset/dia-backend-asset-repository.service'; import { DiaBackendAsseRefreshingService } from '../../../shared/dia-backend/asset/refreshing/dia-backend-asset-refreshing.service'; import { DiaBackendAuthService } from '../../../shared/dia-backend/auth/dia-backend-auth.service'; import { ErrorService } from '../../../shared/error/error.service'; +import { NetworkService } from '../../../shared/network/network.service'; import { getOldProof } from '../../../shared/repositories/proof/old-proof-adapter'; import { Proof } from '../../../shared/repositories/proof/proof'; import { ProofRepository } from '../../../shared/repositories/proof/proof-repository.service'; @@ -20,6 +26,8 @@ import { ProofRepository } from '../../../shared/repositories/proof/proof-reposi styleUrls: ['./capture-tab.component.scss'], }) export class CaptureTabComponent { + categories: 'captured' | 'collected' = 'captured'; + readonly username$ = this.diaBackendAuthService.username$; readonly email$ = this.diaBackendAuthService.email$; @@ -35,11 +43,25 @@ export class CaptureTabComponent { ) ); + readonly networkConnected$ = this.networkService.connected$; + + readonly postCaptures$ = this.networkConnected$.pipe( + switchMap(isConnected => + iif( + () => isConnected, + this.diaBackendAssetRepository.postCaptures$.pipe(pluck('results')) + ) + ), + catchError((err: unknown) => this.errorService.toastError$(err)) + ); + constructor( private readonly proofRepository: ProofRepository, private readonly diaBackendAuthService: DiaBackendAuthService, + private readonly diaBackendAssetRepository: DiaBackendAssetRepository, private readonly diaBackendAssetRefreshingService: DiaBackendAsseRefreshingService, private readonly alertController: AlertController, + private readonly networkService: NetworkService, private readonly translocoService: TranslocoService, private readonly errorService: ErrorService, private readonly blockingActionService: BlockingActionService @@ -97,6 +119,11 @@ export class CaptureTabComponent { return getOldProof(item).hash; } + // eslint-disable-next-line class-methods-use-this + trackPostCapture(_: number, item: DiaBackendAsset) { + return item.id; + } + refreshCaptures(event: Event) { this.diaBackendAssetRefreshingService .refresh() diff --git a/src/app/features/home/explore-tab/explore-tab/explore-tab.component.html b/src/app/features/home/explore-tab/explore-tab/explore-tab.component.html new file mode 100644 index 000000000..e705ef9be --- /dev/null +++ b/src/app/features/home/explore-tab/explore-tab/explore-tab.component.html @@ -0,0 +1,10 @@ +
+ {{ 'message.networkNotConnected' | transloco }} +
+ + + + diff --git a/src/app/features/home/explore-tab/explore-tab/explore-tab.component.scss b/src/app/features/home/explore-tab/explore-tab/explore-tab.component.scss new file mode 100644 index 000000000..85ec92544 --- /dev/null +++ b/src/app/features/home/explore-tab/explore-tab/explore-tab.component.scss @@ -0,0 +1,11 @@ +.no-network-text { + font-size: 18px; + text-align: center; +} + +.bubble-iframe { + background-color: black; + width: 100vw; + height: 100vh; + border: 0; +} diff --git a/src/app/features/home/explore-tab/explore-tab/explore-tab.component.spec.ts b/src/app/features/home/explore-tab/explore-tab/explore-tab.component.spec.ts new file mode 100644 index 000000000..515186ad4 --- /dev/null +++ b/src/app/features/home/explore-tab/explore-tab/explore-tab.component.spec.ts @@ -0,0 +1,26 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { SharedTestingModule } from '../../../../shared/shared-testing.module'; + +import { ExploreTabComponent } from './explore-tab.component'; + +describe('ExploreTabComponent', () => { + let component: ExploreTabComponent; + let fixture: ComponentFixture; + + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ExploreTabComponent], + imports: [SharedTestingModule], + }).compileComponents(); + + fixture = TestBed.createComponent(ExploreTabComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }) + ); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/features/home/explore-tab/explore-tab/explore-tab.component.ts b/src/app/features/home/explore-tab/explore-tab/explore-tab.component.ts new file mode 100644 index 000000000..41e79cac5 --- /dev/null +++ b/src/app/features/home/explore-tab/explore-tab/explore-tab.component.ts @@ -0,0 +1,24 @@ +import { Component } from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; +import { ErrorService } from '../../../../shared/error/error.service'; +import { NetworkService } from '../../../../shared/network/network.service'; + +@Component({ + selector: 'app-explore-tab', + templateUrl: './explore-tab.component.html', + styleUrls: ['./explore-tab.component.scss'], +}) +export class ExploreTabComponent { + // TODO: change url to point to production bubble app + readonly bubbleIframeUrl = this.sanitizer.bypassSecurityTrustResourceUrl( + 'https://captureappiframe.bubbleapps.io/version-test/' + ); + + readonly networkConnected$ = this.networkService.connected$; + + constructor( + private readonly sanitizer: DomSanitizer, + private readonly networkService: NetworkService, + private readonly errorService: ErrorService + ) {} +} diff --git a/src/app/features/home/home.module.ts b/src/app/features/home/home.module.ts index 40961cca2..067e5f565 100644 --- a/src/app/features/home/home.module.ts +++ b/src/app/features/home/home.module.ts @@ -4,6 +4,7 @@ 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 { ExploreTabComponent } from './explore-tab/explore-tab/explore-tab.component'; import { HomePageRoutingModule } from './home-routing.module'; import { HomePage } from './home.page'; import { UpdateAppDialogComponent } from './in-app-updates/update-app-dialog/update-app-dialog.component'; @@ -14,6 +15,7 @@ import { PostCaptureTabComponent } from './post-capture-tab/post-capture-tab.com declarations: [ HomePage, CaptureTabComponent, + ExploreTabComponent, PostCaptureTabComponent, PrefetchingDialogComponent, UpdateAppDialogComponent, diff --git a/src/app/features/home/home.page.html b/src/app/features/home/home.page.html index 224ef492f..67e6b54cd 100644 --- a/src/app/features/home/home.page.html +++ b/src/app/features/home/home.page.html @@ -51,7 +51,7 @@ - + @@ -90,21 +90,21 @@ > - - apps - + > - + - + diff --git a/src/app/features/home/home.page.ts b/src/app/features/home/home.page.ts index 64f54e5e6..8f209a6f4 100644 --- a/src/app/features/home/home.page.ts +++ b/src/app/features/home/home.page.ts @@ -45,7 +45,9 @@ import { PrefetchingDialogComponent } from './onboarding/prefetching-dialog/pref styleUrls: ['./home.page.scss'], }) export class HomePage { - selectedTabIndex = 0; + private readonly initialTabIndex = 2; + private readonly afterCaptureTabIndex = 2; + selectedTabIndex = this.initialTabIndex; readonly username$ = this.diaBackendAuthService.username$; @@ -236,7 +238,7 @@ export class HomePage { capture() { return defer(() => { - const captureIndex = 0; + const captureIndex = this.afterCaptureTabIndex; this.selectedTabIndex = captureIndex; return this.presentCaptureActions$(); }) @@ -253,9 +255,13 @@ export class HomePage { } captureWithCustomCamera() { - const captureIndex = 0; - this.selectedTabIndex = captureIndex; - this.router.navigate(['home', 'custom-camera']); + if (!this.platform.is('android') || !this.platform.is('ios')) { + this.capture(); + } else { + const captureIndex = this.afterCaptureTabIndex; + this.selectedTabIndex = captureIndex; + this.router.navigate(['home', 'custom-camera']); + } } private presentCaptureActions$() { diff --git a/src/assets/i18n/en-us.json b/src/assets/i18n/en-us.json index 314f771b7..b24bb0430 100644 --- a/src/assets/i18n/en-us.json +++ b/src/assets/i18n/en-us.json @@ -257,6 +257,12 @@ "fee": "Gas", "totalCost": "Total Cost" }, + "home": { + "profileTab": { + "captured": "Captured", + "collected": "Collected" + } + }, "details": { "error": { "transferOwnershipActionIsUnavailable": "Transfer ownership action is unavailable. Please try again later.", diff --git a/src/assets/i18n/zh-tw.json b/src/assets/i18n/zh-tw.json index a7f060682..c12921f1a 100644 --- a/src/assets/i18n/zh-tw.json +++ b/src/assets/i18n/zh-tw.json @@ -257,6 +257,12 @@ "fee": "油費", "totalCost": "總額" }, + "home": { + "profileTab": { + "captured": "瞬時影像", + "collected": "收藏" + } + }, "details": { "error": { "transferOwnershipActionIsUnavailable": "暫時無法轉換所有權,請稍後再試。", diff --git a/src/assets/images/icons/capture.svg b/src/assets/images/icons/capture.svg new file mode 100644 index 000000000..69c6d19f2 --- /dev/null +++ b/src/assets/images/icons/capture.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/icons/profile.svg b/src/assets/images/icons/profile.svg new file mode 100644 index 000000000..7e1f97f64 --- /dev/null +++ b/src/assets/images/icons/profile.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/images/icons/search.svg b/src/assets/images/icons/search.svg new file mode 100644 index 000000000..cc1342f1d --- /dev/null +++ b/src/assets/images/icons/search.svg @@ -0,0 +1,8 @@ + + + + + + + +