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 10:33:21 -04:00
commit 57c1942740
33 changed files with 587 additions and 612 deletions

View File

@ -13,14 +13,14 @@
],
"main": "public/index.html",
"window": {
"title": "Copay - A multisignature bitcoin wallet",
"title": "*NAMECASE* - *DESCRIPTION*",
"icon": "./public/img/icons/icon-256.png",
"toolbar": false,
"show": true,
"visible": true,
"resizable": true,
"frame": true,
"width": 800,
"width": 400,
"height": 600,
"position": "center",
"fullscreen": false
@ -85,7 +85,7 @@
"xcode": "^0.8.2"
},
"scripts": {
"preinstall": "bower install && cd app-template && node apply.js",
"preinstall": "bower install && npm i fs-extra && cd app-template && node apply.js",
"postinstall": "npm run build",
"build": "grunt",
"start": "node app.js",

View File

@ -5,7 +5,7 @@
"manifest_version": 2,
"name": "BitPay",
"description": "The BitPay Bitcoin Wallet",
"version": "0.8.0",
"version": "0.10.0",
"permissions": [
"storage",
"unlimitedStorage",

View File

@ -6,7 +6,7 @@
"name": "bitpay",
"description": "The BitPay Bitcoin Wallet",
"author": "BitPay",
"version": "0.8.0",
"version": "0.10.0",
"keywords": [
"wallet",
"copay",
@ -16,14 +16,14 @@
],
"main": "public/index.html",
"window": {
"title": "Copay - A multisignature bitcoin wallet",
"title": "BitPay - The BitPay Bitcoin Wallet",
"icon": "./public/img/icons/icon-256.png",
"toolbar": false,
"show": true,
"visible": true,
"resizable": true,
"frame": true,
"width": 800,
"width": 400,
"height": 600,
"position": "center",
"fullscreen": false
@ -88,7 +88,7 @@
"xcode": "^0.8.2"
},
"scripts": {
"preinstall": "bower install && cd app-template && ./apply.js",
"preinstall": "bower install && npm i fs-extra && cd app-template && node apply.js",
"postinstall": "npm run build",
"build": "grunt",
"start": "node app.js",

View File

@ -1,13 +1,13 @@
<ion-view>
<ion-nav-bar class="bar-royal">
<ion-nav-buttons side="primary">
<button class="button back-button" ui-sref="tabs.home">
<i class="icon ion-ios-arrow-thin-left"></i>
<button class="button button-clear" ui-sref="tabs.home">
Close
</button>
</ion-nav-buttons>
<ion-nav-title>BitPay Card</ion-nav-title>
<ion-nav-buttons side="secondary">
<button class="button no-border" ui-sref="bitpayCard.preferences">
<button class="button button-clear" ui-sref="bitpayCard.preferences">
<i class="icon ion-gear-b"></i>
</button>
</ion-nav-buttons>
@ -93,8 +93,8 @@
</div>
<div ng-show="bitpayCard.bitpayCardAuthenticated && !bitpayCard.visaCardActivated && !addFunds">
<div class="oh pr">
<div class="amount" ng-style="{'background-color': '#293C92'}">
<div id="bitpayCard" class="oh pr">
<div class="amount">
<div ng-show="!loadingHistory && bitpayCard.bitpayCardCurrentBalance" ng-click="bitpayCard.update()">
<strong class="size-36">${{bitpayCard.bitpayCardCurrentBalance}}</strong>
<div class="size-12">Available balance</div>
@ -110,7 +110,7 @@
</div>
</div>
<select ng-model="dateRange" ng-change="bitpayCard.update(dateRange)">
<select class="m10" ng-model="dateRange" ng-change="bitpayCard.update(dateRange)">
<option value="last30Days">Recent Activity</option>
<option value="lastMonth">Last Month</option>
<option value="all">All Activity</option>
@ -127,40 +127,41 @@
<i class="icon ion-android-sync"></i>
</div>
<div
ng-show="!loadingHistory"
ng-repeat="tx in bitpayCard.bitpayCardTransactionHistory | orderBy: ['pending','-timestamp']"
class="row"
ng-init="bitpayCard.getMerchantInfo(tx)">
<div class="col" ng-init="icon = bitpayCard.getIconName(tx)">
<img class="m5t" ng-src="img/mcc-icons/{{icon}}.svg" width="22">
</div>
<div class="col">
<div class="size-12 text-bold">
{{tx.merchant.name}}
</div>
<div class="size-12">
{{tx.merchant.city}}, {{tx.merchant.state}}
</div>
</div>
<div class="card list" ng-show="!loadingHistory">
<div
ng-init="desc = bitpayCard.processDescription(tx)"
class="col">
{{desc}}
</div>
<div class="col">
<img ng-show="!tx.pending" ng-src="img/check.svg" width="14">
<img ng-show="tx.pending" ng-src="img/sync.svg" width="14">
</div>
<div class="col text-right size-12 text-gray">
<div class="size-14"
ng-class="{
'text-success': tx.amount.indexOf('-') == -1 && !tx.pending,
'text-gray': tx.amount.indexOf('-') == -1 && tx.pending}">
{{tx.amount | currency:'$':2 }}
ng-repeat="tx in bitpayCard.bitpayCardTransactionHistory | orderBy: ['pending','-timestamp']"
class="item row"
ng-init="bitpayCard.getMerchantInfo(tx)">
<div class="col" ng-init="icon = bitpayCard.getIconName(tx)">
<img class="m5t" ng-src="img/mcc-icons/{{icon}}.svg" width="22">
</div>
<div class="col">
<div class="size-12 text-bold">
{{tx.merchant.name}}
</div>
<div class="size-12">
{{tx.merchant.city}}, {{tx.merchant.state}}
</div>
</div>
<div
ng-init="desc = bitpayCard.processDescription(tx)"
class="col">
{{desc}}
</div>
<div class="col">
<img ng-show="!tx.pending" ng-src="img/check.svg" width="14">
<img ng-show="tx.pending" ng-src="img/sync.svg" width="14">
</div>
<div class="col text-right size-12 text-gray">
<div class="size-14"
ng-class="{
'text-success': tx.amount.indexOf('-') == -1 && !tx.pending,
'text-gray': tx.amount.indexOf('-') == -1 && tx.pending}">
{{tx.amount | currency:'$':2 }}
</div>
<time>{{tx.timestamp | amTimeAgo}}</time>
</div>
<time>{{tx.timestamp | amTimeAgo}}</time>
</div>
</div>
</div>
@ -171,7 +172,7 @@
ng-submit="bitpayCard.sendFunds()"
novalidate>
<div class="list">
<div class="card list">
<label class="item item-input item-stacked-label">
<span class="input-label">Amount</span>
<input
@ -198,14 +199,14 @@
<div class="row">
<div class="col">
<button class="button button-block button-stable"
<button class="button button-block button-light"
type="button"
ng-click="addFunds = false">
ng-click="addFunds = false; fiat = null">
Cancel
</button>
</div>
<div class="col">
<button class="button button-block"
<button class="button button-block button-positive"
ng-disabled="!fiat"
type="submit">
Send

View File

@ -11,7 +11,7 @@
<h1 class="text-center" translate>Share this invitation with your copayers</h1>
<div ng-click="copySecret()" ng-class="{'enable_text_select': !isCordova}">
<div class="text-center">
<div class="text-center" copy-to-clipboard="secret">
<qrcode size="220" error-correction-level="L" data="{{secret}}"></qrcode>
<div ng-show="!secret" style="position:relative; top:-226px; height:0px">
<div style="height:220px; width:220px; margin:auto; background: white">

View File

@ -1,13 +1,22 @@
<ion-view >
<ion-tabs class="tabs-striped tabs-color-positive tabs-color-active-positive tabs-top">
<ion-view>
<ion-nav-bar class="bar-royal">
<ion-nav-title>{{'Export 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-tab title="File/Text" ui-sref="tabs.preferences.export.file">
<ion-nav-view name="tab-export-file"></ion-nav-view>
</ion-tab>
<ion-content ng-controller="exportController" ng-init="file = true; init();">
<div class="row text-center">
<div class="col" ng-click="file = true" ng-style="file && {'border-bottom': '2px solid'}">
<span class="" translate>File/Text</span>
</div>
<div class="col" ng-click="file = false" ng-style="!file && {'border-bottom': '2px solid'}">
<span class="" translate>QR Code</span>
</div>
</div>
<ion-tab title="QR Code" ui-sref="tabs.preferences.export.qrCode">
<ion-nav-view name="tab-export-qrCode"></ion-nav-view>
</ion-tab>
</ion-tabs>
<div ng-include="'views/tab-export-file.html'" ng-if="file"></div>
<div ng-include="'views/tab-export-qrCode.html'" ng-if="!file"></div>
</ion-content>
</ion-view>

View File

@ -1,11 +1,11 @@
<ion-modal-view>
<ion-header-bar align-title="center" class="tab-bar" ng-style="{'background-color':color}">
<div class="left-small">
<a ng-click="close()" class="p10">
<span class="text-close" translate>Close</span>
</a>
<ion-header-bar align-title="center" class="bar-royal" ng-style="{'background-color':color}">
<button class="button button-clear" ng-click="close()">
Close
</button>
<div class="title" translate>
Search Transactions
</div>
<h1 class="title ellipsis" translate>Search Transactions</h1>
</ion-header-bar>
<ion-content ng-controller="searchController" ng-init="search = ''">
@ -18,14 +18,33 @@
</div>
<div class="list">
<div class="row item" ng-repeat="btx in txHistorySearchResults track by btx.txid" ng-click="openTxModal(btx)">
<div class="col col-10">
<img src="img/icon-receive-history.svg" alt="sync" width="40" ng-if="btx.action == 'received'">
<img src="img/icon-sent-history.svg" alt="sync" width="40" ng-if="btx.action == 'sent'">
<img src="img/icon-moved.svg" alt="sync" width="40" ng-if="btx.action == 'moved'">
</div>
<div class="item" ng-repeat="btx in txHistorySearchResults track by btx.txid" ng-click="openTxModal(btx)">
<div class="col col-50">
<span class="item-note text-right">
<span class="size-16" ng-class="{'text-bold': btx.recent}">
<span ng-if="btx.action == 'received'">+</span>
<span ng-if="btx.action == 'sent'">-</span>
<span class="size-12" ng-if="btx.action == 'invalid'" translate>
(possible double spend)
</span>
<span ng-if="btx.action != 'invalid'">
{{btx.amountStr}}
</span>
</span>
<p>
<time ng-if="btx.time">{{btx.time * 1000 | amTimeAgo}}</time>
<span translate class="text-warning"
ng-show="!btx.time && (!btx.confirmations || btx.confirmations == 0)" translate>
Unconfirmed
</span>
</p>
</span>
<img class="left m10r" src="img/icon-receive-history.svg" alt="sync" width="40" ng-if="btx.action == 'received'">
<img class="left m10r" src="img/icon-sent-history.svg" alt="sync" width="40" ng-if="btx.action == 'sent'">
<img class="left m10r" src="img/icon-moved.svg" alt="sync" width="40" ng-if="btx.action == 'moved'">
<h2>
<div class="padding" ng-if="btx.action == 'received'">
<span class="ellipsis">
<h2 ng-if="btx.note.body">{{btx.note.body}}</h2>
@ -49,31 +68,8 @@
</span>
</div>
<span class="label tu warning radius" ng-if="btx.action == 'invalid'" translate>Invalid</span>
</div>
</h2>
<div class="col col-30 padding">
<span class="size-16" ng-class="{'text-bold': btx.recent}">
<span ng-if="btx.action == 'received'">+</span>
<span ng-if="btx.action == 'sent'">-</span>
<span class="size-12" ng-if="btx.action == 'invalid'" translate>
(possible double spend)
</span>
<span ng-if="btx.action != 'invalid'">
{{btx.amountStr}}
</span>
</span>
<p>
<time ng-if="btx.time">{{btx.time * 1000 | amTimeAgo}}</time>
<span translate class="text-warning"
ng-show="!btx.time && (!btx.confirmations || btx.confirmations == 0)" translate>
Unconfirmed
</span>
</p>
</div>
<div class="col col-10 text-center">
<i class="icon ion-chevron-right"></i>
</div>
</div>
<div class="text-gray text-center size-12 p10t" ng-if="txHistoryShowMore">
<span class="size-12" translate>{{filteredTxHistory.length - txHistorySearchResults.length}} more</span>

View File

@ -1,163 +1,159 @@
<ion-modal-view ng-controller="txDetailsController">
<ion-header-bar align-title="center" class="tab-bar" ng-style="{'background-color':color}">
<div class="left-small">
<a ng-click="cancel()" class="p10">
<span class="text-close" translate>Close</span>
</a>
<ion-header-bar align-title="center" class="bar-royal" ng-style="{'background-color':color}">
<button class="button button-clear" ng-click="cancel()">
Close
</button>
<div class="title" translate>
Transaction
</div>
<h1 class="title ellipsis" translate>Transaction</h1>
</ion-header-bar>
<ion-content ng-style="{'background-color': '#F6F7F9'}">
<div class="modal-content">
<div class="header-modal text-center" ng-init="getAlternativeAmount(btx)">
<div ng-show="btx.action != 'invalid'">
<div ng-show="btx.action == 'received'">
<img src="img/icon-receive-history.svg" alt="sync" width="50">
<p class="m0 text-gray size-14" translate>Received</p>
</div>
<div ng-show="btx.action == 'sent'">
<img src="img/icon-sent-history.svg" alt="sync" width="50">
<p class="m0 text-gray size-14" translate>Sent</p>
</div>
<div ng-show="btx.action == 'moved'">
<img src="img/icon-moved.svg" alt="sync" width="50">
<p class="m0 text-gray size-14" translate>Moved</p>
</div>
<div class="size-36" copy-to-clipboard="btx.amountStr">
<span class="enable_text_select">{{btx.amountStr}}</span>
</div>
<div class="alternative-amount" ng-click="showRate=!showRate" ng-init="showRate = false">
<span class="label gray radius" ng-show="!showRate && alternativeAmountStr">
{{alternativeAmountStr}}
</span>
<span class="size-12" ng-show="showRate && alternativeAmountStr">
{{rateStr}} ({{rateDate | amDateFormat:'MM/DD/YYYY HH:mm a'}})
</span>
</div>
<ion-content>
<div class="header-modal text-center" ng-init="getAlternativeAmount(btx)">
<div ng-show="btx.action != 'invalid'">
<div ng-show="btx.action == 'received'">
<img src="img/icon-receive-history.svg" alt="sync" width="50">
<p class="m0 text-gray size-14" translate>Received</p>
</div>
<div ng-show="btx.action == 'invalid'">
-
<div ng-show="btx.action == 'sent'">
<img src="img/icon-sent-history.svg" alt="sync" width="50">
<p class="m0 text-gray size-14" translate>Sent</p>
</div>
<div ng-show="btx.action == 'moved'">
<img src="img/icon-moved.svg" alt="sync" width="50">
<p class="m0 text-gray size-14" translate>Moved</p>
</div>
<div class="size-36" copy-to-clipboard="btx.amountStr">
<span class="enable_text_select">{{btx.amountStr}}</span>
</div>
<div class="alternative-amount" ng-click="showRate=!showRate" ng-init="showRate = false">
<span class="label gray radius" ng-show="!showRate && alternativeAmountStr">
{{alternativeAmountStr}}
</span>
<span class="size-12" ng-show="showRate && alternativeAmountStr">
{{rateStr}} ({{rateDate | amDateFormat:'MM/DD/YYYY HH:mm a'}})
</span>
</div>
</div>
<div ng-show="btx.action == 'invalid'">
-
</div>
</div>
<h4 class="title m0" translate>Details</h4>
<ul class="no-bullet size-14 m0">
<li ng-if="!btx.hasMultiplesOutputs && btx.addressTo && btx.addressTo != 'N/A'" class="line-b p10 oh"
copy-to-clipboard="btx.addressTo">
<span class="text-gray" translate>To</span>
<span class="right">
<span ng-if="btx.merchant">
<span ng-show="btx.merchant.pr.ca"><i class="fi-lock color-greeni"></i> {{btx.merchant.domain}}</span>
<span ng-show="!btx.merchant.pr.ca"><i class="fi-unlock color-yellowi"></i> {{btx.merchant.domain}}</span>
</span>
<span ng-if="!btx.merchant">
<span ng-show="btx.labelTo">{{btx.labelTo}}</span>
<contact ng-show="!btx.labelTo" class="enable_text_select" address="{{btx.addressTo}}"></contact>
</span>
<ul class="list">
<div class="item item-divider" translate>Details</div>
<li ng-if="!btx.hasMultiplesOutputs && btx.addressTo && btx.addressTo != 'N/A'" class="item"
copy-to-clipboard="btx.addressTo">
<span class="text-gray" translate>To</span>
<span class="right">
<span ng-if="btx.merchant">
<span ng-show="btx.merchant.pr.ca"><i class="fi-lock color-greeni"></i> {{btx.merchant.domain}}</span>
<span ng-show="!btx.merchant.pr.ca"><i class="fi-unlock color-yellowi"></i> {{btx.merchant.domain}}</span>
</span>
</li>
<li ng-show="btx.hasMultiplesOutputs" class="line-b p10 oh"
ng-click="showMultiplesOutputs = !showMultiplesOutputs">
<span class="text-gray" translate>Recipients</span>
<span class="right">{{btx.recipientCount}}
<i ng-show="showMultiplesOutputs" class="icon-arrow-up3 size-24"></i>
<i ng-show="!showMultiplesOutputs" class="icon-arrow-down3 size-24"></i>
<span ng-if="!btx.merchant">
<span ng-show="btx.labelTo">{{btx.labelTo}}</span>
<contact ng-show="!btx.labelTo" class="enable_text_select" address="{{btx.addressTo}}"></contact>
</span>
</li>
</span>
</li>
<div class="line-b" ng-show="btx.hasMultiplesOutputs && showMultiplesOutputs"
ng-repeat="output in btx.outputs"
ng-include="'views/includes/output.html'">
</div>
<li ng-show="btx.hasMultiplesOutputs" class="item"
ng-click="showMultiplesOutputs = !showMultiplesOutputs">
<span class="text-gray" translate>Recipients</span>
<span class="right">{{btx.recipientCount}}
<i ng-show="showMultiplesOutputs" class="icon-arrow-up3 size-24"></i>
<i ng-show="!showMultiplesOutputs" class="icon-arrow-down3 size-24"></i>
</span>
</li>
<li ng-if="btx.action == 'invalid'" class="line-b p10 oh">
<span class="right" translate>
This transaction has become invalid; possibly due to a double spend attempt.
</span>
</li>
<li ng-if="btx.time" class="line-b p10 oh">
<span class="text-gray" translate>Date</span>
<span class="right enable_text_select">
<time>{{ btx.time * 1000 | amDateFormat:'MM/DD/YYYY HH:mm a'}}</time>
<time>({{ btx.time * 1000 | amTimeAgo}})</time>
</span>
</li>
<li class="line-b p10" ng-show="btx.action != 'received'"
copy-to-clipboard="btx.feeStr">
<span class="text-gray" translate>Fee</span>
<span class="right enable_text_select">{{btx.feeStr}}</span>
</li>
<li class="line-b p10 oh" ng-if="btx.message && btx.action != 'received'"
copy-to-clipboard="btx.message">
<span class="text-gray" translate>Description</span>
<span class="right enable_text_select">{{btx.message}}</span>
</li>
<li ng-if="btx.merchant" class="line-b p10 oh"
copy-to-clipboard="btx.merchant.pr.pd.memo">
<span class="text-gray" translate>Merchant message</span>
<span class="right enable_text_select">
{{btx.merchant.pr.pd.memo}}
</span>
</li>
<li ng-if="btx.time" class="line-b p10 oh">
<span class="text-gray" translate>Confirmations</span>
<span class="right" >
<span class="text-warning" ng-show="!btx.confirmations || btx.confirmations == 0" translate>
Unconfirmed
</span>
<span class="label gray radius" ng-show="btx.confirmations>0 && !btx.safeConfirmed">
{{btx.confirmations}}
</span>
<span class="label gray radius" ng-show="btx.safeConfirmed">
{{btx.safeConfirmed}}
</span>
</span>
</li>
<li class="p10 oh" ng-show="btx.note && btx.note.body">
<span class="text-gray" translate>Comment</span>
<span class="right enable_text_select">{{btx.note.body}}</span><br>
<span class="right text-italic text-gray size-12">
<span translate>Edited by</span> <span>{{btx.note.editedByName}}</span>,
<time>{{btx.note.editedOn * 1000 | amTimeAgo}}</time></span>
</span>
</li>
</ul>
<div ng-if="btx.actions[0] && isShared">
<h4 class="title m0" translate>Participants</h4>
<ul class="no-bullet size-14 m0">
<li class="line-b p10 text-gray" ng-repeat="c in btx.actions">
<i class="icon-contact size-24"></i>
<span class="right">
<i ng-if="c.type == 'reject'" class="fi-x icon-sign x db"></i>
<i ng-if="c.type == 'accept'" class="fi-check icon-sign check db"></i>
</span>
{{c.copayerName}} <span ng-if="c.copayerId == copayerId">({{'Me'|translate}})</span>
</li>
</ul>
<div class="item" ng-show="btx.hasMultiplesOutputs && showMultiplesOutputs"
ng-repeat="output in btx.outputs"
ng-include="'views/includes/output.html'">
</div>
<div ng-show="btx.txid" class="tx-details-blockchain">
<div class="text-center m20t">
<button class="button button-positive" ng-click="openExternalLink('https://' +
(getShortNetworkName() == 'test' ? 'test-' : '') + 'insight.bitpay.com/tx/' + btx.txid)">
<span class="text-gray" translate>See it on the blockchain</span>
</button>
<button class="button button-positive" ng-click="showCommentPopup()">
<span class="text-gray" translate ng-show="!btx.note">Add comment</i></span>
<span class="text-gray" translate ng-show="btx.note">Edit comment</span>
</button>
</div>
<li ng-if="btx.action == 'invalid'" class="item">
<span class="right" translate>
This transaction has become invalid; possibly due to a double spend attempt.
</span>
</li>
<li ng-if="btx.time" class="item">
<span class="text-gray" translate>Date</span>
<span class="right enable_text_select">
<time>{{ btx.time * 1000 | amDateFormat:'MM/DD/YYYY HH:mm a'}}</time>
<time>({{ btx.time * 1000 | amTimeAgo}})</time>
</span>
</li>
<li class="item" ng-show="btx.action != 'received'"
copy-to-clipboard="btx.feeStr">
<span class="text-gray" translate>Fee</span>
<span class="right enable_text_select">{{btx.feeStr}}</span>
</li>
<li class="item" ng-if="btx.message && btx.action != 'received'"
copy-to-clipboard="btx.message">
<span class="text-gray" translate>Description</span>
<span class="right enable_text_select">{{btx.message}}</span>
</li>
<li ng-if="btx.merchant" class="item"
copy-to-clipboard="btx.merchant.pr.pd.memo">
<span class="text-gray" translate>Merchant message</span>
<span class="right enable_text_select">
{{btx.merchant.pr.pd.memo}}
</span>
</li>
<li ng-if="btx.time" class="item">
<span class="text-gray" translate>Confirmations</span>
<span class="right" >
<span class="text-warning" ng-show="!btx.confirmations || btx.confirmations == 0" translate>
Unconfirmed
</span>
<span class="label gray radius" ng-show="btx.confirmations>0 && !btx.safeConfirmed">
{{btx.confirmations}}
</span>
<span class="label gray radius" ng-show="btx.safeConfirmed">
{{btx.safeConfirmed}}
</span>
</span>
</li>
<li class="item" ng-show="btx.note && btx.note.body">
<span class="text-gray" translate>Comment</span>
<span class="right enable_text_select">{{btx.note.body}}</span><br>
<span class="right text-italic text-gray size-12">
<span translate>Edited by</span> <span>{{btx.note.editedByName}}</span>,
<time>{{btx.note.editedOn * 1000 | amTimeAgo}}</time></span>
</span>
</li>
</ul>
<div class="list" ng-if="btx.actions[0] && isShared">
<div class="item item-divider" translate>Participants</div>
<div class="item" ng-repeat="c in btx.actions">
<span class="item-note">
<i ng-if="c.type == 'reject'" class="fi-x icon-sign x db"></i>
<i ng-if="c.type == 'accept'" class="fi-check icon-sign check db"></i>
</span>
{{c.copayerName}} <span ng-if="c.copayerId == copayerId">({{'Me'|translate}})</span>
</div>
</div>
<div ng-show="btx.txid" class="row">
<div class="col">
<button class="button button-block button-positive" ng-click="openExternalLink('https://' +
(getShortNetworkName() == 'test' ? 'test-' : '') + 'insight.bitpay.com/tx/' + btx.txid)">
<span class="text-gray" translate>See it on the blockchain</span>
</button>
</div>
<div class="col">
<button class="button button-block button-positive" ng-click="showCommentPopup()">
<span class="text-gray" translate ng-show="!btx.note">Add comment</i></span>
<span class="text-gray" translate ng-show="btx.note">Edit comment</span>
</button>
</div>
</div>
</ion-content>

View File

@ -8,7 +8,7 @@
<span translate>Sent</span>
</div>
<div class="text-center m20t">
<a class="button" ng-click="cancel()" translate>OKAY</a>
<a class="button button-positive" ng-click="cancel()" translate>OKAY</a>
</div>
</div>
@ -19,7 +19,7 @@
<span translate>Payment Proposal Created</span>
</div>
<div class="text-center">
<a class="button" ng-click="cancel()" translate>OKAY</a>
<a class="button button-positive" ng-click="cancel()" translate>OKAY</a>
</div>
</div>
@ -31,7 +31,7 @@
<span translate>Payment Accepted</span>
</div>
<div class="text-center">
<a class="button" ng-click="cancel()" translate>OKAY</a>
<a class="button button-positive" ng-click="cancel()" translate>OKAY</a>
</div>
</div>
@ -41,7 +41,7 @@
<span translate>Payment Rejected</span>
</div>
<div class="text-center">
<a class="button" ng-click="cancel()" translate>OKAY</a>
<a class="button button-positive" ng-click="cancel()" translate>OKAY</a>
</div>
</div>
</ion-modal-view>

View File

@ -1,118 +1,102 @@
<ion-modal-view ng-controller="txpDetailsController">
<ion-header-bar align-title="center" class="tab-bar">
<div class="left-small">
<a ng-click="close()" class="p10">
<span class="text-close" translate>Close</span>
</a>
<ion-header-bar align-title="center" class="bar-royal" ng-style="{'background-color':color}">
<button class="button button-clear" ng-click="close()">
Close
</button>
<div class="title" translate>
Payment Proposal
</div>
<h1 class="title ellipsis" translate>Payment Proposal</h1>
</ion-header-bar>
<ion-content ng-style="{'background-color': '#F6F7F9'}" ng-init="updateCopayerList()">
<div class="list card">
<ul>
<li class="item" >
<ion-content ng-init="updateCopayerList()">
<div class="payment-proposal-head" ng-style="{'background-color':color}">
<div class="size-36">{{tx.amountStr}}</div>
<div class="size-14 text-light" ng-show="tx.alternativeAmountStr">{{tx.alternativeAmountStr}}</div>
<i class="db fi-arrow-down size-24 m10v"></i>
<i class="icon ion-ios-arrow-thin-down"></i>
<span class="payment-proposal-to" copy-to-clipboard="tx.toAddress">
<i class="fi-bitcoin left"></i>
<contact ng-if="!tx.hasMultiplesOutputs" class="dib enable_text_select ellipsis m5t m5b size-14" address="{{tx.toAddress}}"></contact>
<span ng-if="tx.hasMultiplesOutputs" translate>Multiple recipients</span>
</span>
</div>
</li>
<li class="item">
<div class="row" ng-if="tx.removed">
<div class="column m20t text-center text-warning size-12" translate>
The payment was removed by creator
</div>
<div class="row" ng-if="tx.removed">
<div class="column m20t text-center text-warning size-12" translate>
The payment was removed by creator
</div>
</li>
<li class="item">
</div>
<div class="button-bar" ng-if="tx.pendingForUs">
<button class="button button-assertive button-block" ng-click="reject()" ng-disabled="loading" ng-show="isShared">
<i class="fi-x"></i>
<span translate>Reject</span>
</button>
<button class="button button-balanced button-block" ng-click="sign()" ng-style="{'background-color':color}" ng-disabled="loading || paymentExpired" ng-show="canSign">
<i class="fi-check"></i>
<span translate>Accept</span>
<div class="button-bar" ng-if="tx.pendingForUs">
<button class="button button-assertive button-block" ng-click="reject()" ng-disabled="loading" ng-show="isShared">
<i class="fi-x"></i>
<span translate>Reject</span>
</button>
<button class="button button-balanced button-block" ng-click="sign()" ng-style="{'background-color':color}" ng-disabled="loading || paymentExpired" ng-show="canSign">
<i class="fi-check"></i>
<span translate>Accept</span>
</button>
</div>
<div ng-show="tx.status != 'pending'">
<div ng-show="tx.status=='accepted' && !tx.isGlidera">
<div class="m10b" translate>Payment accepted, but not yet broadcasted</div>
<button class="button button-balanced button-block" ng-style="{'background-color':color}" ng-click="broadcast(tx)" ng-disabled="loading">
<i class="fi-upload-cloud"></i>
<span translate>Broadcast Payment</span>
</button>
</div>
</li>
<li class="item">
<div ng-show="tx.status != 'pending'">
<div ng-show="tx.status=='accepted' && !tx.isGlidera">
<div class="m10b" translate>Payment accepted, but not yet broadcasted</div>
<button class="button button-balanced button-block" ng-style="{'background-color':color}" ng-click="broadcast(tx)" ng-disabled="loading">
<i class="fi-upload-cloud"></i>
<span translate>Broadcast Payment</span>
</button>
</div>
<div ng-show="tx.status=='accepted' && tx.isGlidera" >
<div class="m10h" translate>Payment accepted. It will be broadcasted by Glidera. In case there is a problem, it can be deleted 6 hours after it was created.</div>
</div>
<div class="balanced" ng-show="tx.status == 'broadcasted'" translate>Payment Sent</div>
<div class="assertive" ng-show="tx.status=='rejected'" translate>Payment Rejected</div>
<div ng-show="tx.status=='accepted' && tx.isGlidera" >
<div class="m10h" translate>Payment accepted. It will be broadcasted by Glidera. In case there is a problem, it can be deleted 6 hours after it was created.</div>
</div>
</li>
<li class="item">
<h4 class="title m0" translate>Details</h4>
<div class="balanced" ng-show="tx.status == 'broadcasted'" translate>Payment Sent</div>
<div class="assertive" ng-show="tx.status=='rejected'" translate>Payment Rejected</div>
</div>
<ul class="no-bullet size-14 m0">
<li class="line-b p10 oh" ng-show="tx.message">
<ul class="list">
<div class="item item-divider" translate>Details</div>
<li class="item" ng-show="tx.message">
<span class="text-gray" translate>Description</span>
<span class="right">{{tx.message}}</span>
</li>
<li ng-show="tx.hasMultiplesOutputs" class="line-b p10 oh" ng-click="showMultiplesOutputs = !showMultiplesOutputs">
<li ng-show="tx.hasMultiplesOutputs" class="item" ng-click="showMultiplesOutputs = !showMultiplesOutputs">
<span class="text-gray" translate>Recipients</span>
<span class="right">{{tx.recipientCount}}
<i ng-show="showMultiplesOutputs" class="icon-arrow-up3 size-24"></i>
<i ng-show="!showMultiplesOutputs" class="icon-arrow-down3 size-24"></i>
<i ng-show="showMultiplesOutputs" class="icon ion-ios-arrow-up"></i>
<i ng-show="!showMultiplesOutputs" class="icon ion-ios-arrow-up"></i>
</span>
</li>
<div class="line-b" ng-show="tx.hasMultiplesOutputs && showMultiplesOutputs"
<div class="item" ng-show="tx.hasMultiplesOutputs && showMultiplesOutputs"
ng-repeat="output in tx.outputs" ng-include="'views/includes/output.html'">
</div>
<li class="line-b p10">
<li class="item">
<span class="text-gray" translate>Fee</span>
<span class="right">{{tx.feeStr}}</span>
</li>
<li class="line-b p10">
<li class="item">
<span class="text-gray" translate>Time</span>
<span class="right">
<time>{{ (tx.ts || tx.createdOn ) * 1000 | amTimeAgo}}</time>
</span>
</li>
<li class="line-b p10 oh">
<li class="item">
<span class="text-gray" translate>Created by</span>
<span class="right">{{tx.creatorName}}</span>
</li>
</ul>
<div class="p10 text-center size-12" ng-show="!currentSpendUnconfirmed && tx.hasUnconfirmedInputs">
<span class="text-warning" translate>Warning: this transaction has unconfirmed inputs</span>
</div>
</li>
<li class="item">
<div class="item" ng-show="!currentSpendUnconfirmed && tx.hasUnconfirmedInputs">
<span class="text-warning" translate>Warning: this transaction has unconfirmed inputs</span>
</div>
<div ng-if="tx.paypro">
<h4 class="title m0" translate>Payment details</h4>
<ul class="no-bullet size-14 m0">
<li class="line-b p10">
<div ng-if="tx.paypro">
<div class="item item-divider" translate>Payment details</div>
<li class="item">
<span class="text-gray" translate>To</span>
<span class="right">
<span>
@ -122,56 +106,48 @@
<contact address="{{tx.toAddress}}" ng-hide="tx.merchant"></contact>
</span>
</li>
<li class="line-b p10" ng-if="paymentExpired">
<li class="item" ng-if="paymentExpired">
<span class="text-gray" translate>Expired</span>
<span class="right text-alert">
<time>{{tx.paypro.expires * 1000 | amTimeAgo }}</time>
</span>
</li>
<li class="line-b p10" ng-if="!paymentExpired">
<li class="item" ng-if="!paymentExpired">
<span class="text-gray" translate>Expires</span>
<span class="right">
<time>{{expires}}</time>
</span>
</li>
<li class="line-b p10">
<li class="item">
<span class="text-gray" translate>Merchant Message</span>
<span class="db">{{tx.paypro.pr.pd.memo}}</span>
</li>
</ul>
</div>
</div>
</li>
<li class="item" ng-if="tx.actions[0] && !txRejected && !txBroadcasted">
<h4 class="title m0">
<div class="right size-12 text-gray m10r">
{{tx.requiredSignatures}}/{{tx.walletN}}
<div ng-if="tx.actions[0] && !txRejected && !txBroadcasted">
<div class="item item-divider">
<div class="right size-12 text-gray m10r">
{{tx.requiredSignatures}}/{{tx.walletN}}
</div>
<span translate>Participants</span>
</div>
<span translate>Participants</span>
</h4>
<ul class="no-bullet size-14 m0">
<li class="line-b p10 text-gray" ng-repeat="ac in tx.actions">
<i class="icon-contact size-24"></i>
<span class="right">
<i ng-if="ac.type == 'reject'" class="fi-x icon-sign x db"></i>
<i ng-if="ac.type == 'accept'" class="fi-check icon-sign check db"></i>
<li class="item" ng-repeat="ac in tx.actions">
<span class="item-note">
<i ng-if="ac.type == 'reject'" class="icon ion-ios-close-empty"></i>
<i ng-if="ac.type == 'accept'" class="icon ion-ios-checkmark-empty"></i>
</span>
{{ac.copayerName}} <span ng-if="ac.copayerId == copayerId">({{'Me'|translate}})</span>
</li>
</ul>
</div>
</li>
<li class="item" ng-if="tx.canBeRemoved || (tx.status == 'accepted' && !tx.broadcastedOn)">
<div class="text-gray size-12 m20b" ng-show="!tx.isGlidera && isShared" translate>
* A payment proposal can be deleted if 1) you are the creator, and no other copayer has signed, or 2) 24 hours have passed since the proposal was created.
</div>
<button class="button button-assertive button-block" ng-click="remove()" ng-disabled="loading">
<i class="fi-trash size-14 m5r"></i>
<span translate>Delete Payment Proposal</span>
</button>
</li>
</ul>
</ul>
<div class="m20t" ng-if="tx.canBeRemoved || (tx.status == 'accepted' && !tx.broadcastedOn)">
<div class="size-12 padding" ng-show="!tx.isGlidera && isShared" translate>
* A payment proposal can be deleted if 1) you are the creator, and no other copayer has signed, or 2) 24 hours have passed since the proposal was created.
</div>
<button class="button button-assertive button-block" ng-click="remove()" ng-disabled="loading">
<i class="fi-trash size-14 m5r"></i>
<span translate>Delete Payment Proposal</span>
</button>
</div>
</ion-content>
</ion-modal-view>

View File

@ -16,11 +16,9 @@
<input type="email" id="email" name="email" ng-model="email" required></input>
</label>
</form>
<div class="text-center">
<button class="button button-back no-border" ng-click="onboardingMailSkip()">
{{'Skip' | translate}}
</button>
</div>
<button class="button button-block button-positive button-clear" ng-click="onboardingMailSkip()">
{{'Skip' | translate}}
</button>
</div>
<div class="overlay"></div>
</ion-content>

View File

@ -17,7 +17,7 @@
<span translate>Sweep paper wallet</span>
<i class="icon nav-item-arrow-right"></i>
</a>
<a class="item item-icon-right" ui-sref="tabs.preferences.export.file">
<a class="item item-icon-right" ui-sref="tabs.preferences.export">
<span translate>Export Wallet</span>
<i class="icon nav-item-arrow-right"></i>
</a>

View File

@ -8,9 +8,9 @@
<ion-nav-title>Preferences</ion-nav-title>
</ion-nav-bar>
<ion-content ng-controller="preferencesBitpayCardController as bitpay">
<ion-content ng-controller="preferencesBitpayCardController">
<ul class="list">
<li class="item assertive" ng-click="bitpay.logout()">
<li class="item assertive" ng-click="logout()">
Log out
</li>
</ul>

