Merge branch 'ref/design' of github.com:bitpay/bitpay-wallet into scanHandling

This commit is contained in:
Marty Alcala 2016-10-19 16:36:32 -04:00
commit 01d5e1d2eb
36 changed files with 336 additions and 149 deletions

1
.gitignore vendored
View File

@ -106,6 +106,7 @@ src/js/appConfig.js
src/js/externalServices.js
chrome-app/manifest.json
www/img/app
www/index.html
cordova/android/res/

View File

@ -3,7 +3,7 @@
[![Build Status](https://secure.travis-ci.org/bitpay/copay.svg)](http://travis-ci.org/bitpay/copay)
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/copay/localized.png)](https://crowdin.com/project/copay)
Copay is an easy-to-use, open-source, multiplatform, multisignature, secure bitcoin wallet platform for both individuals and companies. Copay uses [Bitcore Wallet Service](https://github.com/bitpay/bitcore-wallet-service) (BWS) for peer synchronization and network interfacing.
Copay is an easy-to-use, open-source, multiplatform, multisignature, secure bitcoin wallet platform for both individuals and companies. Copay uses [Bitcore Wallet Service](https://github.com/bitpay/bitcore-wallet-service) (BWS) for peer synchronization and network interfacing.
Binary versions of Copay are available for download at [Copay.io](https://copay.io/#download). Copay Binaries are signed with the key `copay@bitpay.com` See the section [`How to Verify Copay Signatures`](https://github.com/bitpay/copay#how-to-verify-copay-signatures) for details.
@ -29,7 +29,9 @@ For a list of frequently asked questions please visit the [Copay FAQ](https://gi
- Multiple languages supported
- Available for [iOS](https://itunes.apple.com/us/app/copay/id951330296), [Android](https://play.google.com/store/apps/details?id=com.bitpay.copay&hl=en), [Windows Phone](http://www.windowsphone.com/en-us/store/app/copay-wallet/4372479b-a064-4d18-8bd3-74a3bdb81c3a), [Chrome App](https://chrome.google.com/webstore/detail/copay/cnidaodnidkbaplmghlelgikaiejfhja?hl=en), [Linux](https://github.com/bitpay/copay/releases/latest), [Windows](https://github.com/bitpay/copay/releases/latest) and [OS X](https://github.com/bitpay/copay/releases/latest) devices
## Install For Development
## Testing in a Browser
> **Note:** This method should only be used for development purposes. When running Copay in a normal browser environment, browser extensions and other malicious code might have access to internal data and private keys. For production use, see the latest official [releases](https://github.com/bitpay/copay/releases/).
Clone the repo and open the directory:
@ -47,68 +49,83 @@ npm start
Visit [`localhost:3000`](http://localhost:3000/) to view the app.
> **Note:** This method should only be used for development purposes. When running Copay in a normal browser environment, browser extensions and other malicious code might have access to internal data and private keys. For production use, see the latest official [releases](https://github.com/bitpay/copay/releases/).
A watch task is also available to rebuild components of the app as changes are made. This task can be run in a separate process while the server started by `npm start` is running to quickly test changes.
## Build Copay App Bundles
```
npm run watch
```
## Testing on Real Devices
It's recommended that all final testing be done on a real device both to assess performance and to enable features that are unavailable to the emulator (e.g. a device camera).
### Android
- Install Android SDK
- Run `make android`
Follow the [Cordova Android Platform Guide](https://cordova.apache.org/docs/en/latest/guide/platforms/android/) to set up your development environment.
When your developement enviroment is ready, run the `start:android` npm package script.
```sh
npm run apply:copay
npm run start:android
```
### iOS
- Install Xcode 6.1 (or newer)
- Run `make ios-prod`
Follow the [Cordova iOS Platform Guide](https://cordova.apache.org/docs/en/latest/guide/platforms/android/) to set up your development environment.
##### Notes for Xcode 7.0
When your developement enviroment is ready, run the `start:ios` npm package script.
###### ATS support
Before starting Copay from Xcode, add these lines to "Custom iOS Target Properties":
```
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
```sh
npm run apply:copay
npm run start:ios
```
![Example](http://i.stack.imgur.com/nGw3j.png)
### Desktop (Linux, macOS, and Windows)
The desktop version of Copay currently uses NW.js, an app runtime based on Chromium. To get started, first install NW.js on your system from [the NW.js website](https://nwjs.io/).
App Transport Security (ATS) enforces best practices in the secure connections between an app and its back end. [Read complete documentation](https://developer.apple.com/library/prerelease/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS9.html).
###### Invalid Bundle while submitting application
`iPad Multitasking support requires launch story board in bundle`
To fix this problem, add the following:
When NW.js is installed, run the `start:desktop` npm package script.
```sh
npm run apply:copay
npm run start:desktop
```
<key>UIRequiresFullScreen</key>
<string>YES</string>
## Build Copay App Bundles
Before building the release version for a platform, run the `clean-all` command to delete any untracked files in your current working directory. (Be sure to stash any uncommited changes you've made.) This guarantees consistency across builds for the current state of this repository.
The `final` commands build the production version of the app, and bundle it with the release version of the platform being built.
### Android
```sh
npm run clean-all
npm run apply:copay
npm run final:android
```
###### Build settings, headers search path
Add this line to your Build Settings -> Header Search Paths -> Release
"$(OBJROOT)/UninstalledProducts/$(PLATFORM_NAME)/include"
### iOS
```sh
npm run clean-all
npm run apply:copay
npm run final:ios
```
### Windows Phone
- Install Visual Studio 2013 (or newer)
- Run `make wp8-prod`
### Desktop versions (Windows, OS X, Linux)
### Desktop (Linux, macOS, and Windows)
Copay uses NW.js (also know as node-webkit) for its desktop version. NW.js is an app runtime based on `Chromium` and `node.js`.
- Install NW.js on your system from [nwjs.io](http://nwjs.io/)
- Run `grunt desktop`
```sh
npm run clean-all
npm run apply:copay
npm run final:desktop
```
### Google Chrome App
@ -116,10 +133,6 @@ Copay uses NW.js (also know as node-webkit) for its desktop version. NW.js is an
On success, the Chrome extension will be located at: `browser-extensions/chrome/copay-chrome-extension`. To install it go to `chrome://extensions/` in your browser and ensure you have the 'developer mode' option enabled in the settings. Then click on "Load unpacked chrome extension" and choose the directory mentioned above.
### Firefox Add-on
The Copay Firefox Extension has been deprecated and is no longer supported.
## About Copay
### General

View File

@ -6,6 +6,7 @@
var templates = {
'package.json': '/',
'index.html': 'www/',
'Makefile': 'cordova/',
'ProjectMakefile': 'cordova/',
'config-template.xml': '/',

View File

@ -75,6 +75,7 @@
<platform name="ios">
<config-file platform="ios" target="*-Info.plist" parent="UIStatusBarHidden"><true/></config-file>
<config-file platform="ios" target="*-Info.plist" parent="UIViewControllerBasedStatusBarAppearance"><false/></config-file>
<config-file target="*-Info.plist" parent="ITSAppUsesNonExemptEncryption"><false/></config-file>
<icon src="resources/*PACKAGENAME*/ios/icon/icon-60@3x.png" width="180" height="180" />
<icon src="resources/*PACKAGENAME*/ios/icon/icon-60.png" width="60" height="60" />
<icon src="resources/*PACKAGENAME*/ios/icon/icon-60@2x.png" width="120" height="120" />

View File

@ -7,7 +7,7 @@
<meta name="msapplication-tap-highlight" content="no">
<meta name="format-detection" content="telephone=no">
<link rel="stylesheet" type="text/css" href="css/copay.css">
<title>{{appConfig.nameCase}} - {{appConfig.description}}</title>
<title>*USERVISIBLENAME* - *PURPOSELINE*</title>
<link rel="shortcut icon" href="img/app/favicon.ico">
</head>
<body>

View File

@ -23,6 +23,9 @@
"frame": true,
"width": 400,
"height": 650,
"min_width": 400,
"max_width": 800,
"min_height": 650,
"position": "center",
"fullscreen": false
},
@ -95,6 +98,8 @@
"final:www": "npm run build:www-release",
"final:ios": "npm run final:www && npm run build:ios-release && npm run open:ios",
"final:android": "npm run final:www && npm run build:android-release && npm run run:android",
"final:desktop": "grunt desktop",
"sign:android": "rm -f platforms/android/build/outputs/apk/android-release-signed-aligned.apk; jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ../copay.keystore -signedjar platforms/android/build/outputs/apk/android-release-signed.apk platforms/android/build/outputs/apk/android-release-unsigned.apk copay_play && ../android-sdk-macosx/build-tools/21.1.1/zipalign -v 4 platforms/android/build/outputs/apk/android-release-signed.apk platforms/android/build/outputs/apk/android-release-signed-aligned.apk",
"run:android": "cordova run android --device",
"log:android": "adb logcat | grep chromium",
"apply:copay": "cd app-template && node apply.js copay && cordova prepare",

View File

@ -10,7 +10,7 @@
"angular-mocks": "1.4.10",
"angular-gettext": "2.2.1",
"angular-moment": "0.10.1",
"angular-qrcode": "monospaced/angular-qrcode#~6.2.1",
"angular-qrcode": "bitpay/angular-qrcode#~6.3.0",
"ionic": "1.3.1",
"moment": "2.10.3",
"ng-lodash": "0.2.3",

View File

@ -1,18 +1,116 @@
{
"name": "distribution-not-selected",
"description": "Choose a distribution by running 'npm run apply:copay' or 'npm run apply:bitpay'.",
"primary-package-json": "See the tempate in app-template/package.json",
"scripts": {
"postinstall": "npm run apply:copay && npm install",
"apply:copay": "cd app-template && node apply.js copay",
"apply:bitpay": "cd app-template && node apply.js bitpay"
{
"//":"Changes to this file will be overwritten",
"//":" Modify it in the app-template directory",
"name": "bitpay",
"description": "Secure Bitcoin Wallet",
"author": "BitPay",
"version": "0.14.0",
"keywords": [
"bitcoin",
"wallet",
"bitpay",
"copay",
"multisignature",
"bitcore"
],
"main": "www/index.html",
"window": {
"title": "BitPay - Secure Bitcoin Wallet",
"icon": "www/img/icon-128.png",
"toolbar": false,
"show": true,
"visible": true,
"resizable": true,
"frame": true,
"width": 400,
"height": 650,
"position": "center",
"fullscreen": false
},
"dependencies": {
"fs-extra": "^0.30.0"
"webkit": {
"page-cache": false,
"java": false,
"plugin": false
},
"dom_storage_quota": 200,
"id": "jid1-x7bV5evAaI1P9Q",
"homepage": "https://bitpay.com",
"license": "MIT",
"repository": {
"url": "git://github.com/bitpay/copay.git",
"url": "git://github.com/bitpay/bitpay-wallet.git",
"type": "git"
},
"bugs": {
"url": "https://github.com/bitpay/bitpay-wallet/issues"
},
"dependencies": {
"adm-zip": "^0.4.7",
"angular": "1.4.6",
"angular-mocks": "1.4.10",
"bezier-easing": "^2.0.3",
"bhttp": "^1.2.1",
"bitauth": "^0.3.2",
"bitcore-wallet-client": "4.3.2",
"bower": "^1.7.9",
"chai": "^3.5.0",
"cordova-android": "5.1.1",
"cordova-custom-config": "^3.0.5",
"cordova-plugin-qrscanner": "^2.3.1",
"coveralls": "^2.11.9",
"express": "^4.11.2",
"fs": "0.0.2",
"fs-extra": "^0.30.0",
"grunt-angular-gettext": "^2.2.3",
"grunt-browserify": "^5.0.0",
"grunt-cli": "^1.2.0",
"grunt-contrib-compress": "^1.3.0",
"grunt-contrib-concat": "^1.0.1",
"grunt-contrib-copy": "^1.0.0",
"grunt-contrib-uglify": "^2.0.0",
"grunt-contrib-watch": "^1.0.0",
"grunt-exec": "^1.0.0",
"grunt-nw-builder": "^2.0.3",
"grunt-sass": "^1.2.0",
"load-grunt-tasks": "^3.5.0",
"mocha": "^2.4.5",
"phantomjs-prebuilt": "^2.1.7",
"shelljs": "^0.3.0"
},
"scripts": {
"preinstall": "bower install && npm install fs-extra",
"postinstall": "echo && echo \"To finish, choose a distribution by running 'npm run apply:copay' or 'npm run apply:bitpay'.\" && echo",
"start": "npm run build:www && ionic serve --nolivereload --nogulp -s",
"start:ios": "npm run build:www && npm run build:ios && npm run open:ios",
"start:android": "npm run build:www && npm run build:android && npm run run:android",
"start:desktop": "grunt desktop",
"watch": "grunt watch",
"build:www": "grunt",
"build:www-release": "grunt prod",
"build:ios": "cordova prepare ios && cordova build ios --debug",
"build:android": "cordova prepare android && cordova build android --debug",
"build:ios-release": "cordova prepare ios && cordova build ios --release",
"build:android-release": "cordova prepare android && cordova build android --release",
"open:ios": "open platforms/ios/*.xcodeproj",
"open:android": "open -a open -a /Applications/Android\\ Studio.app platforms/android",
"final:www": "npm run build:www-release",
"final:ios": "npm run final:www && npm run build:ios-release && npm run open:ios",
"final:android": "npm run final:www && npm run build:android-release && npm run run:android",
"final:desktop": "grunt desktop",
"sign:android": "rm -f platforms/android/build/outputs/apk/android-release-signed-aligned.apk; jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ../copay.keystore -signedjar platforms/android/build/outputs/apk/android-release-signed.apk platforms/android/build/outputs/apk/android-release-unsigned.apk copay_play && ../android-sdk-macosx/build-tools/21.1.1/zipalign -v 4 platforms/android/build/outputs/apk/android-release-signed.apk platforms/android/build/outputs/apk/android-release-signed-aligned.apk",
"run:android": "cordova run android --device",
"log:android": "adb logcat | grep chromium",
"apply:copay": "cd app-template && node apply.js copay && cordova prepare",
"apply:bitpay": "cd app-template && node apply.js bitpay && cordova prepare",
"test": "./node_modules/.bin/grunt test-coveralls",
"clean": "trash platforms && trash plugins && cordova prepare",
"clean-all": "git clean -dfx && npm install"
},
"devDependencies": {
"cordova": "^6.3.1",
"grunt": "^1.0.1",
"ionic": "^2.1.0",
"trash-cli": "^1.4.0",
"lodash": "^4.3.0"
}
}

View File

@ -139,7 +139,6 @@ angular.module('copayApp.controllers').controller('buyGlideraController',
$scope.wallets = profileService.getWallets({
network: $scope.network,
n: 1,
onlyComplete: true
});
});

View File

@ -1,14 +1,29 @@
'use strict';
angular.module('copayApp.controllers').controller('notificationsController', function($scope, $state, $timeout, $stateParams, $ionicConfig, profileService, configService) {
angular.module('copayApp.controllers').controller('notificationsController', function($scope, $state, $timeout, $stateParams, $ionicConfig, profileService, configService, $interval) {
$ionicConfig.views.swipeBackEnabled(false);
$scope.walletId = $stateParams.walletId;
$scope.allowNotif = function() {
$scope.notificationDialogOpen = true;
$timeout(function() {
profileService.pushNotificationsInit();
});
$scope.notificationPromise = $interval(function() {
PushNotification.hasPermission(function(data) {
if (data.isEnabled) {
$interval.cancel($scope.notificationPromise);
$state.go('onboarding.backupRequest', {
walletId: $scope.walletId
});
}
});
}, 100);
}
$scope.continue = function() {
$interval.cancel($scope.notificationPromise);
$state.go('onboarding.backupRequest', {
walletId: $scope.walletId
});

View File

@ -113,10 +113,13 @@ angular.module('copayApp.directives')
}
}
})
.directive('contact', ['addressbookService', 'lodash',
function(addressbookService, lodash) {
.directive('contact', ['addressbookService', 'lodash', 'gettextCatalog',
function(addressbookService, lodash, gettextCatalog) {
return {
restrict: 'E',
scope: {
label: '='
},
link: function(scope, element, attrs) {
var addr = attrs.address;
addressbookService.get(addr, function(err, ab) {
@ -124,7 +127,11 @@ angular.module('copayApp.directives')
var name = lodash.isObject(ab) ? ab.name : ab;
element.append(name);
} else {
element.append(addr);
if (scope.label && scope.label == 'Sent') {
element.append(gettextCatalog.getString('Sent'));
} else {
element.append(addr);
}
}
});
}

View File

@ -12,9 +12,10 @@ angular.module('copayApp.directives')
email: '@'
},
link: function(scope, el, attr) {
scope.emailHash = md5.createHash(scope.email || '');
if(typeof scope.email === "string"){
scope.emailHash = md5.createHash(scope.email.toLowerCase() || '');
}
},
template: '<img class="gravatar" alt="{{ name }}" height="{{ height }}" width="{{ width }}" src="https://secure.gravatar.com/avatar/{{ emailHash }}.jpg?s={{ width }}&d=mm">'
}
});

View File

@ -23,10 +23,10 @@ angular.module('copayApp.services').factory('configService', function(storageSer
reconnectDelay: 5000,
idleDurationMin: 4,
settings: {
unitName: 'bits',
unitName: 'BTC',
unitToSatoshi: 100,
unitDecimals: 2,
unitCode: 'bit',
unitCode: 'btc',
alternativeName: 'US Dollar',
alternativeIsoCode: 'USD',
}

View File

@ -601,6 +601,16 @@ angular.module('copayApp.services')
$log.debug('Importing Wallet:', opts);
try {
var c = JSON.parse(str);
if (c.xPrivKey && c.xPrivKeyEncrypted) {
$log.warn('Found both encrypted and decrypted key. Deleting the encrypted version');
delete c.xPrivKeyEncrypted;
delete c.mnemonicEncrypted;
}
str = JSON.stringify(c);
walletClient.import(str, {
compressed: opts.compressed,
password: opts.password
@ -609,14 +619,6 @@ angular.module('copayApp.services')
return cb(gettext('Could not import. Check input file and spending password'));
}
str = JSON.parse(str);
if (str.xPrivKey && str.xPrivKeyEncrypted) {
$log.warn('Found both encrypted and decrypted key. Deleting the encrypted version');
delete str.xPrivKeyEncrypted;
delete str.mnemonicEncrypted;
}
var addressBook = str.addressBook || {};
addAndBindWalletClient(walletClient, {

View File

@ -52,6 +52,9 @@
position: absolute;
bottom: 254px;
top: 66px;
.light {
color: #A4A4A4;
}
}
}
@ -84,7 +87,8 @@
.operator-send {
font-weight: bolder;
background-color: #f7f7f7;
color: #f8f8f8;
background-color: #1e3186;
font-size: 36px;
cursor: pointer;

View File

@ -1,6 +1,5 @@
#tab-home {
.icon-create-wallet {
background-image: url("../img/icon-wallet.svg");
background-color: #4A90E2; // default wallet color
}
.icon-buy-bitcoin {
@ -16,19 +15,17 @@
.icon-amazon {
background-image: url("../img/icon-amazon.svg");
}
.bg {
&.wallet{
padding: .25rem
}
}
.card{
.item {
color: #444;
border-top:none;
padding-bottom: 1.5rem;
padding-top:1.5rem;
&.wallet{
.big-icon-svg{
& > .bg{
padding: .25rem
}
}
}
}
.item-sub {
&:first-child:before {

View File

@ -1,3 +1,30 @@
.wallet-details {
&__tx-amount {
font-size: 16px;
&--recent {
color: $mid-gray;
font-weight: bold;
}
&--received {
color: #30af6c;
}
&--sent {
color: $dark-gray;
}
}
&__tx-time {
color: $light-gray;
}
&__tx-title {
padding-top: 10px;
color: $dark-gray;
}
&__tx-icon {
float: left;
margin-right: 10px;
}
}
#walletDetails {
.bar-header {
border: 0;
@ -31,23 +58,8 @@
.item.item-footer {
font-weight: lighter;
}
}
.wallet-details-release {
cursor: pointer;
cursor: hand;
background-color: #E9E9EC;
margin-top: -30px;
margin-bottom: 5px;
padding-top: 30px;
padding-bottom: 20px;
text-align: center;
text-color: #444;
span {
margin-left: 15px;
}
i {
margin-right: 15px;
.tx-search:before {
font-size: 22px !important;
}
}

11
www/img/icon-tx-moved.svg Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 20.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 34 34" style="enable-background:new 0 0 34 34;" xml:space="preserve">
<style type="text/css">
.st0{opacity:0.8;fill:#F2F2F2;enable-background:new ;}
.st1{fill:none;stroke:#BEBEBE;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;}
</style>
<ellipse transform="matrix(0.7071 -0.7071 0.7071 0.7071 -7.0416 17)" class="st0" cx="17" cy="17" rx="16.5" ry="16.5"/>
<path class="st1" d="M22.7,16.9H11.1 M18,21.9l4.9-5l-4.8-4.9"/>
</svg>

After

Width:  |  Height:  |  Size: 707 B

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 20.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 34 34" style="enable-background:new 0 0 34 34;" xml:space="preserve">
<style type="text/css">
.st0{opacity:0.8;fill:#EFFEF6;enable-background:new ;}
.st1{fill:none;stroke:#7FB197;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;}
</style>
<ellipse transform="matrix(0.7071 -0.7071 0.7071 0.7071 -7.0416 17)" class="st0" cx="17" cy="17" rx="16.5" ry="16.5"/>
<path class="st1" d="M17.2,25.6V8.1 M9.6,18.5l7.4,7.4l7.3-7.1"/>
</svg>

After

Width:  |  Height:  |  Size: 708 B

11
www/img/icon-tx-sent.svg Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 20.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 34 34" style="enable-background:new 0 0 34 34;" xml:space="preserve">
<style type="text/css">
.st0{opacity:0.8;fill:#F2F2F2;enable-background:new ;}
.st1{fill:none;stroke:#BEBEBE;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;}
</style>
<path class="st0" d="M5.3,28.7c-6.4-6.4-6.4-16.9,0-23.3s16.9-6.4,23.3,0s6.4,16.9,0,23.3S11.8,35.1,5.3,28.7z"/>
<path class="st1" d="M17.2,9.4v16.5 M9.6,15.5l7.4-7.4l7.3,7.1"/>
</svg>

After

Width:  |  Height:  |  Size: 700 B

View File

@ -35,15 +35,14 @@
</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" ng-class="{'size-16': smallFont, 'size-17': !smallFont}" ng-show="!showAlternativeAmount">
<div class="text-light text-black m15b" ng-class="{'size-28': smallFont, 'size-36': !smallFont, 'light': !amount}"><span>{{amount || "0.00" }}</div>
<div class="text-light text-black" ng-class="{'size-16': smallFont, 'size-17': !smallFont, 'light': !amountResult}" ng-show="!showAlternativeAmount">
{{globalResult}} <span class="label gray text-white radius">{{amountResult || '0.00'}} {{alternativeIsoCode}}</span>
</div>
<div class="text-light text-black size-17" ng-show="showAlternativeAmount">
{{globalResult}} <span class="label gray text-white radius">{{alternativeResult || '0.00'}} {{unitName}}</span>
</div>
</div>
</div>
<div class="keypad">

View File

@ -33,7 +33,7 @@
ng-submit="buy.confirm()"
novalidate>
<div class="card list">
<div class="list card">
<label class="item item-input item-stacked-label">
<span class="input-label">Amount</span>
<input type="number"

View File

@ -32,7 +32,7 @@
<form name="buyPriceForm" ng-if="token"
ng-submit="buy.get2faCode(token)" novalidate>
<div class="card list">
<div class="list card">
<label class="item item-input item-stacked-label">
<span class="input-label">Amount in {{showAlternative ? 'USD' : 'BTC'}}</span>
<input ng-show="!showAlternative"
@ -66,7 +66,7 @@
<wallets ng-if="wallets[0]" wallets="wallets"></wallets>
<div class="text-center text-gray size-12 m20b" ng-show="!buy.gettingBuyPrice && buy.buyPrice.qty">
<div class="text-center text-gray size-12 m20v" ng-show="!buy.gettingBuyPrice && buy.buyPrice.qty">
Buy
<span ng-show="qty">{{buy.buyPrice.subtotal|currency:'':2}} {{buy.buyPrice.currency}} in Bitcoin</span>
<span ng-show="fiat">{{buy.buyPrice.qty}} BTC</span>
@ -96,7 +96,7 @@
</p>
<form name="buyForm"
ng-submit="buy.sendRequest(token, permissions, twoFaCode)" novalidate>
<div class="card list">
<div class="list card">
<label class="item item-input">
<input type="number" ng-model="twoFaCode" placeholder="2FA Code" required ignore-mouse-wheel>
</label>
@ -106,12 +106,12 @@
Buy
</button>
</form>
<p class="m10t size-12 text-gray">
<p class="m10t size-12 text-gray padding">
Fiat will be immediately withdrawn from your bank account. The bitcoins will be purchased and deposited to your wallet in 2-4 business days.
</p>
</div>
</div>
<div class="text-center" ng-show="buy.success">
<div class="text-center padding" ng-show="buy.success">
<h1>Purchase initiated</h1>
<p class="text-gray">
A transfer has been initiated from your bank account. Your bitcoins should arrive to your wallet in 2-4 business days.

View File

@ -18,7 +18,7 @@
Share this invitation with your copayers
</div>
<div class="item text-center" copy-to-clipboard="secret" ng-click="copySecret()">
<qrcode size="220" error-correction-level="L" data="{{secret}}"></qrcode>
<qrcode size="220" error-correction-level="L" data="{{secret}}" color="#334"></qrcode>
<div ng-show="!secret" style="position:relative; top:-226px; height:0px">
<div style="height:220px; width:220px; margin:auto; background: white">
<ion-spinner class="spinner-dark" icon="lines"></ion-spinner>

View File

@ -52,7 +52,7 @@
</div>
<div ng-show="showOauthForm">
<form name="oauthCodeForm" ng-submit="glidera.submitOauthCode(code)" novalidate>
<div class="card list">
<div class="list">
<label class="item item-input item-stacked-label">
<span class="input-label">OAuth Code</span>
<input type="text"

View File

@ -1,5 +1,5 @@
<ion-modal-view ng-controller="customAmountController">
<ion-header-bar align-title="center" class="tab-bar" ng-style="{'background-color':color}">
<ion-header-bar align-title="center" class="tab-bar" ng-style="{'background-color':color, 'border-color': color}">
<div class="left-small">
<a ng-click="cancel()" class="p10">
<span class="text-close" translate>Close</span>
@ -14,7 +14,7 @@
<h4 class="title m0" translate>QR Code</h4>
<ul class="no-bullet size-14 m0">
<li class="line-b p10 oh text-center">
<qrcode size="220" data="bitcoin:{{addr + '?amount=' + customizedAmountBtc}}"></qrcode>
<qrcode size="220" data="bitcoin:{{addr + '?amount=' + customizedAmountBtc}}" color="#334"></qrcode>
<div class="m10t text-center" ng-show="isCordova">
<span class="button outline dark-gray tiny round"
ng-click="shareAddress('bitcoin:' + addr + '?amount=' + customizedAmountBtc)">

View File

@ -1,5 +1,5 @@
<ion-modal-view ng-controller="payproController">
<ion-header-bar align-title="center" class="bar-royal" ng-style="{'background-color': color}">
<ion-header-bar align-title="center" class="bar-royal" ng-style="{'background-color': color, 'border-color': color}">
<button class="button button-clear" ng-click="cancel()">
{{'Close' | translate}}
</button>

View File

@ -1,5 +1,5 @@
<ion-modal-view>
<ion-header-bar align-title="center" class="bar-royal" ng-style="{'background-color':color}">
<ion-header-bar align-title="center" class="bar-royal" ng-style="{'background-color':color, 'border-color': color}">
<button class="button button-clear" ng-click="close()">
Close
</button>

View File

@ -1,5 +1,5 @@
<ion-modal-view ng-controller="txDetailsController" ng-init="init()" id="tx-details">
<ion-header-bar align-title="center" class="bar-royal" ng-style="{'background-color': color}">
<ion-header-bar align-title="center" class="bar-royal" ng-style="{'background-color': color, 'border-color': color}">
<button class="button button-clear" ng-click="cancel()">
{{'Close' | translate}}
</button>
@ -72,7 +72,7 @@
<div ng-show="btx.hasMultiplesOutputs" class="item item-icon-right item-heading" ng-click="showMultiplesOutputs = !showMultiplesOutputs">
{{'Recipients'|translate}}
[ {{btx.recipientCount}} ]
<i class="icon bp-arrow-up" ng-show="showMultiplesOutputs"></i>
<i class="icon bp-arrow-down" ng-show="!showMultiplesOutputs"></i>
</div>

View File

@ -4,8 +4,9 @@
<div class="onboarding-description" translate>Would you like to receive push notifications about payments?</div>
<div class="onboarding-illustration-notifications"></div>
<div id="cta-buttons">
<button class="button button-standard button-primary" ng-click="allowNotif()" translate>Allow notifications</button>
<button class="button button-standard button-secondary button-clear" ng-click="disableNotif()" translate>Not now</button>
<button class="button button-standard button-primary" ng-click="allowNotif()" translate ng-if="!notificationDialogOpen">Allow notifications</button>
<button class="button button-standard button-secondary button-clear" ng-click="disableNotif()" translate ng-if="!notificationDialogOpen">Not now</button>
<button class="button button-standard button-primary" ng-click="continue()" translate ng-if="notificationDialogOpen">Continue</button>
</div>
</ion-content>
</ion-view>

View File

@ -6,7 +6,7 @@
</ion-nav-bar>
<ion-content>
<div class="card list">
<div class="list">
<label class="item item-input item-stacked-label no-border">
<span class="input-label">Wallet Service URL</span>
<input type="text" id="bwsurl" type="text" name="bwsurl" ng-model="bwsurl.value">

View File

@ -31,7 +31,7 @@
<form name="sellPriceForm" ng-if="token"
ng-submit="sell.get2faCode(token)" novalidate>
<div class="card list">
<div class="list card">
<label class="item item-input item-stacked-label">
<span class="input-label"><span>Amount in</span> {{showAlternative ? 'USD' : 'BTC'}}</span>
<input ng-show="!showAlternative"
@ -65,7 +65,7 @@
<wallets ng-if="wallets[0]" wallets="wallets"></wallets>
<div class="text-center text-gray size-12 m20b" ng-show="!sell.gettingSellPrice && sell.sellPrice.qty">
<div class="text-center text-gray size-12 m20v" ng-show="!sell.gettingSellPrice && sell.sellPrice.qty">
Sell
<span ng-show="qty">{{sell.sellPrice.subtotal|currency:'':2}} {{sell.sellPrice.currency}} in Bitcoin</span>
<span ng-show="fiat">{{sell.sellPrice.qty}} BTC</span>
@ -96,7 +96,7 @@
</p>
<form name="sellForm"
ng-submit="sell.createTx(token, permissions, twoFaCode)" novalidate>
<div class="card list">
<div class="list card">
<label class="item item-input">
<input type="number" ng-model="twoFaCode" placeholder="2FA Code" required ignore-mouse-wheel>
</label>
@ -107,12 +107,12 @@
Sell
</button>
</form>
<p class="m10t size-12 text-gray">
<p class="m10t size-12 text-gray padding">
Bitcoins will be immediately sent from your wallet to Glidera. Fiat will be deposited in your bank account in 4-6 business days.
</p>
</div>
</div>
<div class="text-center" ng-show="sell.success">
<div class="text-center padding" ng-show="sell.success">
<h1>Sale initiated</h1>
<p class="text-gray">
A transfer has been initiated to your bank account and should arrive in 4-6 business days.

View File

@ -1,6 +1,6 @@
<div class="list" ng-show="formData.supported">
<div class="text-center m20t">
<qrcode size="220" version="8" error-correction-level="M" data="{{formData.exportWalletInfo}}"></qrcode>
<qrcode size="220" version="8" error-correction-level="M" data="{{formData.exportWalletInfo}}" color="#334"></qrcode>
</div>
<div class="text-center size-12 m20v" translate>From the destination device, go to Add wallet &gt; Import wallet and scan this QR code</div>
</div>

View File

@ -61,7 +61,7 @@
<div>
<a ng-if="!wallets[0]" ui-sref="tabs.add" class="item item-icon-left item-big-icon-left item-icon-right next-step">
<i class="icon big-icon-svg">
<div class="bg icon-create-wallet"></div>
<img src="img/icon-wallet.svg" class="bg wallet icon-create-wallet"/>
</i>
<span translate>Create a bitcoin wallet</span>
<i class="icon bp-arrow-right"></i>
@ -70,7 +70,7 @@
class="item item-sub item-icon-left item-big-icon-left item-icon-right wallet"
ng-click="openWallet(wallet)">
<i class="icon big-icon-svg">
<img src="img/icon-wallet.svg" ng-style="{'background-color': wallet.color}" class="bg"/>
<img src="img/icon-wallet.svg" ng-style="{'background-color': wallet.color}" class="bg wallet"/>
</i>
<span>
{{wallet.name || wallet.id}}

View File

@ -53,7 +53,7 @@
</div>
<div class="row qr">
<div class="text-center col center-block" copy-to-clipboard="addr">
<qrcode ng-if="addr" size="220" data="bitcoin:{{addr}}"></qrcode>
<qrcode ng-if="addr" size="220" data="bitcoin:{{addr}}" color="#334"></qrcode>
<div ng-if="!addr" style="height:225px; width:220px; margin:auto; background: white; padding-top: 25%;">
...
</div>

View File

@ -4,8 +4,8 @@
<ion-nav-back-button>
</ion-nav-back-button>
<ion-nav-buttons side="secondary">
<button class="button back-button" ng-click="startSearch(); openSearchModal()">
<i class="icon ion-ios-search-strong"></i>
<button class="button back-button" ng-click="startSearch(); openSearchModal()" ng-if="txHistory.length > 4">
<i class="icon ion-ios-search-strong tx-search"></i>
</button>
</ion-nav-buttons>
</ion-nav-bar>
@ -91,7 +91,7 @@
</div>
<div class="card list" ng-if="txps[0]">
<div class="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>
@ -125,12 +125,11 @@
</div>
</div>
<div class="card list" ng-show="txHistory[0]">
<div class="list" ng-show="txHistory[0]">
<div class="item" ng-repeat="btx in txHistory track by $index" 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>
<span class="wallet-details__tx-amount" ng-class="{'wallet-details__tx-amount--recent': btx.recent, 'wallet-details__tx-amount--received': btx.action == 'received', 'wallet-details__tx-amount--sent': btx.action == 'sent'}">
<span ng-if="btx.action == 'sent'"></span>
<span class="size-12" ng-if="btx.action == 'invalid'" translate>
(possible double spend)
</span>
@ -139,42 +138,41 @@
</span>
</span>
<p>
<time ng-if="btx.time">{{btx.time * 1000 | amTimeAgo}}</time>
<time class="wallet-details__tx-time" ng-if="btx.time">{{btx.time * 1000 | amTimeAgo}}</time>
<span translate class="text-warning"
ng-show="!btx.time && (!btx.confirmations || btx.confirmations == 0)">
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'">
<img class="wallet-details__tx-icon" src="img/icon-tx-received.svg" alt="sync" width="40" ng-if="btx.action == 'received'">
<img class="wallet-details__tx-icon" src="img/icon-tx-sent.svg" alt="sync" width="40" ng-if="btx.action == 'sent'">
<img class="wallet-details__tx-icon" src="img/icon-tx-moved.svg" alt="sync" width="40" ng-if="btx.action == 'moved'">
<h2 class="p10t">
<div class="wallet-details__tx-title">
<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>
<div ng-if="btx.note.body">{{btx.note.body}}</div>
<div ng-if="!btx.note.body" translate> Received</div>
</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>
<div ng-if="btx.message">{{btx.message}}</div>
<div ng-if="!btx.message && btx.note.body">{{btx.note.body}}</div>
<contact ng-if="!btx.message && !btx.note.body" class="ellipsis" address="{{btx.addressTo}}" label="'Sent'"></contact>
</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>
<div ng-if="btx.note.body">{{btx.note.body}}</div>
<div ng-if="!btx.note.body" translate>Moved</div>
</span>
</div>
<span class="label tu warning radius" ng-if="btx.action == 'invalid'" translate>Invalid</span>
</h2>
</div>
</div>
</div>
<ion-infinite-scroll