Merge pull request #7230 from Gamboster/feat/createSharedWalletsV4

[V4] Feat: Create shared wallets
This commit is contained in:
Javier Donadío 2017-11-22 12:14:29 -03:00 committed by GitHub
commit d1c90816b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 221 additions and 38 deletions

View File

@ -29,7 +29,7 @@ import { CopayApp } from './app.component';
import { TabsPage } from '../pages/tabs/tabs';
import { AddPage } from '../pages/add/add';
import { CreateWalletPage } from '../pages/add/create-wallet/create-wallet';
import { CopayersPage } from '../pages/copayers/copayers';
import { CopayersPage } from '../pages/add/copayers/copayers';
import { ImportWalletPage } from '../pages/add/import-wallet/import-wallet';
import { JoinWalletPage } from '../pages/add/join-wallet/join-wallet';
import { BackupRequestPage } from '../pages/onboarding/backup-request/backup-request';

View File

@ -0,0 +1,62 @@
<ion-header>
<ion-navbar>
<ion-title *ngIf="wallet">{{ wallet.name }}</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<div *ngIf="wallet" [hidden]="wallet.notAuthorized">
<ion-list class="copayers-secret">
<ion-item>
{{ 'Share this invitation with your copayers' | translate }}
</ion-item>
<ion-item>
<div class="qr-code-container" copy-to-clipboard="{{ secret }}">
<qr-code [level]="L" [size]="220" [foreground]="'#334'" [value]="secret"></qr-code>
<div [hidden]="secret" class="spinner">
<ion-spinner></ion-spinner>
</div>
<div class="secret">
{{ secret || ('Loading...'|translate) }}
</div>
</div>
<button ion-button type="button" *ngIf="secret" (click)="showDeletePopup()" translate>Cancel invitation</button>
</ion-item>
</ion-list>
<div [hidden]="!secret">
<ion-card class="copayers-card">
<ion-card-header>
<span translate>Waiting for copayers</span>
<span>
[ <span translate>{{wallet.m}}-of-{{wallet.n}}</span> ]
</span>
</ion-card-header>
<ion-card-content>
<ion-item *ngFor="let copayer of copayers">
<span [hidden]="copayer.id != wallet.copayerId">
<ion-icon ios="ios-checkmark" md="md-checkmark"></ion-icon>
{{'Me'|translate}}
</span>
<span [hidden]="copayer.id == wallet.copayerId">
<ion-icon ios="ios-checkmark" md="md-checkmark"></ion-icon>
{{copayer.name}}
</span>
</ion-item>
<ion-item *ngIf="!wallet.isComplete()">
<ion-icon ios="ios-repeat" md="md-repeat"></ion-icon> {{'Waiting...'|translate}}
</ion-item>
</ion-card-content>
</ion-card>
<ion-card [hidden]="!wallet.notAuthorized" class="errors-card">
<h1 translate>Wallet incomplete and broken</h1>
<h4 translate>Delete it and create a new one</h4>
</ion-card>
</div>
</div>
</ion-content>

View File

@ -0,0 +1,23 @@
page-copayers {
.copayers-secret {
ion-item {
text-align: center;
}
.qr-code-container {
cursor: pointer;
.secret {
margin-top: 1rem;
margin-bottom: 2rem;
}
}
}
.copayers-card {
ion-card-header {
display: flex;
justify-content: space-between;
}
}
.errors-card {
color: red;
}
}

View File