View File

@ -1,104 +1,93 @@
<ion-view>
<ion-nav-bar class="bar-royal">
<ion-nav-title>{{'Export Wallet' | translate}}</ion-nav-title>
<ion-nav-buttons side="primary">
<button class="button back-button" ui-sref="tabs.preferences.preferencesAdvanced">
<i class="icon ion-ios-arrow-thin-left"></i>
</button>
</ion-nav-buttons>
</ion-nav-bar>
<div ng-show="!backupWalletPlainText">
<div class="size-14" ng-show="error">
<i class="ion-alert-circled"></i>
<span translate>Failed to export</span>
</div>
<ion-content ng-controller="exportController" ng-init="init()" cache-view="true">
<form name="exportForm" novalidate>
<div class="card">
<label class="item item-input item-stacked-label">
<span class="input-label" transalate>Set up a password</span>
<input type="password" placeholder="{{'Your password'|translate}}" ng-model="formData.password">
</label>
<div ng-show="!backupWalletPlainText">
<div class="size-14" ng-show="error">
<i class="ion-alert-circled"></i>
<span translate>Failed to export</span>
</div>
<form name="exportForm" novalidate>
<label class="item item-input item-stacked-label">
<span class="input-label" transalate>Set up a password</span>
<input type="password" placeholder="{{'Your password'|translate}}" name="password" ng-model="password">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label" transalate>Repeat the password</span>
<input type="password" class="form-control" placeholder="{{'Repeat password'|translate}}" name="password" ng-model="repeatpassword">
</label>
</form>
<ion-toggle ng-show="canSign" ng-model="showAdvanced" toggle-class="toggle-balanced">
<span translate ng-show="!showAdvanced">Show advanced options</span>
<span translate ng-show="showAdvanced">Hide advanced options</span>
</ion-toggle>
<ion-toggle ng-model="noSignEnabled" ng-show="showAdvanced" toggle-class="toggle-balanced" class="r0" ng-change="noSignEnabledChange()">
<span class="toggle-label" translate>Do not include private key</span>
</ion-toggle>
<div class="box-notification" ng-show="!canSign">
<span class="size-14">
<i class="ion-alert-circled"></i>
<span translate>
WARNING: The private key of this wallet is not available. The export allows to check the wallet balance, transaction history, and create spend proposals from the export. However, does not allow to approve (sign) proposals, so <b>funds will not be accessible from the export</b>.
</span>
</span>
</div>
<div class="box-notification" ng-show="noSignEnabled">
<span class="size-14">
<i class="ion-alert-circled"></i>
<span translate>
WARNING: Not including the private key allows to check the wallet balance, transaction history, and create spend proposals from the export. However, does not allow to approve (sign) proposals, so <b>funds will not be accessible from the export</b>.
</span>
</span>
</div>
<button
ng-click="downloadWalletBackup()"
class="button button-block button-positive"
ng-disabled="(!password || password != repeatpassword)"
ng-style="{'background-color':wallet.color}"
ng-show="!isSafari && !isCordova">
<i class="fi-download"></i>
<span translate>Download</span>
</button>
<button
ng-click="viewWalletBackup()"
class="button button-block button-positive"
ng-disabled="(!password || password != repeatpassword)"
ng-style="{'background-color':wallet.color}"
ng-show="isSafari && !isCordova">
<i class="fi-eye"></i>
<span translate>View</span>
</button>
<div ng-show="isCordova">
<h4 translate>Export options</h4>
<button class="button button-block button-positive"
ng-disabled="(!password || password != repeatpassword)"
ng-style="{'background-color':wallet.color}"
ng-click="copyWalletBackup()">
<i class="fi-clipboard-pencil"></i>
<span translate>Copy to clipboard</span></button>
<button class="button button-block button-positive" ng-disabled="(!password || password != repeatpassword)"
ng-style="{'background-color':wallet.color}"
ng-click="sendWalletBackup()"><i class="fi-mail"></i>
<span translate>Send by email</span></button>
</div>
<label class="item item-input item-stacked-label">
<span class="input-label" transalate>Repeat the password</span>
<input type="password" placeholder="{{'Repeat password'|translate}}" ng-model="formData.repeatpassword">
</label>
</div>
</form>
<div class="row" ng-show="backupWalletPlainText">
<div class="large-12 columns">
<h3 translate>Wallet Export</h3>
<div class="input">
<textarea rows="12">{{backupWalletPlainText}}</textarea>
</div>
<div class="size-12 text-gray text-right">
<i class="icon-compose"></i>
<span translate>Copy this text as it is to a safe place (notepad or email)</span>
</div>
</div>
</div>
</ion-content>
</ion-view>
<ion-toggle ng-show="canSign" ng-model="formData.showAdvanced" toggle-class="toggle-balanced">
<span translate ng-show="!formData.showAdvanced">Show advanced options</span>
<span translate ng-show="formData.showAdvanced">Hide advanced options</span>
</ion-toggle>
<div class="card" ng-show="formData.showAdvanced">
<ion-checkbox ng-model="formData.noSignEnabled" class="checkbox-balanced" ng-change="noSignEnabledChange()">
<span class="toggle-label" translate>Do not include private key</span>
</ion-checkbox>
</div>
<div class="box-notification error" ng-show="!canSign">
<span class="size-14">
<i class="ion-alert-circled"></i>
<span translate>
WARNING: The private key of this wallet is not available. The export allows to check the wallet balance, transaction history, and create spend proposals from the export. However, does not allow to approve (sign) proposals, so <b>funds will not be accessible from the export</b>.
</span>
</span>
</div>
<div class="box-notification error" ng-show="formData.noSignEnabled">
<span class="size-14">
<i class="ion-alert-circled"></i>
<span translate>
WARNING: Not including the private key allows to check the wallet balance, transaction history, and create spend proposals from the export. However, does not allow to approve (sign) proposals, so <b>funds will not be accessible from the export</b>.
</span>
</span>
</div>
<button
ng-click="downloadWalletBackup()"
class="button button-block button-positive"
ng-disabled="(!formData.password || formData.password != formData.repeatpassword)"
ng-style="{'background-color':wallet.color}"
ng-show="!isSafari && !isCordova">
<i class="fi-download"></i>
<span translate>Download</span>
</button>
<button
ng-click="viewWalletBackup()"
class="button button-block button-positive"
ng-disabled="(!formData.password || formData.password != formData.repeatpassword)"
ng-style="{'background-color':wallet.color}"
ng-show="isSafari && !isCordova">
<i class="fi-eye"></i>
<span translate>View</span>
</button>
<div ng-show="isCordova">
<h4 translate>Export options</h4>
<button class="button button-block button-positive"
ng-disabled="(!formData.password || formData.password != formData.repeatpassword)"
ng-style="{'background-color':wallet.color}"
ng-click="copyWalletBackup()">
<i class="fi-clipboard-pencil"></i>
<span translate>Copy to clipboard</span></button>
<button class="button button-block button-positive" ng-disabled="(!formData.password || formData.password != formData.repeatpassword)"
ng-style="{'background-color':wallet.color}"
ng-click="sendWalletBackup()"><i class="fi-mail"></i>
<span translate>Send by email</span></button>
</div>
</div>
<div ng-show="backupWalletPlainText" class="text-center card">
<label class="item item-input item-stacked-label">
<textarea rows="12">{{backupWalletPlainText}}</textarea>
</label>
<div class="item text-gray item-icon-left">
<i class="icon ion-compose"></i>
<p translate>Copy this text as it is to a safe place (notepad or email)</p>
</div>
</div>

