Merge pull request #1863 from cmgustavo/ux/mobile-cordova-01

Ux/mobile cordova 01
This commit is contained in:
Matias Alejo Garcia 2014-11-22 19:06:56 -03:00
commit d4eba07fb5
24 changed files with 160 additions and 274 deletions

1
.gitignore vendored
View File

@ -75,6 +75,7 @@ shell/scripts/build
dist/darwin
dist/linux
dist/windows
dist/web
dist/*.dmg
dist/*.tar.gz
dist/*.exe

View File

@ -115,7 +115,6 @@ module.exports = function(grunt) {
vendors: {
src: [
'lib/mousetrap/mousetrap.min.js',
'js/shell.js', // shell must be loaded before moment due to the way moment loads in a commonjs env
'lib/moment/min/moment.min.js',
'lib/qrcode-generator/js/qrcode.js',
'lib/lodash/dist/lodash.js',
@ -201,6 +200,30 @@ module.exports = function(grunt) {
}
},
},
copy: {
dist: {
files: [
{
src: [
'index.html',
'init.js',
'config.js',
'css/vendors.min.css',
'css/copay.min.css',
'js/copayBundle.js',
'js/copayMain.js',
'lib/vendors.js',
'lib/angularjs-all.js',
'font/**',
'img/**',
'sound/**',
'views/**'
],
dest: 'dist/web/'
}
],
},
},
jsdoc: {
dist: {
src: ['js/models/*.js', 'js/plugins/*.js'],
@ -216,6 +239,7 @@ module.exports = function(grunt) {
grunt.registerTask('default', ['shell:dev', 'nggettext_compile', 'concat', 'cssmin']);
grunt.registerTask('dist', ['shell:prod', 'nggettext_compile', 'concat', 'cssmin', 'uglify', 'copy:dist']);
grunt.registerTask('prod', ['shell:prod', 'nggettext_compile', 'concat', 'cssmin', 'uglify']);
grunt.registerTask('translate', ['nggettext_extract']);
grunt.registerTask('docs', ['jsdoc']);

View File

@ -8,12 +8,6 @@
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter android:label="Send Bitcoins">
<data android:scheme="bitcoin"/>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:clearTaskOnLaunch="true" android:configChanges="orientation|keyboardHidden" android:exported="false" android:name="com.google.zxing.client.android.CaptureActivity" android:screenOrientation="landscape" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:windowSoftInputMode="stateAlwaysHidden">
<intent-filter>
@ -33,7 +27,6 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<provider android:authorities="com.bitpay.copay.plugin.emailcomposer.attachmentprovider" android:name="de.appplant.cordova.plugin.emailcomposer.AttachmentProvider" />
</application>
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.CAMERA" />

View File

@ -1,40 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.bitpay.copay" version="2.0.0" xmlns="http://www.w3.org/ns/widgets">
<name>Copay</name>
<description>
A secure bitcoin wallet for friends and companies.
</description>
<author email="support@bitpay.com" href="https://copay.io/">
Bitpay Inc.
</author>
<content src="index.html" />
<access origin="*" />
<preference name="loglevel" value="DEBUG" />
<preference name="SplashScreen" value="screen" />
<preference name="SplashScreenDelay" value="10000" />
<preference name="backgroundColor" value="0x2C3E50" />
<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="Clipboard">
<param name="android-package" value="com.verso.cordova.clipboard.Clipboard" />
</feature>
<feature name="EmailComposer">
<param name="android-package" value="de.appplant.cordova.plugin.emailcomposer.EmailComposer" />
</feature>
<feature name="Toast">
<param name="android-package" value="nl.xservices.plugins.Toast" />
</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

@ -67,39 +67,26 @@ 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
cordova plugin add https://github.com/VersoSolutions/CordovaClipboard
checkOK
cordova plugin add de.appplant.cordova.plugin.email-composer && cordova prepare
checkOK
cordova plugin add https://github.com/EddyVerbruggen/Toast-PhoneGap-Plugin.git && cordova prepare
checkOK
cordova plugin add org.apache.cordova.splashscreen
checkOK
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}"
cd $BUILDDIR/..
grunt
grunt dist
checkOK
echo "${OpenColor}${Green}* Coping files...${CloseColor}"
cd $BUILDDIR/..
cp -af {css,font,img,js,lib,sound,views,config.js,version.js,init.js} $PROJECT/www
cp -af dist/web/** $PROJECT/www
checkOK
sed "s/<\!-- PLACEHOLDER: CORDOVA SRIPT -->/<script type='text\/javascript' charset='utf-8' src='cordova.js'><\/script>/g" index.html > $PROJECT/www/index.html
@ -115,11 +102,8 @@ checkOK
cp android/AndroidManifest.xml $PROJECT/platforms/android/AndroidManifest.xml
checkOK
cp android/config.xml $PROJECT/platforms/android/res/xml/config.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

View File

@ -1,5 +1,8 @@
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.bitpay.copay" version="0.6.4" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" android-versionCode="16">
<widget id="com.bitpay.copay"
version="0.8.2"
android-versionCode="17"
ios-CFBundleVersion="0.8.2">
<name>Copay</name>
<description>
A secure bitcoin wallet for friends and companies.
@ -9,8 +12,12 @@
</author>
<content src="index.html" />
<access origin="*" />
<preference name="DisallowOverscroll" value="true"/>
<preference name="HideKeyboardFormAccessoryBar" value="true"/>
<preference name="SplashScreen" value="copayscreen" />
<preference name="SplashScreenDelay" value="10000" />
<preference name="backgroundColor" value="0x2C3E50" />
<preference name="BackgroundColor" value="0x2C3E50" />
<preference name="StatusBarOverlaysWebView" value="false" />
<preference name="StatusBarBackgroundColor" value="#3C4E60" />
<preference name="StatusBarStyle" value="lightcontent" />
</widget>

View File

@ -1,83 +0,0 @@
<?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.6.4</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.6.4</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

@ -140,7 +140,8 @@ header .alt-currency {
right: 14px;
width: 220px;
list-style-type: none;
top: 47px;nt
top: 47px;
z-index: 10001;
}
.head .menu ul li.divider {
@ -666,7 +667,7 @@ input[type=number]::-webkit-outer-spin-button {
}
.dr-notification-container.top {
top: 20px;
top: 60px;
}
.dr-notification-container.center {
@ -675,15 +676,14 @@ input[type=number]::-webkit-outer-spin-button {
}
.dr-notification-wrapper {
width: 360px;
width: 400px;
position: relative;
margin: 10px 0;
margin: 0 0 1px 0;
}
.dr-notification {
width: 360px;
width: 400px;
clear: both;
height: 90px;
overflow: hidden;
}
@ -694,17 +694,15 @@ input[type=number]::-webkit-outer-spin-button {
border-radius: 20px;
display: inline-block;
padding: 5px;
font-size: 12px;
font-size: 18px;
position: absolute;
right: 350px;
top: -8px;
right: 5px;
top: 5px;
cursor: pointer;
z-index: 10;
}
.dr-notification-image {
width: 80px;
height: 90px;
float: left;
display: block;
font-size: 40px;
@ -715,7 +713,7 @@ input[type=number]::-webkit-outer-spin-button {
.dr-notification-image i {
display: block;
width: 100%;
padding-top: 20px;
padding: 20px;
}
.dr-notification-image img {
margin: 15px;
@ -724,15 +722,16 @@ input[type=number]::-webkit-outer-spin-button {
}
.dr-notification-content {
padding-left: 90px;
padding-right: 10px;
padding-left: 80px;
padding-right: 30px;
padding-top: 5px;
padding-bottom: 5px;
}
.dr-notification-title {
color: white;
padding: 0px;
font-size: 18px;
font-size: 16px;
margin-top: 0;
}
@ -740,8 +739,6 @@ input[type=number]::-webkit-outer-spin-button {
background-color: #34495E;
color: #eee;
border: 1px solid #2C3E50;
opacity: 0.9;
}
.dr-notification-close-btn {
background-color: #34495E;

View File

@ -39,6 +39,15 @@
background: #3C4E60;
}
.bottom-bar {
display: block;
position: fixed;
bottom: 0;
width: 100%;
z-index: 5;
background: #3C4E60;
}
.left-off-canvas-menu {
background: #2C3E50;
}
@ -89,6 +98,17 @@
opacity: 0.6;
}
.bottombar-item a {
color: #fff;
padding: 4px 0;
display: block;
}
.bottombar-item a.active {
color: #000;
background-color: #fff;
}
.box-founds {
background-color: #213140;
}
@ -183,5 +203,41 @@
margin-top: 10px;
}
/* notifications */
.dr-notification {
width: 100%;
}
.dr-notification-container {
width: 100%;
}
.dr-notification-container.top {
top: 2.813rem;
}
.dr-notification-wrapper {
width: 100%;
margin: 0;
}
.dr-notification-close-btn {
font-size: 20px;
}
.dr-notification-image {
font-size: 30px;
}
.dr-notification-text {
font-size: 10px;
line-height: 100%;
}
.dr-notification-image i {
padding: 15px;
}
}