@ -0,0 +1,111 @@
import { Component } from '@angular/core';
import { NavController, NavParams, Events } from 'ionic-angular';
import { Logger } from '@nsalaun/ng-logger';
// Pages
import { HomePage } from '../../../pages/home/home';
import { WalletDetailsPage } from '../../../pages/wallet-details/wallet-details';
// Providers
import { AppProvider } from '../../../providers/app/app';
import { BwcErrorProvider } from '../../../providers/bwc-error/bwc-error';
import { OnGoingProcessProvider } from "../../../providers/on-going-process/on-going-process";
import { PlatformProvider } from '../../../providers/platform/platform';
import { PopupProvider } from '../../../providers/popup/popup';
import { ProfileProvider } from '../../../providers/profile/profile';
import { WalletProvider } from '../../../providers/wallet/wallet';
@Component({
selector: 'page-copayers',
templateUrl: 'copayers.html',
})
export class CopayersPage {
public appName: string = this.appProvider.info.userVisibleName;
public appUrl: string = this.appProvider.info.url;
public isCordova: boolean = this.platformProvider.isCordova;
public wallet: any;
public copayers: any;
public secret: any;
constructor(
private appProvider: AppProvider,
private bwcErrorProvider: BwcErrorProvider,
private events: Events,
private logger: Logger,
private navCtrl: NavController,
private navParams: NavParams,
private platformProvider: PlatformProvider,
private popupProvider: PopupProvider,
private profileProvider: ProfileProvider,
private onGoingProcessProvider: OnGoingProcessProvider,
private walletProvider: WalletProvider
) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad CopayersPage');
this.wallet = this.profileProvider.getWallet(this.navParams.data.walletId);
this.updateWallet();
this.events.subscribe('bwsEvent', (walletId, type, n) => {
if (this.wallet && walletId == this.wallet.id && type == ('NewCopayer' || 'WalletComplete')) {
this.updateWallet();
}
});
}
ionViewWillLeave() {
this.events.unsubscribe('bwsEvent');
}
private updateWallet(): void {
this.logger.debug('Updating wallet:' + this.wallet.name)
this.walletProvider.getStatus(this.wallet, {}).then((status: any) => {
this.wallet.status = status;
this.copayers = this.wallet.status.wallet.copayers;
this.secret = this.wallet.status.wallet.secret;
if (status.wallet.status == 'complete') {
this.wallet.openWallet((err: any, status: any) => {
if (err)
this.logger.error(err);
this.navCtrl.setRoot(HomePage);
this.navCtrl.popToRoot();
this.navCtrl.push(WalletDetailsPage, { walletId: this.wallet.credentials.walletId });
});
}
}).catch((err: any) => {
this.popupProvider.ionicAlert(this.bwcErrorProvider.msg(err, 'Could not update wallet')); // TODO: GetTextCatalog
return;
});
}
public showDeletePopup(): void {
let title = 'Confirm'; // TODO: GetTextCatalog
let msg = 'Are you sure you want to cancel and delete this wallet?'; // TODO: GetTextCatalog
this.popupProvider.ionicConfirm(title, msg, 'Ok', 'Cancel').then((res: any) => {
if (res) this.deleteWallet();
});
}
private deleteWallet(): void {
this.onGoingProcessProvider.set('deletingWallet', true);
this.profileProvider.deleteWalletClient(this.wallet).then(() => {
this.onGoingProcessProvider.set('deletingWallet', false);
// TODO: pushNotificationsService.unsubscribe(this.wallet);
this.navCtrl.setRoot(HomePage);
this.navCtrl.popToRoot();
this.navCtrl.parent.select(0);
}).catch((err: any) => {
this.onGoingProcessProvider.set('deletingWallet', false);
this.popupProvider.ionicAlert('Error', err.message || err); // TODO: GetTextCatalog
});
}
}

View File

@ -5,6 +5,7 @@ import { Logger } from '@nsalaun/ng-logger';
// Pages
import { HomePage } from '../../../pages/home/home';
import { CopayersPage } from '../copayers/copayers';
// Providers
import { AppProvider } from '../../../providers/app/app';
@ -260,7 +261,7 @@ export class CreateWalletPage implements OnInit {
if (!wallet.isComplete()) {
this.navCtrl.setRoot(HomePage);
this.navCtrl.popToRoot();
// TODO: tabs.copayers (QR view when shared wallet is created)
this.navCtrl.push(CopayersPage, { walletId: wallet.credentials.walletId });
} else {
this.navCtrl.setRoot(HomePage);
this.navCtrl.popToRoot();

View File

@ -1,8 +0,0 @@
<ion-header>
<ion-navbar>
</ion-navbar>
</ion-header>
<ion-content padding>
</ion-content>

View File

@ -1,13 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'page-copayers',
templateUrl: 'copayers.html',
})
export class CopayersPage {
constructor(
) {
}
}

