Merge branch 'ref/design' of https://github.com/bitpay/bitpay-wallet into feature/onboarding_last_steps

This commit is contained in:
Jamal Jackson 2016-09-08 15:42:47 -04:00
commit 4af098764d
23 changed files with 690 additions and 421 deletions

View file

@ -10,8 +10,13 @@
<ion-content> <ion-content>
<ion-list> <ion-list>
<a class="item item-remove-animate item-icon-right" type="item-text-wrap" ui-sref="tabs.create"> <a class="item item-remove-animate item-icon-right" type="item-text-wrap" ui-sref="tabs.create-personal">
<h2 translate>Create new wallet</h2> <h2 translate>New Personal Wallet</h2>
<i class="icon nav-item-arrow-right"></i>
</a>
<a class="item item-remove-animate item-icon-right" type="item-text-wrap" ui-sref="tabs.create-shared">
<h2 translate>Create Shared Wallet</h2>
<i class="icon nav-item-arrow-right"></i> <i class="icon nav-item-arrow-right"></i>
</a> </a>

View file

@ -1,4 +1,4 @@
<ion-view> <ion-view id="view-amount">
<ion-nav-bar class="bar-royal"> <ion-nav-bar class="bar-royal">
<ion-nav-buttons side="primary"> <ion-nav-buttons side="primary">
<button class="button back-button" ng-click="$ionicGoBack()"> <button class="button back-button" ng-click="$ionicGoBack()">
@ -7,24 +7,26 @@
</ion-nav-buttons> </ion-nav-buttons>
</ion-nav-bar> </ion-nav-bar>
<ion-content class="calculator" scroll="false" class="amount" ng-controller="amountController" ng-init="init()"> <ion-content scroll="false" class="amount" ng-controller="amountController" ng-init="init()">
<div class="card"> <div>
<div class="item item-divider" translate>Recipient</div> <div class="item item-no-bottom-border" translate>Recipient</div>
<div class="item item-text-wrap item-icon-left"> <div class="item item-text-wrap item-icon-left bitcoin-address">
<i class="icon ion-ios-person-outline"></i> <i class="icon ion-ios-person-outline"></i>
{{toName || toAddress}} <span>{{toName || toAddress}}</span>
</div> </div>
</div> </div>
<div class="card"> <div class="amount-pane">
<div class="item item-divider" translate>Amount</div>
<div class="item item-text-wrap item-button-right"> <div class="amount-bar">
<div class="title" translate>Amount</div>
<a class="postfix" ng-click="toggleAlternative()" ng-show="showAlternativeAmount">{{alternativeIsoCode}}</a> <a class="postfix" ng-click="toggleAlternative()" ng-show="showAlternativeAmount">{{alternativeIsoCode}}</a>
<a class="postfix" ng-click="toggleAlternative()" ng-show="!showAlternativeAmount">{{unitName}}</a> <a class="postfix" ng-click="toggleAlternative()" ng-show="!showAlternativeAmount">{{unitName}}</a>
</div>
<div class="amount">
<div class="text-light text-black m15b" ng-class="{'size-28': smallFont, 'size-36': !smallFont}"><span> {{amount || "0.00" }}</div> <div class="text-light text-black m15b" ng-class="{'size-28': smallFont, 'size-36': !smallFont}"><span> {{amount || "0.00" }}</div>
<div class="text-light text-black" ng-class="{'size-16': smallFont, 'size-17': !smallFont}" ng-show="!showAlternativeAmount"> <div class="text-light text-black" ng-class="{'size-16': smallFont, 'size-17': !smallFont}" ng-show="!showAlternativeAmount">
{{globalResult}} <span class="label gray text-white radius">{{amountResult || '0.00'}} {{alternativeIsoCode}}</span> {{globalResult}} <span class="label gray text-white radius">{{amountResult || '0.00'}} {{alternativeIsoCode}}</span>
@ -33,45 +35,42 @@
{{globalResult}} <span class="label gray text-white radius">{{alternativeResult || '0.00'}} {{unitName}}</span> {{globalResult}} <span class="label gray text-white radius">{{alternativeResult || '0.00'}} {{unitName}}</span>
</div> </div>
</div> </div>
</div> </div>
<div class="button-calc"> <div class="keypad">
<div class="row m5b"> <div class="row">
<button class="col columns col-25 text-center m0 operator" ng-click="resetAmount()"> <div class="col col-25 col-offset-75 operator-send"
AC
</button>
<button class="col columns text-center text-white m0"
ng-style="{'background-color':recipientColor || '#4b6178'}"
ng-disabled="alternativeResult <= 0 && amountResult <= 0" ng-click="finish()"> ng-disabled="alternativeResult <= 0 && amountResult <= 0" ng-click="finish()">
OK <i class="icon ion-ios-arrow-thin-right"></i>
</button> </div>
</div> </div>
<div class="row text-center"> <div class="row">
<div class="col columns" ng-click="pushDigit('7')">7</div> <div class="col digit" ng-click="pushDigit('7')">7</div>
<div class="col columns" ng-click="pushDigit('8')">8</div> <div class="col digit" ng-click="pushDigit('8')">8</div>
<div class="col columns" ng-click="pushDigit('9')">9</div> <div class="col digit" ng-click="pushDigit('9')">9</div>
<div class="col columns operator" ng-click="pushOperator('/')">/</div> <div class="col operator" ng-click="pushOperator('/')">/</div>
</div> </div>
<div class="row text-center"> <div class="row">
<div class="col columns" ng-click="pushDigit('4')">4</div> <div class="col digit" ng-click="pushDigit('4')">4</div>
<div class="col columns" ng-click="pushDigit('5')">5</div> <div class="col digit" ng-click="pushDigit('5')">5</div>
<div class="col columns" ng-click="pushDigit('6')">6</div> <div class="col digit" ng-click="pushDigit('6')">6</div>
<div class="col columns operator" ng-click="pushOperator('x')">x</div> <div class="col operator" ng-click="pushOperator('x')">x</div>
</div> </div>
<div class="row text-center"> <div class="row">
<div class="col columns" ng-click="pushDigit('1')">1</div> <div class="col digit" ng-click="pushDigit('1')">1</div>
<div class="col columns" ng-click="pushDigit('2')">2</div> <div class="col digit" ng-click="pushDigit('2')">2</div>
<div class="col columns" ng-click="pushDigit('3')">3</div> <div class="col digit" ng-click="pushDigit('3')">3</div>
<div class="col columns operator" ng-click="pushOperator('+')">+</div> <div class="col operator" ng-click="pushOperator('+')">+</div>
</div> </div>
<div class="row text-center"> <div class="row">
<div class="col columns operator" ng-click="pushDigit('.')">.</div> <div class="col digit" ng-click="pushDigit('.')">.</div>
<div class="col columns" ng-click="pushDigit('0')">0</div> <div class="col digit" ng-click="pushDigit('0')">0</div>
<div class="col columns operator icon ion-arrow-left-a" ng-click="removeDigit()"></div> <div class="col digit icon ion-backspace-outline" ng-click="removeDigit()"></div>
<div class="col columns operator" ng-click="pushOperator('-')">-</div> <div class="col operator" ng-click="pushOperator('-')">-</div>
</div> </div>
</div> </div>
</ion-content> </ion-content>

View file

@ -1,22 +0,0 @@
<ion-view>
<ion-nav-bar class="bar-royal">
<ion-nav-title>{{'Create new wallet' | translate}}</ion-nav-title>
<ion-nav-back-button>
<i class="icon ion-ios-arrow-thin-left"></i>
</ion-nav-back-button>
</ion-nav-bar>
<ion-content ng-controller="createController" ng-init="personal = true; init()">
<div class="row text-center">
<div class="col" ng-click="personal = true; setTotalCopayers(1)" ng-style="personal && {'border-bottom': '2px solid'}">
<span class="" translate>Personal Wallet</span>
</div>
<div class="col" ng-click="personal = false; setTotalCopayers(3)" ng-style="!personal && {'border-bottom': '2px solid'}">
<span class="" translate>Shared Wallet</span>
</div>
</div>
<div ng-include="'views/tab-create-personal.html'" ng-if="personal"></div>
<div ng-include="'views/tab-create-shared.html'" ng-if="!personal"></div>
</ion-content>
</ion-view>

View file

@ -1,16 +1,18 @@
<div class="wallets" ng-show="wallets[0]"> <div class="wallets" ng-show="wallets[0]">
<ion-slides class="slides" slider="data.slider"> <ion-slides class="slides" slider="data.slider">
<ion-slide-page ng-repeat="wallet in wallets track by $index"> <ion-slide-page ng-repeat="wallet in wallets track by $index">
<div class="item item-icon-left item-icon-right"> <div class="card">
<i class="icon ion-briefcase size-21" ng-style="{'color':wallet.color}"></i> <div class="item item-icon-left text-right">
{{wallet.name || wallet.id}} <i class="icon ion-briefcase size-21" ng-style="{'color':wallet.color}"></i>
<span class="item-note" ng-show="wallet.n > 1 && wallet.isComplete()"> <span>{{wallet.name || wallet.id}}</span>
{{wallet.m}}-of-{{wallet.n}} <span class="item-note" ng-show="wallet.n > 1 && wallet.isComplete()">
</span> {{wallet.m}}-of-{{wallet.n}}
<span class="badge badge-assertive" ng-show="!wallet.isComplete()" translate> </span>
Incomplete <span class="badge badge-assertive" ng-show="!wallet.isComplete()" translate>
</span> Incomplete
<i ng-show="wallet.needsBackup" class="icon ion-android-warning assertive"></i> </span>
<!-- <i ng-show="wallet.needsBackup" class="icon ion-android-warning assertive"></i> -->
</div>
</div> </div>
</ion-slide-page> </ion-slide-page>
</ion-slides> </ion-slides>

View file

@ -1,21 +1,21 @@
<ion-view id="terms-of-use"> <ion-modal-view id="terms-of-use">
<ion-nav-bar class="bar-ligt"> <ion-nav-bar class="bar-ligt">
<ion-nav-title>{{'Terms of Use' | translate}}</ion-nav-title> <ion-nav-title>{{'Terms of Use' | translate}}</ion-nav-title>
<ion-nav-buttons side="primary"> <ion-nav-buttons side="primary">
<button class="button no-border" href ui-sref="onboarding.disclaimer"> <button class="button no-border" ng-click="termsModal.hide()">
<i class="icon ion-arrow-left-c"></i> {{'Close' | translate}}
</button> </button>
</ion-nav-buttons> </ion-nav-buttons>
</ion-nav-bar> </ion-nav-bar>
<ion-content ng-controller="termsController" ng-init="accept = false;"> <ion-content class="has-header">
<div ng-include="'views/includes/terms.html'"></div> <div ng-include="'views/includes/terms.html'"></div>
<div class="padding-vertical" ng-show="lang != 'en'"> <div class="padding-vertical" ng-show="lang != 'en'">
<a ng-click="openExternalLink(disclaimerUrl)" translate>Official English Disclaimer</a> <a ng-click="openExternalLink(disclaimerUrl)" translate>Official English Disclaimer</a>
</div> </div>
<div id="agree-to-terms"> <div id="agree-to-terms">
<ion-checkbox ng-model="accept"></ion-checkbox> <ion-checkbox ng-model="terms.accept3"></ion-checkbox>
<p translate>I have read, understood, and agree with the <a ui-sref="onboarding.terms">Terms of use</a>.</p> <p translate>I have read, understood, and agree with the <a ui-sref="onboarding.terms">Terms of use</a>.</p>
<button ng-disabled="!accept" class="button button-block button-positive" ng-click="confirm()" translate>Confirm & Finish</button> <button ng-disabled="!terms.accept3" class="button button-block button-positive" ng-click="termsModal.hide(); confirm()" translate>Confirm & Finish</button>
</div> </div>
</ion-content> </ion-content>
</ion-view> </ion-modal-view>

View file

@ -1,5 +1,5 @@
<ion-view id="onboarding-disclaimer" class="onboarding"> <ion-view id="onboarding-disclaimer" class="onboarding">
<ion-content ng-controller="disclaimerController" ng-init="accept1 = accept2 = accept3 = false"> <ion-content ng-controller="disclaimerController" ng-init=init()>
<div class="row text-center"> <div class="row text-center">
<h3 translate class="col-75 col">Almost done! Let's review</h3> <h3 translate class="col-75 col">Almost done! Let's review</h3>
</div> </div>
@ -12,9 +12,10 @@
<ion-checkbox ng-model="accept1"><span translate>I understand my funds are held securely on this device, not by a company.</span></ion-checkbox> <ion-checkbox ng-model="accept1"><span translate>I understand my funds are held securely on this device, not by a company.</span></ion-checkbox>
<ion-checkbox ng-model="accept2"><span translate>I understand if this wallet is lost or deleted, my bitcoin can only be recovered with the backup phrase.</span></ion-checkbox> <ion-checkbox ng-model="accept2"><span translate>I understand if this wallet is lost or deleted, my bitcoin can only be recovered with the backup phrase.</span></ion-checkbox>
</ion-list> </ion-list>
<div id="agree-to-terms" ng-if="accept1&&accept2"> <div id="agree-to-terms" ng-if="accept1 && accept2">
<ion-checkbox ng-model="accept3"></ion-checkbox><p translate>I have read, understood, and agree with the <a ui-sref="onboarding.terms" translate>Terms of use</a>.</p> <ion-checkbox ng-model="terms.accept3"></ion-checkbox>
<button ng-disabled="!accept1 || !accept2 || !accept3" class="button button-block button-positive" ng-click="confirm()" translate>Confirm & Finish</button> <p translate>I have read, understood, and agree with the <a ng-click="openTermsModal()" translate>Terms of use</a>.</p>
<button ng-disabled="!accept1 || !accept2 || !terms.accept3" class="button button-block button-positive" ng-click="confirm()" translate>Confirm & Finish</button>
</div> </div>
</ion-content> </ion-content>
</ion-view> </ion-view>

View file

@ -1,88 +1,100 @@
<form name="setupForm" ng-submit="create(setupForm)" novalidate> <ion-view>
<div class="card list"> <ion-nav-bar class="bar-royal">
<label class="item item-input item-stacked-label"> <ion-nav-title>{{'Create Personal Wallet' | translate}}</ion-nav-title>
<span class="input-label" translate>Wallet name</span> <ion-nav-back-button>
<input type="text" <i class="icon ion-ios-arrow-thin-left"></i>
placeholder="{{'Family vacation funds'|translate}}" </ion-nav-back-button>
ng-model="formData.walletName" </ion-nav-bar>
ng-required="true"
ng-focus="formFocus('wallet-name')"
ng-blur="formFocus(false)">
</label>
<ion-toggle ng-model="showAdv" toggle-class="toggle-stable" ng-change="showAdvChange()"> <ion-content ng-controller="createController" ng-init="init(1);">
<span translate ng-show="!showAdv">Show advanced options</span> <form name="setupForm" ng-submit="create(setupForm)" novalidate>
<span translate ng-show="showAdv">Hide advanced options</span> <div class="card list">
</ion-toggle> <label class="item item-input item-stacked-label">
<span class="input-label" translate>Wallet name</span>
<input type="text"
placeholder="{{'Family vacation funds'|translate}}"
ng-model="formData.walletName"
ng-required="true"
ng-focus="formFocus('wallet-name')"
ng-blur="formFocus(false)">
</label>
<div ng-show="showAdv"> <ion-toggle ng-model="showAdv" toggle-class="toggle-stable" ng-change="showAdvChange()">
<label class="item item-input item-stacked-label"> <span translate ng-show="!showAdv">Show advanced options</span>
<span class="input-label">Wallet Service URL</span> <span translate ng-show="showAdv">Hide advanced options</span>
<input type="text" ng-model="formData.bwsurl" placeholder="https://bws.bitpay.com/bws/api"> </ion-toggle>
</label>
<label class="item item-input item-select"> <div ng-show="showAdv">
<div class="input-label" translate> <label class="item item-input item-stacked-label">
Wallet Key <span class="input-label">Wallet Service URL</span>
</div> <input type="text" ng-model="formData.bwsurl" placeholder="https://bws.bitpay.com/bws/api">
<select class="m10t" ng-model="seedSource" ng-options="seed as seed.label for seed in seedOptions"></select> </label>
</label>
<label class="item item-input item-stacked-label" ng-show="seedSource.id == 'trezor' || seedSource.id == 'ledger'"> <label class="item item-input item-select">
<span class="input-label" translate>Account Number</span> <div class="input-label" translate>
<input type="number" ng-model="formData.account" ignore-mouse-wheel> Wallet Key
</label> </div>
<select class="m10t" ng-model="seedSource" ng-options="seed as seed.label for seed in seedOptions"></select>
</label>
<div class="card" ng-show="seedSource.id == 'new' && createPassphrase"> <label class="item item-input item-stacked-label" ng-show="seedSource.id == 'trezor' || seedSource.id == 'ledger'">
<div class="item item-text-wrap" translate> <span class="input-label" translate>Account Number</span>
WARNING: The password cannot be recovered. <b>Be sure to write it down</b>. The wallet can not be restored without the password. <input type="number" ng-model="formData.account" ignore-mouse-wheel>
</div> </label>
</div>
<label class="item item-input item-stacked-label" ng-show="seedSource.id == 'new'"> <div class="card" ng-show="seedSource.id == 'new' && createPassphrase">
<span class="input-label" translate>Add a Password</span> <div class="item item-text-wrap" translate>
<input type="text" WARNING: The password cannot be recovered. <b>Be sure to write it down</b>. The wallet can not be restored without the password.
placeholder="{{'Add an optional password to secure the recovery phrase'|translate}}" </div>
autocapitalize="off" </div>
ng-model="formData.createPassphrase">
</label>
<label class="item item-input item-stacked-label" ng-show="seedSource.id == 'set'"> <label class="item item-input item-stacked-label" ng-show="seedSource.id == 'new'">
<span class="input-label" translate>Wallet Recovery Phrase</span> <span class="input-label" translate>Add a Password</span>
<input placeholder="{{'Enter the recovery phrase (BIP39)'|translate}}" <input type="text"
autocapitalize="off" placeholder="{{'Add an optional password to secure the recovery phrase'|translate}}"
type="text" autocapitalize="off"
ng-model="formData.privateKey"> ng-model="formData.createPassphrase">
</label> </label>
<label class="item item-input item-stacked-label" ng-show="seedSource.id == 'set'"> <label class="item item-input item-stacked-label" ng-show="seedSource.id == 'set'">
<span class="input-label" translate>Password</span> <span class="input-label" translate>Wallet Recovery Phrase</span>
<input type="text" <input placeholder="{{'Enter the recovery phrase (BIP39)'|translate}}"
placeholder="{{'The recovery phrase could require a password to be imported'|translate}}" autocapitalize="off"
autocapitalize="off" type="text"
ng-model="formData.passphrase"> ng-model="formData.privateKey">
</label> </label>
<label class="item item-input item-stacked-label" ng-show="seedSource.id == 'set'"> <label class="item item-input item-stacked-label" ng-show="seedSource.id == 'set'">
<span class="input-label" translate>Derivation Path</span> <span class="input-label" translate>Password</span>
<input type="text" <input type="text"
placeholder="{{'BIP32 path for address derivation'|translate}}" placeholder="{{'The recovery phrase could require a password to be imported'|translate}}"
ng-model="formData.derivationPath"> autocapitalize="off"
</label> ng-model="formData.passphrase">
</label>
<ion-toggle ng-show="seedSource.id == 'new'" ng-model="formData.testnetEnabled" toggle-class="toggle-positive"> <label class="item item-input item-stacked-label" ng-show="seedSource.id == 'set'">
<span translate>Testnet</span> <span class="input-label" translate>Derivation Path</span>
</ion-toggle> <input type="text"
placeholder="{{'BIP32 path for address derivation'|translate}}"
ng-model="formData.derivationPath">
</label>
<ion-toggle ng-model="formData.singleAddressEnabled" toggle-class="toggle-positive"> <ion-toggle ng-show="seedSource.id == 'new'" ng-model="formData.testnetEnabled" toggle-class="toggle-positive">
<span translate>Single Address Wallet</span> <span translate>Testnet</span>
<small translate>For audit purposes</small> </ion-toggle>
</ion-toggle>
</div> <!-- advanced --> <ion-toggle ng-model="formData.singleAddressEnabled" toggle-class="toggle-positive">
</div> <!-- list --> <span translate>Single Address Wallet</span>
<small translate>For audit purposes</small>
</ion-toggle>
</div> <!-- advanced -->
</div> <!-- list -->
<button type="submit" class="button button-block button-positive" ng-disabled="setupForm.$invalid">
<span translate>Create new wallet</span>
</button>
</form>
</ion-content>
</ion-view>
<button type="submit" class="button button-block button-positive" ng-disabled="setupForm.$invalid">
<span translate>Create new wallet</span>
</button>
</form>

View file

@ -1,119 +1,131 @@
<form name="setupForm" ng-submit="create(setupForm)" novalidate> <ion-view>
<div class="card list"> <ion-nav-bar class="bar-royal">
<label class="item item-input item-stacked-label"> <ion-nav-title>{{'Create Shared Wallet' | translate}}</ion-nav-title>
<span class="input-label" translate>Wallet name</span> <ion-nav-back-button>
<input type="text" <i class="icon ion-ios-arrow-thin-left"></i>
placeholder="{{'Family vacation funds'|translate}}" </ion-nav-back-button>
ng-model="formData.walletName" </ion-nav-bar>
ng-required="true"
ng-focus="formFocus('wallet-name')"
ng-blur="formFocus(false)">
</label>
<label class="item item-input item-stacked-label"> <ion-content ng-controller="createController" ng-init="init(3);">
<span class="input-label" translate>Your nickname</span> <form name="setupForm" ng-submit="create(setupForm)" novalidate>
<input type="text" <div class="card list">
placeholder="{{'John'|translate}}" <label class="item item-input item-stacked-label">
ng-model="formData.myName" <span class="input-label" translate>Wallet name</span>
ng-required="formData.totalCopayers != 1" <input type="text"
ng-disabled="formData.totalCopayers == 1" placeholder="{{'Family vacation funds'|translate}}"
ng-focus="formFocus('my-name')" ng-model="formData.walletName"
ng-blur="formFocus(false)"> ng-required="true"
</label> ng-focus="formFocus('wallet-name')"
ng-blur="formFocus(false)">
</label>
<label class="item item-input item-select"> <label class="item item-input item-stacked-label">
<div class="input-label" translate> <span class="input-label" translate>Your nickname</span>
Total number of copayers <input type="text"
</div> placeholder="{{'John'|translate}}"
<select class="m10t" ng-model="formData.totalCopayers" ng-options="totalCopayers as totalCopayers for totalCopayers in TCValues" ng-model="formData.myName"
ng-change="setTotalCopayers(formData.totalCopayers)"> ng-required="formData.totalCopayers != 1"
</select> ng-disabled="formData.totalCopayers == 1"
</label> ng-focus="formFocus('my-name')"
ng-blur="formFocus(false)">
</label>
<label class="item item-input item-select"> <label class="item item-input item-select">
<div class="input-label" translate> <div class="input-label" translate>
Required number of signatures Total number of copayers
</div> </div>
<select class="m10t" <select class="m10t" ng-model="formData.totalCopayers" ng-options="totalCopayers as totalCopayers for totalCopayers in TCValues"
ng-model="formData.requiredCopayers" ng-options="requiredCopayers as requiredCopayers for requiredCopayers in RCValues" ng-change="setTotalCopayers(formData.totalCopayers)">
ng-disabled="formData.totalCopayers == 1"> </select>
</select> </label>
</label>
<ion-toggle ng-model="showAdv" toggle-class="toggle-stable" ng-change="showAdvChange()"> <label class="item item-input item-select">
<span translate ng-show="!showAdv">Show advanced options</span> <div class="input-label" translate>
<span translate ng-show="showAdv">Hide advanced options</span> Required number of signatures
</ion-toggle> </div>
<select class="m10t"
ng-model="formData.requiredCopayers" ng-options="requiredCopayers as requiredCopayers for requiredCopayers in RCValues"
ng-disabled="formData.totalCopayers == 1">
</select>
</label>
<div ng-show="showAdv"> <ion-toggle ng-model="showAdv" toggle-class="toggle-stable" ng-change="showAdvChange()">
<label class="item item-input item-stacked-label"> <span translate ng-show="!showAdv">Show advanced options</span>
<span class="input-label">Wallet Service URL</span> <span translate ng-show="showAdv">Hide advanced options</span>
<input type="text" ng-model="formData.bwsurl"> </ion-toggle>
</label>
<label class="item item-input item-select"> <div ng-show="showAdv">
<div class="input-label" translate> <label class="item item-input item-stacked-label">
Wallet Key <span class="input-label">Wallet Service URL</span>
</div> <input type="text" ng-model="formData.bwsurl">
<select class="m10t" ng-model="seedSource" ng-options="seed as seed.label for seed in seedOptions"></select> </label>
</label>
<label class="item item-input item-stacked-label" ng-show="seedSource.id == 'trezor' || seedSource.id == 'ledger'"> <label class="item item-input item-select">
<span class="input-label" translate>Account Number</span> <div class="input-label" translate>
<input type="number" ng-model="formData.account" ignore-mouse-wheel> Wallet Key
</label> </div>
<select class="m10t" ng-model="seedSource" ng-options="seed as seed.label for seed in seedOptions"></select>
</label>
<div class="card" ng-show="seedSource.id =='new' && formData.createPassphrase"> <label class="item item-input item-stacked-label" ng-show="seedSource.id == 'trezor' || seedSource.id == 'ledger'">
<div class="item item-text-wrap" translate> <span class="input-label" translate>Account Number</span>
WARNING: The password cannot be recovered. <b>Be sure to write it down</b>. The wallet can not be restored without the password. <input type="number" ng-model="formData.account" ignore-mouse-wheel>
</div> </label>
</div>
<label class="item item-input item-stacked-label" ng-show="seedSource.id == 'new'"> <div class="card" ng-show="seedSource.id =='new' && formData.createPassphrase">
<span class="input-label" translate>Add a Password</span> <div class="item item-text-wrap" translate>
<input type="text" WARNING: The password cannot be recovered. <b>Be sure to write it down</b>. The wallet can not be restored without the password.
placeholder="{{'Add an optional password to secure the recovery phrase'|translate}}" </div>
autocapitalize="off" </div>
ng-model="formData.createPassphrase">
</label> <label class="item item-input item-stacked-label" ng-show="seedSource.id == 'new'">
<span class="input-label" translate>Add a Password</span>
<input type="text"
placeholder="{{'Add an optional password to secure the recovery phrase'|translate}}"
autocapitalize="off"
ng-model="formData.createPassphrase">
</label>
<label class="item item-input item-stacked-label" ng-show="seedSource.id == 'set'">
<span class="input-label" translate>Wallet Recovery Phrase</span>
<input placeholder="{{'Enter the recovery phrase (BIP39)'|translate}}"
autocapitalize="off"
type="text"
ng-model="formData.privateKey">
</label>
<label class="item item-input item-stacked-label" ng-show="seedSource.id == 'set'">
<span class="input-label" translate>Password</span>
<input type="text"
placeholder="{{'The recovery phrase could require a password to be imported'|translate}}"
autocapitalize="off"
ng-model="formData.passphrase">
</label>
<label class="item item-input item-stacked-label" ng-show="seedSource.id == 'set'">
<span class="input-label" translate>Derivation Path</span>
<input type="text"
placeholder="{{'BIP32 path for address derivation'|translate}}"
ng-model="formData.derivationPath">
</label>
<ion-toggle ng-show="seedSource.id == 'new'" ng-model="formData.testnetEnabled" toggle-class="toggle-positive">
Testnet
</ion-toggle>
<ion-toggle ng-model="formData.singleAddressEnabled" toggle-class="toggle-positive">
<span translate>Single Address Wallet</span>
<small translate>For audit purposes</small>
</ion-toggle>
</div> <!-- advanced -->
</div> <!-- list -->
<button type="submit" class="button button-block button-positive" ng-disabled="setupForm.$invalid">
<span translate>Create {{formData.requiredCopayers}}-of-{{formData.totalCopayers}} wallet</span>
</button>
</form>
</ion-content>
</ion-view>
<label class="item item-input item-stacked-label" ng-show="seedSource.id == 'set'">
<span class="input-label" translate>Wallet Recovery Phrase</span>
<input placeholder="{{'Enter the recovery phrase (BIP39)'|translate}}"
autocapitalize="off"
type="text"
ng-model="formData.privateKey">
</label>
<label class="item item-input item-stacked-label" ng-show="seedSource.id == 'set'">
<span class="input-label" translate>Password</span>
<input type="text"
placeholder="{{'The recovery phrase could require a password to be imported'|translate}}"
autocapitalize="off"
ng-model="formData.passphrase">
</label>
<label class="item item-input item-stacked-label" ng-show="seedSource.id == 'set'">
<span class="input-label" translate>Derivation Path</span>
<input type="text"
placeholder="{{'BIP32 path for address derivation'|translate}}"
ng-model="formData.derivationPath">
</label>
<ion-toggle ng-show="seedSource.id == 'new'" ng-model="formData.testnetEnabled" toggle-class="toggle-positive">
Testnet
</ion-toggle>
<ion-toggle ng-model="formData.singleAddressEnabled" toggle-class="toggle-positive">
<span translate>Single Address Wallet</span>
<small translate>For audit purposes</small>
</ion-toggle>
</div> <!-- advanced -->
</div> <!-- list -->
<button type="submit" class="button button-block button-positive" ng-disabled="setupForm.$invalid">
<span translate>Create {{formData.requiredCopayers}}-of-{{formData.totalCopayers}} wallet</span>
</button>
</form>

