Merge pull request #1873 from cmgustavo/bug/mobile-performance

Bug/mobile performance
This commit is contained in:
Matias Alejo Garcia 2014-11-27 17:57:16 -03:00
commit 29b0c29a1b
34 changed files with 341 additions and 3768 deletions

View file

@ -74,7 +74,6 @@ module.exports = function(grunt) {
'js/directives.js',
'js/filters.js',
'js/routes.js',
'js/mobile.js',
'js/services/*.js',
'js/controllers/*.js'
],
@ -114,7 +113,6 @@ module.exports = function(grunt) {
concat: {
vendors: {
src: [
'lib/mousetrap/mousetrap.min.js',
'lib/moment/min/moment.min.js',
'lib/qrcode-generator/js/qrcode.js',
'lib/lodash/dist/lodash.js',
@ -122,7 +120,6 @@ module.exports = function(grunt) {
'lib/file-saver/FileSaver.js',
'lib/socket.io-client/socket.io.js',
'lib/sjcl.js',
'lib/ios-imagefile-megapixel/megapix-image.js',
'lib/qrcode-decoder-js/lib/qrcode-decoder.min.js'
],
dest: 'lib/vendors.js'
@ -154,7 +151,6 @@ module.exports = function(grunt) {
'js/services/*.js',
'js/controllers/*.js',
'js/translations.js',
'js/mobile.js', // PLACEHOLDER: CORDOVA SRIPT
'js/init.js',
],
dest: 'js/copayMain.js'
@ -209,6 +205,8 @@ module.exports = function(grunt) {
'index.html',
'init.js',
'config.js',
'version.js',
'popup.html',
'css/vendors.min.css',
'css/copay.min.css',
'js/copayBundle.js',

View file

@ -6,7 +6,7 @@
"multisignature"
],
"dependencies": {
"angular": "=1.2.19",
"angular": "~1.2.27",
"angular-foundation": "*",
"angular-route": "~1.2.14",
"angular-qrcode": "~3.1.0",
@ -19,15 +19,14 @@
"qrcode-decoder-js": "*",
"angular-moment": "~0.7.1",
"socket.io-client": ">=1.0.0",
"mousetrap": "1.4.6",
"ng-idle": "*",
"inherits": "~0.0.1",
"angular-load": "0.2.0",
"lodash": "~2.4.1",
"angular-gravatar": "*",
"angular-touch": "~1.3.3"
"angular-touch": "~1.2.27"
},
"resolutions": {
"angular": "=1.2.19"
"angular": "~1.2.0"
}
}

View file

@ -67,6 +67,9 @@ if [ ! -d $PROJECT ]; then
fi
echo "${OpenColor}${Green}* Installing plugins... ${CloseColor}"
cordova plugin add https://github.com/Initsogar/cordova-webintent.git
checkOK
cordova plugin add https://github.com/wildabeast/BarcodeScanner.git
checkOK
@ -77,6 +80,9 @@ if [ ! -d $PROJECT ]; then
cordova plugin add org.apache.cordova.statusbar
checkOK
cordova plugin add https://github.com/EddyVerbruggen/LaunchMyApp-PhoneGap-Plugin.git --variable URL_SCHEME=bitcoin
checkOK
fi
echo "${OpenColor}${Green}* Generating copay bundle...${CloseColor}"
@ -102,19 +108,22 @@ checkOK
cp android/AndroidManifest.xml $PROJECT/platforms/android/AndroidManifest.xml
checkOK
#cp android/project.properties $PROJECT/platforms/android/project.properties
#checkOK
cp android/project.properties $PROJECT/platforms/android/project.properties
checkOK
cp -R android/res/* $PROJECT/platforms/android/res
checkOK
mkdir -p $PROJECT/platforms/ios/Copay/Resources/icons
checkOK
mkdir -p $PROJECT/platforms/ios/Copay/Resources/splash
checkOK
if [[ !$SKIPIOS ]]; then
cp ios/Copay-Info.plist $PROJECT/platforms/ios/Copay-Info.plist
checkOK
mkdir -p $PROJECT/platforms/ios/Copay/Resources/icons
checkOK
mkdir -p $PROJECT/platforms/ios/Copay/Resources/splash
checkOK
cp -R ios/icons/* $PROJECT/platforms/ios/Copay/Resources/icons
checkOK

View file

@ -16,8 +16,24 @@
<preference name="HideKeyboardFormAccessoryBar" value="true"/>
<preference name="SplashScreen" value="copayscreen" />
<preference name="SplashScreenDelay" value="10000" />
<preference name="BackgroundColor" value="0x2C3E50" />
<preference name="BackgroundColor" value="#2C3E50" />
<preference name="StatusBarOverlaysWebView" value="false" />
<preference name="StatusBarBackgroundColor" value="#3C4E60" />
<preference name="StatusBarStyle" value="lightcontent" />
<preference name="BackupWebStorage" value="none"/>
<feature name="App">
<param name="android-package" value="com.bitpay.copay" />
</feature>
<feature name="WebIntent">
<param name="android-package" value="com.borismus.webintent.WebIntent" />
</feature>
<feature name="BarcodeScanner">
<param name="android-package" value="com.phonegap.plugins.barcodescanner.BarcodeScanner" />
</feature>
<feature name="SplashScreen">
<param name="android-package" value="org.apache.cordova.splashscreen.SplashScreen" />
</feature>
<feature name="StatusBar">
<param name="android-package" onload="true" value="org.apache.cordova.statusbar.StatusBar" />
</feature>
</widget>

View file

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string>icon.png</string>
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>icon-40</string>
<string>icon-small</string>
<string>icon-60</string>
<string>icon.png</string>
<string>icon@2x</string>
<string>icon-72</string>
<string>icon-72@2x</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
<key>CFBundleIcons~ipad</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>icon-small</string>
<string>icon-40</string>
<string>icon-50</string>
<string>icon-76</string>
<string>icon-60</string>
<string>icon</string>
<string>icon@2x</string>
<string>icon-72</string>
<string>icon-72@2x</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
<key>CFBundleIdentifier</key>
<string>com.bitpay.copay</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.8.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.8.2</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSMainNibFile</key>
<string></string>
<key>NSMainNibFile~ipad</key>
<string></string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View file

@ -330,7 +330,7 @@ a:hover {
.main {
margin-left: 250px;
padding: 100px 1.5rem;
padding: 85px 1.5rem;
background-color: #F8F8FB;
}
@ -941,7 +941,7 @@ input[type='submit']
input[type=date], input[type=datetime-local], input[type=datetime], input[type=email], input[type=month], input[type=number], input[type=password], input[type=search], input[type=tel], input[type=text], input[type=time], input[type=url], input[type=week], textarea {
color: #7A8C9E;
color: #343c43;
margin-bottom: 1.3rem;
height: 40px;
border-radius: 2px;

View file

@ -7,7 +7,7 @@
@media (max-width: 1024px) {
.logo-setup {
margin: 20px 0;
margin: 0;
padding: 2rem 0;
}
@ -24,11 +24,11 @@
}
.main {
height: 100%;
height: 92%;
margin-top: 40px;
margin-left: 0;
margin-bottom: -40px;
padding: 20px 0 110px 0;
padding: 20px 0 80px 0;
}
.tab-bar {
@ -48,6 +48,16 @@
background: #2C3E50;
}
header {
height: 45px;
line-height: 110%;
}
.col3 a {
height: 45px;
padding: 12px 5px;
}
.left-off-canvas-menu {
background: #E4E8EC;
line-height: 24px;
@ -60,6 +70,14 @@
.page{
height:100%;
}
.avatar-wallet {
margin-top: 5px;
margin-left: 5px;
margin-right: 5px;
padding: 0.35rem 0.65rem;
}
.copayers {
position: relative;
@ -87,6 +105,7 @@
.tab-bar h1 {
font-weight: 100;
text-align: center;
}
ul.off-canvas-list li a {
@ -134,11 +153,11 @@
}
.left-small {
border-right: 1px solid #425568;
border-right: none;
}
.right-small {
border-left: 1px solid #425568;
border-left: none;
}
.right-small a {
@ -189,7 +208,7 @@
padding: 0;
height: 100%;
left: 0;
top: 56px;
top: 45px;
}
ul.off-canvas-list li a:hover {

View file

@ -38,6 +38,11 @@
</div>
</div>
<div ng-show="sessionExpired" class="session-expired">
<i class="fi-battery-empty size-72 text-gray"></i>
<p class="text-gray size-18">Your session is about to expire due to inactivity in {{countdown}} seconds</p>
</div>
<div class="off-canvas-wrap" ng-show="!signingOut">
<div class="inner-wrap">
<span class="status" ng-if="$root.reconnecting">

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('HeadController', function($scope, $rootScope, $filter, notification, controllerUtils) {
angular.module('copayApp.controllers').controller('HeadController', function($scope, $rootScope, $filter, $timeout, notification, controllerUtils) {
$scope.username = $rootScope.iden.getName();
$scope.hoverMenu = false;
@ -42,12 +42,19 @@ angular.module('copayApp.controllers').controller('HeadController', function($sc
});
if ($rootScope.wallet) {
$scope.$on('$idleWarn', function(a, countdown) {
if (!(countdown % 5))
notification.warning('Session will be closed', $filter('translate')('Your session is about to expire due to inactivity in') + ' ' + countdown + ' ' + $filter('translate')('seconds'));
$scope.$on('$idleStart', function() {
});
$scope.$on('$idleWarn', function(a, countdown) {
$rootScope.countdown = countdown;
$rootScope.sessionExpired = true;
});
$scope.$on('$idleEnd', function() {
$timeout(function() {
$rootScope.sessionExpired = null;
}, 500);
});
$scope.$on('$idleTimeout', function() {
$rootScope.sessionExpired = null;
$scope.signout();
notification.warning('Session closed', 'Session closed because a long time of inactivity');
});

View file

@ -1,10 +1,10 @@
'use strict';
angular.module('copayApp.controllers').controller('JoinController',
function($scope, $rootScope, $timeout, controllerUtils, notification) {
function($scope, $rootScope, $timeout, isMobile, controllerUtils, notification) {
$rootScope.fromSetup = false;
$scope.loading = false;
$scope.isMobile = !!window.cordova;
$scope.isMobile = isMobile.any();
$rootScope.title = 'Join shared wallet';
// QR code Scanner

View file

@ -26,6 +26,7 @@ angular.module('copayApp.controllers').controller('SendController',
$scope.rateService = rateService;
$scope.showScanner = false;
$scope.myId = w.getMyCopayerId();
$scope.isMobile = isMobile.any();
rateService.whenAvailable(function() {
$scope.isRateAvailable = true;
@ -96,7 +97,6 @@ angular.module('copayApp.controllers').controller('SendController',
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
$scope.isMobile = isMobile.any();
if (!window.cordova && !navigator.getUserMedia)
$scope.disableScanner = 1;
@ -287,15 +287,13 @@ angular.module('copayApp.controllers').controller('SendController',
function onSuccess(result) {
if (result.cancelled) return;
var bip21 = new bitcore.BIP21(result.text);
$scope.address = bip21.address + '';
$scope.commentText = bip21.data.message;
if (bip21.data.amount) {
$scope.amount = bip21.data.amount * bitcore.util.COIN * satToUnit;
}
$rootScope.$digest();
$timeout(function() {
var data = result.text;
$scope.$apply(function() {
$scope.sendForm.address.$setViewValue(result.text);
$scope.sendForm.address.$render();
});
}, 1000);
},
function onError(error) {
alert('Scanning error');

View file

@ -1,6 +1,27 @@
'use strict';
angular.element(document).ready(function() {
// Init the app
angular.bootstrap(document, ['copayApp']);
var startAngular = function () {
angular.bootstrap(document, ['copayApp']);
};
if (window.cordova !== undefined) {
document.addEventListener('deviceready', function() {
setTimeout(function(){ navigator.splashscreen.hide(); }, 2000);
function handleBitcoinURI(url) {
if (!url) return;
window.location = '#!/uri-payment/' + url;
}
window.plugins.webintent.getUri(handleBitcoinURI);
window.plugins.webintent.onNewIntent(handleBitcoinURI);
window.handleOpenURL = handleBitcoinURI;
startAngular();
}, false);
} else {
startAngular();
}
});

View file

@ -1,17 +0,0 @@
'use strict';
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
setTimeout(function(){ navigator.splashscreen.hide(); }, 2000);
document.addEventListener("menubutton", function() {
var nav = document.getElementsByTagName('nav')[0];
if (!nav) return;
var menu = nav.getElementsByTagName('section')[0].getElementsByTagName('a')[0];
if (menu.offsetParent) menu.click();
}, false);
}

View file

@ -106,8 +106,11 @@ angular
})
.run(function($rootScope, $location, $idle, gettextCatalog, uriHandler) {
gettextCatalog.currentLanguage = config.defaultLanguage;
$idle.watch();
uriHandler.register();
// not for mobileApp
if (!window.cordova) {
$idle.watch();
uriHandler.register();
}
$rootScope.$on('$routeChangeStart', function(event, next, current) {
if (!localStorage || localStorage.length < 1) {
$location.path('unsupported');

View file

@ -38,7 +38,6 @@ module.exports = function(config) {
'lib/file-saver/FileSaver.js',
'lib/socket.io-client/socket.io.js',
'lib/sjcl.js',
'lib/ios-imagefile-megapixel/megapix-image.js',
'lib/qrcode-decoder-js/lib/qrcode-decoder.min.js',
'lib/bitcore.js',

View file

@ -1,253 +0,0 @@
/**
* Mega pixel image rendering library for iOS6 Safari
*
* Fixes iOS6 Safari's image file rendering issue for large size image (over mega-pixel),
* which causes unexpected subsampling when drawing it in canvas.
* By using this library, you can safely render the image with proper stretching.
*
* Copyright (c) 2012 Shinichi Tomita <shinichi.tomita@gmail.com>
* Released under the MIT license
*/
(function() {
/**
* Detect subsampling in loaded image.
* In iOS, larger images than 2M pixels may be subsampled in rendering.
*/
function detectSubsampling(img) {
var iw = img.naturalWidth, ih = img.naturalHeight;
if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image
var canvas = document.createElement('canvas');
canvas.width = canvas.height = 1;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, -iw + 1, 0);
// subsampled image becomes half smaller in rendering size.
// check alpha channel value to confirm image is covering edge pixel or not.
// if alpha value is 0 image is not covering, hence subsampled.
return ctx.getImageData(0, 0, 1, 1).data[3] === 0;
} else {
return false;
}
}
/**
* Detecting vertical squash in loaded image.
* Fixes a bug which squash image vertically while drawing into canvas for some images.
*/
function detectVerticalSquash(img, iw, ih) {
var canvas = document.createElement('canvas');
canvas.width = 1;
canvas.height = ih;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
var data = ctx.getImageData(0, 0, 1, ih).data;
// search image edge pixel position in case it is squashed vertically.
var sy = 0;
var ey = ih;
var py = ih;
while (py > sy) {
var alpha = data[(py - 1) * 4 + 3];
if (alpha === 0) {
ey = py;
} else {
sy = py;
}
py = (ey + sy) >> 1;
}
var ratio = (py / ih);
return (ratio===0)?1:ratio;
}
/**
* Rendering image element (with resizing) and get its data URL
*/
function renderImageToDataURL(img, options, doSquash) {
var canvas = document.createElement('canvas');
renderImageToCanvas(img, canvas, options, doSquash);
return canvas.toDataURL("image/jpeg", options.quality || 0.8);
}
/**
* Rendering image element (with resizing) into the canvas element
*/
function renderImageToCanvas(img, canvas, options, doSquash) {
var iw = img.naturalWidth, ih = img.naturalHeight;
var width = options.width, height = options.height;
var ctx = canvas.getContext('2d');
ctx.save();
transformCoordinate(canvas, ctx, width, height, options.orientation);
var subsampled = detectSubsampling(img);
if (subsampled) {
iw /= 2;
ih /= 2;
}
var d = 1024; // size of tiling canvas
var tmpCanvas = document.createElement('canvas');
tmpCanvas.width = tmpCanvas.height = d;
var tmpCtx = tmpCanvas.getContext('2d');
var vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1;
var dw = Math.ceil(d * width / iw);
var dh = Math.ceil(d * height / ih / vertSquashRatio);
var sy = 0;
var dy = 0;
while (sy < ih) {
var sx = 0;
var dx = 0;
while (sx < iw) {
tmpCtx.clearRect(0, 0, d, d);
tmpCtx.drawImage(img, -sx, -sy);
ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);
sx += d;
dx += dw;
}
sy += d;
dy += dh;
}
ctx.restore();
tmpCanvas = tmpCtx = null;
}
/**
* Transform canvas coordination according to specified frame size and orientation
* Orientation value is from EXIF tag
*/
function transformCoordinate(canvas, ctx, width, height, orientation) {
switch (orientation) {
case 5:
case 6:
case 7:
case 8:
canvas.width = height;
canvas.height = width;
break;
default:
canvas.width = width;
canvas.height = height;
}
switch (orientation) {
case 2:
// horizontal flip
ctx.translate(width, 0);
ctx.scale(-1, 1);
break;
case 3:
// 180 rotate left
ctx.translate(width, height);
ctx.rotate(Math.PI);
break;
case 4:
// vertical flip
ctx.translate(0, height);
ctx.scale(1, -1);
break;
case 5:
// vertical flip + 90 rotate right
ctx.rotate(0.5 * Math.PI);
ctx.scale(1, -1);
break;
case 6:
// 90 rotate right
ctx.rotate(0.5 * Math.PI);
ctx.translate(0, -height);
break;
case 7:
// horizontal flip + 90 rotate right
ctx.rotate(0.5 * Math.PI);
ctx.translate(width, -height);
ctx.scale(-1, 1);
break;
case 8:
// 90 rotate left
ctx.rotate(-0.5 * Math.PI);
ctx.translate(-width, 0);
break;
default:
break;
}
}
/**
* MegaPixImage class
*/
function MegaPixImage(srcImage) {
if (window.Blob && srcImage instanceof Blob) {
var img = new Image();
var URL = window.URL && window.URL.createObjectURL ? window.URL :
window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :
null;
if (!URL) { throw Error("No createObjectURL function found to create blob url"); }
img.src = URL.createObjectURL(srcImage);
this.blob = srcImage;
srcImage = img;
}
if (!srcImage.naturalWidth && !srcImage.naturalHeight) {
var _this = this;
srcImage.onload = function() {
var listeners = _this.imageLoadListeners;
if (listeners) {
_this.imageLoadListeners = null;
for (var i=0, len=listeners.length; i<len; i++) {
listeners[i]();
}
}
};
this.imageLoadListeners = [];
}
this.srcImage = srcImage;
}
/**
* Rendering megapix image into specified target element
*/
MegaPixImage.prototype.render = function(target, options) {
if (this.imageLoadListeners) {
var _this = this;
this.imageLoadListeners.push(function() { _this.render(target, options) });
return;
}
options = options || {};
var imgWidth = this.srcImage.naturalWidth, imgHeight = this.srcImage.naturalHeight,
width = options.width, height = options.height,
maxWidth = options.maxWidth, maxHeight = options.maxHeight,
doSquash = !this.blob || this.blob.type === 'image/jpeg';
if (width && !height) {
height = (imgHeight * width / imgWidth) << 0;
} else if (height && !width) {
width = (imgWidth * height / imgHeight) << 0;
} else {
width = imgWidth;
height = imgHeight;
}
if (maxWidth && width > maxWidth) {
width = maxWidth;
height = (imgHeight * width / imgWidth) << 0;
}
if (maxHeight && height > maxHeight) {
height = maxHeight;
width = (imgWidth * height / imgHeight) << 0;
}
var opt = { width : width, height : height };
for (var k in options) opt[k] = options[k];
var tagName = target.tagName.toLowerCase();
if (tagName === 'img') {
target.src = renderImageToDataURL(this.srcImage, opt, doSquash);
} else if (tagName === 'canvas') {
renderImageToCanvas(this.srcImage, target, opt, doSquash);
}
if (typeof this.onrender === 'function') {
this.onrender(target);
}
};
/**
* Export class to global
*/
if (typeof define === 'function' && define.amd) {
define([], function() { return MegaPixImage; }); // for AMD loader
} else {
this.MegaPixImage = MegaPixImage;
}
})();

File diff suppressed because it is too large Load diff

View file

@ -85,7 +85,6 @@
"mock-fs": "^2.3.1",
"node-cryptojs-aes": "^0.4.0",
"request": "^2.40.0",
"shelljs": "^0.3.0",
"sinon": "^1.10.3",
"sjcl": "*",
"socket.io-client": "^1.0.6",

View file

@ -1,10 +1,14 @@
<div ng-controller="CopayersController">
<div ng-if='$root.wallet && $root.wallet.isReady()' ng-init="goToWallet()"></div>
<h1 translate class="hide-for-large-up">
Waiting copayers for {{$root.wallet.getName()}}
<small>{{$root.wallet.requiredCopayers}}-of-{{$root.wallet.totalCopayers}}</small>
</h1>
<div class="row hide-for-large-up">
<div class="medium-12 small-12 columns">
<h1 translate>
Waiting copayers for {{$root.wallet.getName()}}
<small>{{$root.wallet.requiredCopayers}}-of-{{$root.wallet.totalCopayers}}</small>
</h1>
</div>
</div>
<div class="row">
<div class="large-12 columns">
<div ng-if="!$root.wallet.isReady()">

View file

@ -11,7 +11,11 @@
</div>
</div>
<div class="setup" ng-show="!loading && !$root.starting">
<h1 class="hide-for-large-up">{{$root.title}}</h1>
<div class="row hide-for-large-up">
<div class="medium-12 small-12 columns">
<h1>{{$root.title}}</h1>
</div>
</div>
<form name="setupForm" ng-submit="create(setupForm)" novalidate>
<div class="row">
<div class="large-12 columns">