1
dist/README.md vendored
View File

@ -1 +0,0 @@
This is the destination directory for the built atom-shell binaries and the files used to create them

View File

@ -85,6 +85,11 @@
<section ng-class="{'main':$root.iden && !$root.starting}" ng-view></section>
<div class="bottom-bar" ng-if="$root.wallet &&
$root.wallet.isReady() && !$root.wallet.isLocked">
<div ng-include="'views/includes/bottombar-mobile.html'"></div>
</div>
<a class="exit-off-canvas"></a>
</div>

View File

@ -29,10 +29,6 @@ angular.module('copayApp.controllers').controller('HistoryController',
$scope.downloadHistory = function() {
if (window.cordova) {
log.info('Not available on mobile');
return;
}
var w = $rootScope.wallet;
if (!w) return;

View File

@ -18,14 +18,6 @@ angular.module('copayApp.controllers').controller('ImportController',
$scope.$digest();
}
$scope.openFileDialog = function() {
if (window.cshell) {
return cshell.send('backup:import');
}
$scope.choosefile = !$scope.choosefile;
};
$scope._doImport = function(encryptedObj, password) {
updateStatus('Importing wallet - Procesing backup...');

View File

@ -46,13 +46,6 @@ angular.module('copayApp.controllers').controller('ImportProfileController',
});
};
$scope.openFileDialog = function() {
if (window.cshell) {
return cshell.send('backup:import');
}
$scope.choosefile = !$scope.choosefile;
};
$scope.getFile = function() {
// If we use onloadend, we need to check the readyState.
reader.onloadend = function(evt) {

View File

@ -25,12 +25,6 @@ angular.module('copayApp.controllers').controller('ReceiveController',
$scope.openAddressModal = function(address) {
var ModalInstanceCtrl = function($scope, $modalInstance, address) {
$scope.address = address;
$scope.isMobile = !!window.cordova;
$scope.mobileCopy = function(address) {
window.cordova.plugins.clipboard.copy(address);
window.plugins.toast.showShortBottom('Copied to clipboard');
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');

View File

@ -264,16 +264,6 @@ angular.module('copayApp.directives')
}
};
})
.directive('openExternal', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('click', function() {
window.open('bitcoin:' + attrs.address, '_blank');
});
}
}
})
// From https://gist.github.com/asafge/7430497
.directive('ngReallyClick', [

View File

@ -14,13 +14,4 @@ function onDeviceReady() {
}, false);
function handleBitcoinURI(url) {
if (!url) return;
window.location = '#!/uri-payment/' + url;
}
window.plugins.webintent.getUri(handleBitcoinURI);
window.plugins.webintent.onNewIntent(handleBitcoinURI);
window.handleOpenURL = handleBitcoinURI;
}