View file

@ -1,36 +1,68 @@
<ion-view> <ion-view id="tab-receive">
<ion-nav-bar class="bar-royal"> <ion-nav-bar class="bar-royal">
<ion-nav-title>{{'Receive' | translate}}</ion-nav-title> <ion-nav-title>{{'Receive' | translate}}</ion-nav-title>
<ion-nav-buttons side="secondary">
<button class="no-border">
<i class="ion-help-circled"></i>
</button>
</ion-nav-buttons>
</ion-nav-bar> </ion-nav-bar>
<ion-content ng-controller="tabReceiveController" ng-init="init()"> <ion-content ng-controller="tabReceiveController" ng-init="init()">
<div class="m30v text-center" copy-to-clipboard="addr"> <article id="address">
<qrcode size="220" data="bitcoin:{{addr}}"></qrcode> <div class="row">
<div ng-if="wallet.needsBackup" class="assertive" translate> <div class="m15t text-center col col-60 center-block" copy-to-clipboard="addr">
Before receiving funds, you must backup your wallet. If this device is lost, it is impossible to access your funds without a backup. <qrcode size="220" data="bitcoin:{{addr}}"></qrcode>
<div ng-if="wallet.needsBackup" class="assertive m10t" translate>
Before receiving funds, you must backup your wallet. If this device is lost, it is impossible to access your funds without a backup.
</div>
</div>
</div> </div>
</div> <div class="row">
<div class="col" ng-show="isCordova && addr">
<div class="list card padding text-center" ng-if="!wallets[0]"> <div class="item item-icon-left" ng-click="shareAddress(addr)">
<span translate>No Wallet</span> <i class="icon ion-ios-upload-outline"></i>
</div> <span translate>Share</span>
</div>
<div class="list" ng-if="wallets[0]"> </div>
<div class="item item-icon-left" ng-click="shareAddress(addr)" ng-show="isCordova && addr"> <div class="col" ng-class="{'center-block col-50': !isCordova || !addr}">
<i class="icon ion-ios-upload-outline"></i> <div class="item item-icon-left" ng-click="setAddress(null, true)">
<span translate>Share address</span> <i class="icon ion-ios-loop"></i>
<span translate>Next Address</span>
</div>
</div>
</div> </div>
<div class="item item-icon-left" ng-click="setAddress(null, true)"> <div class="row border-top">
<i class="icon ion-ios-loop"></i> <div class="col col-90 center-block bit-address">
<span translate>Next Address</span> <div class="item item-icon-left">
<i class="icon ion-social-bitcoin-outline"></i>
<span ng-if="generatingAddress">...</span>
<span class="bit-address-gen-address" ng-if="!generatingAddress" copy-to-clipboard="addr">{{addr}}</span>
</div>
</div>
</div> </div>
<div class="item item-icon-left"> </article>
<i class="icon ion-social-bitcoin-outline"></i> <article id="wallets">
<span ng-if="generatingAddress">...</span> <div class="list card padding text-center" ng-if="!wallets[0]">
<span ng-if="!generatingAddress" copy-to-clipboard="addr">{{addr}}</span> <span translate>No Wallet</span>
</div> </div>
<div class="list" ng-if="wallets[0]">
<wallets ng-if="wallets[0]" wallets="wallets"></wallets> <!-- <div class="item item-icon-left" ng-click="setAddress(null, true)">
</div> <i class="icon ion-ios-loop"></i>
<span translate>Next Address</span>
</div> -->
<wallets ng-if="wallets[0]" wallets="wallets"></wallets>
</div>
</article>
</ion-content> </ion-content>
<div id="first-time-tip" ng-if="firstTime">
<i class="ion-close close"></i>
<div class="row">
<h3 class="col col-60 center-block">Receive bitcoin by sharing your address</h3>
</div>
<div class="row">
<p class="col col-60 center-block">
Other bitcoin users can scan this code to send you money
</p>
</div>
</div>
</ion-view> </ion-view>

View file

