From bbd00cf2d606af32474e9f8402471dd10a4bcd87 Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Thu, 27 Nov 2014 18:05:17 -0300 Subject: [PATCH 1/8] Creating a chrome app --- browser-extensions/chrome/initial.js | 8 ++++++++ browser-extensions/chrome/manifest.json | 15 ++++++--------- browser-extensions/include | 1 + initial.js | 8 ++++++++ 4 files changed, 23 insertions(+), 9 deletions(-) create mode 100644 browser-extensions/chrome/initial.js create mode 100644 initial.js diff --git a/browser-extensions/chrome/initial.js b/browser-extensions/chrome/initial.js new file mode 100644 index 000000000..fc12301b5 --- /dev/null +++ b/browser-extensions/chrome/initial.js @@ -0,0 +1,8 @@ +chrome.app.runtime.onLaunched.addListener(function() { + chrome.app.window.create('index.html', { + 'bounds': { + 'width': 1200, + 'height': 800 + } + }); +}); diff --git a/browser-extensions/chrome/manifest.json b/browser-extensions/chrome/manifest.json index 7b8e6517f..55b3ea479 100644 --- a/browser-extensions/chrome/manifest.json +++ b/browser-extensions/chrome/manifest.json @@ -3,17 +3,14 @@ "name": "Copay", "description": "A multisignature bitcoin wallet", "version": "APP_VERSION", - "homepage_url": "http://bitpay.github.io/copay", - "browser_action": { - "default_title": "Copay", - "default_icon": "img/icons/icon.png", - "default_popup": "popup.html" - }, - "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'", "permissions": [ - "tabs", "storage", "notifications" + "storage", "notifications" ], - "options_page": "index.html#/settings", + "app": { + "background": { + "scripts": ["initial.js"] + } + }, "icons": { "128": "img/icons/icon.png" } diff --git a/browser-extensions/include b/browser-extensions/include index 346645ba0..f4860b28b 100644 --- a/browser-extensions/include +++ b/browser-extensions/include @@ -6,6 +6,7 @@ sound views config.js init.js +initial.js version.js index.html popup.html diff --git a/initial.js b/initial.js new file mode 100644 index 000000000..5af877804 --- /dev/null +++ b/initial.js @@ -0,0 +1,8 @@ +chrome.app.runtime.onLaunched.addListener(function() { + chrome.app.window.create('index.html', { + 'bounds': { + 'width': 1280, + 'height': 800 + } + }); +}); From 40910c3b34e96ad8f9ddbba587c0aa00c9ca9a39 Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Mon, 1 Dec 2014 11:19:18 -0300 Subject: [PATCH 2/8] Solving chrome app problems --- browser-extensions/chrome/manifest.json | 3 +- init.js | 11 +- initial.js | 4 +- js/app.js | 23 ++++- js/controllers/head.js | 18 ++-- js/controllers/settings.js | 12 +++ js/controllers/unsupported.js | 9 ++ js/plugins/LocalStorage.js | 129 +++++++++++++++++++----- js/routes.js | 13 +++ js/services/notifications.js | 26 ++++- js/util/log.js | 3 +- 11 files changed, 205 insertions(+), 46 deletions(-) diff --git a/browser-extensions/chrome/manifest.json b/browser-extensions/chrome/manifest.json index 55b3ea479..e9f0361c2 100644 --- a/browser-extensions/chrome/manifest.json +++ b/browser-extensions/chrome/manifest.json @@ -4,7 +4,8 @@ "description": "A multisignature bitcoin wallet", "version": "APP_VERSION", "permissions": [ - "storage", "notifications" + "storage", + "notifications" ], "app": { "background": { diff --git a/init.js b/init.js index c4cb7298a..5376f93de 100644 --- a/init.js +++ b/init.js @@ -1,7 +1,12 @@ -var ld = (document.all); +var isChromeApp = window.chrome && chrome.runtime && chrome.runtime.id; +var ld; +if (!isChromeApp) { + ld = (document.all); +} + var ns4 = document.layers; -var ns6 = document.getElementById && !document.all; -var ie4 = document.all; +var ns6 = !isChromeApp && document.getElementById && !document.all; +var ie4 = !isChromeApp && document.all; if (ns4) { ld = document.loading; } else if (ns6) { diff --git a/initial.js b/initial.js index 5af877804..728ed4f7f 100644 --- a/initial.js +++ b/initial.js @@ -1,8 +1,8 @@ chrome.app.runtime.onLaunched.addListener(function() { chrome.app.window.create('index.html', { 'bounds': { - 'width': 1280, - 'height': 800 + 'width': 1024, + 'height': 768 } }); }); diff --git a/js/app.js b/js/app.js index 4ff3e5ba9..c2d32926f 100644 --- a/js/app.js +++ b/js/app.js @@ -3,7 +3,23 @@ var copay = require('copay'); var _ = require('lodash'); var config = defaultConfig; -var localConfig = JSON.parse(localStorage.getItem('config')); + +var localStorage; +if (window.chrome && chrome.runtime && chrome.runtime.id) { + console.log('Is a chrome app!'); + localStorage = chrome.storage.local; + console.log('localStorage', localStorage); +} else { + console.log('Is web!'); + localStorage = window.localStorage; +} + +var localConfig; +if (localStorage) { + localConfig = JSON.parse(localStorage.getItem('config')); +} + + var defaults = JSON.parse(JSON.stringify(defaultConfig)); if (localConfig) { @@ -47,9 +63,10 @@ copayApp.config(function($sceDelegateProvider) { }); angular.module('ui.gravatar').config([ - 'gravatarServiceProvider', function(gravatarServiceProvider) { + 'gravatarServiceProvider', + function(gravatarServiceProvider) { gravatarServiceProvider.defaults = { - size : 35 + size: 35 }; // Use https endpoint gravatarServiceProvider.secure = true; diff --git a/js/controllers/head.js b/js/controllers/head.js index 58ff90dbc..047b4caca 100644 --- a/js/controllers/head.js +++ b/js/controllers/head.js @@ -4,6 +4,8 @@ angular.module('copayApp.controllers').controller('HeadController', function($sc $scope.username = $rootScope.iden.getName(); $scope.hoverMenu = false; + console.log('$scope.username', $scope.username); + $scope.hoverIn = function() { this.hoverMenu = true; }; @@ -30,14 +32,16 @@ angular.module('copayApp.controllers').controller('HeadController', function($sc } }; - // Ensures a graceful disconnect - window.onbeforeunload = function() { - $scope.signout(); - }; - $scope.$on('$destroy', function() { - window.onbeforeunload = undefined; - }); + //mpando restore after solve some chrome app error + // Ensures a graceful disconnect + // window.onbeforeunload = function() { + // $scope.signout(); + // }; + + // $scope.$on('$destroy', function() { + // window.onbeforeunload = undefined; + // }); $scope.init = function() { if (!$rootScope.wallet) return; diff --git a/js/controllers/settings.js b/js/controllers/settings.js index 012605b0a..894b40702 100644 --- a/js/controllers/settings.js +++ b/js/controllers/settings.js @@ -7,6 +7,18 @@ angular.module('copayApp.controllers').controller('SettingsController', function $scope.insightTestnet = config.network.testnet.url; $scope.defaultLogLevel = config.logLevel || 'log'; + + var localStorage; + + var isChromeApp = window.chrome && chrome.runtime && chrome.runtime.id; + if (isChromeApp) { + console.log('Is a chrome app!'); + localStorage = chrome.storage.local; + } else { + console.log('Is web!'); + localStorage = window.localStorage; + } + var logLevels = copay.logger.getLevels(); $scope.availableLogLevels = []; diff --git a/js/controllers/unsupported.js b/js/controllers/unsupported.js index 2617a81df..714b01c19 100644 --- a/js/controllers/unsupported.js +++ b/js/controllers/unsupported.js @@ -2,6 +2,15 @@ angular.module('copayApp.controllers').controller('UnsupportedController', function($scope, $location) { + + var localStorage; + if (window.chrome && chrome.runtime && chrome.runtime.id) { + console.log('Is a chrome app!'); + localStorage = chrome.storage.local; + } else { + console.log('Is web!'); + localStorage = window.localStorage; + } if (localStorage && localStorage.length > 0) { $location.path('/'); } diff --git a/js/plugins/LocalStorage.js b/js/plugins/LocalStorage.js index 8e4ee75e3..b0d852892 100644 --- a/js/plugins/LocalStorage.js +++ b/js/plugins/LocalStorage.js @@ -1,58 +1,133 @@ 'use strict'; var _ = require('lodash'); var preconditions = require('preconditions').singleton(); +var isChromeApp = window.chrome && chrome.runtime && chrome.runtime.id; -function LocalStorage(opts) { + +function LocalStorage() { this.type = 'DB'; - opts = opts || {}; - - this.ls = opts.ls - || ( (typeof localStorage !== 'undefined') ? localStorage : null ); + if (isChromeApp) { + localStorage = chrome.storage.local; + window.localStorage = chrome.storage.local; + } - preconditions.checkState(this.ls, + preconditions.checkState(typeof localStorage !== 'undefined', 'localstorage not available, cannot run plugin'); }; -LocalStorage.prototype.init = function() { -}; +LocalStorage.prototype.init = function() {}; LocalStorage.prototype.setCredentials = function(email, password, opts) { - // NOP + this.email = email; + this.password = password; }; -LocalStorage.prototype.getItem = function(k,cb) { - preconditions.checkArgument(_.isFunction(cb)); - return cb(null, this.ls.getItem(k)); +LocalStorage.prototype.getItem = function(k, cb) { + if (isChromeApp) { + chrome.storage.local.get(k, + function(data) { + //TODO check for errors + return cb(null, data[k]); + }); + } else { + return cb(null, localStorage.getItem(k)); + } }; /** * Same as setItem, but fails if an item already exists */ LocalStorage.prototype.createItem = function(name, value, callback) { - preconditions.checkArgument(_.isFunction(callback)); - if (this.ls.getItem(name)) { - return callback('EEXISTS'); + var self = this; + console.log('createItem '); + self.getItem(name, + function(err, data) { + console.log('error ', err); + console.log('data ', data); + if (data) { + return callback('EEXISTS'); + } else { + console.log('calling setitem '); + return self.setItem(name, value, callback); + } + }); +}; + +LocalStorage.prototype.setItem = function(k, v, cb) { + if (isChromeApp) { + console.log('.............key', k); + console.log('.............value', v); + + var obj = {}; + obj[k] = v; + + chrome.storage.local.set(obj, cb); + } else { + localStorage.setItem(k, v); + return cb(); } - return this.setItem(name, value, callback); + }; -LocalStorage.prototype.setItem = function(k,v,cb) { - preconditions.checkArgument(_.isFunction(cb)); - this.ls.setItem(k,v); +LocalStorage.prototype.removeItem = function(k, cb) { + if (isChromeApp) { + chrome.storage.remove(k, cb); + } else { + localStorage.removeItem(k); + return cb(); + } + +}; + +LocalStorage.prototype.clear = function(cb) { + if (isChromeApp) { + chrome.storage.clear(); + } else { + localStorage.clear(); + } return cb(); }; -LocalStorage.prototype.removeItem = function(k,cb) { - preconditions.checkArgument(_.isFunction(cb)); - this.ls.removeItem(k); - return cb(); +LocalStorage.prototype.allKeys = function(cb) { + + if (isChromeApp) { + chrome.storage.local.get(null, function(items) { + return cb(null, _.keys(items)); + }); + } else { + var ret = []; + var l = localStorage.length; + + for (var i = 0; i < l; i++) + ret.push(localStorage.key(i)); + + return cb(null, ret); + } }; -LocalStorage.prototype.clear = function(cb) { - preconditions.checkArgument(_.isFunction(cb)); - this.ls.clear(); - return cb(); +LocalStorage.prototype.getFirst = function(prefix, opts, cb) { + opts = opts || {}; + var that = this; + + this.allKeys(function(err, allKeys) { + var keys = _.filter(allKeys, function(k) { + if ((k === prefix) || k.indexOf(prefix) === 0) return true; + }); + + if (keys.length === 0) + return cb(new Error('not found')); + + if (opts.onlyKey) + return cb(null, null, keys[0]); + + that.getItem(keys[0], function(err, data) { + if (err) { + return cb(err); + } + return cb(null, data, keys[0]); + }); + }); }; module.exports = LocalStorage; diff --git a/js/routes.js b/js/routes.js index 12d8b93f2..8f5bf78ba 100644 --- a/js/routes.js +++ b/js/routes.js @@ -118,6 +118,19 @@ angular uriHandler.register(); } $rootScope.$on('$routeChangeStart', function(event, next, current) { + + var localStorage; + if (window.chrome && chrome.runtime && chrome.runtime.id) { + console.log('Is a chrome app!'); + localStorage = chrome.storage.local; + + console.log('chrome.storage', chrome.storage); + console.log('localStorage', localStorage); + } else { + console.log('Is web!'); + localStorage = window.localStorage; + } + if (!localStorage || localStorage.length < 1) { $location.path('unsupported'); } else { diff --git a/js/services/notifications.js b/js/services/notifications.js index 3f5b324ea..cfb665938 100644 --- a/js/services/notifications.js +++ b/js/services/notifications.js @@ -4,9 +4,31 @@ angular.module('copayApp.services'). factory('notification', ['$timeout', function($timeout) { - var notifications = JSON.parse(localStorage.getItem('notifications')) || [], - queue = []; + var localStorage; + if (window.chrome && chrome.runtime && chrome.runtime.id) { + console.log('Is a chrome app!'); + localStorage = chrome.storage.local; + } else { + console.log('Is web!'); + localStorage = window.localStorage; + } + var notifications = []; + + if (window.chrome && chrome.runtime && chrome.runtime.id) { + localStorage.get('notifications', function(data) { + console.log('data', data); + if (data) { + notifications = JSON.parse(data); + } + }); + + } else { + notifications = JSON.parse(localStorage.getItem('notifications')) || []; + } + + + var queue = []; var settings = { info: { duration: 6000, diff --git a/js/util/log.js b/js/util/log.js index 220fc2a02..e5a71daa7 100644 --- a/js/util/log.js +++ b/js/util/log.js @@ -5,7 +5,7 @@ var ls; try { var LS = require('../js/plugins/LocalStorage'); ls = new LS(); -} catch(e) {}; +} catch (e) {}; /** * @desc @@ -126,6 +126,7 @@ var error = new Error(); var logLevel = config.logLevel || 'info'; + if (ls && ls.getItem) { ls.getItem("config", function(err, value) { if (err) return; From 834c57a51af86711787ee5b5a1ad8f57b6b1b26a Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Tue, 2 Dec 2014 10:40:24 -0300 Subject: [PATCH 3/8] Multiple fixes for chrome app --- browser-extensions/include | 1 + css/src/main.css | 2 ++ index.html | 1 + init.js | 12 ++++++++ initial.js | 4 +-- js/app.js | 54 +++++++++++++++++++++++++++++++++-- js/controllers/settings.js | 4 ++- js/controllers/unsupported.js | 2 +- js/models/Compatibility.js | 9 ++++++ js/plugins/LocalStorage.js | 1 + js/routes.js | 6 ++-- js/services/notifications.js | 2 +- 12 files changed, 88 insertions(+), 10 deletions(-) diff --git a/browser-extensions/include b/browser-extensions/include index f4860b28b..5a43929ed 100644 --- a/browser-extensions/include +++ b/browser-extensions/include @@ -13,3 +13,4 @@ popup.html lib/angular/angular-csp.css lib/angular/angular.min.js.map lib/angular-route/angular-route.min.js.map +lib/angular-touch/angular-touch.min.js.map diff --git a/css/src/main.css b/css/src/main.css index 4a4b32666..e83fc982d 100644 --- a/css/src/main.css +++ b/css/src/main.css @@ -22,6 +22,7 @@ color: #B7C2CD; } + #qr-canvas { display: none; } #qrcode-scanner-video { display: block; @@ -60,6 +61,7 @@ body, html{ height:100%; width:100%; color: #2C3E50; + -webkit-user-select: text; } header { diff --git a/index.html b/index.html index 5aac51371..b349ec383 100644 --- a/index.html +++ b/index.html @@ -21,6 +21,7 @@ +
Loading...
diff --git a/init.js b/init.js index 5376f93de..69fb26301 100644 --- a/init.js +++ b/init.js @@ -20,6 +20,18 @@ function init() { ld.visibility = "hidden"; } else if (ns6 || ie4) { ld.display = "none"; + } else { + console.log('Warning!! is a chrome app!'); + console.log('ns4', ns4); + console.log('ns6', ns6); + console.log('ie4', ie4); + + ld = document.loading; + + ld = document.getElementById("loading").style; + + ld.visibility = "hidden"; + ld.display = "none"; } } init(); diff --git a/initial.js b/initial.js index 728ed4f7f..fc12301b5 100644 --- a/initial.js +++ b/initial.js @@ -1,8 +1,8 @@ chrome.app.runtime.onLaunched.addListener(function() { chrome.app.window.create('index.html', { 'bounds': { - 'width': 1024, - 'height': 768 + 'width': 1200, + 'height': 800 } }); }); diff --git a/js/app.js b/js/app.js index c2d32926f..f6549f34a 100644 --- a/js/app.js +++ b/js/app.js @@ -4,19 +4,67 @@ var copay = require('copay'); var _ = require('lodash'); var config = defaultConfig; +var isChromeApp = window.chrome && chrome.runtime && chrome.runtime.id; + var localStorage; -if (window.chrome && chrome.runtime && chrome.runtime.id) { - console.log('Is a chrome app!'); +if (isChromeApp) { + var storage = chrome.storage.local; + + var myAccess = 'myAccess'; + + var obj = {}; + + obj[myAccess] = Math.floor((Math.random() * 1000) + 1);; + + storage.get(myAccess, function(result) { + console.log('Last access 1', JSON.stringify(myAccess), JSON.stringify(result)); + }); + + storage.set(obj); + + storage.get(myAccess, function(result) { + console.log('Last access 2', JSON.stringify(myAccess), JSON.stringify(result)); + }); + + + + console.log('Is a chrome app!...app.js'); + console.log('chrome.storage', chrome.storage); + chrome.storage.local.set({ + 'MiNombre': 'Matias' + }, function(done) { + console.log('Saving to local storage', done); + }); localStorage = chrome.storage.local; + + + console.log('localStorage', localStorage); } else { console.log('Is web!'); localStorage = window.localStorage; } +console.log('access to localStorage'); + var localConfig; if (localStorage) { - localConfig = JSON.parse(localStorage.getItem('config')); + + if (isChromeApp) { + var result; + localStorage.getItem('config', function(data) { + result = data; + }); + + console.log('retrieving data from local storage', result); + localConfig = JSON.parse(result); + } else { + localConfig = JSON.parse(localStorage.getItem('config')); + console.log('localStorage', localConfig); + } +} else { + + console.log('localStorage is null '); } diff --git a/js/controllers/settings.js b/js/controllers/settings.js index 894b40702..e3de9e3d7 100644 --- a/js/controllers/settings.js +++ b/js/controllers/settings.js @@ -12,7 +12,7 @@ angular.module('copayApp.controllers').controller('SettingsController', function var isChromeApp = window.chrome && chrome.runtime && chrome.runtime.id; if (isChromeApp) { - console.log('Is a chrome app!'); + console.log('Is a chrome app!...settings.js'); localStorage = chrome.storage.local; } else { console.log('Is web!'); @@ -92,6 +92,7 @@ angular.module('copayApp.controllers').controller('SettingsController', function plugins[$scope.selectedStorage.pluginName] = true; copay.logger.setLevel($scope.selectedLogLevel.name); + localstorageService.setItem('config', JSON.stringify({ network: insightSettings, version: copay.version, @@ -107,6 +108,7 @@ angular.module('copayApp.controllers').controller('SettingsController', function }), function() { applicationService.restart(); }); + }; diff --git a/js/controllers/unsupported.js b/js/controllers/unsupported.js index 714b01c19..661ca3141 100644 --- a/js/controllers/unsupported.js +++ b/js/controllers/unsupported.js @@ -5,7 +5,7 @@ angular.module('copayApp.controllers').controller('UnsupportedController', var localStorage; if (window.chrome && chrome.runtime && chrome.runtime.id) { - console.log('Is a chrome app!'); + console.log('Is a chrome app!..unssoported.js'); localStorage = chrome.storage.local; } else { console.log('Is web!'); diff --git a/js/models/Compatibility.js b/js/models/Compatibility.js index bab4f5b57..7a7c733d3 100644 --- a/js/models/Compatibility.js +++ b/js/models/Compatibility.js @@ -76,6 +76,15 @@ Compatibility._decrypt = function(base64, passphrase) { Compatibility._read = function(k, passphrase, cb) { preconditions.checkArgument(cb); + var localStorage; + if (window.chrome && chrome.runtime && chrome.runtime.id) { + console.log('Is a chrome app!..Compatibility.js'); + localStorage = chrome.storage.local; + } else { + console.log('Is web!'); + localStorage = window.localStorage; + } + var ret = localStorage.getItem(k); if (!ret) return cb(null); var ret = self._decrypt(ret, passphrase); diff --git a/js/plugins/LocalStorage.js b/js/plugins/LocalStorage.js index b0d852892..fc25aa894 100644 --- a/js/plugins/LocalStorage.js +++ b/js/plugins/LocalStorage.js @@ -7,6 +7,7 @@ var isChromeApp = window.chrome && chrome.runtime && chrome.runtime.id; function LocalStorage() { this.type = 'DB'; + if (isChromeApp) { localStorage = chrome.storage.local; window.localStorage = chrome.storage.local; diff --git a/js/routes.js b/js/routes.js index 8f5bf78ba..78609d2c1 100644 --- a/js/routes.js +++ b/js/routes.js @@ -119,12 +119,14 @@ angular } $rootScope.$on('$routeChangeStart', function(event, next, current) { + var localStorage; if (window.chrome && chrome.runtime && chrome.runtime.id) { - console.log('Is a chrome app!'); + console.log('Is a chrome app!...routes.js'); + console.log('chrome.storage', chrome.storage); + console.log('chrome.storage.local', chrome.storage.local); localStorage = chrome.storage.local; - console.log('chrome.storage', chrome.storage); console.log('localStorage', localStorage); } else { console.log('Is web!'); diff --git a/js/services/notifications.js b/js/services/notifications.js index cfb665938..42187f159 100644 --- a/js/services/notifications.js +++ b/js/services/notifications.js @@ -6,7 +6,7 @@ factory('notification', ['$timeout', var localStorage; if (window.chrome && chrome.runtime && chrome.runtime.id) { - console.log('Is a chrome app!'); + console.log('Is a chrome app!...notification.js'); localStorage = chrome.storage.local; } else { console.log('Is web!'); From ebcf64da6566c59c7db58cf9db527b528c3d2781 Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Wed, 3 Dec 2014 11:35:38 -0300 Subject: [PATCH 4/8] Gramatical errors and added camera permission --- browser-extensions/chrome/manifest.json | 3 ++- views/settings.html | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/browser-extensions/chrome/manifest.json b/browser-extensions/chrome/manifest.json index e9f0361c2..6c9388801 100644 --- a/browser-extensions/chrome/manifest.json +++ b/browser-extensions/chrome/manifest.json @@ -5,7 +5,8 @@ "version": "APP_VERSION", "permissions": [ "storage", - "notifications" + "notifications", + "videoCapture" ], "app": { "background": { diff --git a/views/settings.html b/views/settings.html index 9c2d20fdd..5f962a066 100644 --- a/views/settings.html +++ b/views/settings.html @@ -64,7 +64,7 @@
- Log level shows information on the console. This is usefull to find bugs and help users. 'debug' is the most verbose level while 'fatal' only shows unexcpected errors + Log level shows information on the console. This is useful to find bugs and to help users. 'debug' is the most verbose level while 'fatal' only shows unexpected errors