View File

@ -14,25 +14,6 @@ BackupService.prototype._download = function(ew, walletName, filename) {
type: 'text/plain;charset=utf-8'
});
// show a native save dialog if we are in the shell
// and pass the wallet to the shell to convert to node Buffer
if (window.cshell) {
return window.cshell.send('backup:download', {
name: walletName,
wallet: ew
});
}
// throw an email intent if we are in the mobile version
if (window.cordova) {
var name = wallet.name ? wallet.name + ' ' : '';
return window.plugin.email.open({
subject: 'Copay - ' + name + 'Wallet ' + 'Backup',
body: 'Here is the encrypted backup of the wallet ' + wallet.id,
attachments: ['base64:' + filename + '//' + btoa(ew)]
});
}
this.notifications.success('Backup created', 'Encrypted backup file saved');
// otherwise lean on the browser implementation

View File

@ -43,6 +43,7 @@
"verify": "gpg --verify browser-extensions/firefox/copay.xpi.sig browser-extensions/firefox/copay.xpi; gpg --verify browser-extensions/chrome/copay-chrome-extension.zip.sig browser-extensions/chrome/copay-chrome-extension.zip"
},
"devDependencies": {
"angular-gravatar": "*",
"async": "^0.9.0",
"bitcore": "^0.1.36",
"blanket": "^1.1.6",
@ -61,6 +62,7 @@
"grunt-browserify": "^2.0.8",
"grunt-cli": "^0.1.13",
"grunt-contrib-concat": "^0.5.0",
"grunt-contrib-copy": "^0.7.0",
"grunt-contrib-cssmin": "^0.10.0",
"grunt-contrib-uglify": "^0.5.1",
"grunt-contrib-watch": "^0.5.3",
@ -81,14 +83,13 @@
"mocha": "^1.18.2",
"mocha-lcov-reporter": "^0.0.1",
"mock-fs": "^2.3.1",
"sjcl": "*",
"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",
"travis-cov": "^0.2.5",
"uglifyify": "^1.2.3",
"angular-gravatar": "*"
"uglifyify": "^1.2.3"
}
}