View file

@ -1,26 +0,0 @@
<div class="backup" ng-controller="CreateWalletController">
<h1 class="hide-for-large-up">{{$root.title}}</h1>
<div class="row">
<div class="large-4 columns" >
<div class="panel text-center" ui-route="{{create}}">
<div><i class="size-72 fi-plus text-gray"></i></div>
<p class="text-gray">Create a new Wallet</p>
<a href="#!/create" class="button primary radius" title="Create"> {{'Create' | translate }} </a>
</div>
</div>
<div class="large-4 columns" ui-route="{{create}}">
<div class="panel text-center">
<div><i class="size-72 fi-torsos-all text-gray"></i></div>
<p class="text-gray">Join an existing Wallet</p>
<a href="#!/join" class="button secondary radius" title="Join"> {{'Join' | translate }} </a>
</div>
</div>
<div class="large-4 columns" ui-route="{{create}}">
<div class="panel text-center">
<div><i class="size-72 fi-download text-gray"></i></div>
<p class="text-gray">Import a Wallet to Copay</p>
<a href="#!/import" class="button black radius" title="Import"> {{'Import wallet' | translate }}</a>
</div>
</div>
</div>
</div>

View file

@ -1,20 +1,32 @@
<div class="transactions" data-ng-controller="HistoryController" data-ng-init="update()">
<div ng-show='$root.wallet.isReady()'>
<h1 class="hide-for-large-up">{{$root.title}}</h1>
<div ng-if="loading" class="m20b">
<i class="fi-bitcoin-circle icon-rotate spinner"></i>
<span translate>Loading...</span>
</div>
<div ng-if="!blockchain_txs[0].txid && !loading">
<em><strong translate>No transactions yet.</strong></em>
<div class="row">
<div class="large-12 medium-12 small-12 columns">
<h1 class="hide-for-large-up">{{$root.title}}</h1>
<div ng-if="loading" class="m20b">
<i class="fi-bitcoin-circle icon-rotate spinner"></i>
<span translate>Loading...</span>
</div>
<div ng-if="!blockchain_txs[0].txid && !loading">
<em><strong translate>No transactions yet.</strong></em>
</div>
</div>
</div>
<div class="row" ng-if="blockchain_txs[0].txid">
<div class="large-12 columns">
<div class="panel"
ng-repeat="btx in blockchain_txs | orderBy:'-ts'" ng-click="btx.showDetails = !btx.showDetails">
ng-repeat="btx in blockchain_txs | orderBy:'-ts'">
<div class="row size-14">
<div class="large-2 medium-2 small-12 columns">
<div class="tx-date">
<div class="large-2 medium-2 small-12 columns" ng-click="btx.showDetails = !btx.showDetails">
<div class="tx-date oh">
<div class="right hide-for-large-only">
<span ng-show="!btx.showDetails">
<i class="icon-arrow-down2"></i>
</span>
<span ng-show="btx.showDetails">
<i class="icon-arrow-up2"></i>
</span>
</div>
<time
class="hastip"
ng-if="btx.ts"
@ -61,7 +73,7 @@
</div>
<div class="large-1 columns show-for-large-up text-gray text-right" ng-init="btx.showDetails = false">
<a>
<a ng-click="btx.showDetails = !btx.showDetails">
<i ng-if="!btx.showDetails" class="icon-arrow-down4"></i>
<i ng-if="btx.showDetails" class="icon-arrow-up4"></i>
</a>
@ -77,7 +89,7 @@
<span ng-show="tx.merchant.domain">[{{btx.merchant.domain}}]</span>
</div>
<table class="last-transactions-content" ng-if="btx.actionList.0">
<table class="last-transactions-content" ng-if="btx.actionList[0]">
<tbody>
<tr ng-repeat="c in btx.actionList">
<td class="copayer-name text-gray" width="100%">{{c.cId === $root.wallet.getMyCopayerId() ? 'Me' : $root.wallet.publicKeyRing.nicknameForCopayer(c.cId)}}
@ -105,8 +117,15 @@
</div>
</div>
</div>
<div class="line-white"></div>
<div class="right size-12">
</div>
</div>
<div ng-show="blockchain_txs[0].txid">
<div class="line-white"></div>
<div class="row">
<div class="large-9 columns">
<pagination page="currentPage" total-items="totalItems" items-per-page="itemsPerPage" on-select-page="selectPage(page)" max-size="10" />
</div>
<div class="large-3 columns m5t text-right size-12 show-for-large-only">
<div ng-if="generating">
<i class="fi-bitcoin-circle icon-rotate spinner"></i>
<span translate>Generating file...</span>
@ -118,7 +137,6 @@
</a>
</div>
</div>
<pagination page="currentPage" total-items="totalItems" items-per-page="itemsPerPage" on-select-page="selectPage(page)" max-size="10" />
</div>
</div>
</div>

