mirror of https://github.com/BTCPrivate/copay.git
Merge pull request #7025 from gabrielbazan7/feat/getAddrTest
Ref Receive view
This commit is contained in:
commit
094a6837f1
|
@ -27,6 +27,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 { 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';
|
||||
|
@ -89,6 +90,7 @@ export function createTranslateLoader(http: Http) {
|
|||
let pages: any = [
|
||||
AddPage,
|
||||
CreateWalletPage,
|
||||
CopayersPage,
|
||||
ImportWalletPage,
|
||||
JoinWalletPage,
|
||||
BackupWarningPage,
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<ion-header>
|
||||
<ion-navbar>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
|
||||
</ion-content>
|
|
@ -0,0 +1,13 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'page-copayers',
|
||||
templateUrl: 'copayers.html',
|
||||
})
|
||||
export class CopayersPage {
|
||||
|
||||
constructor(
|
||||
) {
|
||||
}
|
||||
|
||||
}
|
|
@ -1,27 +1,52 @@
|
|||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>{{ "Receive" | translate }}</ion-title>
|
||||
<ion-title>{{'Receive'|translate}}</ion-title>
|
||||
<ion-buttons *ngIf="showShareButton" (click)="shareAddress()" end>
|
||||
<ion-icon name="share"></ion-icon>
|
||||
</ion-buttons>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
<div *ngIf="wallet" class="qr-container">
|
||||
<ion-content>
|
||||
<div ng-if="wallet && wallet.isComplete() && wallet.needsBackup" (click)="openBackupNeededModal()" class="needs-backup-container">
|
||||
<div class="backup">
|
||||
<ion-icon name="alert"></ion-icon>
|
||||
<span translate>Wallet not backed up</span>
|
||||
<ion-icon name="arrow-forward"></ion-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="wallet && wallet.isComplete()" class="qr-container">
|
||||
<qr-code *ngIf="address" [value]="qrAddress" [level]="M" [size]="220" [foreground]="'#334'"></qr-code>
|
||||
<div>
|
||||
<span>{{ address }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<button [hidden]="!address" class="button-request" (click)="requestSpecificAmount()">
|
||||
<span translate>Request Specific amount</span>
|
||||
<ion-icon name="arrow-forward"></ion-icon>
|
||||
</button>
|
||||
<span translate>Request Specific amount</span>
|
||||
<ion-icon name="arrow-forward"></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button [hidden]="!address" class="button-address" (click)="setAddress(true)">
|
||||
<span translate>Generate new address</span>
|
||||
<span translate>Generate new address</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="wallet && !wallet.isComplete()" class="incomplete-wallet-container">
|
||||
<div class="title">
|
||||
<span translate>Incomplete wallet</span>
|
||||
</div>
|
||||
<div class="subtitle">
|
||||
<span translate>All signing devices must be added to this multisig wallet before bitcoin addresses can be created.</span>
|
||||
</div>
|
||||
<button ion-button (click)="goCopayers()" translate>Open wallet</button>
|
||||
</div>
|
||||
<div *ngIf="wallets" class="wallets-container" (click)="showWallets()">
|
||||
<img src="assets/img/icon-wallet.svg" class="icon-wallet">
|
||||
<div class="wallet-text">
|
||||
<div>{{wallet.name}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="!wallet">
|
||||
<ion-card>
|
||||
<ion-item>
|
||||
|
|
|
@ -1,5 +1,27 @@
|
|||
page-receive {
|
||||
$v-text-accent-color: #1abb9b;
|
||||
.incomplete-wallet-container {
|
||||
.title {
|
||||
padding-top: 10%;
|
||||
font-size: 25px;
|
||||
color: #444;
|
||||
text-align: center;
|
||||
}
|
||||
.subtitle {
|
||||
padding: 20px;
|
||||
color: #444;
|
||||
margin-top: 10%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.needs-backup-container {
|
||||
.backup {
|
||||
cursor: pointer;
|
||||
background-color: orange;
|
||||
color: #fff;
|
||||
padding: 5px 0;
|
||||
}
|
||||
}
|
||||
.qr-container {
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
|
@ -22,4 +44,47 @@ page-receive {
|
|||
color: $v-text-accent-color;
|
||||
}
|
||||
}
|
||||
.wallets-container {
|
||||
position: absolute;
|
||||
bottom: 0rem;
|
||||
width: 100%;
|
||||
border-top: solid 1px rgb(242, 242, 242);
|
||||
min-height: 78px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
img.icon-wallet {
|
||||
width: 35px !important;
|
||||
background-color: #647ce8;
|
||||
}
|
||||
.wallet-text {
|
||||
padding-left: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin wallets-list {
|
||||
height: 4rem;
|
||||
width: 4rem;
|
||||
content: " ";
|
||||
position: absolute;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0px 6px 12px 0px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.wallets::before {
|
||||
@include wallets-list;
|
||||
background: #647ce8 url('../assets/img/icon-wallet.svg') no-repeat 0px 0px;
|
||||
}
|
||||
|
||||
.action-sheet-container {
|
||||
.action-sheet-button {
|
||||
display: flex;
|
||||
justify-content: baseline;
|
||||
align-items: center;
|
||||
padding: 2.5rem;
|
||||
.button-inner {
|
||||
padding-left: 5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,18 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { NavController, NavParams } from 'ionic-angular';
|
||||
import { NavController, NavParams, Events, ActionSheetController, ModalController } from 'ionic-angular';
|
||||
|
||||
//native
|
||||
import { SocialSharing } from '@ionic-native/social-sharing';
|
||||
|
||||
//pages
|
||||
import { AmountPage } from '../send/amount/amount';
|
||||
import { CopayersPage } from '../copayers/copayers';
|
||||
import { BackupWarningModalPage } from '../backup/backup-warning-modal/backup-warning-modal';
|
||||
//providers
|
||||
import { WalletProvider } from '../../providers/wallet/wallet';
|
||||
import { ProfileProvider } from '../../providers/profile/profile';
|
||||
import { PopupProvider } from '../../providers/popup/popup';
|
||||
import { PlatformProvider } from '../../providers/platform/platform';
|
||||
|
||||
import * as _ from 'lodash';
|
||||
|
||||
|
@ -17,12 +27,19 @@ export class ReceivePage {
|
|||
public qrAddress: string;
|
||||
public wallets: any;
|
||||
public wallet: any;
|
||||
public showShareButton: boolean;
|
||||
|
||||
constructor(
|
||||
private navCtrl: NavController,
|
||||
private navParams: NavParams,
|
||||
private profileProvider: ProfileProvider,
|
||||
private walletProvider: WalletProvider
|
||||
private walletProvider: WalletProvider,
|
||||
private popupProvider: PopupProvider,
|
||||
private platformProvider: PlatformProvider,
|
||||
private events: Events,
|
||||
private actionSheetCtrl: ActionSheetController,
|
||||
private socialSharing: SocialSharing,
|
||||
private modalCtrl: ModalController
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -34,6 +51,15 @@ export class ReceivePage {
|
|||
this.wallets = this.profileProvider.getWallets();
|
||||
this.updateQrAddress();
|
||||
this.onSelect(this.checkSelectedWallet(this.wallet, this.wallets));
|
||||
this.showShareButton = this.platformProvider.isCordova;
|
||||
this.events.subscribe('bwsEvent', (e, walletId, type, n) => {
|
||||
// Update current address
|
||||
if (this.wallet && walletId == this.wallet.id && type == 'NewIncomingTx') this.setAddress(true);
|
||||
});
|
||||
}
|
||||
|
||||
ionViewWillLeave() {
|
||||
this.events.unsubscribe('bwsEvent');
|
||||
}
|
||||
|
||||
private onSelect(wallet: any): any {
|
||||
|
@ -45,7 +71,7 @@ export class ReceivePage {
|
|||
}
|
||||
|
||||
private setProtocolHandler(): void {
|
||||
this.protocolHandler = this.walletProvider.getProtocolHandler(this.wallet);
|
||||
this.protocolHandler = this.walletProvider.getProtocolHandler(this.wallet.coin);
|
||||
}
|
||||
|
||||
private checkSelectedWallet(wallet: any, wallets: any): any {
|
||||
|
@ -62,11 +88,14 @@ export class ReceivePage {
|
|||
}
|
||||
|
||||
private setAddress(newAddr?: boolean): void {
|
||||
|
||||
this.walletProvider.getAddress(this.wallet, newAddr).then((addr) => {
|
||||
this.address = addr;
|
||||
this.updateQrAddress();
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
if (err) {
|
||||
this.popupProvider.ionicAlert(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -74,4 +103,46 @@ export class ReceivePage {
|
|||
this.qrAddress = this.protocolHandler + ":" + this.address;
|
||||
}
|
||||
|
||||
public shareAddress(): void {
|
||||
let protocol = 'bitcoin';
|
||||
if (this.wallet.coin == 'bch') protocol += 'cash';
|
||||
this.socialSharing.share(protocol + ':' + this.address);
|
||||
}
|
||||
|
||||
public showWallets(): void {
|
||||
let buttons: Array<any> = [];
|
||||
let coinClass: string = "wallets";
|
||||
|
||||
this.wallets.forEach((wallet, index) => {
|
||||
|
||||
let walletButton: Object = {
|
||||
text: wallet.credentials.walletName,
|
||||
cssClass: coinClass,
|
||||
handler: () => {
|
||||
this.onSelect(wallet);
|
||||
}
|
||||
}
|
||||
buttons.push(walletButton);
|
||||
});
|
||||
|
||||
const actionSheet = this.actionSheetCtrl.create({
|
||||
title: 'Select a wallet',
|
||||
buttons: buttons
|
||||
});
|
||||
|
||||
actionSheet.present();
|
||||
}
|
||||
|
||||
public goCopayers(): void {
|
||||
this.navCtrl.push(CopayersPage, { walletId: this.wallet.credentials.walletId });
|
||||
};
|
||||
|
||||
public openBackupNeededModal(): void {
|
||||
const myModal = this.modalCtrl.create(BackupWarningModalPage, {}, {
|
||||
showBackdrop: true,
|
||||
enableBackdropDismiss: true,
|
||||
});
|
||||
myModal.present();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
import { TestBed, async } from '@angular/core/testing';
|
||||
import { HttpModule } from '@angular/http';
|
||||
import { ConfigProvider } from '../config/config';
|
||||
import { WalletProvider } from './wallet';
|
||||
import { Logger, Level as LoggerLevel } from '@nsalaun/ng-logger';
|
||||
import { BwcProvider } from '../bwc/bwc';
|
||||
import { TxFormatProvider } from '../tx-format/tx-format';
|
||||
import { PersistenceProvider } from '../persistence/persistence';
|
||||
import { BwcErrorProvider } from '../bwc-error/bwc-error';
|
||||
import { RateProvider } from '../rate/rate';
|
||||
import { Filter } from '../filter/filter';
|
||||
import { PopupProvider } from '../popup/popup';
|
||||
import { OnGoingProcess } from '../on-going-process/on-going-process';
|
||||
import { TouchIdProvider } from '../touchid/touchid';
|
||||
|
||||
describe('Provider: Wallet Provider', () => {
|
||||
let walletProvider: WalletProvider;
|
||||
|
||||
class BwcProviderMock {
|
||||
constructor() {
|
||||
};
|
||||
getErrors() {
|
||||
return "error";
|
||||
}
|
||||
}
|
||||
|
||||
class PersistenceProviderMock {
|
||||
constructor() {
|
||||
};
|
||||
getLastAddress(walletId: any) {
|
||||
return Promise.resolve('storedAddress');
|
||||
}
|
||||
storeLastAddress(walletId: any, address: any) {
|
||||
return Promise.resolve(address);
|
||||
}
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [HttpModule],
|
||||
providers: [
|
||||
WalletProvider,
|
||||
{ provide: ConfigProvider },
|
||||
{ provide: PersistenceProvider, useClass: PersistenceProviderMock },
|
||||
{ provide: Logger, useValue: new Logger(LoggerLevel.DEBUG) },
|
||||
{ provide: TxFormatProvider },
|
||||
{ provide: BwcProvider, useClass: BwcProviderMock },
|
||||
{ provide: BwcErrorProvider },
|
||||
{ provide: RateProvider },
|
||||
{ provide: Filter },
|
||||
{ provide: PopupProvider },
|
||||
{ provide: OnGoingProcess },
|
||||
{ provide: TouchIdProvider },
|
||||
],
|
||||
});
|
||||
walletProvider = TestBed.get(WalletProvider);
|
||||
});
|
||||
|
||||
describe('Function: Get Address Function', () => {
|
||||
|
||||
it('should get the last address stored', () => {
|
||||
let wallet = {
|
||||
isComplete: function () {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
let force = false;
|
||||
walletProvider.getAddress(wallet, force).then((address) => {
|
||||
expect(address).toEqual('storedAddress');
|
||||
});
|
||||
})
|
||||
|
||||
it('should reject to generate new address if wallet is not complete', () => {
|
||||
let wallet = {
|
||||
isComplete: function () {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
let force = true;
|
||||
walletProvider.getAddress(wallet, force).catch((err) => {
|
||||
expect(err).toEqual('WALLET_NOT_COMPLETE');
|
||||
});
|
||||
})
|
||||
|
||||
it('should force to generate new address', () => {
|
||||
let wallet = {
|
||||
isComplete: function () {
|
||||
return true;
|
||||
},
|
||||
createAddress: function ({ }, cb) {
|
||||
return cb(null, { address: 'newAddress' });
|
||||
}
|
||||
};
|
||||
let force = true;
|
||||
walletProvider.getAddress(wallet, force).then((address) => {
|
||||
expect(address).toEqual('newAddress');
|
||||
});
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
describe('Function: Get Protocol Handler Function', () => {
|
||||
|
||||
it('should return bitcoincash if coin is bch', () => {
|
||||
let coin = 'bch';
|
||||
let protocol = walletProvider.getProtocolHandler(coin);
|
||||
expect(protocol).toEqual('bitcoincash');
|
||||
})
|
||||
|
||||
it('should return bitcoin if coin is btc', () => {
|
||||
let coin = 'btc';
|
||||
let protocol = walletProvider.getProtocolHandler(coin);
|
||||
expect(protocol).toEqual('bitcoin');
|
||||
})
|
||||
|
||||
});
|
||||
});
|
|
@ -1252,8 +1252,8 @@ export class WalletProvider {
|
|||
});
|
||||
};
|
||||
|
||||
public getProtocolHandler(wallet: any): string {
|
||||
if (wallet.coin == 'bch') return 'bitcoincash';
|
||||
public getProtocolHandler(coin: string): string {
|
||||
if (coin == 'bch') return 'bitcoincash';
|
||||
else return 'bitcoin';
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue