diff --git a/js/controllers/create.js b/js/controllers/create.js index 52db78e95..6631dcce9 100644 --- a/js/controllers/create.js +++ b/js/controllers/create.js @@ -86,8 +86,9 @@ angular.module('copayApp.controllers').controller('CreateController', privateKeyHex: $scope.private, networkName: $scope.networkName, }; - var w = walletFactory.create(opts); - controllerUtils.startNetwork(w, $scope); + walletFactory.create(opts, function(err, w) { + controllerUtils.startNetwork(w, $scope); + }); }); }; diff --git a/js/controllers/open.js b/js/controllers/open.js index 005bba83d..403f4f9fd 100644 --- a/js/controllers/open.js +++ b/js/controllers/open.js @@ -16,19 +16,19 @@ angular.module('copayApp.controllers').controller('OpenController', function($sc $scope.loading = false; walletFactory.getWallets(function(wallets) { $scope.wallets = wallets.sort(cmp); - }); - walletFactory.storage.getLastOpened(function(ret) { - $scope.selectedWalletId = ret || ($scope.wallets[0] && $scope.wallets[0].id); + if (!$scope.wallets.length) { + $location.path('/'); + } + + walletFactory.storage.getLastOpened(function(ret) { + $scope.selectedWalletId = ret || ($scope.wallets[0] && $scope.wallets[0].id); + }); }); $scope.openPassword = ''; $scope.isMobile = !!window.cordova; - if (!$scope.wallets.length) { - $location.path('/'); - } - $scope.open = function(form) { if (form && form.$invalid) { notification.error('Error', 'Please enter the required fields'); diff --git a/js/models/Storage.js b/js/models/Storage.js index 17757192f..e23ab530d 100644 --- a/js/models/Storage.js +++ b/js/models/Storage.js @@ -83,6 +83,7 @@ Storage.prototype.getGlobal = function(k, cb) { preconditions.checkArgument(cb); this.storage.getItem(k, function(item) { +console.log('[Storage.js.96:item:]',item); //TODO cb(item == 'undefined' ? undefined : item); }); }; @@ -118,18 +119,34 @@ Storage.prototype.get = function(walletId, k, cb) { this._read(this._key(walletId, k), cb); }; + +Storage.prototype._readHelper = function(walletId, k, cb) { +console.log('[Storage.js.134:walletId:]',walletId,k); //TODO + var wk = this._key(walletId, k); + + this._read(wk, function(v){ + return cb(v,k); + }); +}; + Storage.prototype.getMany = function(walletId, keys, cb) { preconditions.checkArgument(cb); var self = this; var ret = {}; +console.log('[Storage.js.142:keys:]',keys); //TODO + + var l = keys.length, i=0; - var l = keys.length - 1; for (var ii in keys) { - var k = keys[ii]; - this._read(this._key(walletId, k), function(v) { + this._readHelper(walletId, keys[ii], function(v, k) { ret[k] = v; - if (ii == l) return cb(ret); +console.log('[Storage.js.144:ret:]',k,i,l,v); //TODO + if (++i == l) { + +console.log('[Storage.js.157] LKIST', ret); //TODO + return cb(ret); + } }); } }; @@ -148,9 +165,8 @@ Storage.prototype.setName = function(walletId, name, cb) { this.setGlobal('nameFor::' + walletId, name, cb); }; -Storage.prototype.getName = function(walletId) { - var ret = this.getGlobal('nameFor::' + walletId); - return ret; +Storage.prototype.getName = function(walletId, cb) { + this.getGlobal('nameFor::' + walletId, cb); }; Storage.prototype.getWalletIds = function(cb) { @@ -185,17 +201,21 @@ Storage.prototype.getWallets = function(cb) { var self = this; this.getWalletIds(function(ids) { - var l = ids.length - 1; +console.log('[Storage.js.197:ids:]',ids); //TODO + var l = ids.length, i=0; if (!l) return cb([]); - for (var i in ids) { - self.getName(ids[i], function(name) { + for (var ii in ids) { + var id = ids[ii]; +console.log('[Storage.js.206:id:]',id); //TODO + self.getName(id, function(name) { wallets.push({ - id: ids[i], + id: id, name: name, }); - if (i == l) { +console.log('[Storage.js.208:wallets:]',wallets); //TODO + if (++i == l) { return cb(wallets); } }) @@ -232,7 +252,6 @@ Storage.prototype.setFromObj = function(walletId, obj, cb) { preconditions.checkArgument(cb); var self = this; - console.log('[Storage.js.241]'); //TODO var l = Object.keys(obj).length, i = 0; for (var k in obj) { diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index f164c533f..18d5ed063 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -178,10 +178,10 @@ WalletFactory.prototype.read = function(walletId, skipFields, cb) { * @TODO: Figure out in what unit is this reconnect delay. * @param {number} opts.reconnectDelay milliseconds? * @param {number=} opts.version + * @param {callback} opts.version * @return {Wallet} */ -WalletFactory.prototype.create = function(opts) { - +WalletFactory.prototype.create = function(opts, cb) { opts = opts || {}; opts.networkName = opts.networkName || 'testnet'; @@ -230,9 +230,12 @@ WalletFactory.prototype.create = function(opts) { opts.version = opts.version || this.version; var w = new Wallet(opts); - w.store(); - this.storage.setLastOpened(w.id); - return w; + var self = this; + w.store(function() { + self.storage.setLastOpened(w.id, function() { + return cb(null, w); + }); + }); }; /** @@ -364,15 +367,13 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras connectedOnce = true; }); - << << << < HEAD - joinNetwork.on('serverError', function() { === === = - self.network.on('serverError', function() { >>> >>> > wallet listing working - return cb('joinError'); - }); + joinNetwork.on('serverError', function() { + return cb('joinError'); + }); - joinNetwork.start(opts, function() { - joinNetwork.greet(decodedSecret.pubKey, opts.secretNumber); - joinNetwork.on('data', function(sender, data) { + joinNetwork.start(opts, function() { + joinNetwork.greet(decodedSecret.pubKey, opts.secretNumber); + joinNetwork.on('data', function(sender, data) { if (data.type === 'walletId') { if (data.networkName !== decodedSecret.networkName) { return cb('badNetwork'); @@ -382,14 +383,18 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras data.opts.nickname = nickname; data.opts.passphrase = passphrase; data.opts.id = data.walletId; - var w = self.create(data.opts); - w.sendWalletReady(decodedSecret.pubKey); - return cb(null, w); - } else { - return cb('walletFull', w); - } - }); - }); - }; + self.create(data.opts, function(err, w) { + if (!err & w) { + w.sendWalletReady(s.pubKey); + } else { + if (!err) err = 'walletFull'; + } + return cb(err, w); + }); - module.exports = WalletFactory; + }); + }); + }; +}; + +module.exports = WalletFactory; diff --git a/js/models/core/WalletLock.js b/js/models/core/WalletLock.js index ef33fa196..a8a1729b7 100644 --- a/js/models/core/WalletLock.js +++ b/js/models/core/WalletLock.js @@ -10,7 +10,7 @@ function WalletLock(storage, walletId, timeoutMin) { this.storage = storage; this.timeoutMin = timeoutMin || 5; this.key = WalletLock._keyFor(walletId); - this._setLock(function() {}); + // this._setLock(function() {}); } WalletLock._keyFor = function(walletId) { @@ -18,7 +18,9 @@ WalletLock._keyFor = function(walletId) { }; WalletLock.prototype._isLockedByOther = function(cb) { - var self=this; + var self = this; + + console.log('[WalletLock.js.22]'); //TODO this.storage.getGlobal(this.key, function(json) { var wl = json ? JSON.parse(json) : null; var t = wl ? (Date.now() - wl.expireTs) : false; @@ -33,10 +35,13 @@ WalletLock.prototype._isLockedByOther = function(cb) { WalletLock.prototype._setLock = function(cb) { + this.storage.setGlobal(this.key, { sessionId: this.sessionId, expireTs: Date.now() + this.timeoutMin * 60 * 1000, - }, cb); + }, function() { + cb(null); + }); }; @@ -45,6 +50,7 @@ WalletLock.prototype.keepAlive = function(cb) { var self = this; this._isLockedByOther(function(t) { + if (t) return cb(new Error('Wallet is already open. Close it to proceed or wait ' + t + ' seconds if you close it already')); diff --git a/js/routes.js b/js/routes.js index 02c036251..6f01ffc23 100644 --- a/js/routes.js +++ b/js/routes.js @@ -76,8 +76,8 @@ angular // IDLE timeout var timeout = config.wallet.idleDurationMin * 60 || 300; $idleProvider.idleDuration(timeout); // in seconds - $idleProvider.warningDuration(20); // in seconds - $keepaliveProvider.interval(2); // in seconds + $idleProvider.warningDuration(40); // in seconds + $keepaliveProvider.interval(30); // in seconds }) .run(function($rootScope, $location, $idle, gettextCatalog) { gettextCatalog.currentLanguage = config.defaultLanguage; diff --git a/plugins/googleDrive.js b/plugins/googleDrive.js index 7811640b9..8cf41d72e 100644 --- a/plugins/googleDrive.js +++ b/plugins/googleDrive.js @@ -25,7 +25,7 @@ function GoogleDrive(config) { window.InitGoogleDrive = function() { - console.log('[googleDrive.js.18] setting loaded'); //TODO + // console.log('[googleDrive.js.18] setting loaded'); //TODO loaded = 1; }; @@ -47,7 +47,7 @@ GoogleDrive.prototype.initLoaded = function() { */ GoogleDrive.prototype.checkAuth = function() { - console.log('\tChecking google Auth'); //TODO + console.log('\tChecking google Auth'); gapi.auth.authorize({ 'client_id': this.clientId, 'scope': SCOPES, @@ -61,7 +61,7 @@ GoogleDrive.prototype.checkAuth = function() { */ GoogleDrive.prototype.handleAuthResult = function(authResult) { var self = this; - console.log('[googleDrive.js.39:authResult:]', authResult); //TODO + // console.log('[googleDrive.js.39:authResult:]', authResult); //TODO if (authResult.error) { if (authResult.error) { @@ -81,61 +81,121 @@ GoogleDrive.prototype.checkReady = function() { throw new Error('goggle drive is not ready!'); }; -GoogleDrive.prototype.getItem = function(k) { - this.checkReady(); - throw new Error('getItem not implemented'); +GoogleDrive.prototype._httpGet = function(theUrl) { + var accessToken = gapi.auth.getToken().access_token; + var xmlHttp = null; + + xmlHttp = new XMLHttpRequest(); + xmlHttp.open("GET", theUrl, false); + xmlHttp.setRequestHeader('Authorization', 'Bearer ' + accessToken); + xmlHttp.send(null); + return xmlHttp.responseText; +} + +GoogleDrive.prototype.getItem = function(k, cb) { + console.log('[googleDrive.js.95:getItem:]', k); //TODO + var self = this; + + self.checkReady(); + self._idForName(k, function(kId) { + // console.log('[googleDrive.js.89:kId:]', kId); //TODO + if (!kId) + return cb(null); + + + var args = { + 'path': '/drive/v2/files/' + kId, + 'method': 'GET', + }; + // console.log('[googleDrive.js.95:args:]', args); //TODO + + var request = gapi.client.request(args); + request.execute(function(res) { + // console.log('[googleDrive.js.175:res:]', res); //TODO + if (!res || !res.downloadUrl) + return cb(null); + + return cb(self._httpGet(res.downloadUrl)); + }); + + }); }; GoogleDrive.prototype.setItem = function(k, v, cb) { + // console.log('[googleDrive.js.111:setItem:]', k, v); //TODO var self = this; - this.checkReady(); + self.checkReady(); + self._idForName(this.home, function(parentId) { + preconditions.checkState(parentId); + // console.log('[googleDrive.js.118:parentId:]', parentId); //TODO + self._idForName(k, function(kId) { - var parendId = self._idForName[this.home]; - preconditions.checkState(parentId); + // console.log('[googleDrive.js.105]', parentId, kId); //TODO - var boundary = '-------314159265358979323846'; - var delimiter = "\r\n--" + boundary + "\r\n"; - var close_delim = "\r\n--" + boundary + "--"; + var boundary = '-------314159265358979323846'; + var delimiter = "\r\n--" + boundary + "\r\n"; + var close_delim = "\r\n--" + boundary + "--"; - var metadata = { - 'title': k, - 'mimeType': 'application/octet-stream', - 'parents': [parentId], - }; + var metadata = { + 'title': k, + 'mimeType': 'application/octet-stream', + 'parents': [{ + 'id': parentId + }], + }; - var base64Data = btoa(v); - var multipartRequestBody = - delimiter + - 'Content-Type: application/json\r\n\r\n' + - JSON.stringify(metadata) + - delimiter + - 'Content-Type: application/octet-stream \r\n' + - 'Content-Transfer-Encoding: base64\r\n' + - '\r\n' + - base64Data + - close_delim; -console.log('[googleDrive.js.105:multipartRequestBody:]',multipartRequestBody); //TODO + var base64Data = btoa(v); + var multipartRequestBody = + delimiter + + 'Content-Type: application/json\r\n\r\n' + + JSON.stringify(metadata) + + delimiter + + 'Content-Type: application/octet-stream \r\n' + + 'Content-Transfer-Encoding: base64\r\n' + + '\r\n' + + base64Data + + close_delim; - var request = gapi.client.request({ - 'path': '/upload/drive/v2/files', - 'method': 'POST', - 'params': { - 'uploadType': 'multipart', - }, - 'headers': { - 'Content-Type': 'multipart/mixed; boundary="' + boundary + '"' - }, - 'body': multipartRequestBody + var args = { + 'path': '/upload/drive/v2/files' + (kId ? '/' + kId : ''), + 'method': kId ? 'PUT' : 'POST', + 'params': { + 'uploadType': 'multipart', + }, + 'headers': { + 'Content-Type': 'multipart/mixed; boundary="' + boundary + '"' + }, + 'body': multipartRequestBody + } + // console.log('[googleDrive.js.148:args:]', args); //TODO + + var request = gapi.client.request(args); + request.execute(cb); + }); }); - request.execute(cb); }; -GoogleDrive.prototype.removeItem = function(k) { - this.checkReady(); +GoogleDrive.prototype.removeItem = function(k, cb) { + var self = this; - throw new Error('removeItem not implemented'); + self.checkReady(); + self._idForName(this.home, function(parentId) { + preconditions.checkState(parentId); + self._idForName(k, function(kId) { + + var args = { + 'path': '/drive/v2/files/' + kId, + 'method': 'DELETE', + }; + var request = gapi.client.request(args); + request.execute(function() { + if (cb) + cb(); + }); + }); + }); }; GoogleDrive.prototype.clear = function() { @@ -158,13 +218,14 @@ GoogleDrive.prototype._mkdir = function(cb) { 'mimeType': "application/vnd.google-apps.folder", }), }); - request.execute(function(){ - self._idForName(this.home, cb); + request.execute(function() { + self._idForName(self.home, cb); }); }; GoogleDrive.prototype._idForName = function(name, cb) { + // console.log('[googleDrive.js.199:_idForName:]', name); //TODO preconditions.checkArgument(name); preconditions.checkArgument(cb); var self = this; @@ -174,17 +235,24 @@ GoogleDrive.prototype._idForName = function(name, cb) { self.ts = self.ts * 1.5; return setTimeout(self._idForName.bind(self, name, cb), self.ts); } -console.log('[googleDrive.js.178:name:]',name); //TODO + // console.log('[googleDrive.js.178:name:]', name); //TODO - if (self.idCache[name]) + if (self.idCache[name]) { + // console.log('[googleDrive.js.212:] FROM CACHE', name, self.idCache[name]); //TODO return cb(self.idCache[name]); + } console.log('Querying for: ', name); //TODO var args; - var idParent = name == this.home ? 'root' : self.idCache[this.home] ; + var idParent = name == this.home ? 'root' : self.idCache[this.home]; -console.log('[googleDrive.js.177:idParent:]',idParent); //TODO + if (!idParent) { + return self._mkdir(function() { + self._idForName(name, cb); + }); + } + // console.log('[googleDrive.js.177:idParent:]', idParent); //TODO preconditions.checkState(idParent); args = { @@ -195,13 +263,12 @@ console.log('[googleDrive.js.177:idParent:]',idParent); //TODO } }; - console.log('[googleDrive.js.196:args:]', args); //TODO var request = gapi.client.request(args); request.execute(function(res) { - console.log('[googleDrive.js.175:res:]', res); //TODO var i = res.items && res.items[0] ? res.items[0].id : false; if (i) self.idCache[name] = i; + // console.log('[googleDrive.js.238] CACHING ' + name + ':' + i); //TODO return cb(self.idCache[name]); }); }; @@ -232,13 +299,13 @@ GoogleDrive.prototype.allKeys = function(cb) { }, }); request.execute(function(res) { - console.log('[googleDrive.js.152:res:]', res); //TODO + // console.log('[googleDrive.js.152:res:]', res); //TODO if (res.error) throw new Error(res.error.message); var ret = []; for (var ii in res.items) { - ret.push(res[ii].id); + ret.push(res.items[ii].title); } return cb(ret); });