@ -1,26 +1,23 @@
<ion-view> <ion-view id="tab-send">
<ion-nav-bar class="bar-royal"> <ion-nav-bar class="bar-royal">
<ion-nav-title>{{'Send' | translate}}</ion-nav-title> <ion-nav-title>{{'Send' | translate}}</ion-nav-title>
</ion-nav-bar> </ion-nav-bar>
<ion-content ng-controller="tabSendController" ng-init="init()"> <ion-content ng-controller="tabSendController" ng-init="init()">
<div class="card"> <div>
<div class="item item-divider" translate>Recipient</div> <div class="item item-heading" translate>Recipient</div>
<label class="item item-input bitcoin-address">
<div class="list list-inset"> <i class="icon ion-search placeholder-icon"></i>
<label class="item item-input"> <input type="text"
<i class="icon ion-search placeholder-icon"></i> placeholder="Search or enter bitcoin address"
<input type="text" ng-model="search"
placeholder="Search or enter bitcoin address" ng-change="findContact(search)"
ng-model="search" ng-model-onblur>
ng-change="findContact(search)" </label>
ng-model-onblur>
</label>
</div>
</div> </div>
<div class="card" ng-if="list[0]"> <div class="card" ng-if="list[0]">
<div class="item item-divider item-icon-right"> <div class="item item-heading item-icon-right">
<span translate>Contacts & Wallets</span> <span translate>Contacts & Wallets</span>
<i class="icon ion-person-add" ng-click="openAddressbookModal()"></i> <i class="icon ion-person-add" ng-click="openAddressbookModal()"></i>
</div> </div>

View file

@ -19,6 +19,11 @@
<button class="outline white tiny round" translate>Tap to retry</button> <button class="outline white tiny round" translate>Tap to retry</button>
</div> </div>
<div class="m20t" ng-show="walletNotRegistered" ng-click='recreate()'>
<span class="size-12 db m10b" translate>This wallet is not registered at the given Bitcore Wallet Service (BWS). You can recreate it from the local information.</span>
<button class="outline white tiny round" translate>Recreate</button>
</div>
<div ng-show="wallet.walletScanStatus == 'error'" ng-click='retryScan()'> <div ng-show="wallet.walletScanStatus == 'error'" ng-click='retryScan()'>
<span translate>Scan status finished with error</span> <span translate>Scan status finished with error</span>
<br><span translate>Tap to retry</span> <br><span translate>Tap to retry</span>

View file

