diff --git a/src/js/controllers/walletDetails.js b/src/js/controllers/walletDetails.js
index 1aeb09fd1..a6553612e 100644
--- a/src/js/controllers/walletDetails.js
+++ b/src/js/controllers/walletDetails.js
@@ -1,6 +1,6 @@
'use strict';
-angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $state, $stateParams, $ionicHistory, profileService, lodash, configService, gettextCatalog, platformInfo, walletService, txpModalService, externalLinkService, popupService, addressbookService) {
+angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $state, $stateParams, $ionicHistory, profileService, lodash, configService, gettextCatalog, platformInfo, walletService, txpModalService, externalLinkService, popupService, addressbookService, storageService, $ionicScrollDelegate, $window) {
var HISTORY_SHOW_LIMIT = 10;
var currentTxHistoryPage = 0;
@@ -10,6 +10,9 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
$scope.openTxpModal = txpModalService.open;
$scope.isCordova = platformInfo.isCordova;
$scope.isAndroid = platformInfo.isAndroid;
+ $scope.isIOS = platformInfo.isIOS;
+
+ $scope.amountIsCollapsible = !$scope.isAndroid;
$scope.openExternalLink = function(url, target) {
externalLinkService.open(url, target);
@@ -158,6 +161,52 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
}
};
+ $scope.getDate = function(txCreated) {
+ var date = new Date(txCreated * 1000);
+ return date;
+ };
+
+ $scope.isFirstInGroup = function(index) {
+ if (index === 0) {
+ return true;
+ }
+ var curTx = $scope.txHistory[index];
+ var prevTx = $scope.txHistory[index - 1];
+ return !createdDuringSameMonth(curTx, prevTx);
+ };
+
+ $scope.isLastInGroup = function(index) {
+ if (index === $scope.txHistory.length - 1) {
+ return true;
+ }
+ return $scope.isFirstInGroup(index + 1);
+ };
+
+ function createdDuringSameMonth(tx1, tx2) {
+ var date1 = new Date(tx1.time * 1000);
+ var date2 = new Date(tx2.time * 1000);
+ return getMonthYear(date1) === getMonthYear(date2);
+ }
+
+ $scope.createdWithinPastDay = function(time) {
+ var now = new Date();
+ var date = new Date(time * 1000);
+ return (now.getTime() - date.getTime()) < (1000 * 60 * 60 * 24);
+ };
+
+ $scope.isDateInCurrentMonth = function(date) {
+ var now = new Date();
+ return getMonthYear(now) === getMonthYear(date);
+ };
+
+ function getMonthYear(date) {
+ return date.getMonth() + date.getFullYear();
+ }
+
+ $scope.isUnconfirmed = function(tx) {
+ return !tx.confirmations || tx.confirmations === 0;
+ };
+
$scope.showMore = function() {
$timeout(function() {
currentTxHistoryPage++;
@@ -184,9 +233,75 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
});
};
- $scope.$on("$ionicView.beforeEnter", function(event, data) {
+ var prevPos;
+ var screenInactive = true;
- $scope.wallet = profileService.getWallet(data.stateParams.walletId);
+ function getScrollPosition() {
+ var scrollPosition = $ionicScrollDelegate.getScrollPosition();
+ if (!scrollPosition || screenInactive) {
+ $window.requestAnimationFrame(function() {
+ getScrollPosition();
+ });
+ return;
+ }
+ var pos = scrollPosition.top;
+ if (pos === prevPos) {
+ $window.requestAnimationFrame(function() {
+ getScrollPosition();
+ });
+ return;
+ }
+ prevPos = pos;
+ var amountHeight = 180 - pos;
+ if (amountHeight < 80) {
+ amountHeight = 80;
+ }
+ var contentMargin = amountHeight;
+ if (contentMargin > 180) {
+ contentMargin = 180;
+ }
+
+ var amountScale = (amountHeight / 180);
+ if (amountScale < 0.5) {
+ amountScale = 0.5;
+ }
+ if (amountScale > 1.1) {
+ amountScale = 1.1;
+ }
+
+ var s = amountScale;
+
+ $scope.altAmountOpacity = (amountHeight - 100) / 80;
+ $window.requestAnimationFrame(function() {
+ $scope.amountHeight = amountHeight + 'px';
+ $scope.contentMargin = contentMargin + 'px';
+ $scope.amountScale = 'scale3d(' + s + ',' + s + ',' + s + ')';
+ $scope.$digest();
+ getScrollPosition();
+ });
+ }
+
+ var scrollWatcherInitialized;
+
+ $scope.$on("$ionicView.enter", function(event, data) {
+ $timeout(function() {
+ screenInactive = false;
+ }, 200);
+ if (scrollWatcherInitialized || !$scope.amountIsCollapsible) {
+ return;
+ }
+ scrollWatcherInitialized = true;
+ $timeout(function() {
+ getScrollPosition();
+ }, 100);
+ });
+
+ $scope.$on("$ionicView.beforeEnter", function(event, data) {
+ $scope.walletId = data.stateParams.walletId;
+ storageService.getBackupFlag($scope.walletId, function(err, flag) {
+ $scope.isBackedUp = flag ? true : false;
+ });
+ $scope.wallet = profileService.getWallet($scope.walletId);
$scope.requiresMultipleSignatures = $scope.wallet.credentials.m > 1;
addressbookService.list(function(err, ab) {
@@ -208,7 +323,12 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
];
});
+ // $scope.$on("$ionicView.beforeLeave", function(event, data) {
+ // $interval.cancel(scrollInterval);
+ // });
+
$scope.$on("$ionicView.leave", function(event, data) {
+ screenInactive = true;
lodash.each(listeners, function(x) {
x();
});
diff --git a/src/js/directives/gravatar.js b/src/js/directives/gravatar.js
index c76817b5e..2f85fe0eb 100644
--- a/src/js/directives/gravatar.js
+++ b/src/js/directives/gravatar.js
@@ -16,6 +16,6 @@ angular.module('copayApp.directives')
scope.emailHash = md5.createHash(scope.email.toLowerCase() || '');
}
},
- template: '
'
- }
+ template: '
'
+ };
});
diff --git a/src/js/routes.js b/src/js/routes.js
index a80c3e791..04303b272 100644
--- a/src/js/routes.js
+++ b/src/js/routes.js
@@ -151,7 +151,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
*/
.state('tabs.wallet', {
- url: '/wallet/{walletId}/{fromOnboarding}',
+ url: '/wallet/:walletId/:fromOnboarding',
views: {
'tab-home@tabs': {
controller: 'walletDetailsController',
@@ -186,6 +186,23 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
}
})
+ .state('tabs.wallet.backupWarning', {
+ url: '/backupWarning/:from/:walletId',
+ views: {
+ 'tab-home@tabs': {
+ templateUrl: 'views/backupWarning.html'
+ }
+ }
+ })
+ .state('tabs.wallet.backup', {
+ url: '/backup/:walletId',
+ views: {
+ 'tab-home@tabs': {
+ templateUrl: 'views/backup.html',
+ controller: 'backupController'
+ }
+ }
+ })
/*
*
@@ -601,7 +618,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
/*
*
- * Back flow from receive
+ * Init backup flow
*
*/
diff --git a/src/sass/views/bitpayCard.scss b/src/sass/views/bitpayCard.scss
index 70bd2d762..fb796869c 100644
--- a/src/sass/views/bitpayCard.scss
+++ b/src/sass/views/bitpayCard.scss
@@ -1,4 +1,5 @@
#bitpayCard {
+ background: white;
.bar-header {
border: 0;
background: #1e3186;
@@ -9,15 +10,35 @@
background-color: transparent;
}
}
+ .amount-wrapper {
+ position: relative;
+ overflow: visible;
+
+ .amount-bg {
+ content: '';
+ top: -1000px;
+ left: 0;
+ position: absolute;
+ height: 1000px;
+ width: 100%;
+ background-color: #1e3186;
+ }
+ }
.amount {
width: 100%;
text-align: center;
padding: 2rem 1rem 1.5rem 1rem;
- height: 140px;
+ height: 160px;
border-color: #172565;
background-color: #1e3186;
background-image: linear-gradient(0deg, #172565, #172565 0%, transparent 0%);
color: #fff;
+
+ &__balance {
+ margin-bottom: 25px;
+ font-weight: 600;
+ font-size: 34px;
+ }
}
.wallet-details-wallet-info {
bottom: 5px;
@@ -37,4 +58,26 @@
.item-select select {
color: #667;
}
+
+ .get-started {
+
+ margin-top: 20px;
+
+ &__arrow {
+ font-size: 56px;
+ opacity: .2;
+ }
+
+ h1 {
+ font-size: 28px;
+ color: #4A4A4A;
+ }
+
+ &__text {
+ font-weight: 300;
+ color: #8e8e8e;
+ max-width: 300px;
+ margin: 0 auto;
+ }
+ }
}
diff --git a/src/sass/views/confirm.scss b/src/sass/views/confirm.scss
index 172f82173..6ae3d89d1 100644
--- a/src/sass/views/confirm.scss
+++ b/src/sass/views/confirm.scss
@@ -1,3 +1,5 @@
#view-confirm {
-
+ .tx-details-content > .scroll {
+ padding-bottom: .25rem;
+ }
}
diff --git a/src/sass/views/includes/txp-details.scss b/src/sass/views/includes/txp-details.scss
index 8c5e7c723..9ebb8ad67 100644
--- a/src/sass/views/includes/txp-details.scss
+++ b/src/sass/views/includes/txp-details.scss
@@ -23,6 +23,8 @@
img {
margin-right: 1rem;
+ height: 35px;
+ width: 35px;
}
span {
diff --git a/src/sass/views/tab-home.scss b/src/sass/views/tab-home.scss
index ae1f52936..ca1a7bde9 100644
--- a/src/sass/views/tab-home.scss
+++ b/src/sass/views/tab-home.scss
@@ -52,6 +52,15 @@
}
}
}
+ .wallet-details__item.item {
+ padding-top: 0;
+ padding-bottom: 0;
+
+ .wallet-details__tx-icon {
+ background: #fff;
+ border-radius: 50px;
+ }
+ }
.next-step.item {
padding-top: 27px;
padding-bottom: 27px;
diff --git a/src/sass/views/walletDetails.scss b/src/sass/views/walletDetails.scss
index 37438bc1d..0a48b5da5 100644
--- a/src/sass/views/walletDetails.scss
+++ b/src/sass/views/walletDetails.scss
@@ -6,7 +6,7 @@
font-weight: bold;
}
&--received {
- color: #30af6c;
+ color: #09C286;
}
&--sent {
color: $dark-gray;
@@ -14,18 +14,101 @@
}
&__tx-time {
color: $light-gray;
+ font-size: 12.5px;
}
&__tx-title {
- padding-top: 10px;
+ flex-grow: 1;
color: $dark-gray;
+ overflow: hidden;
}
&__tx-icon {
float: left;
- margin-right: 10px;
+ margin-right: 25px;
+ }
+ &__tx-message {
+ margin-right: 1rem;
+ }
+
+ &__list {
+
+ }
+
+ .item {
+ display: flex;
+ align-items: center;
+ background: #fff;
+ padding-left: 1rem;
+ }
+
+ &__item {
+ display: flex;
+ align-items: center;
+ background: #fff;
+ padding: 0;
+ margin: 0;
+ border: 0;
+ padding-left: 1rem;
+
+ &.proposal {
+ position: relative;
+ }
+
+ &__marker {
+ position: absolute;
+ height: 100%;
+ width: 3px;
+ background: #F5A623;
+ left: 0;
+ }
+ }
+
+ &__tx-content {
+ display: flex;
+ align-items: center;
+ flex-grow: 1;
+ padding: 1rem 0;
+ padding-right: 1rem;
+ border-bottom: 1px solid rgb(245, 245, 245);
+ overflow: hidden;
+
+ &.no-border {
+ border: 0;
+ }
+ }
+
+ &__tx-amount {
+ white-space: nowrap;
+ }
+
+ &__group-label {
+ font-size: 14px;
+ font-weight: 300;
+ color: #727272;
+ padding: 2px 1rem;
+ background: #f8f8f9;
}
}
#walletDetails {
+ background: #F8F8F9;
+
+ .ionic-refresher-content {
+ color: white !important;
+ }
+
+ .spinner svg {
+ stroke: white;
+ fill: white;
+ }
+
+ .bp-content {
+ position: relative;
+ height: 100%;
+
+ &.status-bar {
+ margin-top: 20px;
+ }
+ }
.bar-header {
border: 0;
background: none;
@@ -39,13 +122,66 @@
.nav-bar-block, .bar {
background-color: inherit !important;
}
+ ion-content {
+
+ &.collapsible {
+ margin-top: 180px;
+ }
+
+ padding-top: 0;
+ top: 0;
+ .scroll {
+ background: rgb(248, 248, 249);
+ min-height: 300px;
+ }
+ }
+ .amount-wrapper {
+ position: relative;
+ overflow: visible;
+
+ .amount-bg {
+ content: '';
+ top: 0;
+ left: 0;
+ position: absolute;
+ width: 100%;
+ height: 500px;
+ transform: translateY(-499px);
+
+ &.collapsible {
+ top: initial;
+ bottom: 0;
+ left: 0;
+ position: absolute;
+ width: 100%;
+ height: 200px;
+ transform: translateY(100px);
+ }
+ }
+ }
.amount {
width: 100%;
text-align: center;
- padding: 2rem 1rem 1.5rem 1rem;
color: #fff;
- height: 140px;
- margin-bottom: 10px;
+ height: 180px;
+ padding-top: 40px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ &.collapsible {
+ margin-bottom: 10px;
+ }
+
+ &__balance {
+ transform: scale3d(1, 1, 1);
+ margin-top: 5px;
+ }
+
+ &__updating {
+ z-index: 999;
+ margin-top: -2.1rem;
+ }
&-alternative {
line-height: 36px;
@@ -77,3 +213,18 @@
font-size: 20px;
color: #fff;
}
+
+.wallet-not-backed-up-warning {
+ background: orange;
+ text-align: center;
+ color: white;
+ font-size: 14px;
+ display: block;
+ text-decoration: none;
+ z-index: 9999;
+ position: relative;
+}
+
+a.item {
+ cursor: pointer;
+}
diff --git a/www/img/icon-confirming.svg b/www/img/icon-confirming.svg
new file mode 100644
index 000000000..989af61aa
--- /dev/null
+++ b/www/img/icon-confirming.svg
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file
diff --git a/www/img/icon-proposal-pending.svg b/www/img/icon-proposal-pending.svg
new file mode 100644
index 000000000..6314b99ff
--- /dev/null
+++ b/www/img/icon-proposal-pending.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/www/img/icon-tx-moved-outline.svg b/www/img/icon-tx-moved-outline.svg
new file mode 100644
index 000000000..1f15f2d7e
--- /dev/null
+++ b/www/img/icon-tx-moved-outline.svg
@@ -0,0 +1,21 @@
+
+
\ No newline at end of file
diff --git a/www/img/icon-tx-received-outline.svg b/www/img/icon-tx-received-outline.svg
new file mode 100644
index 000000000..fe902fab0
--- /dev/null
+++ b/www/img/icon-tx-received-outline.svg
@@ -0,0 +1,15 @@
+
+
+
diff --git a/www/img/icon-tx-sent-outline.svg b/www/img/icon-tx-sent-outline.svg
new file mode 100644
index 000000000..790099585
--- /dev/null
+++ b/www/img/icon-tx-sent-outline.svg
@@ -0,0 +1,21 @@
+
+
\ No newline at end of file
diff --git a/www/views/bitpayCard.html b/www/views/bitpayCard.html
index bf36da1fd..e9a9a53da 100644
--- a/www/views/bitpayCard.html
+++ b/www/views/bitpayCard.html
@@ -16,10 +16,11 @@
Sandbox version. Only for testing purpose
-
- - {{tx.wallet.name}} - -
+ + + – + + (possible double spend) + + + – {{tx.amountStr}} + + +