View file

@ -1,11 +1,5 @@
<div class="home" ng-controller="HomeController">
<!-- <div class="session-expired">
<i class="fi-battery-empty size-72 text-gray"></i>
<p class="text-gray size-18">Your session is about to expire due to inactivity in </p>
<button class="radius primary">Cancel</button>
</div> -->
<div class="loading-screen" ng-show="$root.starting">
<div class="spinner">
<div class="contener_general">
@ -18,7 +12,7 @@
</div>
</div>
<div class="large-4 large-centered medium-6 medium-centered columns" ng-show="!$root.starting">
<div class="large-4 large-centered medium-7 medium-centered columns" ng-show="!$root.starting">
<div class="logo-setup">
<img src="img/logo-negative-beta.svg" alt="Copay" width="146" height="59">
<div ng-include="'views/includes/version.html'"></div>

View file

@ -1,6 +1,10 @@
<div class="home-wallet" ng-controller="HomeWalletController">
<div ng-show='$root.wallet.isReady()'>
<h1 translate class="hide-for-large-up">Home</h1>
<div class="row hide-for-large-up">
<div class="medium-12 small-12 columns">
<h1 translate>Home</h1>
</div>
</div>
<div class="row">
<div class="large-12 columns">

View file

@ -12,7 +12,11 @@
</div>
<div ng-show="!loading">
<h1 class="hide-for-large-up">{{$root.title}}</h1>
<div class="row hide-for-large-up">
<div class="large-12 medium-12 small-12 columns">
<h1>{{$root.title}}</h1>
</div>
</div>
<div class="row">
<div class="large-12 columns">
<div class="panel">