@ -23,7 +23,7 @@ angular.module('copayApp.controllers').controller('createController',
12: 1, 12: 1,
}; };
$scope.init = function() { $scope.init = function(tc) {
$scope.formData = {}; $scope.formData = {};
var defaults = configService.getDefaults(); var defaults = configService.getDefaults();
$scope.formData.account = 1; $scope.formData.account = 1;
@ -31,9 +31,9 @@ angular.module('copayApp.controllers').controller('createController',
$scope.TCValues = lodash.range(2, defaults.limits.totalCopayers + 1); $scope.TCValues = lodash.range(2, defaults.limits.totalCopayers + 1);
$scope.formData.totalCopayers = defaults.wallet.totalCopayers; $scope.formData.totalCopayers = defaults.wallet.totalCopayers;
$scope.formData.derivationPath = derivationPathHelper.default; $scope.formData.derivationPath = derivationPathHelper.default;
$scope.setTotalCopayers(1); $scope.setTotalCopayers(tc);
updateRCSelect(1); updateRCSelect(tc);
updateSeedSourceSelect(1); updateSeedSourceSelect(tc);
}; };
$scope.showAdvChange = function() { $scope.showAdvChange = function() {

View file

@ -1,6 +1,14 @@
'use strict'; 'use strict';
angular.module('copayApp.controllers').controller('disclaimerController', function($scope, $state, $log, $ionicModal, profileService) { angular.module('copayApp.controllers').controller('disclaimerController', function($scope, $timeout, $state, $log, $ionicModal, profileService) {
$scope.init = function() {
$scope.terms = {};
$scope.accept1 = $scope.accept2 = $scope.accept3 = false;
$timeout(function() {
$scope.$apply();
}, 1);
};
$scope.confirm = function() { $scope.confirm = function() {
profileService.setDisclaimerAccepted(function(err) { profileService.setDisclaimerAccepted(function(err) {
@ -11,14 +19,12 @@ angular.module('copayApp.controllers').controller('disclaimerController', functi
}); });
}; };
this.openModal = function() { $scope.openTermsModal = function() {
$ionicModal.fromTemplateUrl('views/modals/terms.html', {
$ionicModal.fromTemplateUrl('views/modals/addressbook.html', {
scope: $scope scope: $scope
}).then(function(modal) { }).then(function(modal) {
$scope.addressbookModal = modal; $scope.termsModal = modal;
$scope.addressbookModal.show(); $scope.termsModal.show();
}); });
}; };
}); });

View file

@ -1,6 +1,11 @@
'use strict'; 'use strict';
angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $ionicNavBarDelegate, $state, $stateParams, bwcError, profileService, lodash, configService, gettext, gettextCatalog, platformInfo, walletService, $ionicPopup, txpModalService, externalLinkService) { angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $ionicNavBarDelegate, $state, $stateParams, profileService, lodash, configService, gettext, gettextCatalog, platformInfo, walletService, $ionicPopup, txpModalService, externalLinkService) {
var isCordova = platformInfo.isCordova;
var isWP = platformInfo.isWP;
var isAndroid = platformInfo.isAndroid;
var isChromeApp = platformInfo.isChromeApp;
var HISTORY_SHOW_LIMIT = 10; var HISTORY_SHOW_LIMIT = 10;
var currentTxHistoryPage; var currentTxHistoryPage;
var wallet; var wallet;
@ -65,14 +70,19 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
$scope.updateStatus = function(force) { $scope.updateStatus = function(force) {
$scope.updatingStatus = true; $scope.updatingStatus = true;
$scope.updateStatusError = false; $scope.updateStatusError = false;
$scope.walletNotRegistered = false;
walletService.getStatus(wallet, { walletService.getStatus(wallet, {
force: !!force, force: !!force,
}, function(err, status) { }, function(err, status) {
$scope.updatingStatus = false; $scope.updatingStatus = false;
if (err) { if (err) {
if (err === 'WALLET_NOT_REGISTERED') {
$scope.walletNotRegistered = true;
} else {
$scope.updateStatusError = true;
}
$scope.status = null; $scope.status = null;
$scope.updateStatusError = true;
return; return;
} }
@ -140,7 +150,15 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
}; };
$scope.recreate = function() { $scope.recreate = function() {
walletService.recreate(); walletService.recreate(wallet, function(err) {
$scope.init();
if (err) return;
$timeout(function() {
walletService.startScan(wallet, function() {
$scope.$apply();
});
});
});
}; };
$scope.updateTxHistory = function(cb) { $scope.updateTxHistory = function(cb) {
@ -158,7 +176,6 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
$timeout(function() { $timeout(function() {
$scope.$apply(); $scope.$apply();
}, 1); }, 1);
}; };
$timeout(function() { $timeout(function() {

View file

@ -282,11 +282,19 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}, },
}, },
}) })
.state('tabs.create', { .state('tabs.create-personal', {
url: '/create', url: '/create-personal',
views: { views: {
'tab-home': { 'tab-home': {
templateUrl: 'views/create.html' templateUrl: 'views/tab-create-personal.html'
},
}
})
.state('tabs.create-shared', {
url: '/create-shared',
views: {
'tab-home': {
templateUrl: 'views/tab-create-shared.html'
}, },
} }
}) })

View file

@ -7,31 +7,31 @@ angular.module('copayApp.services').factory('ongoingProcess', function($log, $ti
var ongoingProcess = {}; var ongoingProcess = {};
var processNames = { var processNames = {
'scanning': gettext('Scanning Wallet funds...'),
'recreating': gettext('Recreating Wallet...'),
'generatingCSV': gettext('Generating .csv file...'),
'creatingTx': gettext('Creating transaction'),
'sendingTx': gettext('Sending transaction'),
'signingTx': gettext('Signing transaction'),
'broadcastingTx': gettext('Broadcasting transaction'), 'broadcastingTx': gettext('Broadcasting transaction'),
'rejectTx': gettext('Rejecting payment proposal'),
'removeTx': gettext('Deleting payment proposal'),
'fetchingPayPro': gettext('Fetching Payment Information'),
'calculatingFee': gettext('Calculating fee'), 'calculatingFee': gettext('Calculating fee'),
'joiningWallet': gettext('Joining Wallet...'),
'retrivingInputs': gettext('Retrieving inputs information'),
'creatingWallet': gettext('Creating Wallet...'),
'validatingWallet': gettext('Validating wallet integrity...'),
'connectingledger': gettext('Waiting for Ledger...'),
'connectingtrezor': gettext('Waiting for Trezor...'),
'validatingWords': gettext('Validating recovery phrase...'),
'connectingCoinbase': gettext('Connecting to Coinbase...'), 'connectingCoinbase': gettext('Connecting to Coinbase...'),
'connectingGlidera': gettext('Connecting to Glidera...'), 'connectingGlidera': gettext('Connecting to Glidera...'),
'importingWallet': gettext('Importing Wallet...'), 'connectingledger': gettext('Waiting for Ledger...'),
'sweepingWallet': gettext('Sweeping Wallet...'), 'connectingtrezor': gettext('Waiting for Trezor...'),
'creatingTx': gettext('Creating transaction'),
'creatingWallet': gettext('Creating Wallet...'),
'deletingWallet': gettext('Deleting Wallet...'), 'deletingWallet': gettext('Deleting Wallet...'),
'extractingWalletInfo': gettext('Extracting Wallet Information...'), 'extractingWalletInfo': gettext('Extracting Wallet Information...'),
'fetchingPayPro': gettext('Fetching Payment Information'),
'generatingCSV': gettext('Generating .csv file...'),
'gettingFeeLevels': gettext('Getting fee levels...'), 'gettingFeeLevels': gettext('Getting fee levels...'),
'importingWallet': gettext('Importing Wallet...'),
'joiningWallet': gettext('Joining Wallet...'),
'recreating': gettext('Recreating Wallet...'),
'rejectTx': gettext('Rejecting payment proposal'),
'removeTx': gettext('Deleting payment proposal'),
'retrivingInputs': gettext('Retrieving inputs information'),
'scanning': gettext('Scanning Wallet funds...'),
'sendingTx': gettext('Sending transaction'),
'signingTx': gettext('Signing transaction'),
'sweepingWallet': gettext('Sweeping Wallet...'),
'validatingWallet': gettext('Validating wallet integrity...'),
'validatingWords': gettext('Validating recovery phrase...'),
}; };
root.clear = function() { root.clear = function() {

View file

@ -10,6 +10,8 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
root.SOFT_CONFIRMATION_LIMIT = 12; root.SOFT_CONFIRMATION_LIMIT = 12;
root.SAFE_CONFIRMATIONS = 6; root.SAFE_CONFIRMATIONS = 6;
var errors = bwcService.getErrors();
// UI Related // UI Related
root.openStatusModal = function(type, txp, cb) { root.openStatusModal = function(type, txp, cb) {
var scope = $rootScope.$new(true); var scope = $rootScope.$new(true);
@ -175,6 +177,9 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
twoStep: true twoStep: true
}, function(err, ret) { }, function(err, ret) {
if (err) { if (err) {
if (err instanceof errors.NOT_AUTHORIZED) {
return cb('WALLET_NOT_REGISTERED');
}
return cb(bwcError.msg(err, gettext('Could not update Wallet'))); return cb(bwcError.msg(err, gettext('Could not update Wallet')));
} }
return cb(null, ret); return cb(null, ret);
@ -296,7 +301,6 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
}; };
var getSavedTxs = function(walletId, cb) { var getSavedTxs = function(walletId, cb) {
storageService.getTxHistory(walletId, function(err, txs) { storageService.getTxHistory(walletId, function(err, txs) {
if (err) return cb(err); if (err) return cb(err);
@ -671,41 +675,30 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
}); });
}; };
// walletHome
root.recreate = function(wallet, cb) { root.recreate = function(wallet, cb) {
$log.debug('Recreating wallet:', wallet.id);
ongoingProcess.set('recreating', true); ongoingProcess.set('recreating', true);
wallet.recreateWallet(function(err) { wallet.recreateWallet(function(err) {
wallet.notAuthorized = false; wallet.notAuthorized = false;
ongoingProcess.set('recreating', false); ongoingProcess.set('recreating', false);
return cb(err);
if (err) {
handleError(err);
return;
}
root.startScan(wallet);
// TODO TODO TODO TODO:
// Do it on the controller
// profileService.bindWalletClient(wallet, {
// force: true
// });
}); });
}; };
root.startScan = function(wallet) { root.startScan = function(wallet, cb) {
$log.debug('Scanning wallet ' + wallet.credentials.walletId); cb = cb || function() {};
$log.debug('Scanning wallet ' + wallet.id);
if (!wallet.isComplete()) return; if (!wallet.isComplete()) return;
// wallet.updating = true; wallet.updating = true;
ongoingProcess.set('scanning', true);
wallet.startScan({ wallet.startScan({
includeCopayerBranches: true, includeCopayerBranches: true,
}, function(err) { }, function(err) {
wallet.updating = false;
if (err && wallet.walletId == walletId) { ongoingProcess.set('scanning', false);
wallet.updating = false; return cb(err);
handleError(err);
}
}); });
}; };
@ -956,8 +949,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
$rootScope.$emit('Local/TxAction', wallet.id); $rootScope.$emit('Local/TxAction', wallet.id);
var type = root.getViewStatus(wallet, broadcastedTxp); var type = root.getViewStatus(wallet, broadcastedTxp);
root.openStatusModal(type, broadcastedTxp, function() { root.openStatusModal(type, broadcastedTxp, function() {});
});
return cb(null, broadcastedTxp) return cb(null, broadcastedTxp)
}); });
@ -965,8 +957,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
$rootScope.$emit('Local/TxAction', wallet.id); $rootScope.$emit('Local/TxAction', wallet.id);
var type = root.getViewStatus(wallet, signedTxp); var type = root.getViewStatus(wallet, signedTxp);
root.openStatusModal(type, signedTxp, function() { root.openStatusModal(type, signedTxp, function() {});
});
return cb(null, signedTxp); return cb(null, signedTxp);
} }
}); });

View file