View File

@ -0,0 +1,13 @@
<div class="row" ng-controller="SidebarController">
<div class="medium-3 small-3 columns text-center bottombar-item" data-ng-repeat="item in menu" ui-route="{{item.link}}" ng-if="item.link!='more'">
<a href="#!/{{item.link}}" ng-class="{active: isActive(item)}">
<i class="size-24 {{item.icon}} db"></i>
<div class="size-10">
{{item.title}}
<span class="label alert round" ng-if="item.link=='send' && $root.pendingTxCount > 0">{{$root.pendingTxCount}}</span>
</div>
</a>
</div>
</div>

View File

@ -22,10 +22,7 @@
</div>
<div ng-if="walletSelection">
<div class="side-nav wallets" ng-show="!wallets.0">
<p class="size-12" translate>You do not have another wallets. Creates one more from link below.</p>
<div class="text-center">
<i class="fi-arrow-down"></i>
</div>
<p class="size-12" translate>You do not have another wallets.</p>
</div>
<ul class="side-nav wallets off-canvas-list" ng-show="wallets.0"
ng-click="toggleWalletSelection()"
@ -78,30 +75,28 @@
<div class="line-t p0"></div>
<ul class="off-canvas-list" ng-show="!walletSelection">
<li data-ng-repeat="item in menu" ui-route="{{item.link}}" class="nav-item" data-ng-class="{active: isActive(item)}">
<a href="#!/{{item.link}}" class="db p20h">
<i class="size-24 m20r {{item.icon}}"></i> {{item.title}}
<span class="label alert round" ng-if="item.link=='send' && $root.pendingTxCount > 0">{{$root.pendingTxCount}}</span>
</a>
</li>
<li>
<a href="#!/create" class="db p20h" title="Create new wallet">
<a href="#!/more" class="db p20h nav-item" title="Settings">
<i class="size-24 m20r fi-widget"></i> {{'Settings' | translate }} </a>
</li>
<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" title="Join shared wallet">
<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" title="Import wallet">
<a href="#!/import" class="db p20h nav-item" title="Import wallet">
<i class="size-24 m20r fi-download"></i> {{'Import wallet' | translate }} </a>
</li>
<li>
<a href="#!/profile" class="db p20h" title="Profile">
<a href="#!/profile" class="db p20h nav-item" title="Profile">
<i class="size-24 m20r fi-torso"></i> {{'Profile' | translate }} </a>
</li>
<li>
<a href="#!/" class="db p20h" title="Close"
<a href="#!/" class="db p20h nav-item" title="Close"
ng-click="signout()"><i class="size-24 m20r fi-power"></i> {{'Close'|translate}}</a>
</li>
</ul>