View file

@ -0,0 +1,15 @@
<div class="text-centered">
<canvas id="qr-canvas" width="200" height="150"></canvas>
<div ng-show="isMobile">
<div id="file-input-wrapper" class="btn btn-primary">
<span class="pull-left text-centered">
<i class="glyphicon glyphicon-refresh icon-rotate"></i>
<span translate>Get QR code</span>
</span>
<input id="qrcode-camera" type="file" capture="camera" accept="image/*">
</div>
</div>
<div ng-hide="isMobile">
<video id="qrcode-scanner-video" width="300" height="225" ng-hide="isMobile"></video>
</div>
</div>

View file

@ -35,12 +35,12 @@
</div>
</div>
<div ng-show="walletSelection">
<div class="side-nav wallets text-center off-canvas-list" ng-show="!wallets.0">
<div class="side-nav wallets text-center off-canvas-list" ng-show="!wallets[0]">
<p class="size-12 text-gray m10t" translate>You do not have another wallets.</p>
<a href="#!/create" class="db button secondary tiny" title="Create new wallet">
<i class="m20r fi-plus"></i> {{'Create new wallet' | translate }} </a>
<i class="m10r fi-plus"></i> {{'Create new wallet' | translate }} </a>
</div>
<ul class="side-nav wallets off-canvas-list" ng-show="wallets.0"
<ul class="side-nav wallets off-canvas-list" ng-show="wallets[0]"
ng-click="toggleWalletSelection()">
<li data-ng-repeat="item in wallets track by $index"
class="nav-item"