View File

@ -1,15 +1,20 @@
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { AddPage } from "../add/add";
import { ProfileProvider } from '../../providers/profile/profile';
import { ReleaseProvider } from '../../providers/release/release';
import { WalletProvider } from '../../providers/wallet/wallet';
import { BwcErrorProvider } from '../../providers/bwc-error/bwc-error';
import { WalletDetailsPage } from '../wallet-details/wallet-details';
import { Logger } from '@nsalaun/ng-logger';
import * as _ from 'lodash';
import * as moment from 'moment';
// Pages
import { AddPage } from "../add/add";
import { CopayersPage } from '../add/copayers/copayers';
import { WalletDetailsPage } from '../wallet-details/wallet-details';
// Providers
import { BwcErrorProvider } from '../../providers/bwc-error/bwc-error';
import { ProfileProvider } from '../../providers/profile/profile';
import { ReleaseProvider } from '../../providers/release/release';
import { WalletProvider } from '../../providers/wallet/wallet';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
@ -27,7 +32,7 @@ export class HomePage {
private walletProvider: WalletProvider,
private bwcErrorProvider: BwcErrorProvider,
private logger: Logger
) {
) {
this.cachedBalanceUpdateOn = '';
}
@ -85,6 +90,9 @@ export class HomePage {
}
goToWalletDetails(wallet: any) {
if (!wallet.isComplete()) {
return this.navCtrl.push(CopayersPage, { walletId: wallet.credentials.walletId });
}
this.navCtrl.push(WalletDetailsPage, { walletId: wallet.credentials.walletId });
}
}

View File

@ -6,7 +6,7 @@ import { SocialSharing } from '@ionic-native/social-sharing';
//pages
import { AmountPage } from '../send/amount/amount';
import { CopayersPage } from '../copayers/copayers';
import { CopayersPage } from './../add/copayers/copayers';
import { BackupGamePage } from '../backup/backup-game/backup-game';
//providers
import { WalletProvider } from '../../providers/wallet/wallet';
@ -51,7 +51,7 @@ export class ReceivePage {
this.updateQrAddress();
this.onSelect(this.checkSelectedWallet(this.wallet, this.wallets));
this.showShareButton = this.platformProvider.isCordova;
this.events.subscribe('bwsEvent', (e, walletId, type, n) => {
this.events.subscribe('bwsEvent', (walletId, type, n) => {
// Update current address
if (this.wallet && walletId == this.wallet.id && type == 'NewIncomingTx') this.setAddress(true);
});

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { Logger } from '@nsalaun/ng-logger';
import { Events } from 'ionic-angular';
import { Logger } from '@nsalaun/ng-logger';
import * as _ from 'lodash';
//providers
@ -150,9 +150,8 @@ export class ProfileProvider {
wallet.on('walletCompleted', () => {
this.logger.debug('Wallet completed');
this.updateCredentials(JSON.parse(wallet.export()))
//$rootScope.$emit('Local/WalletCompleted', walletId); TODO
this.events.publish('Local/WalletCompleted', walletId);
});
wallet.initialize({
@ -191,7 +190,7 @@ export class ProfileProvider {
if (wallet.cachedTxps)
wallet.cachedTxps.isValid = false;
//$rootScope.$emit('bwsEvent', wallet.id, n.type, n); TODO
this.events.publish('bwsEvent', wallet.id, n.type, n);
}
public updateCredentials(credentials: any): void {
@ -615,7 +614,7 @@ export class ProfileProvider {
return reject(err);
});
}).catch((err: any) => {
//$rootScope.$emit('Local/DeviceError', err); TODO
this.events.publish('Local/DeviceError', err);
return reject(err);
});
});

View File

@ -14,7 +14,7 @@ import { BwcProvider } from '../bwc/bwc';
//pages
import { WalletDetailsPage } from '../../pages/wallet-details/wallet-details';
import { HomePage } from '../../pages/home/home';
import { CopayersPage } from '../../pages/copayers/copayers';
import { CopayersPage } from '../../pages/add/copayers/copayers';
import * as _ from 'lodash';