@ -21,6 +21,10 @@
padding-left: 74px; padding-left: 74px;
} }
.item-no-bottom-border + .item {
border-top: 0;
}
.icon.big-icon-svg { .icon.big-icon-svg {
padding: 0 7px; padding: 0 7px;
> img { > img {
@ -30,7 +34,7 @@
box-shadow: 0px 6px 12px 0px rgba(0, 0, 0, 0.3); box-shadow: 0px 6px 12px 0px rgba(0, 0, 0, 0.3);
} }
} }
.overlay{ .overlay {
position: absolute; position: absolute;
top:0; top:0;
left:0; left:0;
@ -72,3 +76,7 @@ ion-header-bar{
border:none; border:none;
} }
} }
.border-top{
border-top:1px solid rgb(228,228,228);
}

View file

@ -772,6 +772,10 @@ ul.wallet-selection.wallets {
margin: 30px 0; margin: 30px 0;
} }
.m15v {
margin: 15px 0;
}
.m10h { .m10h {
margin: 0 10px; margin: 0 10px;
} }
@ -897,44 +901,6 @@ input[type=file] {
font-size: 16px; font-size: 16px;
} }
/*
* Calculator
*/
.calculator .header-calc {
position: absolute;
width: 100%;
text-align: center;
}
.calculator .button-calc {
position: absolute;
width: 100%;
bottom: 0;
}
.calculator .button-calc .row {
padding: 0 !important;
}
.calculator .button-calc .columns {
cursor: pointer;
text-align: center;
}
.calculator .button-calc .operator {
color: #2C3E50;
background-color: #eee;
}
.calculator .button-calc .columns:active {
background-color: #eee;
}
.calculator .button-calc .operator:active {
background-color: #f8f8f8;
}
// No looks likes locked // No looks likes locked
input[type="number"] { input[type="number"] {
&[readonly] { &[readonly] {
@ -994,8 +960,12 @@ input[type=number] {
@import "forms"; @import "forms";
@import 'mixins/mixins'; @import 'mixins/mixins';
@import "views/add"; @import "views/add";
@import "views/amount";
@import "views/tab-home"; @import "views/tab-home";
@import "views/tab-receive";
@import "views/tab-send";
@import "views/walletDetails"; @import "views/walletDetails";
@import "views/bitpayCard"; @import "views/bitpayCard";
@import 'views/onboarding/onboarding'; @import 'views/onboarding/onboarding';
@import "views/includes/walletActivity"; @import "views/includes/walletActivity";
@import "views/includes/wallets";

View file

@ -0,0 +1,88 @@
#view-amount {
@media(max-width: 480px) {
.bitcoin-address {
.icon {
left: 8px;
font-size: 24px;
}
font-size: 11px;
padding-left: 48px;
}
}
.amount-pane {
position: absolute;
top: 125px;
bottom: 0;
width: 100%;
background-color: #fff;
padding: 0 16px;
.amount-bar {
padding: 24px 0;
font-size: 18px;
.title {
float: left;
padding-top: 10px;
}
}
.amount {
display: flex;
flex-direction: column;
justify-content: center;
flex-grow: 1;
position: absolute;
bottom: 254px;
top: 66px;
}
}
.keypad {
text-align: center;
font-size: 24px;
font-weight: lighter;
position: absolute;
bottom: 0;
width: 100%;
.row {
padding: 0 !important;
margin: 0 !important;
}
.col {
line-height: 40px;
}
.operator {
background-color: #eaeaea;
font-weight: normal;
cursor: pointer;
&:active {
background-color: #f8f8f8;
}
}
.operator-send {
font-weight: bolder;
background-color: #f7f7f7;
font-size: 36px;
cursor: pointer;
&:active {
background-color: #eaeaea;
}
}
.digit{
cursor: pointer;
border-top: 1px solid #eaeaea;
border-left: 1px solid #eaeaea;
&:active {
background-color: #eaeaea;
}
}
}
}

View file

@ -0,0 +1,33 @@
.wallets{
.slides{
.swiper-container{
width:75% !important;
overflow:visible;
}
.card{
padding: .7rem;
padding-left:.25rem;
padding-right:.25rem;
border-radius: .25rem;
}
.swiper-slide{
width:100% !important;
&.swiper-slide-prev, &.swiper-slide-next{
opacity: .2;
}
&.swiper-slide-prev{
left:-5%;
}
&.swiper-slide-next{
left:4%;
}
span{
float:right;
clear:both;
}
}
}
.swiper-pagination{
visibility: hidden;
}
}

View file

@ -0,0 +1,91 @@
#tab-receive {
ion-header-bar{
button{
i{
color:#fff;
font-size: 1.1rem;
}
}
}
#address {
background: #fff;
.item {
border: none;
font-size: .8rem;
i {
font-size: 1.3rem;
&.ion-social-bitcoin-outline {
border-right: 1px solid rgb(228, 228, 228);
}
}
}
.bit-address {
font-size: .8rem;
.item {
padding-top: 5px;
padding-bottom: 5px;
}
&-gen-address {}
}
}
#wallets {
position: relative;
&:before {
content: "";
display: inline-block;
width: 0;
height: 0;
border-style: solid;
border-width: 0 20px 20px 20px;
border-color: transparent transparent #f5f5f5 transparent;
top: -9px;
position: absolute;
left: 45%;
}
}
#first-time-tip {
background: rgba(30, 49, 134, 1);
background: -moz-linear-gradient(top, rgba(30, 49, 134, 1) 0%, rgba(30, 49, 134, 0) 88%, rgba(30, 49, 134, 0) 100%);
background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(30, 49, 134, 1)), color-stop(88%, rgba(30, 49, 134, 0)), color-stop(100%, rgba(30, 49, 134, 0)));
background: -webkit-linear-gradient(top, rgba(30, 49, 134, 1) 0%, rgba(30, 49, 134, 0) 88%, rgba(30, 49, 134, 0) 100%);
background: -o-linear-gradient(top, rgba(30, 49, 134, 1) 0%, rgba(30, 49, 134, 0) 88%, rgba(30, 49, 134, 0) 100%);
background: -ms-linear-gradient(top, rgba(30, 49, 134, 1) 0%, rgba(30, 49, 134, 0) 88%, rgba(30, 49, 134, 0) 100%);
background: linear-gradient(to bottom, rgba(30, 49, 134, 1) 0%, rgba(30, 49, 134, 0) 88%, rgba(30, 49, 134, 0) 100%);
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
animation-name: fadeIn;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: .4s;
animation-delay: 2s;
animation-fill-mode: forwards;
z-index: 10;
text-align: center;
color: #fff;
padding-top: 3rem;
.close {
top: .5rem;
right: 1rem;
position: absolute;
font-size: 1.5rem;
opacity: .5;
}
h3 {
color: #fff;
margin-bottom:1rem;
}
}
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

View file

@ -0,0 +1,14 @@
#tab-send {
.bitcoin-address {
@media(max-width: 480px) {
input {
font-size: 12px;
}
}
.icon {
line-height: 31px;
padding-top: 2px;
padding-bottom: 1px;
}
}
}