View file

@ -3,7 +3,7 @@
<div class="col1">
<div class="avatar-wallet">{{$root.wallet.getName() | limitTo: 1}}</div>
</div>
<div class="col2" ng-class="{'col2_full':!wallets.0}">
<div class="col2" ng-class="{'col2_full':!wallets[0]}">
<div class="oh m5t m10r">
<div class="right size-10">[ {{$root.wallet.requiredCopayers}} of {{$root.wallet.totalCopayers}} ]</div>
<div class="name-wallet">
@ -22,7 +22,7 @@
</div>
</div>
</div>
<div class="col3" ng-if="wallets.0">
<div class="col3" ng-if="wallets[0]">
<a ng-class="{'selected':walletSelection}"
ng-click="toggleWalletSelection()">
<span ng-show="!walletSelection">
@ -50,7 +50,7 @@
</div>
<div>
<ul class="side-nav wallets" ng-class="{'pullDown': walletSelection}" ng-show="wallets.0">
<ul class="side-nav wallets" ng-class="{'pullDown': walletSelection}" ng-show="wallets[0]">
<li data-ng-repeat="item in wallets track by $index" class="nav-item" ng-if="item.id != $root.wallet.id" ng-click="switchWallet(item.id)">
<div class="col1">
<div class="avatar-wallet">{{(item.name || item.id) | limitTo: 1}}</div>
@ -75,7 +75,7 @@
</ul>
</div>
<ul class="side-nav" ng-if="(!walletSelection || !wallets.0) && $root.wallet.isReady()">
<ul class="side-nav" ng-if="(!walletSelection || !wallets[0]) && $root.wallet.isReady()">
<li data-ng-repeat="item in menu" ui-route="{{item.link}}" class="nav-item" data-ng-class="{active: isActive(item)}">
<a href="#!/{{item.link}}" ng-click="toggleCollapse()" class="db p20h">
<i class="size-21 m20r {{item.icon}}"></i> {{item.title|translate}}

