commit
d8026bd45e
23 changed files with 501 additions and 104 deletions
|
|
@ -126,6 +126,9 @@ if [ ! -d $PROJECT ]; then
|
|||
cordova plugin add hu.dpal.phonegap.plugins.uniquedeviceid
|
||||
checkOK
|
||||
|
||||
cordova plugin add org.apache.cordova.file
|
||||
checkOK
|
||||
|
||||
fi
|
||||
|
||||
if $DBGJS
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@
|
|||
</author>
|
||||
<content src="index.html" />
|
||||
<access origin="*" />
|
||||
<preference name="AndroidPersistentFileLocation" value="Internal" />
|
||||
<preference name="iosPersistentFileLocation" value="Library" />
|
||||
|
||||
<preference name="DisallowOverscroll" value="true"/>
|
||||
<preference name="HideKeyboardFormAccessoryBar" value="true"/>
|
||||
<preference name="SplashScreen" value="copayscreen" />
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<span ng-controller="versionController as v">
|
||||
<small>v{{v.version}}</small>
|
||||
<small>#{{v.commitHash}}</small>
|
||||
</span>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
<ul class="no-bullet m0 size-14">
|
||||
<h4 class="title m0" translate>{{index.walletName}} settings</h4>
|
||||
|
||||
<li class="line-b p20" ng-click="$root.go('preferencesColor')">
|
||||
<span translate>Color</span>
|
||||
<span class="right text-gray">
|
||||
|
|
@ -58,6 +59,11 @@
|
|||
{{preferences.bwsurl}}
|
||||
</span>
|
||||
</li>
|
||||
<li class="line-b p20" ng-click="$root.go('about')">
|
||||
<i class="icon-arrow-right3 size-24 right text-gray"></i>
|
||||
<span translate>About Copay</span>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
34
public/views/preferencesAbout.html
Normal file
34
public/views/preferencesAbout.html
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<div class="content p20v" ng-controller="preferencesAbout as about">
|
||||
<ul class="no-bullet m0 size-14">
|
||||
<div class="m20t m20b text-center">
|
||||
<img src="img/logo.svg" alt="Copay" width="120">
|
||||
</div>
|
||||
<h4 class="title m0" translate>Release Information</h4>
|
||||
|
||||
<div ng-controller="versionController as v">
|
||||
<li class="line-b p20" ng-conf>
|
||||
<span translate>Version</span>
|
||||
<span class="right text-gray">
|
||||
v{{v.version}}
|
||||
</span>
|
||||
</li>
|
||||
<li class="line-b p20" ng-conf ng-click="$root.openExternalLink('https://github.com/bitpay/copay/tree/'+v.commitHash)">
|
||||
<span translate>Commit hash</span>
|
||||
<span class="right text-gray">
|
||||
#{{v.commitHash}}
|
||||
<i class="icon-arrow-right3 size-24 right text-gray"></i>
|
||||
</span>
|
||||
</li>
|
||||
</div>
|
||||
|
||||
<h4 class="title m0" translate> </h4>
|
||||
<li class="line-b p20" ng-conf ng-click="$root.go('logs')">
|
||||
<span translate>View session logs</span>
|
||||
<span class="right text-gray">
|
||||
<i class="icon-arrow-right3 size-24 right text-gray"></i>
|
||||
</span>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
16
public/views/preferencesLogs.html
Normal file
16
public/views/preferencesLogs.html
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<div class="content p20v" ng-controller="preferencesLogs as logs">
|
||||
|
||||
<button class="black radius expand" ng-show="logs.isCordova" ng-style="{'background-color':index.backgroundColor}" ng-click="logs.sendLogs()" ><i class="fi-mail"></i>
|
||||
|
||||
<span translate>Send by email</span>
|
||||
</button>
|
||||
|
||||
<ul class="no-bullet m0 size-14">
|
||||
<li class="line-b" ng-repeat="l in logs.logs">
|
||||
|
||||
<span ng-class="{'text-warning': l.level=='warn', 'text-secondary': l.level=='debug', 'text-primary': l.level=='info', 'text-alert': l.level=='error' }">
|
||||
{{l.msg}}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -881,6 +881,7 @@ input.ng-invalid-match, input.ng-invalid-match:focus {
|
|||
.text-secondary {color: #3498DB;}
|
||||
.text-white {color: #fff;}
|
||||
.text-warning {color: #ED4A43;}
|
||||
.text-alert {color: red;}
|
||||
.text-success {color: #1ABC9C;}
|
||||
|
||||
.panel {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('indexController', function($rootScope, $scope, $log, $filter, $timeout, lodash, go, profileService, configService, isCordova, rateService, storageService, gettextCatalog, amMoment) {
|
||||
|
||||
var self = this;
|
||||
self.isCordova = isCordova;
|
||||
self.onGoingProcess = {};
|
||||
|
|
@ -96,7 +97,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r
|
|||
self.copayers = [];
|
||||
|
||||
storageService.getBackupFlag(self.walletId, function(err, val) {
|
||||
self.needsBackup = !val;
|
||||
self.needsBackup = self.network == 'testnet' ? false : !val;
|
||||
self.openWallet();
|
||||
});
|
||||
});
|
||||
|
|
@ -414,7 +415,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r
|
|||
};
|
||||
|
||||
|
||||
self.clientError = function (err) {
|
||||
self.clientError = function(err) {
|
||||
if (isCordova) {
|
||||
navigator.notification.confirm(
|
||||
err,
|
||||
|
|
@ -426,6 +427,19 @@ angular.module('copayApp.controllers').controller('indexController', function($r
|
|||
}
|
||||
};
|
||||
|
||||
self.deviceError = function(err) {
|
||||
if (isCordova) {
|
||||
navigator.notification.confirm(
|
||||
err,
|
||||
function() {},
|
||||
'Device Error', ['OK']
|
||||
);
|
||||
} else {
|
||||
alert(err);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
self.recreate = function(cb) {
|
||||
var fc = profileService.focusedClient;
|
||||
self.setOngoingProcess('recreating', true);
|
||||
|
|
@ -521,11 +535,16 @@ angular.module('copayApp.controllers').controller('indexController', function($r
|
|||
self.updateColor();
|
||||
});
|
||||
|
||||
$rootScope.$on('Local/ConfigurationUpdated', function(event) {
|
||||
$rootScope.$on('Local/UnitSettingUpdated', function(event) {
|
||||
self.updateAll();
|
||||
self.updateTxHistory();
|
||||
});
|
||||
|
||||
|
||||
$rootScope.$on('Local/BWSUpdated', function(event) {
|
||||
profileService.applyConfig();
|
||||
});
|
||||
|
||||
$rootScope.$on('Local/WalletCompleted', function(event) {
|
||||
self.setFocusedWallet();
|
||||
go.walletHome();
|
||||
|
|
@ -543,7 +562,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r
|
|||
$rootScope.$on('Local/Offline', function(event) {
|
||||
$log.debug('Offline event');
|
||||
self.isOffline = true;
|
||||
$timeout(function(){
|
||||
$timeout(function() {
|
||||
$rootScope.$apply();
|
||||
});
|
||||
});
|
||||
|
|
@ -563,6 +582,11 @@ angular.module('copayApp.controllers').controller('indexController', function($r
|
|||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
$rootScope.$on('Local/DeviceError', function(event, err) {
|
||||
self.deviceError(err);
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
$rootScope.$on('Local/ClientError', function(event, err) {
|
||||
if (err.code && err.code === 'NOTAUTHORIZED') {
|
||||
// Show not error, just redirect to home (where the recreate option is shown)
|
||||
|
|
@ -575,7 +599,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r
|
|||
var msg = 'Error at Wallet Service: ';
|
||||
if (err.message) msg = msg + err.message;
|
||||
else if (err.error) msg = msg + err.error;
|
||||
else msg = msg + err;
|
||||
else msg = msg + err;
|
||||
self.clientError(msg);
|
||||
}
|
||||
$rootScope.$apply();
|
||||
|
|
|
|||
4
src/js/controllers/preferencesAbout.js
Normal file
4
src/js/controllers/preferencesAbout.js
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('preferencesAbout',
|
||||
function() {});
|
||||
|
|
@ -49,7 +49,7 @@ angular.module('copayApp.controllers').controller('preferencesAltCurrencyControl
|
|||
|
||||
configService.set(opts, function(err) {
|
||||
if (err) console.log(err);
|
||||
$scope.$emit('Local/ConfigurationUpdated');
|
||||
$scope.$emit('Local/UnitSettingUpdated');
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ angular.module('copayApp.controllers').controller('preferencesBwsUrlController',
|
|||
|
||||
configService.set(opts, function(err) {
|
||||
if (err) console.log(err);
|
||||
$scope.$emit('Local/BWSUpdated');
|
||||
applicationService.restart(true);
|
||||
go.walletHome();
|
||||
$scope.$emit('Local/ConfigurationUpdated');
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,10 @@ angular.module('copayApp.controllers').controller('preferencesColorController',
|
|||
opts.colorFor[walletId] = color;
|
||||
|
||||
configService.set(opts, function(err) {
|
||||
if (err) console.log(err);
|
||||
if (err) {
|
||||
$scope.$emit('Local/DeviceError', err);
|
||||
return;
|
||||
}
|
||||
self.color = color;
|
||||
$scope.$emit('Local/ColorUpdated');
|
||||
});
|
||||
|
|
|
|||
22
src/js/controllers/preferencesLogs.js
Normal file
22
src/js/controllers/preferencesLogs.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('preferencesLogs',
|
||||
function(historicLog, isCordova) {
|
||||
this.logs = historicLog.get();
|
||||
this.isCordova = isCordova;
|
||||
|
||||
this.sendLogs = function() {
|
||||
var body = 'Copay Session Logs\n Be careful, this could contain sensitive private data\n\n';
|
||||
body += '\n\n';
|
||||
body += this.logs.map(function(v) {
|
||||
return v.msg;
|
||||
}).join('\n');
|
||||
|
||||
var properties = {
|
||||
subject: 'Copay Logs',
|
||||
body: body,
|
||||
isHtml: false
|
||||
};
|
||||
window.plugin.email.open(properties);
|
||||
};
|
||||
});
|
||||
|
|
@ -52,7 +52,7 @@ angular.module('copayApp.controllers').controller('preferencesUnitController',
|
|||
|
||||
configService.set(opts, function(err) {
|
||||
if (err) console.log(err);
|
||||
$scope.$emit('Local/ConfigurationUpdated');
|
||||
$scope.$emit('Local/UnitSettingUpdated');
|
||||
});
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,9 +16,47 @@ if (window && window.navigator) {
|
|||
//Setting up route
|
||||
angular
|
||||
.module('copayApp')
|
||||
.config(function(bwcServiceProvider, $stateProvider, $urlRouterProvider) {
|
||||
.config(function(historicLogProvider, $provide, $logProvider, $stateProvider, $urlRouterProvider) {
|
||||
$urlRouterProvider.otherwise('/');
|
||||
|
||||
$logProvider.debugEnabled(true);
|
||||
$provide.decorator('$log', ['$delegate',
|
||||
function($delegate) {
|
||||
var historicLog = historicLogProvider.$get();
|
||||
|
||||
['debug', 'info', 'warn', 'error', 'log'].forEach(function(level) {
|
||||
var orig = $delegate[level];
|
||||
$delegate[level] = function() {
|
||||
var args = [].slice.call(arguments);
|
||||
args = args.map(function(v) {
|
||||
try {
|
||||
if (typeof v == 'undefined') v = 'undefined';
|
||||
if (typeof v == 'object') {
|
||||
v = JSON.stringify(v);
|
||||
}
|
||||
v = v.toString();
|
||||
if (v.length > 200)
|
||||
v = v.substr(0, 197) + '...';
|
||||
} catch (e) {
|
||||
console.log('Error at log decorator:', e);
|
||||
v = 'undefined';
|
||||
}
|
||||
return v;
|
||||
});
|
||||
try {
|
||||
if (window.cordova)
|
||||
console.log(args.join(' '));
|
||||
orig.apply(null, args)
|
||||
historicLog.add(level, args.join(' '));
|
||||
} catch (e) {
|
||||
console.log('Error at log decorator:', e);
|
||||
}
|
||||
};
|
||||
});
|
||||
return $delegate;
|
||||
}
|
||||
]);
|
||||
|
||||
$stateProvider
|
||||
.state('splash', {
|
||||
url: '/splash',
|
||||
|
|
@ -305,6 +343,42 @@ angular
|
|||
}
|
||||
}
|
||||
})
|
||||
.state('about', {
|
||||
url: '/about',
|
||||
templateUrl: 'views/preferencesAbout.html',
|
||||
walletShouldBeComplete: true,
|
||||
needProfile: true,
|
||||
views: {
|
||||
'main': {
|
||||
templateUrl: 'views/preferencesAbout.html'
|
||||
},
|
||||
'topbar': {
|
||||
templateUrl: 'views/includes/topbar.html',
|
||||
controller: function($scope) {
|
||||
$scope.titleSection = 'About';
|
||||
$scope.goBackToState = 'preferences';
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.state('logs', {
|
||||
url: '/logs',
|
||||
templateUrl: 'views/preferencesLogs.html',
|
||||
walletShouldBeComplete: true,
|
||||
needProfile: true,
|
||||
views: {
|
||||
'main': {
|
||||
templateUrl: 'views/preferencesLogs.html'
|
||||
},
|
||||
'topbar': {
|
||||
templateUrl: 'views/includes/topbar.html',
|
||||
controller: function($scope) {
|
||||
$scope.titleSection = 'Logs';
|
||||
$scope.goBackToState = 'about';
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.state('backup', {
|
||||
url: '/backup',
|
||||
templateUrl: 'views/backup.html',
|
||||
|
|
@ -361,9 +435,9 @@ angular
|
|||
case 'resume':
|
||||
$scope.$emit('Local/Resume');
|
||||
break;
|
||||
// case 'online':
|
||||
// // $scope.$emit('Local/Online');
|
||||
// break;
|
||||
// case 'online':
|
||||
// // $scope.$emit('Local/Online');
|
||||
// break;
|
||||
case 'offline':
|
||||
$scope.$emit('Local/Offline');
|
||||
break;
|
||||
|
|
@ -376,10 +450,7 @@ angular
|
|||
});
|
||||
})
|
||||
.run(function($rootScope, $state, $log, gettextCatalog, uriHandler, isCordova, amMoment, profileService) {
|
||||
|
||||
console.log('Attaching FastClick');
|
||||
FastClick.attach(document.body);
|
||||
|
||||
|
||||
// Auto-detect browser language
|
||||
var userLang, androidLang;
|
||||
|
|
@ -413,6 +484,8 @@ angular
|
|||
preferencesUnit: 12,
|
||||
preferencesAltCurrency: 12,
|
||||
preferencesBwsUrl: 12,
|
||||
about: 12,
|
||||
logs: 13,
|
||||
add: 0,
|
||||
create: 12,
|
||||
join: 12,
|
||||
|
|
@ -434,18 +507,21 @@ angular
|
|||
|
||||
if (!profileService.profile && toState.needProfile) {
|
||||
|
||||
// Give us time to open / create the profile
|
||||
event.preventDefault();
|
||||
|
||||
// Try to open local profile
|
||||
profileService.loadAndBindProfile(function(err) {
|
||||
if (err) {
|
||||
if (err.message.match('NOPROFILE')) {
|
||||
$log.debug('No profile... redirecting');
|
||||
$state.transitionTo('splash');
|
||||
event.preventDefault();
|
||||
} else {
|
||||
throw new Error(err); // TODO
|
||||
}
|
||||
} else {
|
||||
// Profile was loaded
|
||||
$log.debug('Profile loaded ... Starting UX.');
|
||||
$state.transitionTo(toState, toParams);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.services').factory('configService', function(localStorageService, lodash, bwcService) {
|
||||
angular.module('copayApp.services').factory('configService', function(storageService, lodash, $log) {
|
||||
var root = {};
|
||||
|
||||
var defaultConfig = {
|
||||
|
|
@ -15,18 +15,6 @@ angular.module('copayApp.services').factory('configService', function(localStora
|
|||
url: 'https://bws.bitpay.com/bws/api',
|
||||
},
|
||||
|
||||
// insight
|
||||
insight: {
|
||||
testnet: {
|
||||
url: 'https://test-insight.bitpay.com:443',
|
||||
transports: ['polling'],
|
||||
},
|
||||
livenet: {
|
||||
url: 'https://insight.bitpay.com:443',
|
||||
transports: ['polling'],
|
||||
},
|
||||
},
|
||||
|
||||
// wallet default config
|
||||
wallet: {
|
||||
requiredCopayers: 2,
|
||||
|
|
@ -44,12 +32,6 @@ angular.module('copayApp.services').factory('configService', function(localStora
|
|||
}
|
||||
},
|
||||
|
||||
// local encryption/security config
|
||||
passphraseConfig: {
|
||||
iterations: 5000,
|
||||
storageSalt: 'mjuBtGybi/4=',
|
||||
},
|
||||
|
||||
rates: {
|
||||
url: 'https://insight.bitpay.com:443/api/rates',
|
||||
},
|
||||
|
|
@ -66,8 +48,8 @@ angular.module('copayApp.services').factory('configService', function(localStora
|
|||
};
|
||||
|
||||
root.get = function(cb) {
|
||||
localStorageService.get('config', function(err, localConfig) {
|
||||
|
||||
storageService.getConfig(function(err, localConfig) {
|
||||
if (localConfig) {
|
||||
configCache = JSON.parse(localConfig);
|
||||
|
||||
|
|
@ -80,16 +62,16 @@ angular.module('copayApp.services').factory('configService', function(localStora
|
|||
}
|
||||
|
||||
} else {
|
||||
configCache = defaultConfig;
|
||||
configCache = lodash.clone(defaultConfig);
|
||||
};
|
||||
|
||||
$log.debug('Preferences read:', configCache)
|
||||
return cb(err, configCache);
|
||||
});
|
||||
};
|
||||
|
||||
root.set = function(newOpts, cb) {
|
||||
var config = defaultConfig;
|
||||
localStorageService.get('config', function(err, oldOpts) {
|
||||
storageService.getConfig(function(err, oldOpts) {
|
||||
if (lodash.isString(oldOpts)) {
|
||||
oldOpts = JSON.parse(oldOpts);
|
||||
}
|
||||
|
|
@ -102,23 +84,19 @@ angular.module('copayApp.services').factory('configService', function(localStora
|
|||
lodash.merge(config, oldOpts, newOpts);
|
||||
configCache = config;
|
||||
|
||||
localStorageService.set('config', JSON.stringify(config), cb);
|
||||
storageService.storeConfig(JSON.stringify(config), cb);
|
||||
});
|
||||
};
|
||||
|
||||
root.reset = function(cb) {
|
||||
localStorageService.remove('config', cb);
|
||||
configCache = lodash.clone(defaultConfig);
|
||||
storageService.removeConfig(cb);
|
||||
};
|
||||
|
||||
root.getDefaults = function() {
|
||||
return defaultConfig;
|
||||
return lodash.clone(defaultConfig);
|
||||
};
|
||||
|
||||
root.get(function(err, c) {
|
||||
if (err) throw Error(err);
|
||||
bwcService.setBaseUrl(c.bws.url);
|
||||
bwcService.setTransports(['polling']);
|
||||
});
|
||||
|
||||
return root;
|
||||
});
|
||||
|
|
|
|||
145
src/js/services/fileStorage.js
Normal file
145
src/js/services/fileStorage.js
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.services')
|
||||
.factory('fileStorageService', function(lodash, $log) {
|
||||
var root = {},
|
||||
fs;
|
||||
|
||||
|
||||
root.init = function(cb) {
|
||||
if (fs) return cb(null, fs);
|
||||
|
||||
function onFileSystemSuccess(fileSystem) {
|
||||
console.log('File system started: ', fileSystem.name, fileSystem.root.name);
|
||||
fs = fileSystem;
|
||||
return cb(null, fs);
|
||||
}
|
||||
|
||||
function fail(evt) {
|
||||
var msg = 'Could not init file system: ' + evt.target.error.code;
|
||||
console.log(msg);
|
||||
return cb(msg);
|
||||
};
|
||||
|
||||
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFileSystemSuccess, fail);
|
||||
};
|
||||
|
||||
|
||||
root.get = function(k, cb) {
|
||||
root.init(function(err, fs) {
|
||||
if (err) return cb(err);
|
||||
root.getDir(function(err, dir) {
|
||||
if (err) return cb(err);
|
||||
$log.debug(".get: Got main dir:", dir.nativeURL);
|
||||
dir.getFile(k, {
|
||||
create: false,
|
||||
}, function(fileEntry) {
|
||||
if (!fileEntry) return cb();
|
||||
fileEntry.file(function(file) {
|
||||
var reader = new FileReader();
|
||||
|
||||
reader.onloadend = function(e) {
|
||||
if (this.result)
|
||||
$log.debug("Read: ", this.result);
|
||||
return cb(null, this.result)
|
||||
}
|
||||
|
||||
reader.readAsText(file);
|
||||
});
|
||||
}, function(err) {
|
||||
// Not found
|
||||
if (err.code == 1) return cb();
|
||||
else return cb(err);
|
||||
});
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
root.set = function(k, v, cb) {
|
||||
root.init(function(err, fs) {
|
||||
if (err) return cb(err);
|
||||
root.getDir(function(err, dir) {
|
||||
if (err) return cb(err);
|
||||
$log.debug(".set: Got main dir:", dir.nativeURL);
|
||||
dir.getFile(k, {
|
||||
create: true,
|
||||
}, function(fileEntry) {
|
||||
// Create a FileWriter object for our FileEntry (log.txt).
|
||||
fileEntry.createWriter(function(fileWriter) {
|
||||
|
||||
fileWriter.onwriteend = function(e) {
|
||||
console.log('Write completed.');
|
||||
return cb();
|
||||
};
|
||||
|
||||
fileWriter.onerror = function(e) {
|
||||
console.log('Write failed: ' + e.toString());
|
||||
return cb('Fail to write:', e.toString());
|
||||
};
|
||||
|
||||
if (lodash.isObject(v))
|
||||
v = JSON.stringify(v);
|
||||
|
||||
$log.debug('Writing:', k, v);
|
||||
var blob = new Blob([v], {
|
||||
type: "text/plain"
|
||||
});
|
||||
fileWriter.write(blob);
|
||||
|
||||
}, cb);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// See https://github.com/apache/cordova-plugin-file/#where-to-store-files
|
||||
root.getDir = function(cb) {
|
||||
if (!cordova.file) {
|
||||
return cb('Could not write on device storage');
|
||||
}
|
||||
|
||||
var url = cordova.file.dataDirectory;
|
||||
// This could be needed for windows
|
||||
// if (cordova.file === undefined) {
|
||||
// url = 'ms-appdata:///local/';
|
||||
window.resolveLocalFileSystemURL(url, function(dir) {
|
||||
return cb(null, dir);
|
||||
});
|
||||
};
|
||||
|
||||
root.remove = function(k, cb) {
|
||||
root.init(function(err, fs) {
|
||||
if (err) return cb(err);
|
||||
root.getDir(function(err, dir) {
|
||||
if (err) return cb(err);
|
||||
dir.getFile(k, {
|
||||
create: false,
|
||||
}, function(fileEntry) {
|
||||
// Create a FileWriter object for our FileEntry (log.txt).
|
||||
fileEntry.remove(function() {
|
||||
console.log('File removed.');
|
||||
return cb();
|
||||
}, cb, cb);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Same as setItem, but fails if an item already exists
|
||||
*/
|
||||
root.create = function(name, value, callback) {
|
||||
root.get(name,
|
||||
function(err, data) {
|
||||
if (data) {
|
||||
return callback('EEXISTS');
|
||||
} else {
|
||||
return root.set(name, value, callback);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
return root;
|
||||
});
|
||||
19
src/js/services/historicLog.js
Normal file
19
src/js/services/historicLog.js
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
'use strict';
|
||||
var logs = [];
|
||||
angular.module('copayApp.services')
|
||||
.factory('historicLog', function historicLog() {
|
||||
var root = {};
|
||||
|
||||
root.add = function(level, msg) {
|
||||
logs.push({
|
||||
level: level,
|
||||
msg: msg,
|
||||
});
|
||||
};
|
||||
|
||||
root.get = function() {
|
||||
return logs;
|
||||
};
|
||||
|
||||
return root;
|
||||
});
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.services').value('isChromeApp', window.chrome && chrome.runtime && chrome.runtime.id);
|
||||
angular.module('copayApp.services').value('isChromeApp', !!(window.chrome && chrome.runtime && chrome.runtime.id));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.services')
|
||||
.factory('localStorageService', function() {
|
||||
|
||||
var isChromeApp = typeof window !== "undefined" && window.chrome && chrome.runtime && chrome.runtime.id;
|
||||
.factory('localStorageService', function(isChromeApp, $timeout) {
|
||||
var root = {};
|
||||
|
||||
var ls = ((typeof localStorage !== "undefined") ? localStorage : null);
|
||||
var ls = ((typeof window.localStorage !== "undefined") ? window.localStorage : null);
|
||||
|
||||
if (isChromeApp && !ls) {
|
||||
ls = localStorage = chrome.storage.local;
|
||||
|
|
@ -14,9 +11,7 @@ angular.module('copayApp.services')
|
|||
}
|
||||
|
||||
if (!ls)
|
||||
throw new Error('localstorage not available, cannot run plugin');
|
||||
|
||||
root.init = function() {};
|
||||
throw new Error('localstorage not available');
|
||||
|
||||
root.get = function(k, cb) {
|
||||
if (isChromeApp) {
|
||||
|
|
@ -67,26 +62,5 @@ angular.module('copayApp.services')
|
|||
|
||||
};
|
||||
|
||||
root.clear = function(cb) {
|
||||
// NOP
|
||||
return cb();
|
||||
};
|
||||
|
||||
root.list = function(cb) {
|
||||
if (isChromeApp) {
|
||||
chrome.storage.local.get(null, function(items) {
|
||||
return cb(null, lodash.keys(items));
|
||||
});
|
||||
} else {
|
||||
var ret = [];
|
||||
var l = ls.length;
|
||||
|
||||
for (var i = 0; i < l; i++)
|
||||
ret.push(ls.key(i));
|
||||
|
||||
return cb(null, ret);
|
||||
}
|
||||
};
|
||||
|
||||
return root;
|
||||
});
|
||||
|
|
|
|||
8
src/js/services/logHeader.js
Normal file
8
src/js/services/logHeader.js
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
'use strict';
|
||||
angular.module('copayApp.services')
|
||||
.factory('logHeader', function($log, isChromeApp, isCordova) {
|
||||
$log.info('Starting Copay v' + window.version + ' #' + window.commitHash);
|
||||
$log.info('Client: isCordova:', isCordova, 'isChromeApp:', isChromeApp);
|
||||
$log.info('Navigator:', navigator.userAgent);
|
||||
return {};
|
||||
});
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
'use strict';
|
||||
angular.module('copayApp.services')
|
||||
.factory('profileService', function profileServiceFactory($rootScope, $location, $timeout, $filter, $log, lodash, pluginManager, balanceService, applicationService, storageService, bwcService, configService, notificationService, notification, isChromeApp) {
|
||||
.factory('profileService', function profileServiceFactory($rootScope, $location, $timeout, $filter, $log, lodash, storageService, bwcService, configService, notificationService, isChromeApp, isCordova) {
|
||||
|
||||
var root = {};
|
||||
|
||||
|
|
@ -110,11 +110,20 @@ angular.module('copayApp.services')
|
|||
};
|
||||
|
||||
|
||||
root.applyConfig = function() {
|
||||
var config = configService.getSync();
|
||||
$log.debug('Applying preferences');
|
||||
bwcService.setBaseUrl(config.bws.url);
|
||||
bwcService.setTransports(['polling']);
|
||||
};
|
||||
|
||||
root.bindProfile = function(profile, cb) {
|
||||
root.profile = profile;
|
||||
|
||||
configService.get(function(err) {
|
||||
$log.debug('Preferences read');
|
||||
if (err) return cb(err);
|
||||
root.applyConfig();
|
||||
$rootScope.$emit('Local/DefaultLanguage');
|
||||
root.setWalletClients();
|
||||
storageService.getFocusedWalletId(function(err, focusedWalletId) {
|
||||
|
|
@ -124,16 +133,27 @@ angular.module('copayApp.services')
|
|||
});
|
||||
};
|
||||
|
||||
|
||||
root.loadAndBindProfile = function(cb) {
|
||||
storageService.getProfile(function(err, profile) {
|
||||
if (err) {
|
||||
notification.error('CRITICAL ERROR: ' + err);
|
||||
$rootScope.$emit('Local/DeviceError', err);
|
||||
return cb(err);
|
||||
}
|
||||
if (!profile) return cb(new Error('NOPROFILE: No profile'));
|
||||
if (!profile) {
|
||||
// Migration??
|
||||
storageService.tryToMigrate(function(err, migratedProfile) {
|
||||
if (err) return cb(err);
|
||||
if (!migratedProfile)
|
||||
return cb(new Error('NOPROFILE: No profile'));
|
||||
|
||||
profile = migratedProfile;
|
||||
return root.bindProfile(profile, cb);
|
||||
})
|
||||
} else {
|
||||
$log.debug('Profile read');
|
||||
return root.bindProfile(profile, cb);
|
||||
}
|
||||
|
||||
return root.bindProfile(profile, cb);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -188,7 +208,6 @@ angular.module('copayApp.services')
|
|||
return cb('Could not join using the specified extended private key');
|
||||
}
|
||||
}
|
||||
// TODO name
|
||||
walletClient.joinWallet(opts.secret, opts.myName || 'me', function(err) {
|
||||
if (err) return cb(err);
|
||||
|
||||
|
|
@ -260,11 +279,17 @@ angular.module('copayApp.services')
|
|||
|
||||
|
||||
root.create = function(cb) {
|
||||
root._createNewProfile(function(err, p) {
|
||||
if (err) return cb(err);
|
||||
root.bindProfile(p, function(err) {
|
||||
storageService.storeNewProfile(p, function(err) {
|
||||
return cb(err);
|
||||
$log.info('Creating profile');
|
||||
configService.get(function(err) {
|
||||
root.applyConfig();
|
||||
root._createNewProfile(function(err, p) {
|
||||
if (err) return cb(err);
|
||||
|
||||
console.log('[profileService.js.287]'); //TODO
|
||||
root.bindProfile(p, function(err) {
|
||||
storageService.storeNewProfile(p, function(err) {
|
||||
return cb(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,9 +1,17 @@
|
|||
'use strict';
|
||||
angular.module('copayApp.services')
|
||||
.factory('storageService', function(localStorageService, sjcl, $log, lodash) {
|
||||
.factory('storageService', function(logHeader, fileStorageService, localStorageService, sjcl, $log, lodash, isCordova) {
|
||||
|
||||
var root = {};
|
||||
|
||||
// File storage is not supported for writting according to
|
||||
// https://github.com/apache/cordova-plugin-file/#supported-platforms
|
||||
var shouldUseFileStorage = isCordova && !isMobile.Windows();
|
||||
$log.debug('Using file storage:', shouldUseFileStorage);
|
||||
|
||||
|
||||
var storage = shouldUseFileStorage ? fileStorageService : localStorageService;
|
||||
|
||||
var getUUID = function(cb) {
|
||||
// TO SIMULATE MOBILE
|
||||
//return cb('hola');
|
||||
|
|
@ -46,21 +54,57 @@ angular.module('copayApp.services')
|
|||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
root.tryToMigrate = function(cb) {
|
||||
if (!shouldUseFileStorage) return cb();
|
||||
|
||||
localStorageService.get('profile', function(err, str) {
|
||||
if (err) return cb(err);
|
||||
if (!str) return cb();
|
||||
|
||||
$log.info('Starting Migration profile to File storage...')
|
||||
|
||||
fileStorageService.create('profile', str, function(err) {
|
||||
if (err) cb(err);
|
||||
$log.info('Profile Migrated successfully');
|
||||
|
||||
localStorageService.get('config', function(err, c) {
|
||||
if (err) return cb(err);
|
||||
if (!c) return root.getProfile(cb);
|
||||
|
||||
fileStorageService.create('config', c, function(err) {
|
||||
|
||||
if (err) {
|
||||
$log.info('Error migrating config: ignoring', err);
|
||||
return root.getProfile(cb);
|
||||
}
|
||||
$log.info('Config Migrated successfully');
|
||||
return root.getProfile(cb);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
root.storeNewProfile = function(profile, cb) {
|
||||
encryptOnMobile(profile.toObj(), function(err, x) {
|
||||
localStorageService.create('profile', x, cb);
|
||||
storage.create('profile', x, cb);
|
||||
});
|
||||
};
|
||||
|
||||
root.storeProfile = function(profile, cb) {
|
||||
encryptOnMobile(profile.toObj(), function(err, x) {
|
||||
localStorageService.set('profile', x, cb);
|
||||
storage.set('profile', x, cb);
|
||||
});
|
||||
};
|
||||
|
||||
root.getProfile = function(cb) {
|
||||
localStorageService.get('profile', function(err, str) {
|
||||
if (err || !str) return cb(err);
|
||||
storage.get('profile', function(err, str) {
|
||||
|
||||
if (err || !str)
|
||||
// Migrate ?
|
||||
return cb(err);
|
||||
|
||||
decryptOnMobile(str, function(err, str) {
|
||||
if (err) return cb(err);
|
||||
|
|
@ -76,35 +120,48 @@ angular.module('copayApp.services')
|
|||
};
|
||||
|
||||
root.deleteProfile = function(cb) {
|
||||
localStorageService.remove('profile', cb);
|
||||
storage.remove('profile', cb);
|
||||
};
|
||||
|
||||
root.storeFocusedWalletId = function(id, cb) {
|
||||
localStorageService.set('focusedWalletId', id, cb);
|
||||
storage.set('focusedWalletId', id, cb);
|
||||
};
|
||||
|
||||
root.getFocusedWalletId = function(cb) {
|
||||
localStorageService.get('focusedWalletId', cb);
|
||||
storage.get('focusedWalletId', cb);
|
||||
};
|
||||
|
||||
root.getLastAddress = function(walletId, cb) {
|
||||
localStorageService.get('lastAddress-' + walletId, cb);
|
||||
storage.get('lastAddress-' + walletId, cb);
|
||||
};
|
||||
|
||||
root.storeLastAddress = function(walletId, address, cb) {
|
||||
localStorageService.set('lastAddress-' + walletId, address, cb);
|
||||
storage.set('lastAddress-' + walletId, address, cb);
|
||||
};
|
||||
|
||||
root.clearLastAddress = function(walletId, cb) {
|
||||
localStorageService.remove('lastAddress-' + walletId, cb);
|
||||
storage.remove('lastAddress-' + walletId, cb);
|
||||
};
|
||||
|
||||
root.setBackupFlag = function(walletId, cb) {
|
||||
localStorageService.set('backup-' + walletId, Date.now(), cb);
|
||||
storage.set('backup-' + walletId, Date.now(), cb);
|
||||
};
|
||||
|
||||
root.getBackupFlag = function(walletId, cb) {
|
||||
localStorageService.get('backup-' + walletId, cb);
|
||||
storage.get('backup-' + walletId, cb);
|
||||
};
|
||||
|
||||
root.getConfig = function(cb) {
|
||||
storage.get('config', cb);
|
||||
};
|
||||
|
||||
root.storeConfig = function(val, cb) {
|
||||
$log.debug('Storing Preferences', val);
|
||||
storage.set('config', val, cb);
|
||||
};
|
||||
|
||||
root.clearConfig = function(cb) {
|
||||
storage.remove('config', cb);
|
||||
};
|
||||
|
||||
return root;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue