From 4c1cdcabcb53d81ed92f510d998b94b68f2e19bb Mon Sep 17 00:00:00 2001 From: Benoit Lavenier <benoit.lavenier@e-is.pro> Date: Mon, 19 Sep 2022 22:59:03 +0200 Subject: [PATCH] [enh] Wallet: allow to add account --- package.json | 1 + src/app/auth/auth.controller.ts | 18 ++-- src/app/home/home.page.html | 2 +- src/app/home/home.page.ts | 8 +- src/app/shared/pages/base.page.ts | 4 +- .../services/storage/storage.service.ts | 2 +- src/app/transfer/transfer.controller.ts | 31 ++++--- src/app/transfer/transfer.page.ts | 19 ++-- src/app/wallet/wallet.page.html | 13 +-- src/assets/i18n/fr.json | 1 + src/environments/environment.class.ts | 2 +- yarn.lock | 90 +++++++++++++++++++ 12 files changed, 153 insertions(+), 38 deletions(-) diff --git a/package.json b/package.json index af6c3d8..c67d543 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "@polkadot/ui-settings": "^2.9.7", "@polkadot/util": "^10.1.6", "@polkadot/util-crypto": "^10.1.6", + "@rx-angular/state": "^1.7.0", "angular2-qrcode": "^2.0.3", "crypto-browserify": "^3.12.0", "jdenticon": "^3.1.1", diff --git a/src/app/auth/auth.controller.ts b/src/app/auth/auth.controller.ts index 5bcd6e7..bfd71bb 100644 --- a/src/app/auth/auth.controller.ts +++ b/src/app/auth/auth.controller.ts @@ -14,6 +14,7 @@ import {TranslateService} from "@ngx-translate/core"; import {AuthModal, AuthModalOptions} from "@app/auth/auth.modal"; import {Router} from "@angular/router"; import {RegisterModal, RegisterModalOptions} from "@app/register/register.modal"; +import { Account } from "@app/wallet/account.model"; export declare type LoginMethodType = 'v1' | 'v2' | 'keyfile-v1'; export const LoginMethods: ListItem[] = [ @@ -120,7 +121,7 @@ export class AuthController { return data; } - async register(opts?: { redirectToWalletPage?: boolean; }) { + async register(opts?: { redirectToWalletPage?: boolean; }): Promise<Account> { const modal = await this.modalCtrl.create({ component: RegisterModal, componentProps: <RegisterModalOptions>{ @@ -132,10 +133,17 @@ export class AuthController { const {data} = await modal.onWillDismiss(); - if (data?.address && opts.redirectToWalletPage === true) { - setTimeout(() => this.router.navigate(['/wallet', data.address])); - } + try { + if (!data?.address) return null; // Skip - return data; + if (opts?.redirectToWalletPage) { + setTimeout(() => this.router.navigate(['/wallet', data.address])); + } + + return data as Account; + } + finally { + await modal.onDidDismiss(); + } } } diff --git a/src/app/home/home.page.html b/src/app/home/home.page.html index 7d658f0..30cbe6a 100644 --- a/src/app/home/home.page.html +++ b/src/app/home/home.page.html @@ -54,7 +54,7 @@ </ion-button> <!-- transfer --> - <ion-button expand="block" [routerLink]="'/transfer'"> + <ion-button expand="block" (click)="transfer()"> <ion-icon name="paper-plane" slot="start"></ion-icon> <ion-label translate>COMMON.BTN_SEND_MONEY</ion-label> </ion-button> diff --git a/src/app/home/home.page.ts b/src/app/home/home.page.ts index 6cf6c3b..539a6a0 100644 --- a/src/app/home/home.page.ts +++ b/src/app/home/home.page.ts @@ -7,6 +7,7 @@ import {Account} from "@app/wallet/account.model"; import {fadeInAnimation} from "@app/shared/animations"; import {Router} from "@angular/router"; import {AuthController} from "@app/auth/auth.controller"; +import { TransferController } from '@app/transfer/transfer.controller'; @Component({ selector: 'app-home', @@ -28,6 +29,7 @@ export class HomePage extends BasePage<Settings> implements OnInit { public networkService: NetworkService, public accountService: AccountService, public authController: AuthController, + public transferController: TransferController, public router: Router, @Inject(APP_LOCALES) public locales: LocaleConfig[] ) { @@ -78,9 +80,13 @@ export class HomePage extends BasePage<Settings> implements OnInit { } } - logout(event) { + logout(even?: UIEvent) { event?.preventDefault(); this.accountService.forgetAll(); this.defaultAccount = null; } + + transfer(event?: UIEvent) { + return this.transferController.transfer(event); + } } diff --git a/src/app/shared/pages/base.page.ts b/src/app/shared/pages/base.page.ts index cdf4715..5212c75 100644 --- a/src/app/shared/pages/base.page.ts +++ b/src/app/shared/pages/base.page.ts @@ -21,8 +21,8 @@ export abstract class BasePage< > implements OnInit, OnDestroy { - private _cd: ChangeDetectorRef; - private _subscription: Subscription; + protected _cd: ChangeDetectorRef; + protected _subscription: Subscription; protected translate: TranslateService; protected settings: SettingsService; diff --git a/src/app/shared/services/storage/storage.service.ts b/src/app/shared/services/storage/storage.service.ts index ef2608b..64b28c1 100644 --- a/src/app/shared/services/storage/storage.service.ts +++ b/src/app/shared/services/storage/storage.service.ts @@ -4,7 +4,7 @@ import {StartableService} from "@app/shared/services/startable-service.class"; import {IStorage} from "@app/shared/services/storage/storage.utils"; import {Platform} from '@ionic/angular'; import {environment} from "@environments/environment"; -import cordovaSQLiteDriver from 'localforage-cordovasqlitedriver'; +import * as cordovaSQLiteDriver from 'localforage-cordovasqlitedriver'; @Injectable({providedIn: 'root'}) export class StorageService extends StartableService<Storage> diff --git a/src/app/transfer/transfer.controller.ts b/src/app/transfer/transfer.controller.ts index 1567a1a..91f083b 100644 --- a/src/app/transfer/transfer.controller.ts +++ b/src/app/transfer/transfer.controller.ts @@ -25,24 +25,31 @@ export class TransferController { constructor( private platform: PlatformService, private translate: TranslateService, - private modalCtrl: ModalController + private modalCtrl: ModalController, + private router: Router ) { } async transfer(event: UIEvent, opts?: TransferPageOptions): Promise<string|undefined> { - console.info('[transfer] Opening transfer modal'); + if (this._mobile) { + console.info('[transfer] Opening transfer page'); + this.router.navigateByUrl('/transfer'); + } + else { + console.info('[transfer] Opening transfer modal'); - const modal = await this.modalCtrl.create({ - component: TransferPage, - componentProps: <TransferPageOptions>{ - ...opts, - dismissOnSubmit: true - } - }); - await modal.present(); - const {data} = await modal.onWillDismiss(); + const modal = await this.modalCtrl.create({ + component: TransferPage, + componentProps: <TransferPageOptions>{ + ...opts, + dismissOnSubmit: true + } + }); + await modal.present(); + const {data} = await modal.onWillDismiss(); - return data; + return data; + } } } diff --git a/src/app/transfer/transfer.page.ts b/src/app/transfer/transfer.page.ts index fbb8960..ed74baa 100644 --- a/src/app/transfer/transfer.page.ts +++ b/src/app/transfer/transfer.page.ts @@ -19,7 +19,7 @@ import {Currency} from "@app/network/currency.model"; import {Router} from "@angular/router"; import {BarcodeScanner} from "@capacitor-community/barcode-scanner"; import {Capacitor} from "@capacitor/core"; -import {CapacitorPlugins} from "@app/shared/services/plugins"; +import {CapacitorPlugins} from "@app/shared/capacitor/plugins"; export interface TransferPageOptions { issuer?: Account; @@ -187,10 +187,10 @@ export class TransferPage extends BasePage<Observable<Account[]>> implements OnD } } - protected hideWotModal(event?: UIEvent) { + protected async hideWotModal(event?: UIEvent) { if (this.wotModal && this.wotModal.isCmpOpen) { - this.wotModal.dismiss(); this._autoOpenWotModal = false; + await this.wotModal.dismiss(); } } @@ -234,7 +234,9 @@ export class TransferPage extends BasePage<Observable<Account[]>> implements OnD } async close(data?: any) { + // As a page if (this.routerOutlet) { + console.debug('[transfer] Closing page with result: ', data); if (this.routerOutlet?.canGoBack()) { this.routerOutlet.pop(); } @@ -242,10 +244,15 @@ export class TransferPage extends BasePage<Observable<Account[]>> implements OnD await this.router.navigateByUrl('/wallet'); } } + // As a modal else { - const hasTop = !!(await this.modalCtrl.getTop()) - if (hasTop) { - await this.modalCtrl.dismiss(data); + // First close wot modal (if opened) + await this.hideWotModal(); + + const modal = await this.modalCtrl.getTop(); + const hasModal = !!modal; + if (hasModal) { + this.modalCtrl.dismiss(data); } } diff --git a/src/app/wallet/wallet.page.html b/src/app/wallet/wallet.page.html index 2b75279..06c81ec 100644 --- a/src/app/wallet/wallet.page.html +++ b/src/app/wallet/wallet.page.html @@ -5,25 +5,20 @@ </ion-buttons> <ion-title translate>ACCOUNT.TITLE</ion-title> <ion-buttons slot="end"> - <ion-select *ngIf="$account|async; let accounts" + <ion-select *ngIf="$accounts|async; let accounts" [class.cdk-visually-hidden]="accounts|isEmptyArray" [(ngModel)]="data" + (ionChange)="onAccountChange($event)" [interface]="mobile ? 'action-sheet' : 'popover'" [interfaceOptions]="mobile ? actionSheetOptions : popoverOptions" [okText]="'COMMON.BTN_OK'|translate" [cancelText]="'COMMON.BTN_CANCEL'|translate"> <ion-select-option *ngFor="let account of accounts" [value]="account"> - - <ion-avatar *ngIf="loaded"> - <svg width="40" width="40" [data-jdenticon-value]="data.data?.randomId||data.address"></svg> - </ion-avatar> {{account|accountName}} </ion-select-option> - - <ion-select-option (click)="addNewWallet($event)" - [value]="null" - translate>ACCOUNT.WALLET_LIST.BTN_NEW</ion-select-option> + <ion-select-option [value]="new" + translate>ACCOUNT.WALLET_LIST.BTN_NEW_DOTS</ion-select-option> </ion-select> </ion-buttons> diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index 1e7c46c..00eb6b0 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -575,6 +575,7 @@ "WALLET_LIST": { "TITLE": "Mes portefeuilles", "BTN_NEW": "Ajouter un portefeuille", + "BTN_NEW_DOTS": "Ajouter un portefeuille...", "BTN_DOWNLOAD": "Télécharger la liste", "BTN_IMPORT_FILE_DOTS": "Importer depuis un fichier...", "NO_WALLET": "Aucun portefeuille secondaire", diff --git a/src/environments/environment.class.ts b/src/environments/environment.class.ts index fd7b959..fd9ab0d 100644 --- a/src/environments/environment.class.ts +++ b/src/environments/environment.class.ts @@ -1,5 +1,5 @@ import {AuthData} from "@app/auth/auth.model"; -import {StorageConfig} from '@ionic/storage-angular'; +import {StorageConfig} from '@ionic/storage'; export interface Environment { name: string; diff --git a/yarn.lock b/yarn.lock index 78bbb45..554f6a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2388,6 +2388,14 @@ "@types/websocket" "^1.0.5" websocket "^1.0.34" +"@rx-angular/state@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@rx-angular/state/-/state-1.7.0.tgz#54a1dbe34145c49b5101f13f89775f3e17aec34c" + integrity sha512-rrM5qlI6lDsSbTVo+uBoGpOuZ//msi2q72WYvw1MESPDrb9TnOLtVceDaYL0FBMDBhcqtmUsdOs6OoICaroSew== + dependencies: + ng-morph "^2.0.0" + tslib "^2.0.0" + "@schematics/angular@14.2.2": version "14.2.2" resolved "https://registry.npmjs.org/@schematics/angular/-/angular-14.2.2.tgz#3a9be8912e4f5a2d59c50e866b2853097fd656ff" @@ -2458,6 +2466,16 @@ resolved "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== +"@ts-morph/common@~0.9.0": + version "0.9.2" + resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.9.2.tgz#fc63ed4f8d3a45e4ed6849fe20a57f4f2baecc5d" + integrity sha512-IPyg+c3Am0EBoa63W0f/AKeLrJhvzMzQ4BIvD1baxLopmiHOj1HFTXYxC6e8iTZ+UYtN+/WFM9UyGRnoA20b8g== + dependencies: + fast-glob "^3.2.5" + minimatch "^3.0.4" + mkdirp "^1.0.4" + path-browserify "^1.0.1" + "@types/bn.js@^5.1.0": version "5.1.0" resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz" @@ -2606,6 +2624,11 @@ resolved "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz" integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== +"@types/minimatch@^3.0.3": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" + integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== + "@types/node-fetch@^2.6.2": version "2.6.2" resolved "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz" @@ -3212,6 +3235,11 @@ aria-query@^4.2.2: "@babel/runtime" "^7.10.2" "@babel/runtime-corejs3" "^7.10.2" +array-differ@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-3.0.0.tgz#3cbb3d0f316810eafcc47624734237d6aee4ae6b" + integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg== + array-flatten@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" @@ -3265,6 +3293,11 @@ arrify@^1.0.0: resolved "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= +arrify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" + integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== + asn1.js@^5.2.0: version "5.4.1" resolved "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz" @@ -3928,6 +3961,11 @@ clone@^1.0.2: resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= +code-block-writer@^10.1.1: + version "10.1.1" + resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-10.1.1.tgz#ad5684ed4bfb2b0783c8b131281ae84ee640a42f" + integrity sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw== + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" @@ -5831,6 +5869,17 @@ fast-glob@^3.2.11, fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" +fast-glob@^3.2.5: + version "3.2.12" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-json-stable-stringify@2.1.0, fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" @@ -7830,6 +7879,13 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz" integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== +minimatch@3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + minimatch@3.0.5, minimatch@^3.0.4: version "3.0.5" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz" @@ -7975,6 +8031,17 @@ multicast-dns@^7.2.5: dns-packet "^5.2.2" thunky "^1.0.2" +multimatch@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-5.0.0.tgz#932b800963cea7a31a033328fa1e0c3a1874dbe6" + integrity sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA== + dependencies: + "@types/minimatch" "^3.0.3" + array-differ "^3.0.0" + array-union "^2.1.0" + arrify "^2.0.1" + minimatch "^3.0.4" + mute-stream@0.0.8: version "0.0.8" resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz" @@ -8036,6 +8103,16 @@ next-tick@^1.1.0: resolved "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz" integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== +ng-morph@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ng-morph/-/ng-morph-2.1.0.tgz#3f5735962b112981de531c375b42311f18fa74d5" + integrity sha512-jn34Ter6HlY7E3yOoMhfk3cnUwjLlvcGTsAJ7jS0pZ3SAGi3hzqlf3oyUQO6fNfbFnydc33yNqQtUIrbHKCtNA== + dependencies: + jsonc-parser "3.0.0" + minimatch "3.0.4" + multimatch "5.0.0" + ts-morph "10.0.2" + ngx-color-picker@^12.0.1: version "12.0.1" resolved "https://registry.npmjs.org/ngx-color-picker/-/ngx-color-picker-12.0.1.tgz#bb3159fd685dfd23505e5a27300fa32bb42ebce8" @@ -8644,6 +8721,11 @@ parseurl@~1.3.2, parseurl@~1.3.3: resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== +path-browserify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + path-exists@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" @@ -10497,6 +10579,14 @@ tree-kill@1.2.2, tree-kill@^1.2.2: resolved "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== +ts-morph@10.0.2: + version "10.0.2" + resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-10.0.2.tgz#292418207db467326231b2be92828b5e295e7946" + integrity sha512-TVuIfEqtr9dW25K3Jajqpqx7t/zLRFxKu2rXQZSDjTm4MO4lfmuj1hn8WEryjeDDBFcNOCi+yOmYUYR4HucrAg== + dependencies: + "@ts-morph/common" "~0.9.0" + code-block-writer "^10.1.1" + ts-node@^8.10.2: version "8.10.2" resolved "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz#eee03764633b1234ddd37f8db9ec10b75ec7fb8d" -- GitLab