View File

@ -1,25 +1,10 @@
<ion-view>
<ion-nav-bar class="bar-royal">
<ion-nav-title>{{'Export Wallet' | translate}}</ion-nav-title>
<ion-nav-buttons side="primary">
<button class="button back-button" ui-sref="tabs.preferences.preferencesAdvanced">
<i class="icon ion-ios-arrow-thin-left"></i>
</button>
</ion-nav-buttons>
</ion-nav-bar>
<div class="m20t text-gray" ng-show="formData.supported">
<div class="text-center m20b">
<qrcode size="220" version="8" error-correction-level="M" data="{{formData.exportWalletInfo}}"></qrcode>
</div>
<div class="text-center size-12 m10" translate>From the destination device, go to Add wallet &gt; Import wallet and scan this QR code</div>
</div>
<ion-content ng-controller="exportController" ng-init="init()">
<div class="m20t text-gray" ng-show="supported">
<div class="text-center m20b">
<qrcode size="220" version="8" error-correction-level="M" data="{{exportWalletInfo}}"></qrcode>
</div>
<div class="text-center size-12 m10" translate>From the destination device, go to Add wallet &gt; Import wallet and scan this QR code</div>
</div>
<div class="m20t text-gray" ng-show="!supported">
<div class="text-center size-12 m10" translate>Exporting via QR not supported for this wallet</div>
</div>
</ion-content>
</ion-view>
<div class="m20t text-gray" ng-show="!formData.supported">
<div class="text-center size-12 m10" translate>Exporting via QR not supported for this wallet</div>
</div>

View File

@ -19,7 +19,7 @@
</a>
</div>
<div class="list card">
<div class="list card" ng-if="notifications[0]">
<a class="item item-icon-right item-heading" ui-sref="tabs.activity" translate>
Recent Activity
<i class="icon nav-item-arrow-right"></i>
@ -28,7 +28,7 @@
<ion-spinner icon="lines"></ion-spinner>
<div translate>Updating activity. Please stand by</div>
</span>
<a ng-if="notifications[0]" class="item" ng-repeat="x in notifications" ng-click="x.action()">
<a class="item" ng-repeat="x in notifications" ng-click="x.action()">
<span ng-include="'views/includes/walletActivity.html'"></span>
</a>
</div>

View File

@ -6,10 +6,9 @@
<ion-content ng-controller="tabSettingsController" ng-init="init()">
<div class="list">
<div class="item item-divider"></div>
<a class="item item-icon-left item-icon-right" ng-click="openAddressbookModal()">
<a class="item item-icon-left" ng-click="openAddressbookModal()">
<i class="icon ion-ios-book-outline"></i>
<span translate>Address Book</span>
<i class="icon nav-item-arrow-right"></i>
</a>
<div class="item item-divider" translate>Preferences</div>

View File

@ -84,29 +84,23 @@
</div>
<div ng-if="txps[0]">
<h4 ng-show="requiresMultipleSignatures" class="title m0" translate>Payment Proposals</h4>
<h4 ng-show="!requiresMultipleSignatures" class="title m0" translate>Unsent transactions</h4>
<div class="list card">
<ul>
<li ng-repeat="tx in txps" class="item item-icon-left" ng-click="openTxpModal(tx)">
<span ng-include="'views/includes/txp.html'"></span>
</li>
</ul>
<div ng-show="lockedBalanceSat">
<span translate>Total Locked Balance</span>:
<b>{{lockedBalanceStr}} </b>
<span> {{lockedBalanceAlternative}} {{alternativeIsoCode}} </span>
</div>
<div class="card list" ng-if="txps[0]">
<div class="item item-heading" translate>
<span ng-show="requiresMultipleSignatures" translate>Payment Proposals</span>
<span ng-show="!requiresMultipleSignatures" translate>Unsent transactions</span>
</div>
<div ng-repeat="tx in txps" class="item item-icon-left" ng-click="openTxpModal(tx)">
<span ng-include="'views/includes/txp.html'"></span>
</div>
<div class="item item-footer" ng-show="status.lockedBalanceSat">
<span translate>Total Locked Balance</span>:
<b>{{status.lockedBalanceStr}} </b>
<span> {{status.lockedBalanceAlternative}} {{status.alternativeIsoCode}} </span>
</div>
</div>
<!-- Transactions -->
<h4 class="title" ng-show="!notAuthorized">
<span translate>Activity</span>
</h4>
<div class="oh pr m20t text-gray size-12 text-center"
ng-show="!txHistory[0] && !updatingTxHistory && !txHistoryError && !updateStatusError && !notAuthorized"
@ -139,41 +133,9 @@
</div>
</div>
<div class="list">
<div class="row item" ng-repeat="btx in txHistory track by btx.txid" ng-click="openTxModal(btx)">
<div class="col col-10">
<img src="img/icon-receive-history.svg" alt="sync" width="40" ng-if="btx.action == 'received'">
<img src="img/icon-sent-history.svg" alt="sync" width="40" ng-if="btx.action == 'sent'">
<img src="img/icon-moved.svg" alt="sync" width="40" ng-if="btx.action == 'moved'">
</div>
<div class="col col-50">
<div class="padding" ng-if="btx.action == 'received'">
<span class="ellipsis">
<h2 ng-if="btx.note.body">{{btx.note.body}}</h2>
<h2 ng-if="!btx.note.body" translate> Received</h2>
</span>
</div>
<div class="padding" ng-if="btx.action == 'sent'">
<span class="ellipsis">
<h2 ng-if="btx.message">{{btx.message}}</h2>
<h2 ng-if="!btx.message && btx.note.body">{{btx.note.body}}</h2>
<h2 ng-if="!btx.message && !btx.note.body && wallet.addressbook[btx.addressTo]">{{wallet.addressbook[btx.addressTo]}}</h2>
<h2 ng-if="!btx.message && !btx.note.body && !wallet.addressbook[btx.addressTo]" translate> Sent</h2>
</span>
</div>
<div class="padding" ng-if="btx.action == 'moved'">
<span class="ellipsis">
<h2 ng-if="btx.note.body">{{btx.note.body}}</h2>
<h2 ng-if="!btx.note.body" translate>Moved</h2>
</span>
</div>
<span class="label tu warning radius" ng-if="btx.action == 'invalid'" translate>Invalid</span>
</div>
<div class="col col-30 padding">
<div class="card list" ng-show="txHistory[0]">
<div class="item" ng-repeat="btx in txHistory track by btx.txid" ng-click="openTxModal(btx)">
<span class="item-note text-right">
<span class="size-16" ng-class="{'text-bold': btx.recent}">
<span ng-if="btx.action == 'received'">+</span>
<span ng-if="btx.action == 'sent'">-</span>
@ -191,11 +153,37 @@
Unconfirmed
</span>
</p>
</div>
</span>
<img class="left m10r" src="img/icon-receive-history.svg" alt="sync" width="40" ng-if="btx.action == 'received'">
<img class="left m10r" src="img/icon-sent-history.svg" alt="sync" width="40" ng-if="btx.action == 'sent'">
<img class="left m10r" src="img/icon-moved.svg" alt="sync" width="40" ng-if="btx.action == 'moved'">
<h2 class="p10t">
<div ng-if="btx.action == 'received'">
<span class="ellipsis">
<h2 ng-if="btx.note.body">{{btx.note.body}}</h2>
<h2 ng-if="!btx.note.body" translate> Received</h2>
</span>
</div>
<div ng-if="btx.action == 'sent'">
<span class="ellipsis">
<h2 ng-if="btx.message">{{btx.message}}</h2>
<h2 ng-if="!btx.message && btx.note.body">{{btx.note.body}}</h2>
<h2 ng-if="!btx.message && !btx.note.body && wallet.addressbook[btx.addressTo]">{{wallet.addressbook[btx.addressTo]}}</h2>
<h2 ng-if="!btx.message && !btx.note.body && !wallet.addressbook[btx.addressTo]" translate> Sent</h2>
</span>
</div>
<div ng-if="btx.action == 'moved'">
<span class="ellipsis">
<h2 ng-if="btx.note.body">{{btx.note.body}}</h2>
<h2 ng-if="!btx.note.body" translate>Moved</h2>
</span>
</div>
<span class="label tu warning radius" ng-if="btx.action == 'invalid'" translate>Invalid</span>
</h2>
<div class="col col-10 text-center">
<i class="icon ion-chevron-right"></i>
</div>
</div>
<ion-infinite-scroll

