diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 5fed58ee0..b0f917d4b 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -33,14 +33,6 @@ const routes: Routes = [{
path: 'about',
loadChildren: () => import('./pages/about/about.module').then(m => m.AboutPageModule),
canActivate: [AuthGuardService],
-}, {
- path: 'proof',
- loadChildren: () => import('./pages/proof/proof.module').then(m => m.ProofPageModule),
- canActivate: [AuthGuardService],
-}, {
- path: 'information',
- loadChildren: () => import('./pages/information/information.module').then(m => m.InformationPageModule),
- canActivate: [AuthGuardService],
}, {
path: 'publishers',
redirectTo: 'settings',
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 1afd4a1fe..fd4f5ec6f 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -7,7 +7,7 @@ import { map } from 'rxjs/operators';
import { CameraService } from './services/camera/camera.service';
import { CollectorService } from './services/collector/collector.service';
import { CapacitorProvider } from './services/collector/information/capacitor-provider/capacitor-provider';
-import { DefaultSignatureProvider } from './services/collector/signature/default-provider/default-provider';
+import { WebCryptoApiProvider } from './services/collector/signature/web-crypto-api-provider/web-crypto-api-provider';
import { CaptionRepository } from './services/data/caption/caption-repository.service';
import { InformationRepository } from './services/data/information/information-repository.service';
import { ProofRepository } from './services/data/proof/proof-repository.service';
@@ -68,12 +68,12 @@ export class AppComponent {
}
initializeCollector() {
- DefaultSignatureProvider.initialize$().pipe(untilDestroyed(this)).subscribe();
+ WebCryptoApiProvider.initialize$().pipe(untilDestroyed(this)).subscribe();
this.collectorService.addInformationProvider(
new CapacitorProvider(this.informationRepository, this.translocoService)
);
this.collectorService.addSignatureProvider(
- new DefaultSignatureProvider(this.signatureRepository, this.serializationService)
+ new WebCryptoApiProvider(this.signatureRepository, this.serializationService)
);
}
diff --git a/src/app/pages/information/information.page.html b/src/app/pages/information/information.page.html
deleted file mode 100644
index 8ddba8475..000000000
--- a/src/app/pages/information/information.page.html
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-
-
-
-
-
- {{ t('informationDetails') }}
-
-
-
-
-
-
-
- {{ t('location') }}
-
-
-
-
-
- {{ information.name }}
- {{ information.value }}
-
-
-
-
-
-
-
-
-
-
-
- {{ t('other') }}
-
-
-
-
-
- {{ information.name }}
- {{ information.value }}
-
-
-
-
-
-
-
-
-
-
-
- {{ t('device') }}
-
-
-
-
-
- {{ information.name }}
- {{ information.value }}
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/app/pages/information/information.page.scss b/src/app/pages/information/information.page.scss
deleted file mode 100644
index 410d97ad1..000000000
--- a/src/app/pages/information/information.page.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-.slide-card {
- width: 100%;
-}
-
-.multiline {
- white-space: pre-wrap;
-}
diff --git a/src/app/pages/login/login.page.scss b/src/app/pages/login/login.page.scss
index daafa53a5..4bbc65906 100644
--- a/src/app/pages/login/login.page.scss
+++ b/src/app/pages/login/login.page.scss
@@ -1,10 +1,12 @@
ion-title {
color: #333;
}
+
ion-grid {
height: 100%;
background: #fff !important;
}
+
ion-button {
&[disabled] {
opacity: 1;
@@ -18,9 +20,11 @@ ion-button {
--height: 50px !important;
--background: #564dfc !important;
}
+
ion-title {
width: 100%;
}
+
ion-input {
width: calc(100vw - var(--ion-padding, 23px));
text-align: left;
@@ -29,18 +33,22 @@ ion-input {
margin-bottom: 10px !important;
color: #000;
}
+
.input_msg {
width: 100%;
height: 40px;
color: red !important;
text-align: center;
}
+
.input_R {
text-align: right;
}
+
.input_C {
text-align: center;
}
+
.input {
width: calc(100vw - var(--ion-padding, 23px)) !important;
border-color: #564dfc !important;
@@ -50,9 +58,11 @@ ion-input {
padding-left: 10px !important;
padding-right: 10px !important;
}
+
.img {
--height: 127.15px !important;
}
+
.logo {
width: 100%;
display: flex;
@@ -63,18 +73,21 @@ ion-input {
justify-content: center;
align-items: center;
}
+
.inputs {
width: 100% !important;
display: flex;
flex: 1;
height: 35vh;
}
+
.buttons {
width: 100% !important;
display: flex;
flex: 1;
bottom: 0px;
}
+
ion-content {
display: flex;
flex: 1;
diff --git a/src/app/pages/profile/profile.page.scss b/src/app/pages/profile/profile.page.scss
index 5fe742012..51e5470f5 100644
--- a/src/app/pages/profile/profile.page.scss
+++ b/src/app/pages/profile/profile.page.scss
@@ -7,7 +7,3 @@ mat-toolbar {
width: 50%;
margin: 10vw auto;
}
-
-.expand {
- width: 100%;
-}
diff --git a/src/app/pages/profile/profile.page.ts b/src/app/pages/profile/profile.page.ts
index 3ea5d90b1..b51b43672 100644
--- a/src/app/pages/profile/profile.page.ts
+++ b/src/app/pages/profile/profile.page.ts
@@ -8,7 +8,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { defer } from 'rxjs';
import { catchError, concatMapTo } from 'rxjs/operators';
import { BlockingActionService } from '../../services/blocking-action/blocking-action.service';
-import { DefaultSignatureProvider } from '../../services/collector/signature/default-provider/default-provider';
+import { WebCryptoApiProvider } from '../../services/collector/signature/web-crypto-api-provider/web-crypto-api-provider';
import { NumbersStorageApi } from '../../services/publisher/numbers-storage/numbers-storage-api.service';
const { Clipboard } = Plugins;
@@ -23,8 +23,8 @@ export class ProfilePage {
readonly userName$ = this.numbersStorageApi.getUserName$();
readonly email$ = this.numbersStorageApi.getEmail$();
- readonly publicKey$ = DefaultSignatureProvider.getPublicKey$();
- readonly privateKey$ = DefaultSignatureProvider.getPrivateKey$();
+ readonly publicKey$ = WebCryptoApiProvider.getPublicKey$();
+ readonly privateKey$ = WebCryptoApiProvider.getPrivateKey$();
constructor(
private readonly router: Router,
diff --git a/src/app/pages/proof/proof.page.html b/src/app/pages/proof/proof.page.html
deleted file mode 100644
index 0ca53eccf..000000000
--- a/src/app/pages/proof/proof.page.html
+++ /dev/null
@@ -1,118 +0,0 @@
-
-
-
-
-
-
-
- {{ t('proofDetails') }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ t('caption') }}
- {{ (caption$ | async) === '' ? '(' + ( t('nothingHere') ) + ')' : (caption$ | async) }}
-
-
-
-
-
-
-
-
- {{ t('hash') }}
- {{ hash$ | async }}
-
-
-
-
-
- {{ t('mimeType') }}
- {{ mimeType$ | async }}
-
-
-
-
-
- {{ t('timestamp') }}
- {{ timestamp$ | async }}
-
-
-
-
- {{ t('information') }}
-
-
-
-
-
-
-
- {{ providerWithInformationList.provider }}
-
-
-
-
-
- {{ information.name }}
- {{ information.value }}
-
-
-
-
-
-
-
-
-
-
-
- {{ t('signatures') }}
-
-
-
-
-
-
-
- {{ signature.provider }}
-
-
-
-
-
- {{ t('signature') }}
- {{ signature.signature }}
-
-
-
-
- {{ t('publicKey') }}
- {{ signature.publicKey }}
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/app/pages/proof/proof.page.scss b/src/app/pages/proof/proof.page.scss
deleted file mode 100644
index 142776949..000000000
--- a/src/app/pages/proof/proof.page.scss
+++ /dev/null
@@ -1,12 +0,0 @@
-ion-slides {
- width: 100%;
-}
-
-.slide-card {
- width: 100%;
- margin-bottom: 35px;
-}
-
-.multiline {
- white-space: pre-wrap;
-}
diff --git a/src/app/pages/signup/signup.page.scss b/src/app/pages/signup/signup.page.scss
index 0218f8780..51fc067a9 100644
--- a/src/app/pages/signup/signup.page.scss
+++ b/src/app/pages/signup/signup.page.scss
@@ -1,10 +1,12 @@
ion-title {
color: #333;
}
+
ion-grid {
height: 100%;
background: #fff !important;
}
+
ion-button {
&[disabled] {
opacity: 1;
@@ -22,6 +24,7 @@ ion-button {
ion-title {
width: 100%;
}
+
ion-input {
color: #000;
width: calc(100vw - var(--ion-padding, 23px));
@@ -32,6 +35,7 @@ ion-input {
border-width: 10px !important;
border-bottom: 10px !important;
}
+
.native-input.sc-ion-input-ios {
text-align: left;
border-color: gray !important;
@@ -40,17 +44,21 @@ ion-input {
border-width: 10px !important;
border-bottom: 10px !important;
}
+
.input_msg {
width: 100%;
height: 80px;
text-align: center;
}
+
.input_R {
text-align: right;
}
+
.input_C {
text-align: center;
}
+
.input {
width: calc(100vw - var(--ion-padding, 23px)) !important;
border-color: #564dfc !important;
@@ -60,9 +68,11 @@ ion-input {
padding-left: 10px !important;
padding-right: 10px !important;
}
+
.img {
--height: 127.15px !important;
}
+
.logo {
width: 100%;
display: flex;
@@ -73,18 +83,21 @@ ion-input {
justify-content: center;
align-items: center;
}
+
.inputs {
width: 100% !important;
display: flex;
flex: 1;
height: 35vh;
}
+
.buttons {
width: 100% !important;
display: flex;
flex: 1;
bottom: 0px;
}
+
ion-content {
display: flex;
flex: 1;
diff --git a/src/app/pages/information/information-routing.module.ts b/src/app/pages/storage/proof/information/information-routing.module.ts
similarity index 100%
rename from src/app/pages/information/information-routing.module.ts
rename to src/app/pages/storage/proof/information/information-routing.module.ts
diff --git a/src/app/pages/information/information.module.ts b/src/app/pages/storage/proof/information/information.module.ts
similarity index 53%
rename from src/app/pages/information/information.module.ts
rename to src/app/pages/storage/proof/information/information.module.ts
index c0b55be49..b74acb954 100644
--- a/src/app/pages/information/information.module.ts
+++ b/src/app/pages/storage/proof/information/information.module.ts
@@ -1,6 +1,10 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
-import { FormsModule } from '@angular/forms';
+import { MatButtonModule } from '@angular/material/button';
+import { MatIconModule } from '@angular/material/icon';
+import { MatListModule } from '@angular/material/list';
+import { MatSnackBarModule } from '@angular/material/snack-bar';
+import { MatToolbarModule } from '@angular/material/toolbar';
import { IonicModule } from '@ionic/angular';
import { TranslocoModule } from '@ngneat/transloco';
import { InformationPageRoutingModule } from './information-routing.module';
@@ -9,10 +13,14 @@ import { InformationPage } from './information.page';
@NgModule({
imports: [
CommonModule,
- FormsModule,
IonicModule,
InformationPageRoutingModule,
- TranslocoModule
+ TranslocoModule,
+ MatToolbarModule,
+ MatButtonModule,
+ MatIconModule,
+ MatListModule,
+ MatSnackBarModule
],
declarations: [InformationPage]
})
diff --git a/src/app/pages/storage/proof/information/information.page.html b/src/app/pages/storage/proof/information/information.page.html
new file mode 100644
index 000000000..2395c88e4
--- /dev/null
+++ b/src/app/pages/storage/proof/information/information.page.html
@@ -0,0 +1,38 @@
+
+
+ {{ t('informationDetails') }}
+
+
+
+
+ {{ t('location') }}
+
+ information
+ {{ information.name }}
+ {{ information.value }}
+
+
+ {{ t('device') }}
+
+ information
+ {{ information.name }}
+ {{ information.value }}
+
+
+ {{ t('other') }}
+
+ information
+ {{ information.name }}
+ {{ information.value }}
+
+
+
+
\ No newline at end of file
diff --git a/src/app/pages/storage/proof/information/information.page.scss b/src/app/pages/storage/proof/information/information.page.scss
new file mode 100644
index 000000000..0d9c2d0d0
--- /dev/null
+++ b/src/app/pages/storage/proof/information/information.page.scss
@@ -0,0 +1,3 @@
+mat-toolbar {
+ background: white;
+}
diff --git a/src/app/pages/information/information.page.spec.ts b/src/app/pages/storage/proof/information/information.page.spec.ts
similarity index 59%
rename from src/app/pages/information/information.page.spec.ts
rename to src/app/pages/storage/proof/information/information.page.spec.ts
index 53322231a..ded686776 100644
--- a/src/app/pages/information/information.page.spec.ts
+++ b/src/app/pages/storage/proof/information/information.page.spec.ts
@@ -1,4 +1,9 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { MatButtonModule } from '@angular/material/button';
+import { MatIconModule } from '@angular/material/icon';
+import { MatListModule } from '@angular/material/list';
+import { MatSnackBarModule } from '@angular/material/snack-bar';
+import { MatToolbarModule } from '@angular/material/toolbar';
import { RouterTestingModule } from '@angular/router/testing';
import { IonicModule } from '@ionic/angular';
import { getTranslocoModule } from 'src/app/transloco/transloco-root.module.spec';
@@ -11,7 +16,16 @@ describe('InformationPage', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [InformationPage],
- imports: [IonicModule.forRoot(), RouterTestingModule, getTranslocoModule()]
+ imports: [
+ IonicModule.forRoot(),
+ RouterTestingModule,
+ getTranslocoModule(),
+ MatToolbarModule,
+ MatButtonModule,
+ MatIconModule,
+ MatListModule,
+ MatSnackBarModule
+ ]
}).compileComponents();
fixture = TestBed.createComponent(InformationPage);
diff --git a/src/app/pages/information/information.page.ts b/src/app/pages/storage/proof/information/information.page.ts
similarity index 78%
rename from src/app/pages/information/information.page.ts
rename to src/app/pages/storage/proof/information/information.page.ts
index a57b8b4da..3fb1aa917 100644
--- a/src/app/pages/information/information.page.ts
+++ b/src/app/pages/storage/proof/information/information.page.ts
@@ -1,12 +1,17 @@
import { Component } from '@angular/core';
+import { MatSnackBar } from '@angular/material/snack-bar';
import { ActivatedRoute } from '@angular/router';
+import { Plugins } from '@capacitor/core';
+import { TranslocoService } from '@ngneat/transloco';
import { UntilDestroy } from '@ngneat/until-destroy';
-import { map, pluck, switchMap } from 'rxjs/operators';
+import { map, switchMap } from 'rxjs/operators';
import { InformationType } from 'src/app/services/data/information/information';
import { InformationRepository } from 'src/app/services/data/information/information-repository.service';
import { ProofRepository } from 'src/app/services/data/proof/proof-repository.service';
import { isNonNullable } from 'src/app/utils/rx-operators';
+const { Clipboard } = Plugins;
+
@UntilDestroy({ checkProperties: true })
@Component({
selector: 'app-information',
@@ -22,26 +27,31 @@ export class InformationPage {
isNonNullable()
);
- readonly hash$ = this.proof$.pipe(pluck('hash'));
-
readonly locationInformation$ = this.proof$.pipe(
switchMap(proof => this.informationRepository.getByProof$(proof)),
map(informationList => informationList.filter(information => information.type === InformationType.Location))
);
- readonly otherInformation$ = this.proof$.pipe(
+ readonly deviceInformation$ = this.proof$.pipe(
switchMap(proof => this.informationRepository.getByProof$(proof)),
- map(informationList => informationList.filter(information => information.type === InformationType.Other))
+ map(informationList => informationList.filter(information => information.type === InformationType.Device))
);
- readonly deviceInformation$ = this.proof$.pipe(
+ readonly otherInformation$ = this.proof$.pipe(
switchMap(proof => this.informationRepository.getByProof$(proof)),
- map(informationList => informationList.filter(information => information.type === InformationType.Device))
+ map(informationList => informationList.filter(information => information.type === InformationType.Other))
);
constructor(
private readonly route: ActivatedRoute,
private readonly proofRepository: ProofRepository,
private readonly informationRepository: InformationRepository,
+ private readonly translocoService: TranslocoService,
+ private readonly snackBar: MatSnackBar,
) { }
+
+ copyToClipboard(value: string) {
+ Clipboard.write({ string: value });
+ this.snackBar.open(this.translocoService.translate('message.copiedToClipboard'));
+ }
}
diff --git a/src/app/pages/proof/proof-routing.module.ts b/src/app/pages/storage/proof/proof-routing.module.ts
similarity index 58%
rename from src/app/pages/proof/proof-routing.module.ts
rename to src/app/pages/storage/proof/proof-routing.module.ts
index 81d70a329..812a1f7c3 100644
--- a/src/app/pages/proof/proof-routing.module.ts
+++ b/src/app/pages/storage/proof/proof-routing.module.ts
@@ -1,10 +1,15 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
+import { AuthGuardService } from 'src/app/services/auth/auth-guard.service';
import { ProofPage } from './proof.page';
const routes: Routes = [{
path: '',
component: ProofPage
+}, {
+ path: 'information',
+ loadChildren: () => import('./information/information.module').then(m => m.InformationPageModule),
+ canActivate: [AuthGuardService],
}];
@NgModule({
diff --git a/src/app/pages/proof/proof.module.ts b/src/app/pages/storage/proof/proof.module.ts
similarity index 51%
rename from src/app/pages/proof/proof.module.ts
rename to src/app/pages/storage/proof/proof.module.ts
index 76dccc501..af3e1e033 100644
--- a/src/app/pages/proof/proof.module.ts
+++ b/src/app/pages/storage/proof/proof.module.ts
@@ -1,6 +1,10 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
-import { FormsModule } from '@angular/forms';
+import { MatButtonModule } from '@angular/material/button';
+import { MatIconModule } from '@angular/material/icon';
+import { MatListModule } from '@angular/material/list';
+import { MatSnackBarModule } from '@angular/material/snack-bar';
+import { MatToolbarModule } from '@angular/material/toolbar';
import { IonicModule } from '@ionic/angular';
import { TranslocoModule } from '@ngneat/transloco';
import { ProofPageRoutingModule } from './proof-routing.module';
@@ -9,10 +13,14 @@ import { ProofPage } from './proof.page';
@NgModule({
imports: [
CommonModule,
- FormsModule,
IonicModule,
ProofPageRoutingModule,
- TranslocoModule
+ TranslocoModule,
+ MatToolbarModule,
+ MatButtonModule,
+ MatIconModule,
+ MatListModule,
+ MatSnackBarModule
],
declarations: [ProofPage]
})
diff --git a/src/app/pages/storage/proof/proof.page.html b/src/app/pages/storage/proof/proof.page.html
new file mode 100644
index 000000000..eb8b03670
--- /dev/null
+++ b/src/app/pages/storage/proof/proof.page.html
@@ -0,0 +1,69 @@
+
+
+ {{ t('proofDetails') }}
+
+
+
+
+
+
+
+
+ {{ t('information') }}
+
+ sticky_note_2
+ {{ t('caption') }}
+ {{ caption$ | async }}
+
+
+ code
+ {{ t('hash') }}
+ {{ hash$ | async }}
+
+
+
+ access_time
+ {{ t('timestamp') }}
+ {{ timestamp$ | async | date:'long' }}
+
+
+ image
+ {{ t('mimeType') }}
+ {{ mimeType$ | async }}
+
+
+ place
+ {{ t('location') }}
+ {{ location$ | async }}
+
+
+
+
+ {{ t('signature') }}
+
+ policy
+ {{ t('signature') }}
+ {{ (signature$ | async)?.signature }}
+
+
+
+ lock
+ {{ t('publicKey') }}
+ {{ (signature$ | async)?.publicKey }}
+
+
+
+
\ No newline at end of file
diff --git a/src/app/pages/storage/proof/proof.page.scss b/src/app/pages/storage/proof/proof.page.scss
new file mode 100644
index 000000000..177f16d44
--- /dev/null
+++ b/src/app/pages/storage/proof/proof.page.scss
@@ -0,0 +1,20 @@
+mat-toolbar {
+ background: white;
+}
+
+.toolbar-spacer {
+ flex: 1 1 auto;
+}
+
+.page-content {
+ padding-bottom: 16px;
+}
+
+button.center {
+ display: block;
+ margin: 0 auto;
+}
+
+.proof-image {
+ width: 100%;
+}
diff --git a/src/app/pages/proof/proof.page.spec.ts b/src/app/pages/storage/proof/proof.page.spec.ts
similarity index 58%
rename from src/app/pages/proof/proof.page.spec.ts
rename to src/app/pages/storage/proof/proof.page.spec.ts
index edd0581c4..14a01608f 100644
--- a/src/app/pages/proof/proof.page.spec.ts
+++ b/src/app/pages/storage/proof/proof.page.spec.ts
@@ -1,4 +1,9 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { MatButtonModule } from '@angular/material/button';
+import { MatIconModule } from '@angular/material/icon';
+import { MatListModule } from '@angular/material/list';
+import { MatSnackBarModule } from '@angular/material/snack-bar';
+import { MatToolbarModule } from '@angular/material/toolbar';
import { RouterTestingModule } from '@angular/router/testing';
import { IonicModule } from '@ionic/angular';
import { getTranslocoModule } from 'src/app/transloco/transloco-root.module.spec';
@@ -11,7 +16,16 @@ describe('ProofPage', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ProofPage],
- imports: [IonicModule.forRoot(), RouterTestingModule, getTranslocoModule()]
+ imports: [
+ IonicModule.forRoot(),
+ RouterTestingModule,
+ getTranslocoModule(),
+ MatToolbarModule,
+ MatButtonModule,
+ MatIconModule,
+ MatListModule,
+ MatSnackBarModule
+ ]
}).compileComponents();
fixture = TestBed.createComponent(ProofPage);
diff --git a/src/app/pages/proof/proof.page.ts b/src/app/pages/storage/proof/proof.page.ts
similarity index 57%
rename from src/app/pages/proof/proof.page.ts
rename to src/app/pages/storage/proof/proof.page.ts
index d9fe06fba..11c675f35 100644
--- a/src/app/pages/proof/proof.page.ts
+++ b/src/app/pages/storage/proof/proof.page.ts
@@ -1,20 +1,23 @@
import { Component } from '@angular/core';
+import { MatSnackBar } from '@angular/material/snack-bar';
import { ActivatedRoute, Router } from '@angular/router';
-import { AlertController } from '@ionic/angular';
+import { Plugins } from '@capacitor/core';
import { TranslocoService } from '@ngneat/transloco';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { defer } from 'rxjs';
-import { first, map, pluck, switchMap, switchMapTo } from 'rxjs/operators';
+import { map, pluck, switchMap, switchMapTo } from 'rxjs/operators';
import { BlockingActionService } from 'src/app/services/blocking-action/blocking-action.service';
+import { CapacitorProvider } from 'src/app/services/collector/information/capacitor-provider/capacitor-provider';
+import { WebCryptoApiProvider } from 'src/app/services/collector/signature/web-crypto-api-provider/web-crypto-api-provider';
import { ConfirmAlert } from 'src/app/services/confirm-alert/confirm-alert.service';
import { CaptionRepository } from 'src/app/services/data/caption/caption-repository.service';
-import { Importance } from 'src/app/services/data/information/information';
import { InformationRepository } from 'src/app/services/data/information/information-repository.service';
import { ProofRepository } from 'src/app/services/data/proof/proof-repository.service';
import { SignatureRepository } from 'src/app/services/data/signature/signature-repository.service';
-import { PublishersAlert } from 'src/app/services/publisher/publishers-alert/publishers-alert.service';
import { isNonNullable } from 'src/app/utils/rx-operators';
+const { Clipboard } = Plugins;
+
@UntilDestroy({ checkProperties: true })
@Component({
selector: 'app-proof',
@@ -34,9 +37,6 @@ export class ProofPage {
switchMap(proof => this.proofRepository.getRawFile$(proof)),
map(rawBase64 => `data:image/png;base64,${rawBase64}`)
);
- readonly hash$ = this.proof$.pipe(pluck('hash'));
- readonly mimeType$ = this.proof$.pipe(pluck('mimeType'));
- readonly timestamp$ = this.proof$.pipe(map(proof => new Date(proof.timestamp)));
readonly caption$ = this.proof$.pipe(
switchMap(proof => this.captionRepository.getByProof$(proof)),
map(caption => {
@@ -44,46 +44,34 @@ export class ProofPage {
return '';
})
);
-
- readonly providersWithImportantInformation$ = this.proof$.pipe(
+ readonly hash$ = this.proof$.pipe(pluck('hash'));
+ readonly timestamp$ = this.proof$.pipe(pluck('timestamp'));
+ readonly mimeType$ = this.proof$.pipe(pluck('mimeType'));
+ readonly location$ = this.proof$.pipe(
switchMap(proof => this.informationRepository.getByProof$(proof)),
- map(informationList => {
- const providers = new Set(informationList.map(information => information.provider));
- return [...providers].map(provider => ({
- provider,
- informationList: informationList.filter(
- information => information.provider === provider && information.importance === Importance.High
- )
- }));
- })
+ map(informationList => informationList.find(information => information.provider === CapacitorProvider.ID && information.name === 'Location')),
+ isNonNullable(),
+ pluck('value')
);
-
- readonly signatures$ = this.proof$.pipe(
- switchMap(proof => this.signatureRepository.getByProof$(proof))
+ readonly signature$ = this.proof$.pipe(
+ switchMap(proof => this.signatureRepository.getByProof$(proof)),
+ map(signatures => signatures.find(signature => signature.provider === WebCryptoApiProvider.ID)),
+ isNonNullable()
);
constructor(
private readonly router: Router,
private readonly route: ActivatedRoute,
private readonly translocoService: TranslocoService,
- private readonly alertController: AlertController,
private readonly confirmAlert: ConfirmAlert,
- private readonly publishersAlert: PublishersAlert,
private readonly proofRepository: ProofRepository,
private readonly captionRepository: CaptionRepository,
private readonly informationRepository: InformationRepository,
private readonly signatureRepository: SignatureRepository,
- private readonly blockingActionService: BlockingActionService
+ private readonly blockingActionService: BlockingActionService,
+ private readonly snackBar: MatSnackBar
) { }
- publish() {
- this.proof$.pipe(
- first(),
- switchMap(proof => this.publishersAlert.present$(proof)),
- untilDestroyed(this)
- ).subscribe();
- }
-
remove() {
const onConfirm = () => this.blockingActionService.run$(
this.proof$.pipe(
@@ -96,38 +84,8 @@ export class ProofPage {
return this.confirmAlert.present$(onConfirm).pipe(untilDestroyed(this)).subscribe();
}
- editCaption() {
- const captionInputName = 'captionInputName';
- this.caption$.pipe(
- first(),
- switchMap(caption => this.alertController.create({
- header: this.translocoService.translate('editCaption'),
- inputs: [{
- name: captionInputName,
- type: 'text',
- value: caption,
- placeholder: this.translocoService.translate('nothingHere')
- }],
- buttons: [{
- text: this.translocoService.translate('cancel'),
- role: 'cancel'
- }, {
- text: this.translocoService.translate('ok'),
- handler: (inputs) => this.saveCaption(inputs[captionInputName])
- }]
- })),
- switchMap(alertElement => alertElement.present()),
- untilDestroyed(this)
- ).subscribe();
- }
-
- private saveCaption(text: string) {
- this.proof$.pipe(
- switchMap(proof => this.captionRepository.addOrEdit$({
- proofHash: proof.hash,
- text
- })),
- untilDestroyed(this)
- ).subscribe();
+ copyToClipboard(value: string) {
+ Clipboard.write({ string: value });
+ this.snackBar.open(this.translocoService.translate('message.copiedToClipboard'));
}
}
diff --git a/src/app/pages/storage/storage-routing.module.ts b/src/app/pages/storage/storage-routing.module.ts
index 55267d4cc..aa44a1218 100644
--- a/src/app/pages/storage/storage-routing.module.ts
+++ b/src/app/pages/storage/storage-routing.module.ts
@@ -5,6 +5,9 @@ import { StoragePage } from './storage.page';
const routes: Routes = [{
path: '',
component: StoragePage,
+}, {
+ path: 'proof',
+ loadChildren: () => import('./proof/proof.module').then(m => m.ProofPageModule),
}];
@NgModule({
diff --git a/src/app/pages/storage/storage.page.html b/src/app/pages/storage/storage.page.html
index 9e74cf512..5445f7eb7 100644
--- a/src/app/pages/storage/storage.page.html
+++ b/src/app/pages/storage/storage.page.html
@@ -45,7 +45,7 @@
{{ proofsWithRaw[0].date }}
diff --git a/src/app/pages/storage/storage.page.scss b/src/app/pages/storage/storage.page.scss
index e64736bca..b3e3d3a59 100644
--- a/src/app/pages/storage/storage.page.scss
+++ b/src/app/pages/storage/storage.page.scss
@@ -11,6 +11,10 @@ mat-sidenav {
width: 60%;
}
+mat-sidenav-content {
+ overflow: hidden;
+}
+
mat-toolbar {
background: white;
}
diff --git a/src/app/services/blocking-action/blocking-action.service.ts b/src/app/services/blocking-action/blocking-action.service.ts
index 96e67317f..321e6b383 100644
--- a/src/app/services/blocking-action/blocking-action.service.ts
+++ b/src/app/services/blocking-action/blocking-action.service.ts
@@ -13,8 +13,11 @@ export class BlockingActionService {
private readonly loadingController: LoadingController
) { }
- run$(action$: Observable, opts: LoadingOptions) {
- return defer(() => this.loadingController.create(opts)).pipe(
+ run$(action$: Observable, opts: Partial) {
+ return defer(() => this.loadingController.create({
+ mode: 'md',
+ ...opts
+ })).pipe(
switchMap(loading => this._run$(action$, loading))
);
}
diff --git a/src/app/services/collector/information/capacitor-provider/capacitor-provider.ts b/src/app/services/collector/information/capacitor-provider/capacitor-provider.ts
index 2005d8726..4fff03219 100644
--- a/src/app/services/collector/information/capacitor-provider/capacitor-provider.ts
+++ b/src/app/services/collector/information/capacitor-provider/capacitor-provider.ts
@@ -10,7 +10,7 @@ import { InformationProvider } from '../information-provider';
const { Device, Geolocation } = Plugins;
-const preferences = PreferenceManager.DEFAULT_INFORMATION_PROVIDER_PREF;
+const preferences = PreferenceManager.CAPACITOR_PROVIDER_PREF;
const enum PrefKeys {
CollectDeviceInfo = 'collectDeviceInfo',
CollectLocationInfo = 'collectLocationInfo'
@@ -18,7 +18,8 @@ const enum PrefKeys {
export class CapacitorProvider extends InformationProvider {
- readonly name = 'Capacitor';
+ static readonly ID = 'capacitor';
+ readonly id = CapacitorProvider.ID;
constructor(
informationRepository: InformationRepository,
@@ -63,91 +64,91 @@ export class CapacitorProvider extends InformationProvider {
if (deviceInfo !== undefined) {
informationList.push({
proofHash: proof.hash,
- provider: this.name,
+ provider: this.id,
name: this.translocoService.translate('uuid'),
value: String(deviceInfo.uuid),
importance: Importance.High,
- type: InformationType.Other
+ type: InformationType.Device
}, {
proofHash: proof.hash,
- provider: this.name,
+ provider: this.id,
name: this.translocoService.translate('deviceName'),
value: String(deviceInfo.name),
importance: Importance.Low,
type: InformationType.Device
}, {
proofHash: proof.hash,
- provider: this.name,
+ provider: this.id,
name: this.translocoService.translate('deviceModel'),
value: String(deviceInfo.model),
importance: Importance.Low,
type: InformationType.Device
}, {
proofHash: proof.hash,
- provider: this.name,
+ provider: this.id,
name: this.translocoService.translate('devicePlatform'),
value: String(deviceInfo.platform),
importance: Importance.Low,
type: InformationType.Device
}, {
proofHash: proof.hash,
- provider: this.name,
+ provider: this.id,
name: this.translocoService.translate('appVersion'),
value: String(deviceInfo.appVersion),
importance: Importance.Low,
type: InformationType.Device
}, {
proofHash: proof.hash,
- provider: this.name,
+ provider: this.id,
name: this.translocoService.translate('appVersionCode'),
value: String(deviceInfo.appBuild),
importance: Importance.Low,
type: InformationType.Device
}, {
proofHash: proof.hash,
- provider: this.name,
+ provider: this.id,
name: this.translocoService.translate('operatingSystem'),
value: String(deviceInfo.operatingSystem),
importance: Importance.Low,
type: InformationType.Device
}, {
proofHash: proof.hash,
- provider: this.name,
+ provider: this.id,
name: this.translocoService.translate('osVersion'),
value: String(deviceInfo.osVersion),
importance: Importance.Low,
type: InformationType.Device
}, {
proofHash: proof.hash,
- provider: this.name,
+ provider: this.id,
name: this.translocoService.translate('deviceManufacturer'),
value: String(deviceInfo.manufacturer),
importance: Importance.Low,
type: InformationType.Device
}, {
proofHash: proof.hash,
- provider: this.name,
+ provider: this.id,
name: this.translocoService.translate('runningOnVm'),
value: String(deviceInfo.isVirtual),
importance: Importance.Low,
type: InformationType.Device
}, {
proofHash: proof.hash,
- provider: this.name,
+ provider: this.id,
name: this.translocoService.translate('usedMemory'),
value: String(deviceInfo.memUsed),
importance: Importance.Low,
type: InformationType.Device
}, {
proofHash: proof.hash,
- provider: this.name,
+ provider: this.id,
name: this.translocoService.translate('freeDiskSpace'),
value: String(deviceInfo.diskFree),
importance: Importance.Low,
type: InformationType.Device
}, {
proofHash: proof.hash,
- provider: this.name,
+ provider: this.id,
name: this.translocoService.translate('totalDiskSpace'),
value: String(deviceInfo.diskTotal),
importance: Importance.Low,
@@ -157,14 +158,14 @@ export class CapacitorProvider extends InformationProvider {
if (batteryInfo !== undefined) {
informationList.push({
proofHash: proof.hash,
- provider: this.name,
+ provider: this.id,
name: this.translocoService.translate('batteryLevel'),
value: String(batteryInfo.batteryLevel),
importance: Importance.Low,
type: InformationType.Device
}, {
proofHash: proof.hash,
- provider: this.name,
+ provider: this.id,
name: this.translocoService.translate('batteryCharging'),
value: String(batteryInfo.isCharging),
importance: Importance.Low,
@@ -174,7 +175,7 @@ export class CapacitorProvider extends InformationProvider {
if (languageCode !== undefined) {
informationList.push({
proofHash: proof.hash,
- provider: this.name,
+ provider: this.id,
name: this.translocoService.translate('deviceLanguageCode'),
value: String(languageCode.value),
importance: Importance.Low,
@@ -184,7 +185,7 @@ export class CapacitorProvider extends InformationProvider {
if (geolocationPosition !== undefined) {
informationList.push({
proofHash: proof.hash,
- provider: this.name,
+ provider: this.id,
name: this.translocoService.translate('location'),
value: `(${geolocationPosition.coords.latitude}, ${geolocationPosition.coords.longitude})`,
importance: Importance.High,
diff --git a/src/app/services/collector/information/information-provider.ts b/src/app/services/collector/information/information-provider.ts
index 5ddfbaade..46d9162b5 100644
--- a/src/app/services/collector/information/information-provider.ts
+++ b/src/app/services/collector/information/information-provider.ts
@@ -6,7 +6,7 @@ import { Proof } from '../../data/proof/proof';
export abstract class InformationProvider {
- abstract readonly name: string;
+ abstract readonly id: string;
constructor(
private readonly informationRepository: InformationRepository
diff --git a/src/app/services/collector/signature/signature-provider.ts b/src/app/services/collector/signature/signature-provider.ts
index dad87d54d..00f858b9e 100644
--- a/src/app/services/collector/signature/signature-provider.ts
+++ b/src/app/services/collector/signature/signature-provider.ts
@@ -7,7 +7,7 @@ import { SerializationService } from '../../serialization/serialization.service'
export abstract class SignatureProvider {
- abstract readonly name: string;
+ abstract readonly id: string;
constructor(
private readonly signatureRepository: SignatureRepository,
diff --git a/src/app/services/collector/signature/default-provider/default-provider.spec.ts b/src/app/services/collector/signature/web-crypto-api-provider/web-crypto-api-provider.spec.ts
similarity index 100%
rename from src/app/services/collector/signature/default-provider/default-provider.spec.ts
rename to src/app/services/collector/signature/web-crypto-api-provider/web-crypto-api-provider.spec.ts
diff --git a/src/app/services/collector/signature/default-provider/default-provider.ts b/src/app/services/collector/signature/web-crypto-api-provider/web-crypto-api-provider.ts
similarity index 80%
rename from src/app/services/collector/signature/default-provider/default-provider.ts
rename to src/app/services/collector/signature/web-crypto-api-provider/web-crypto-api-provider.ts
index 066184839..3c905de5d 100644
--- a/src/app/services/collector/signature/default-provider/default-provider.ts
+++ b/src/app/services/collector/signature/web-crypto-api-provider/web-crypto-api-provider.ts
@@ -6,15 +6,16 @@ import { createEcKeyPair$, signWithSha256AndEcdsa$ } from 'src/app/utils/crypto/
import { PreferenceManager } from 'src/app/utils/preferences/preference-manager';
import { SignatureProvider } from '../signature-provider';
-const preferences = PreferenceManager.DEFAULT_SIGNATURE_PROVIDER_PREF;
+const preferences = PreferenceManager.WEB_CRYPTO_API_PROVIDER_PREF;
const enum PrefKeys {
PublicKey = 'publicKey',
PrivateKey = 'privateKey'
}
-export class DefaultSignatureProvider extends SignatureProvider {
+export class WebCryptoApiProvider extends SignatureProvider {
- readonly name = 'Web Crypto API';
+ static readonly ID = 'web-crypto-api';
+ readonly id = WebCryptoApiProvider.ID;
static initialize$() {
return zip(
@@ -40,14 +41,14 @@ export class DefaultSignatureProvider extends SignatureProvider {
}
protected provide$(proof: Proof, serialized: string): Observable {
- return DefaultSignatureProvider.getPrivateKey$().pipe(
+ return WebCryptoApiProvider.getPrivateKey$().pipe(
first(),
switchMap(privateKeyHex => signWithSha256AndEcdsa$(serialized, privateKeyHex)),
- switchMap(signatureHex => zip(of(signatureHex), DefaultSignatureProvider.getPublicKey$())),
+ switchMap(signatureHex => zip(of(signatureHex), WebCryptoApiProvider.getPublicKey$())),
first(),
map(([signatureHex, publicKeyHex]) => ({
proofHash: proof.hash,
- provider: this.name,
+ provider: this.id,
signature: signatureHex,
publicKey: publicKeyHex
}))
diff --git a/src/app/services/confirm-alert/confirm-alert.service.ts b/src/app/services/confirm-alert/confirm-alert.service.ts
index 8ccf12290..92ac61e7a 100644
--- a/src/app/services/confirm-alert/confirm-alert.service.ts
+++ b/src/app/services/confirm-alert/confirm-alert.service.ts
@@ -24,7 +24,8 @@ export class ConfirmAlert {
}, {
text: this.translocoService.translate('ok'),
handler: onConfirm
- }]
+ }],
+ mode: 'md'
})).pipe(
switchMap(alertElement => alertElement.present())
);
diff --git a/src/app/services/publisher/publishers-alert/publishers-alert.service.ts b/src/app/services/publisher/publishers-alert/publishers-alert.service.ts
index 6945bce95..f856c4cbf 100644
--- a/src/app/services/publisher/publishers-alert/publishers-alert.service.ts
+++ b/src/app/services/publisher/publishers-alert/publishers-alert.service.ts
@@ -39,7 +39,8 @@ export class PublishersAlert {
}, {
text: this.translocoService.translate('ok'),
handler: (name) => this.getPublisherByName(name)?.publish(proof)
- }]
+ }],
+ mode: 'md'
})),
switchMap(alertElement => alertElement.present())
);
diff --git a/src/app/utils/preferences/preference-manager.ts b/src/app/utils/preferences/preference-manager.ts
index bffc7b4de..6ff899417 100644
--- a/src/app/utils/preferences/preference-manager.ts
+++ b/src/app/utils/preferences/preference-manager.ts
@@ -2,15 +2,15 @@ import { Preferences } from './preferences';
const enum RepositoryName {
Language = 'language',
- DefaultInformationProvider = 'defaultInformationProvider',
- DefaultSignatureProvider = 'defaultSignatureProvider',
+ CapacitorProvider = 'capacitorProvider',
+ WebCryptoApiProvider = 'webCryptoApiProvider',
NumbersStoragePublisher = 'numbersStoragePublisher'
}
export class PreferenceManager {
static readonly LANGUAGE_PREF = new Preferences(RepositoryName.Language);
- static readonly DEFAULT_INFORMATION_PROVIDER_PREF = new Preferences(RepositoryName.DefaultInformationProvider);
- static readonly DEFAULT_SIGNATURE_PROVIDER_PREF = new Preferences(RepositoryName.DefaultSignatureProvider);
+ static readonly CAPACITOR_PROVIDER_PREF = new Preferences(RepositoryName.CapacitorProvider);
+ static readonly WEB_CRYPTO_API_PROVIDER_PREF = new Preferences(RepositoryName.WebCryptoApiProvider);
static readonly NUMBERS_STORAGE_PUBLISHER_PREF = new Preferences(RepositoryName.NumbersStoragePublisher);
}
diff --git a/src/assets/i18n/en-us.json b/src/assets/i18n/en-us.json
index 3804b561f..f9af7f5bd 100644
--- a/src/assets/i18n/en-us.json
+++ b/src/assets/i18n/en-us.json
@@ -76,6 +76,7 @@
"viewAll": "View All",
"address": "Address",
"mediaId": "Media ID",
+ "media": "Media",
"message": {
"areYouSure": "This action cannot be undone.",
"verificationEmailSent": "A verification email has been sent to your email address.",
diff --git a/src/assets/i18n/zh-tw.json b/src/assets/i18n/zh-tw.json
index bff5b3a2e..a4a960c58 100644
--- a/src/assets/i18n/zh-tw.json
+++ b/src/assets/i18n/zh-tw.json
@@ -76,6 +76,7 @@
"viewAll": "檢視全部",
"address": "地址",
"mediaId": "媒體 ID",
+ "media": "媒體",
"message": {
"areYouSure": "此操作不可撤銷。",
"verificationEmailSent": "驗證電子郵件已發送到您的電子郵件地址。",
diff --git a/src/global.scss b/src/global.scss
index 5a081185e..8fabbe675 100644
--- a/src/global.scss
+++ b/src/global.scss
@@ -26,10 +26,19 @@
// @import "~@ionic/angular/css/flex-utils.css";
.ion-page {
- display: initial !important;
background-color: white;
}
.page-content {
- padding: 8px 16px;
+ flex: 1 1 auto;
+ overflow: auto;
+}
+
+mat-toolbar {
+ min-height: 56px;
+}
+
+button.expand {
+ width: calc(100vw - 16px);
+ margin: 0 8px;
}
diff --git a/src/theme/variables.scss b/src/theme/variables.scss
index 84e9bf65b..0958d6e47 100644
--- a/src/theme/variables.scss
+++ b/src/theme/variables.scss
@@ -266,6 +266,7 @@ html,
body {
height: 100%;
}
+
body {
margin: 0;
font-family: Roboto, "Helvetica Neue", sans-serif;