View file

@ -12,7 +12,11 @@
</div>
<div ng-show="!loading">
<h1 class="hide-for-large-up">{{$root.title}}</h1>
<div class="row hide-for-large-up">
<div class="large-12 medium-12 small-12 columns">
<h1>{{$root.title}}</h1>
</div>
</div>
<div class="row">
<div class="large-12 columns">
<form name="joinForm" ng-submit="join(joinForm)" novalidate>
@ -32,7 +36,7 @@
<div class="pr">
<input id="connectionId" type="text" class="columns" placeholder="{{'Paste wallet secret here'|translate}}" name="connectionId" ng-model="connectionId" wallet-secret required auto-focus>
<input id="connectionId" type="text" class="columns" placeholder="{{'Paste wallet secret here'|translate}}" name="connectionId" ng-model="connectionId" wallet-secret required>
<div ng-hide="showScanner || disableScanner">
<a class="postfix button black" ng-click="openScanner()"><i class="fi-camera">&nbsp;</i></a>
</div>
@ -41,23 +45,11 @@
</div>
</div>
<div id="scanner" class="row" ng-if="showScanner">
<div class="text-centered">
<canvas id="qr-canvas" width="200" height="150"></canvas>
<div ng-show="isMobile">
<div id="file-input-wrapper" class="btn btn-primary">
<span class="pull-left text-centered">
<i class="glyphicon glyphicon-refresh icon-rotate"></i>
<span translate>Get QR code</span>
</span>
<input id="qrcode-camera" type="file" capture="camera" accept="image/*">
</div>
</div>
<div ng-hide="isMobile">
<video id="qrcode-scanner-video" width="300" height="225" ng-hide="isMobile"></video>
</div>
</div>
</div>
<div id="scanner"
class="row"
ng-if="showScanner"
ng-include="'views/includes/scanner.html'"></div>
</div>
<div class="line-dashed-h"></div>

View file