View File

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('bitpayCardController', function($scope, $timeout, $log, lodash, bitpayCardService, configService, profileService, walletService, ongoingProcess, pbkdf2Service, moment, popupService) {
angular.module('copayApp.controllers').controller('bitpayCardController', function($scope, $timeout, $log, lodash, bitpayCardService, configService, profileService, walletService, ongoingProcess, pbkdf2Service, moment, popupService, gettextCatalog, bwcError) {
var self = this;
var wallet;
@ -168,6 +168,7 @@ angular.module('copayApp.controllers').controller('bitpayCardController', functi
};
walletService.createTx(wallet, txp, function(err, createdTxp) {
ongoingProcess.set('Processing Transaction...', false);
if (err) {
popupService.showAlert(gettextCatalog.getString('Error'), bwcError.msg(err));
return;

View File

@ -17,6 +17,11 @@ angular.module('copayApp.controllers').controller('confirmController', function(
$scope.showDescriptionPopup = function() {
$scope.data = {
comment: null
};
var commentPopup = $ionicPopup.show({
templateUrl: "views/includes/note.html",
title: gettextCatalog.getString('Set description'),
@ -25,9 +30,9 @@ angular.module('copayApp.controllers').controller('confirmController', function(
$scope.commentPopupClose = function() {
commentPopup.close();
};
$scope.commentPopupSave = function(description) {
$log.debug('Saving description: ' + description);
$scope.description = description;
$scope.commentPopupSave = function() {
$log.debug('Saving description: ' + $scope.data.comment);
$scope.description = $scope.data.comment;
commentPopup.close();
};
};

View File

@ -1,20 +1,15 @@
'use strict';
angular.module('copayApp.controllers').controller('exportController',
function($rootScope, $scope, $timeout, $log, $ionicHistory, lodash, backupService, walletService, storageService, profileService, platformInfo, gettext, gettextCatalog, $state, $stateParams, popupService) {
var prevState;
var isWP = platformInfo.isWP;
var isAndroid = platformInfo.isAndroid;
function($scope, $timeout, $log, $ionicHistory, backupService, walletService, storageService, profileService, platformInfo, gettextCatalog, $state, $stateParams, popupService) {
var wallet = profileService.getWallet($stateParams.walletId);
$scope.isEncrypted = wallet.isPrivKeyEncrypted();
$scope.isCordova = platformInfo.isCordova;
$scope.isSafari = platformInfo.isSafari;
$scope.init = function() {
$scope.supported = true;
$scope.exportQR = false;
$scope.noSignEnabled = false;
$scope.formData = {};
$scope.isEncrypted = wallet.isPrivKeyEncrypted();
$scope.isCordova = platformInfo.isCordova;
$scope.isSafari = platformInfo.isSafari;
$scope.formData.noSignEnabled = false;
$scope.showAdvanced = false;
$scope.wallet = wallet;
$scope.canSign = wallet.canSign();
@ -22,13 +17,15 @@ angular.module('copayApp.controllers').controller('exportController',
walletService.getEncodedWalletInfo(wallet, function(err, code) {
if (err || !code) {
$log.warn(err);
return $state.go('wallet.preferencesAdvanced')
return $ionicHistory.goBack();
}
if (!code)
$scope.supported = false;
else
$scope.exportWalletInfo = code;
$scope.formData.supported = false;
else {
$scope.formData.supported = true;
$scope.formData.exportWalletInfo = code;
}
$timeout(function() {
$scope.$apply();
@ -38,14 +35,25 @@ angular.module('copayApp.controllers').controller('exportController',
/*
EXPORT WITHOUT PRIVATE KEY - PENDING
*/
$scope.noSignEnabledChange = function() {
$scope.exportWalletInfo = encodeWalletInfo();
$timeout(function() {
$scope.$apply();
}, 1);
if (!$scope.formData.supported) return;
walletService.getEncodedWalletInfo(wallet, function(err, code) {
if (err) {
$log.error(err);
$scope.formData.supported = false;
$scope.formData.exportWalletInfo = null;
} else {
$scope.formData.supported = true;
$scope.formData.exportWalletInfo = code;
}
$timeout(function() {
$scope.$apply();
}, 1);
});
};
*/
$scope.downloadWalletBackup = function() {
$scope.getAddressbook(function(err, localAddressBook) {
@ -54,11 +62,11 @@ angular.module('copayApp.controllers').controller('exportController',
return;
}
var opts = {
noSign: $scope.noSignEnabled,
noSign: $scope.formData.noSignEnabled,
addressBook: localAddressBook
};
backupService.walletDownload($scope.password, opts, function(err) {
backupService.walletDownload($scope.formData.password, opts, function(err) {
if (err) {
popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to export'));
return;
@ -91,11 +99,11 @@ angular.module('copayApp.controllers').controller('exportController',
return cb(null);
}
var opts = {
noSign: $scope.noSignEnabled,
noSign: $scope.formData.noSignEnabled,
addressBook: localAddressBook
};
var ew = backupService.walletExport($scope.password, opts);
var ew = backupService.walletExport($scope.formData.password, opts);
if (!ew) {
popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to export'));
}
@ -132,7 +140,7 @@ angular.module('copayApp.controllers').controller('exportController',
var ew = backup;
if (!ew) return;
if ($scope.noSignEnabled)
if ($scope.formData.noSignEnabled)
name = name + '(No Private Key)';
var subject = 'Copay Wallet Backup: ' + name;

View File

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('termsController', function($scope, $log, $state, uxLanguage, profileService, externalLinkService) {
angular.module('copayApp.controllers').controller('termsController', function($scope, $log, $state, $window, uxLanguage, profileService, externalLinkService) {
$scope.lang = uxLanguage.currentLanguage;
$scope.disclaimerUrl = $window.appConfig.disclaimerUrl;

View File

@ -1,15 +1,20 @@
'use strict';
angular.module('copayApp.controllers').controller('preferencesBitpayCardController',
function($scope, $ionicModal, bitpayCardService) {
function($scope, $state, $timeout, bitpayCardService, popupService) {
this.logout = function() {
$ionicModal.fromTemplateUrl('views/modals/bitpay-card-confirmation.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.bitpayCardConfirmationModal = modal;
$scope.bitpayCardConfirmationModal.show();
$scope.logout = function() {
var title = 'Are you sure you would like to log out of your Bitpay Card account?';
popupService.showConfirm(title, null, function(res) {
if (res) logout();
});
};
var logout = function() {
bitpayCardService.logout(function() {
$timeout(function() {
$state.go('bitpayCard.main');
}, 100);
});
};

View File

@ -144,7 +144,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
};
$scope.updateTxHistory = function(cb) {
if (!cb) cb = function() {};
if ($scope.updatingTxHistory) return;
$scope.updatingTxHistory = true;

View File

@ -434,7 +434,6 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
})
.state('tabs.preferences.export', {
abstract: true,
url: '/export',
views: {
'preferences': {
@ -442,24 +441,6 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
}
})
.state('tabs.preferences.export.file', {
url: '/tab-export-file',
needProfile: true,
views: {
'tab-export-file': {
templateUrl: 'views/tab-export-file.html',
},
}
})
.state('tabs.preferences.export.qrCode', {
url: '/tab-export-qrCode',
needProfile: true,
views: {
'tab-export-qrCode': {
templateUrl: 'views/tab-export-qrCode.html',
},
}
})
.state('tabs.preferences.preferencesBwsUrl', {
url: '/preferencesBwsUrl',
views: {

View File

@ -30,7 +30,7 @@ angular.module('copayApp.services')
root.updateWalletSettings = function(wallet) {
var defaults = configService.getDefaults();
configService.whenAvailable(function(config){
configService.whenAvailable(function(config) {
wallet.usingCustomBWS = config.bwsFor && config.bwsFor[wallet.id] && (config.bwsFor[wallet.id] != defaults.bws.url);
wallet.name = (config.aliasFor && config.aliasFor[wallet.id]) || wallet.credentials.walletName;
wallet.color = (config.colorFor && config.colorFor[wallet.id]) || '#4A90E2';
@ -77,7 +77,7 @@ angular.module('copayApp.services')
var opts = opts || {};
var walletId = wallet.credentials.walletId;
if ((root.wallet[walletId] && root.wallet[walletId].started) && !opts.force) {
if ((root.wallet[walletId] && root.wallet[walletId].started) && !opts.force) {
return false;
}
@ -762,7 +762,7 @@ angular.module('copayApp.services')
var TIME_STAMP = 60 * 60 * 24 * 7;
var MAX = 100;
var ignored = {
var typeFilter1 = {
'NewBlock': 1,
'BalanceUpdated': 1,
'NewOutgoingTxByThirdParty': 1,
@ -771,6 +771,12 @@ angular.module('copayApp.services')
'TxProposalFinallyRejected': 1,
};
var typeFilter2 = {
'TxProposalAcceptedBy': 1,
'TxProposalRejectedBy': 1,
'NewTxProposal': 1,
}
var w = root.getWallets();
if (lodash.isEmpty(w)) return cb();
@ -868,9 +874,15 @@ angular.module('copayApp.services')
$log.warn('Error updating notifications:' + err);
} else {
var n = lodash.filter(wallet.cachedActivity.n, function(x) {
return !ignored[x.type];
return !typeFilter1[x.type];
});
if (wallet.n == 1) {
var n = lodash.filter(n, function(x) {
return !typeFilter2[x.type];
});
}
var idToName = {};
if (wallet.cachedStatus) {
lodash.each(wallet.cachedStatus.wallet.copayers, function(c) {
@ -911,7 +923,7 @@ angular.module('copayApp.services')
txps = txps.concat(x.pendingTxps);
});
txps = lodash.sortBy(txps, 'pendingForUs', 'createdOn');
txps = lodash.compact(lodash.flatten(txps)).slice(0,MAX);
txps = lodash.compact(lodash.flatten(txps)).slice(0, MAX);
var n = txps.length;
return cb(null, txps, n);
};

View File

@ -8,6 +8,10 @@
font-weight: bold;
}
.item.item-footer {
font-weight: lighter;
}
.icon.list-add-button {
color: #666;
font-size: 38px;

View File

@ -343,7 +343,7 @@ ul.wallet-selection.wallets {
position: absolute;
top: inherit;
left: 10px;
bottom: 26px;
bottom: 15px;
font-size: 20px;
color: #fff;
}
@ -996,5 +996,6 @@ input[type=number] {
@import "views/add";
@import "views/tab-home";
@import "views/walletDetails";
@import "views/bitpayCard";
@import 'views/onboarding/onboarding';
@import "views/includes/walletActivity";

View File

@ -0,0 +1,16 @@
#bitpayCard {
.amount {
width: 100%;
text-align: center;
padding: 2rem 1rem 1.5rem 1rem;
min-height: 115px;
margin-bottom: 25px;
border-color: #172565;
background-color: #1e3186;
background-image: linear-gradient(0deg, #172565, #172565 0%, transparent 0%);
color: #fff;
}
strong {
line-height: 100%;
}
}

View File

@ -14,14 +14,14 @@
opacity: 1;
background: #fff;
color: rgb(108, 108, 108);
height: 13rem;
height: 14rem;
animation-name: topBottom;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 1s;
animation-delay: 2s;
position: absolute;
bottom: -13rem;
bottom: -14rem;
animation-fill-mode: forwards;
z-index: 5;
margin-top: 0;

View File

@ -1,6 +1,7 @@
#walletDetails {
.bar-header {
border: 0;
background: none;
.title, .button {
color: #fff;
}
@ -12,13 +13,17 @@
.amount {
width: 100%;
text-align: center;
padding: 2.5rem 1rem 1.5rem 1rem;
padding: 2rem 1rem 1.5rem 1rem;
color: #fff;
height: 150px;
margin-bottom: 25px;
min-height: 115px;
margin-bottom: 10px;
&-alternative {
line-height: 48px;
line-height: 36px;
}
strong {
line-height: 100%;
}
}
}

View File

@ -1,6 +1,6 @@
[Desktop Entry]
Type=Application
Version=0.8.0
Version=0.10.0
Name=BitPay
Comment=The BitPay Bitcoin Wallet
Exec=bitpay

View File

@ -2,7 +2,7 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "bitpay"
#define MyAppVersion "0.8.0"
#define MyAppVersion "0.10.0"
#define MyAppPublisher "BitPay"
#define MyAppURL "https://bitpay.com"
#define MyAppExeName "*NAMECASENOSPACE.exe"