View File

@ -1,22 +1,21 @@
<div class="text-center">
<qrcode size="220" data="bitcoin:{{address.address}}"></qrcode>
<qrcode size="220" data="{{address.address}}"></qrcode>
<div class="m10t">
<h4 class="size-12">{{address.address}} <span class="btn-copy" clip-copy="address.address"></span></h4>
<span ng-if="$root.updatingBalance">
<i class="fi-bitcoin-circle icon-rotate spinner"></i>
</span>
<p class="m15b size-18" ng-if="!$root.updatingBalance">
{{address.balance || 0|noFractionNumber}} {{$root.wallet.settings.unitName}}
<div class="m10t" ng-init="label = $root.wallet.addressBook[address.address].label">
<div class="size-12">
{{address.address}} <small class="label" ng-show="address.isChange">change</small>
</div>
<b class="db m5t" ng-show="label">
({{label}})
</b>
<p class="m10t size-18">
<span ng-show="$root.updatingBalance">
<i class="fi-bitcoin-circle icon-rotate spinner"></i>
</span>
<span ng-show="!$root.updatingBalance">
{{address.balance || 0|noFractionNumber}} {{$root.wallet.settings.unitName}}
</span>
</p>
<div class="small-10 columns small-centered">
<button class="m15t button secondary hide-for-large-up" ng-show="isMobile" ng-click="mobileCopy(address.address)">
<i class="fi-link">&nbsp;</i> <span translate>Copy to clipboard</span>
</button>
<a class="m15t secondary" open-external address="{{address.address}}">
<span translate>Open in external application</span>
</a>
</div>
</div>
</div>
<a class="close-reveal-modal" ng-click="cancel()">&#215;</a>

View File

@ -11,9 +11,7 @@
<div class="row show-for-large-up">
<div class="large-7 medium-9 columns">
<div class="list-addr">
<span>
<contact address="{{addr.address}}" tooltip-popup-delay="500" tooltip tooltip-placement="right">
</span>
<contact address="{{addr.address}}" tooltip-popup-delay="500" tooltip tooltip-placement="right">
<small translate class="label" ng-if="addr.isChange">change</small>
</div>
</div>

View File

@ -50,10 +50,10 @@
<input class="columns" type="text" id="address" name="address" ng-disabled="loading || !!$root.merchant"
placeholder="{{'Bitcoin address'|translate}}" ng-model="address" ng-change="onChanged()" valid-address required auto-focus>
<div ng-hide="showScanner || disableScanner">
<button class="postfix button black" ng-click="openScanner()"><i class="fi-camera size-24"></i></button>
<a class="postfix button black" ng-click="openScanner()"><i class="fi-camera size-24"></i></a>
</div>
<div ng-show="showScanner">
<button translate class="postfix button warning" ng-click="cancelScanner()"><i class="fi-x size-18"></i></button>
<a translate class="postfix button warning" ng-click="cancelScanner()"><i class="fi-x size-18"></i></a>
</div>
</div>