@ -1,7 +1,11 @@
<div class="backup" ng-controller="MoreController">
<h1 class="hide-for-large-up">{{$root.title}}</h1>
<div class="row">
<form name="settingsForm">
<div class="row hide-for-large-up">
<div class="large-12 medium-12 small-12 columns">
<h1>{{$root.title}}</h1>
</div>
</div>
<form name="settingsForm">
<div class="row">
<div class="large-6 medium-6 columns">
<fieldset>
<legend translate>Wallet Unit</legend>
@ -16,20 +20,22 @@
</select>
</fieldset>
</div>
</form>
</div>
</div>
</form>
<div class="line-dashed-h m20b"></div>
<div class="m20b">
<a class="size-12" ng-click="hideAdv=!hideAdv">
<i class="fi-widget m3r"></i>
<span translate ng-hide="!hideAdv">Show</span>
<span translate ng-hide="hideAdv">Hide</span>
<span translate>advanced options</span>
<i ng-if="hideAdv" class="icon-arrow-down4"></i>
<i ng-if="!hideAdv" class="icon-arrow-up4"></i>
</a>
<div class="m20b row">
<div class="large-12 columns">
<a class="size-12" ng-click="hideAdv=!hideAdv">
<i class="fi-widget m3r"></i>
<span translate ng-hide="!hideAdv">Show</span>
<span translate ng-hide="hideAdv">Hide</span>
<span translate>advanced options</span>
<i ng-if="hideAdv" class="icon-arrow-down4"></i>
<i ng-if="!hideAdv" class="icon-arrow-up4"></i>
</a>
</div>
</div>
<div ng-hide="hideAdv" class="row">

View file

@ -1,7 +1,7 @@
<div ng-controller="PaymentIntentController" ng-init="open()">
<script type="text/ng-template" id="myModalContent.html">
<h3>Select a wallet to make the payment</h3>
<ul class="w-popup-menu" ng-show="wallets.0"
<ul class="w-popup-menu" ng-show="wallets[0]"
ng-class="{'large':wallets.length > 4, 'medium':wallets.length > 2 && wallets.length < 5}">
<li data-ng-repeat="item in wallets track by $index" class="nav-item" ng-click="ok(item)">
<div class="w-popup-icon">

View file

@ -1,6 +1,9 @@
<div class="backup" ng-controller="ProfileController">
<h1 class="hide-for-large-up">{{$root.title}}</h1>
<div class="row hide-for-large-up">
<div class="large-12 medium-12 small-12 columns">
<h1>{{$root.title}}</h1>
</div>
</div>
<div class="row">
<div class="large-12 columns">
<div class="panel">

View file

@ -1,8 +1,12 @@
<div class="addresses" ng-controller="ReceiveController">
<div ng-show='$root.wallet.isReady()'>
<h1 class="hide-for-large-up">{{$root.title}}</h1>
<div ng-show="!addresses[0]">
<i class="fi-bitcoin-circle icon-rotate spinner"></i>
<div class="row">
<div class="large-12 medium-12 small-12 columns">
<h1 class="hide-for-large-up">{{$root.title}}</h1>
<div ng-show="!addresses[0]">
<i class="fi-bitcoin-circle icon-rotate spinner"></i>
</div>
</div>
</div>
<div class="row">
<div class="large-12 columns" ng-if="!!(addresses|removeEmpty).length">

View file

@ -9,13 +9,18 @@
ng-include="'views/includes/transaction.html'"></div>
</div>
</div>
<div ng-show="$root.txps.length != 0" class="line-dashed-h m20b"></div>
<h1 class="hide-for-large-up">{{$root.title}}</h1>
<div class="row">
<div class="large-12 medium-12 small-12 columns">
<div ng-show="$root.txps.length != 0" class="line-dashed-h m20b"></div>
<h1 class="hide-for-large-up">{{$root.title}}</h1>
</div>
</div>
<div class="row">
<div class="large-12 columns">
<form name="sendForm" ng-submit="submitForm(sendForm)" novalidate>
<div class="panel">
<form name="sendForm" ng-submit="submitForm(sendForm)" novalidate>
<p class="text-warning size-16"
ng-show="error">
<i class="fi-alert"></i>
@ -27,8 +32,6 @@
{{success|translate}}
</p>
<div class="row collapse">
<label for="address" class="left">
<span translate>To</span>
@ -57,23 +60,11 @@
</div>
</div>
</div>
<div id="scanner" ng-if="showScanner">
<div class="text-centered">
<canvas id="qr-canvas" width="200" height="150"></canvas>
<div ng-show="isMobile">
<div id="file-input-wrapper" class="btn btn-primary">
<span class="pull-left text-centered">
<i class="glyphicon glyphicon-refresh icon-rotate"></i>
<span translate>Get QR code</span>
</span>
<input id="qrcode-camera" type="file" capture="camera" accept="image/*">
</div>
</div>
<div ng-hide="isMobile">
<video id="qrcode-scanner-video" width="300" height="225" ng-hide="isMobile"></video>
</div>
</div>
<div id="scanner"
class="row"
ng-if="showScanner"
ng-include="'views/includes/scanner.html'"></div>
</div>
<div class="row">
@ -184,10 +175,11 @@
</button>
</div>
</div>
</form>
</div>
</div>
</form>
</div>
</div><!-- end of row -->
<div class="row m20b" ng-show="$root.alternativeConversionRate > 0">
<div class="large-12 columns size-12">
<i class="fi-bitcoin-circle"></i>