Merge pull request #1979 from cmgustavo/feature/wallet-bar-mobile

Feature/wallet bar mobile
This commit is contained in:
Matias Alejo Garcia 2014-12-04 23:46:22 -03:00
commit d4699d0ae6
19 changed files with 178 additions and 203 deletions

View File

@ -24,7 +24,6 @@
"angular-load": "0.2.0",
"lodash": "~2.4.1",
"angular-gravatar": "*",
"fastclick": "*",
"angular-touch": "~1.3.0"
},
"resolutions": {

View File

@ -25,9 +25,9 @@
.main {
height: 92%;
margin-top: 40px;
margin-top: 30px;
margin-left: 0;
margin-bottom: -40px;
margin-bottom: -30px;
padding: 20px 0 80px 0;
}
@ -53,6 +53,11 @@
line-height: 110%;
}
header h1 {
color: #fff;
text-align: center;
}
.col3 a {
height: 45px;
padding: 12px 5px;
@ -63,6 +68,10 @@
left: 0;
}
.right-off-canvas-menu {
background-color: #213140 ;
}
.left-off-canvas-menu {
background: #E4E8EC;
line-height: 24px;
@ -177,11 +186,6 @@
margin-left: 0;
font-size: 14px;
}
.top-balance {
width: auto;
padding: 0 5px;
}
a.missing-copayers {
bottom: -34px;
@ -204,14 +208,7 @@
.footer-setup {
margin-bottom: 50px;
}
.side-nav.wallets {
padding: 0;
height: 100%;
left: 0;
top: 45px;
}
}
ul.off-canvas-list li a:hover {
background: transparent;
@ -222,6 +219,18 @@
padding: 0.15rem 0.2rem;
}
.side-nav.wallets {
z-index: 100;
overflow-y: inherit;
position: inherit;
height: auto;
border-bottom: none;
}
.side-nav li.nav-item.selected {
background-color: #3C4E60;
}
}
@media (max-width: 640px) {

View File

@ -38,7 +38,7 @@
</div>
<div ng-show="sessionExpired" class="session-expired">
<i class="fi-battery-empty size-72 text-gray"></i>
<i class="fi-clock 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>
@ -56,37 +56,40 @@
</span>
</span>
<nav class="tab-bar" ng-if="$root.iden && !$root.hideNavigation" >
<section class="left-small">
<a class="left-off-canvas-toggle menu-icon" ><span></span></a>
</section>
<section class="right-small text-center top-balance" ng-if="$root.wallet && $root.wallet.isComplete() && !$root.wallet.isLocked" >
<span ng-if="$root.updatingBalance">
<i class="fi-bitcoin-circle icon-rotate spinner"></i>
</span>
<span class="size-14" ng-if="!$root.updatingBalance">
{{$root.wallet.balanceInfo.totalBalance || 0}} {{$root.wallet.settings.unitName}}
</span>
</section>
<div ng-controller="SidebarController" ng-init="init()" ng-if="$root.iden && !$root.hideNavigation">
<nav class="tab-bar" >
<section class="left-small">
<a class="left-off-canvas-toggle menu-icon" ><span></span></a>
</section>
<section class="right-small">
<a class="right-off-canvas-toggle p10"><i class="icon-wallet size-24"></i></a>
</section>
<section class="middle tab-bar-section">
<h1 class="title ellipsis">
{{$root.wallet.getName()}}
</h1>
</section>
</nav>
<section class="middle tab-bar-section">
<h1 class="title">
<img src="img/logo-negative-beta.svg" alt="Copay" width="60">
</h1>
</section>
</nav>
<aside class="left-off-canvas-menu" ng-if="$root.iden">
<div ng-include="'views/includes/sidebar-mobile.html'"></div>
</aside>
<aside class="left-off-canvas-menu">
<div ng-include="'views/includes/sidebar-mobile.html'"></div>
</aside>
<div notifications="right top"></div>
<aside class="right-off-canvas-menu">
<div ng-include="'views/includes/walletbar-mobile.html'"></div>
</aside>
<div
ng-include="'views/includes/sidebar.html'"
role='navigation'
class="sidebar"></div>
<div class="bottom-bar" ng-if="$root.wallet &&
$root.wallet.isComplete() && !$root.wallet.isLocked">
<div ng-include="'views/includes/bottombar-mobile.html'"></div>
</div>
</div>
<div
ng-include="'views/includes/sidebar.html'"
role='navigation'
class="sidebar"
ng-if="$root.iden"></div>
<div notifications="right top"></div>
<div
ng-controller="HeadController"
@ -96,12 +99,7 @@
ng-class="{'dni':$root.hideNavigation}"
></div>
<section ng-class="{'main':$root.iden && !$root.starting}" ng-view></section>
<div class="bottom-bar" ng-if="$root.wallet &&
$root.wallet.isComplete() && !$root.wallet.isLocked">
<div ng-include="'views/includes/bottombar-mobile.html'"></div>
</div>
<section ng-class="{'main':$root.iden && !$root.starting}" ng-view></section>
<a class="exit-off-canvas"></a>

View File

@ -1,11 +1,12 @@
'use strict';
angular.module('copayApp.controllers').controller('CreateProfileController', function($scope, $rootScope, $location, $timeout, notification, pluginManager, identityService, pinService) {
angular.module('copayApp.controllers').controller('CreateProfileController', function($scope, $rootScope, $location, $timeout, notification, pluginManager, identityService, pinService, isMobile) {
var _credentials, _firstpin;
$scope.init = function() {
identityService.goWalletHome();
$scope.isMobile = isMobile.any();
pinService.makePinInput($scope, 'newpin', function(newValue) {
_firstpin = newValue;
@ -88,7 +89,7 @@ angular.module('copayApp.controllers').controller('CreateProfileController', fun
} else {
$scope.error = null;
// mobile
if (isMobile.any()) {
if ($scope.isMobile) {
_credentials = {
email: form.email.$modelValue,
password: form.password.$modelValue,

View File

@ -6,6 +6,8 @@ angular.module('copayApp.controllers').controller('HomeController', function($sc
var _credentials, _firstpin;
$scope.init = function() {
$scope.isMobile = isMobile.any();
// This is only for backwards compat, insight api should link to #!/confirmed directly
if (getParam('confirmed')) {
var hashIndex = window.location.href.indexOf('/?');
@ -158,7 +160,7 @@ angular.module('copayApp.controllers').controller('HomeController', function($sc
$scope.confirmedEmail = false;
// mobile
if (isMobile.any() && !$rootScope.hasPin) {
if ($scope.isMobile && !$rootScope.hasPin) {
$scope.done();
_credentials = {
email: email,

View File

@ -1,9 +1,16 @@
'use strict';
angular.module('copayApp.controllers').controller('HomeWalletController', function($scope, $rootScope, $timeout, $filter, rateService, notification) {
angular.module('copayApp.controllers').controller('HomeWalletController', function($scope, $rootScope, $timeout, $filter, $location, rateService, notification, identityService) {
$scope.init = function() {
$rootScope.title = 'Home';
// fix for Safari and mobile devices
var walletId = $location.hash();
if (walletId) {
$location.hash('');
identityService.setFocusedWallet(walletId);
}
$scope.rateService = rateService;
$scope.isRateAvailable = false;
@ -100,8 +107,6 @@ angular.module('copayApp.controllers').controller('HomeWalletController', functi
},1)
}, 100);
$scope.sign = function(ntxid) {
var w = $rootScope.wallet;
$scope.loading = true;

View File

@ -1,6 +1,8 @@
'use strict';
angular.module('copayApp.controllers').controller('SidebarController', function($scope, $rootScope, $location, $timeout, identityService) {
angular.module('copayApp.controllers').controller('SidebarController', function($scope, $rootScope, $location, $timeout, identityService, isMobile) {
$scope.isMobile = isMobile.any()
$scope.menu = [{
'title': 'Home',
@ -49,7 +51,6 @@ angular.module('copayApp.controllers').controller('SidebarController', function(
$scope.setWallets();
};
$scope.init = function() {
// This should be called only once.
@ -61,7 +62,7 @@ angular.module('copayApp.controllers').controller('SidebarController', function(
});
}
// wallet list chane
// wallet list change
if ($rootScope.iden) {
var iden = $rootScope.iden;
iden.on('newWallet', function() {
@ -90,8 +91,8 @@ angular.module('copayApp.controllers').controller('SidebarController', function(
$scope.setWallets = function() {
if (!$rootScope.iden) return;
var ret = _.filter($rootScope.iden.listWallets(), function(w) {
return !identityService.isFocused(w.getId());
return w;
});
$scope.wallets = ret;
$scope.wallets = _.sortBy(ret, 'name');
};
});

View File

@ -280,16 +280,6 @@ angular.module('copayApp.directives')
}
}
])
.directive('autoFocus', function($timeout) {
return {
restrict: 'AC',
link: function(_scope, _element) {
$timeout(function() {
_element[0].focus();
});
}
};
})
.directive('showFocus', function($timeout) {
return function(scope, element, attrs) {
scope.$watch(attrs.showFocus,

View File

@ -24,7 +24,8 @@ angular.module('copayApp.services')
r.availableBalanceBTC = (safeBalanceSat / COIN);
r.safeUnspentCount = safeUnspentCount;
r.lockedBalance = (balanceSat - safeBalanceSat) * satToUnit;
var lockedBalance = (balanceSat - safeBalanceSat) * satToUnit;
r.lockedBalance = lockedBalance ? $filter('noFractionNumber')(lockedBalance) : null;
r.lockedBalanceBTC = (balanceSat - safeBalanceSat) / COIN;

View File

@ -86,7 +86,7 @@ describe("Angular services", function() {
expect(b.totalBalance).to.be.equal('1,000,000.01');
expect(b.availableBalance).to.be.equal('900,000.02');
expect(b.lockedBalance).to.be.equal(99999.99);
expect(b.lockedBalance).to.be.equal('99,999.99');
expect(b.balanceByAddr[Waddr]).to.equal(2);
expect(b.safeUnspentCount).to.equal(5);

View File

@ -32,7 +32,7 @@
<div class="panel">
<label><span translate>Wallet name</span>
<div class="input">
<input type="text" placeholder="{{'Family vacation funds'|translate}}" class="form-control" ng-model="walletName" auto-focus>
<input type="text" placeholder="{{'Family vacation funds'|translate}}" class="form-control" ng-model="walletName">
<i class="icon-wallet"></i>
</div>
</label>

View File

@ -46,7 +46,8 @@
!profileForm.email.$pristine"><i class="fi-check"></i></span>
</div>
<div class="input">
<input type="email" ng-model="email" class="form-control fi-email" name="email" placeholder="Email" required auto-focus>
<input type="email" ng-model="email" class="form-control fi-email" name="email" placeholder="Email"
show-focus="!isMobile" required>
<i class="icon-email"></i>
</div>

View File

@ -110,7 +110,7 @@
<input id="pin" type="tel" ng-model="pin" class="form-control"
ng-maxlength="4" ng-minlength="4" maxlength="4"
ng-pattern="/^[0-9]{1,4}$/"
placeholder="Pin number" name="pin" required auto-focus>
placeholder="Pin number" name="pin" required>
<i class="icon-locked"></i>
</div>
@ -142,7 +142,7 @@
</p>
<div class="input">
<input type="email" ng-model="email" class="form-control"
name="email" placeholder="Email" required auto-focus>
name="email" placeholder="Email" required show-focus="!isMobile">
<i class="icon-email"></i>
</div>
<div class="input">

View File

@ -9,11 +9,13 @@
<div class="large-12 columns">
<div class="panel oh">
<div class="row">
<div class="large-8 medium-6 small-3 columns">
<div class="avatar-wallet left">{{$root.wallet.getName() | limitTo: 1}}</div>
<h2 class="ellipsis m10t left hide-for-small-only">{{$root.wallet.getName()}}</h2>
<div class="large-8 medium-6 small-12 columns">
<div class="ellipsis oh">
<div class="avatar-wallet left">{{$root.wallet.getName() | limitTo: 1}}</div>
<h2 class="m10t left">{{$root.wallet.getName()}}</h2>
</div>
</div>
<div class="large-4 medium-6 small-9 columns">
<div class="large-4 medium-6 small-12 columns">
<div class="text-right">
<span class="size-21">
<strong>

View File

@ -1,4 +1,4 @@
<div class="row collapse" ng-controller="SidebarController">
<div class="row collapse">
<div class="medium-3 small-3 columns text-center bottombar-item" ng-repeat="item in menu" ui-route="{{item.link}}" ng-if="item.link!='more'">
<a ng-click="go(item.link)" ng-class="{active: isActive(item)}">
<i class="size-36 {{item.icon}} db"></i>

View File

@ -1,78 +1,6 @@
<div ng-controller="SidebarController" ng-init="init()">
<header>
<div ng-click="toggleWalletSelection()" ng-if="$root.wallet">
<div class="col1">
<div class="avatar-wallet">{{$root.wallet.getName() | limitTo: 1}}</div>
</div>
<div class="col2">
<div class="oh m5t m10r">
<div class="right size-10 text-white">[ {{$root.wallet.requiredCopayers}} of {{$root.wallet.totalCopayers}} ]</div>
<div class="name-wallet">
<div class="ellipsis">{{$root.wallet.getName()}}</div>
</div>
</div>
<div class="founds size-12">
<span ng-if="!$root.wallet.isComplete()">Waiting for copayers...</span>
<div ng-if="$root.wallet.isComplete()">
<span ng-if="$root.wallet.balanceInfo.updatingBalance"><i class="fi-bitcoin-circle icon-rotate spinner"></i></span>
<div ng-if="$root.wallet && !$root.wallet.balanceInfo.updatingBalance" data-options="disable_for_touch:true">
<b class="m5r">{{$root.wallet.balanceInfo.totalBalance || 0}} {{$root.wallet.settings.unitName}}</b>
<span ng-if="$root.wallet.balanceInfo.alternativeBalanceAvailable" class="alt-currency">{{$root.wallet.balanceInfo.totalBalanceAlternative}} {{$root.wallet.balanceInfo.alternativeIsoCode}}</span>
<span ng-if="!$root.wallet.balanceInfo.alternativeBalanceAvailable" class="alt-currency">N/A</span>
</div>
</div>
</div>
</div>
<div class="col3">
<a ng-class="{'selected':walletSelection}">
<span ng-show="!walletSelection">
<i class="icon-arrow-down2"></i>
</span>
<span ng-show="walletSelection">
<i class="icon-arrow-up2"></i>
</span>
</a>
</div>
</div>
<div ng-show="walletSelection">
<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="m10r fi-plus"></i> {{'Create new wallet' | translate }} </a>
</div>
<ul class="side-nav wallets off-canvas-list" 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="toggleWalletSelection(); switchWallet(item.id)">
<div class="col1">
<div class="avatar-wallet">{{(item.name || item.id) | limitTo: 1}}</div>
</div>
<div class="col2">
<a class="size-12 wallet-item">
<div class="oh">
<div class="right size-10 type-wallet">
[ {{item.requiredCopayers}} of {{item.totalCopayers}} ]</div>
<div class="ellipsis name-wallet">{{item.name || item.id}}</div>
</div>
<div class="oh">
<span ng-if="item.isComplete() && item.balanceInfo.updatingBalance"><i class="fi-bitcoin-circle icon-rotate spinner"></i></span>
<div ng-if="item.isComplete() && !item.balanceInfo.updatingBalance" data-options="disable_for_touch:true">
<b class="m5r size-12">{{item.balanceInfo.totalBalance || 0}} {{item.settings.unitName}}</b>
<span class="alt-currency size-10">{{item.balanceInfo.totalBalanceAlternative}} {{item.balanceInfo.alternativeIsoCode}}</span>
</div>
<span ng-if="!item.isComplete()">Waiting for copayers...</span>
</div>
</a>
</div>
</li>
</ul>
</div>
</header>
<div ng-show="!walletSelection" ng-init="username = $root.iden.getName()">
<div class="off-canvas-list">
<a href="#!/profile" class="columns text-center m10v" title="Profile">
<div ng-init="username = $root.iden.getName()">
<div class="text-center off-canvas-list">
<a href="#!/profile" class="columns m10v" title="Profile">
<div class="photo-container">
<img gravatar-src="'{{username}}'" gravatar-size="35">
</div>
@ -82,34 +10,33 @@
</span>
</a>
</div>
<ul class="off-canvas-list columns">
<li>
<a href="#!/create" class="db p20h nav-item" title="Create new wallet">
<i class="size-24 m20r fi-plus"></i> {{'Create new wallet' | translate }} </a>
</li>
<li>
<a href="#!/join" class="db p20h nav-item" title="Join shared wallet">
<i class="size-24 m20r fi-torsos-all"></i> {{'Join shared wallet' | translate }} </a>
</li>
<li>
<a href="#!/import" class="db p20h nav-item" title="Import wallet">
<i class="size-24 m20r fi-download"></i> {{'Import a wallet' | translate }} </a>
</li>
<li ng-if="$root.wallet">
<a href="#!/more" class="db p20h nav-item" title="Settings" >
<i class="size-24 m20r fi-widget"></i> {{'Wallet Settings' | translate }} </a>
</li>
<li>
<a href="#!/" class="db p20h nav-item" title="Close"
ng-click="signout()">
<span ng-if="!$root.hasPin"><i class="size-24 m20r fi-power"></i> {{'Close'|translate}}</span>
<span ng-if="$root.hasPin"><i class="size-24 m20r fi-lock"></i> {{'Lock'|translate}}</span>
</a>
</li>
</ul>
<div class="text-gray size-12 text-center columns">
<div ng-include="'views/includes/version.html'"></div>
</div>
<ul class="off-canvas-list">
<li>
<a href="#!/create" class="db p20h nav-item" title="Create new wallet">
<i class="size-24 m20r fi-plus"></i> {{'Create new wallet' | translate }} </a>
</li>
<li>
<a href="#!/join" class="db p20h nav-item" title="Join shared wallet">
<i class="size-24 m20r fi-torsos-all"></i> {{'Join shared wallet' | translate }} </a>
</li>
<li>
<a href="#!/import" class="db p20h nav-item" title="Import wallet">
<i class="size-24 m20r fi-download"></i> {{'Import a wallet' | translate }} </a>
</li>
<li ng-if="$root.wallet">
<a href="#!/more" class="db p20h nav-item" title="Settings" >
<i class="size-24 m20r fi-widget"></i> {{'Wallet Settings' | translate }} </a>
</li>
<li>
<a href="#!/" class="db p20h nav-item" title="Close"
ng-click="signout()">
<span ng-if="!$root.hasPin"><i class="size-24 m20r fi-power"></i> {{'Close'|translate}}</span>
<span ng-if="$root.hasPin"><i class="size-24 m20r fi-lock"></i> {{'Lock'|translate}}</span>
</a>
</li>
</ul>
<div class="text-gray size-12 text-center columns">
<div ng-include="'views/includes/version.html'"></div>
</div>
</div>

View File

@ -1,4 +1,4 @@
<div ng-controller="SidebarController" ng-init="init()">
<div>
<header ng-show="$root.wallet">
<div class="col1">
<div class="avatar-wallet">{{$root.wallet.getName() | limitTo: 1}}</div>
@ -39,7 +39,9 @@
<i class="fi-lock"></i> {{'Locked'|translate}} &nbsp;
</span>
<span ng-if="$root.wallet.balanceInfo.updatingBalance"><i class="fi-bitcoin-circle icon-rotate spinner"></i></span>
<span ng-if="$root.wallet && !$root.wallet.balanceInfo.updatingBalance" class="text-gray"><b>{{$root.wallet.balanceInfo.lockedBalance || 0}} {{$root.wallet.settings.unitName}} </b> - {{$root.wallet.balanceInfo.lockedBalanceAlternative}} {{$root.wallet.balanceInfo.alternativeIsoCode}}
<span ng-if="$root.wallet && !$root.wallet.balanceInfo.updatingBalance" class="text-gray">
<b>{{$root.wallet.balanceInfo.lockedBalance}} {{$root.wallet.settings.unitName}} </b>
- {{$root.wallet.balanceInfo.lockedBalanceAlternative}} {{$root.wallet.balanceInfo.alternativeIsoCode}}
</span>
<i class="fi-info medium right text-gray size-14"
tooltip="{{'Balance locked in pending transaction proposals'|translate}}"
@ -51,7 +53,11 @@
<div>
<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)">
<li
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>
</div>

View File

@ -0,0 +1,37 @@
<div>
<header ng-show="$root.wallet">
<h1>My wallets</h1>
</header>
<div class="side-nav 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="m10r fi-plus"></i> {{'Create new wallet' | translate }} </a>
</div>
<ul class="side-nav wallets off-canvas-list" ng-show="wallets[0]">
<li
ng-repeat="item in wallets track by $index"
ng-class="{'selected': item.id == $root.wallet.id}"
class="nav-item">
<div class="col1">
<div class="avatar-wallet">{{(item.name || item.id) | limitTo: 1}}</div>
</div>
<div class="col2">
<a href="#!/homeWallet#{{item.id}}" class="size-12 wallet-item">
<div class="oh">
<div class="right size-10 type-wallet">
[ {{item.requiredCopayers}} of {{item.totalCopayers}} ]</div>
<div class="ellipsis name-wallet">{{item.name || item.id}}</div>
</div>
<div class="oh">
<span ng-if="item.isComplete() && item.balanceInfo.updatingBalance"><i class="fi-bitcoin-circle icon-rotate spinner"></i></span>
<div ng-if="item.isComplete() && !item.balanceInfo.updatingBalance" data-options="disable_for_touch:true">
<b class="m5r size-12">{{item.balanceInfo.totalBalance || 0}} {{item.settings.unitName}}</b>
<span class="alt-currency size-10">{{item.balanceInfo.totalBalanceAlternative}} {{item.balanceInfo.alternativeIsoCode}}</span>
</div>
<span ng-if="!item.isComplete()">Waiting for copayers...</span>
</div>
</a>
</div>
</li>
</ul>
</div>

View File

@ -8,23 +8,19 @@
<div class="row">
<!-- Address-->
<div class="large-12 columns" ng-if="addr">
<div class="panel oh">
<div class="row">
<h2 class="line-b" translate>My Bitcoin address:</h2>
<div class="text-center" ng-if="!loading">
<qrcode size="220" data="bitcoin:{{addr}}"></qrcode>
<div class="m10t">
<h4 class="size-12">{{addr}}</h4>
</div>
</div>
<div class="text-center" ng-if="loading">
Generating new address...
<div class="panel">
<h2 class="line-b" translate>My Bitcoin address:</h2>
<div class="text-center" ng-if="!loading">
<qrcode size="220" data="bitcoin:{{addr}}"></qrcode>
<div class="m10t">
<h4 class="size-12">{{addr}}</h4>
</div>
</div>
<div class="row">
<div class="large-12 columns line-t m10t size-12">
Share this with anyone to have them send you payments. To protect your privacy, new addresses are generated automatically once you use them.
</div>
<div class="text-center" ng-if="loading">
Generating new address...
</div>
<div class="line-t m10t size-12">
Share this with anyone to have them send you payments. To protect your privacy, new addresses are generated automatically once you use them.
</div>
</div>
</div>