From 989020a436d763f4c2e95babd36867beebeb3b6a Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 6 Nov 2020 17:13:41 +0100 Subject: [PATCH] Open pads in offline mode --- www/common/cryptpad-common.js | 57 ++++++++++++++++++++++++----- www/common/inner/common-mediatag.js | 2 +- www/common/messenger-ui.js | 1 + www/common/outer/async-store.js | 12 +++--- www/common/sframe-app-outer.js | 1 + www/common/sframe-common-outer.js | 4 ++ www/common/sframe-common.js | 30 +++++++++++---- www/common/toolbar.js | 5 ++- 8 files changed, 88 insertions(+), 24 deletions(-) diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 2ac4101f7..2c8c64099 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -11,11 +11,13 @@ define([ '/common/outer/local-store.js', '/common/outer/worker-channel.js', '/common/outer/login-block.js', + '/common/outer/cache-store.js', '/customize/application_config.js', '/bower_components/nthen/index.js', ], function (Config, Messages, Util, Hash, Messaging, Constants, Feedback, Visible, UserObject, LocalStore, Channel, Block, + Cache, AppConfig, Nthen) { /* This file exposes functionality which is specific to Cryptpad, but not to @@ -437,10 +439,35 @@ define([ }); }; - common.getFileSize = function (href, password, cb) { - postMessage("GET_FILE_SIZE", {href: href, password: password}, function (obj) { - if (obj && obj.error) { return void cb(obj.error); } - cb(undefined, obj.size); + common.getFileSize = function (href, password, _cb) { + var cb = Util.once(Util.mkAsync(_cb)); + var channel = Hash.hrefToHexChannelId(href, password); + var error; + Nthen(function (waitFor) { + // Blobs can't change, if it's in the cache, use it + Cache.getBlobCache(channel, waitFor(function(err, blob) { + if (err) { return; } + waitFor.abort(); + cb(null, blob.length); + })); + + }).nThen(function (waitFor) { + // If it's not in the cache or it's not a blob, try to get the value from the server + postMessage("GET_FILE_SIZE", {channel:channel}, waitFor(function (obj) { + if (obj && obj.error) { + // If disconnected, try to get the value from the channel cache (next nThen) + error = obj.error; + return; + } + waitFor.abort(); + cb(undefined, obj.size); + })); + }).nThen(function () { + Cache.getChannelCache(channel, function(err, data) { + if (err) { return void cb(error); } + var size = data && Array.isArray(data.c) && data.c.join('').length; + cb(null, size || 0); + }); }); }; @@ -451,11 +478,23 @@ define([ }); }; - common.isNewChannel = function (href, password, cb) { - postMessage('IS_NEW_CHANNEL', {href: href, password: password}, function (obj) { - if (obj.error) { return void cb(obj.error); } - if (!obj) { return void cb('INVALID_RESPONSE'); } - cb(undefined, obj.isNew); + common.isNewChannel = function (href, password, _cb) { + var cb = Util.once(Util.mkAsync(_cb)); + var channel = Hash.hrefToHexChannelId(href, password); + var error; + Nthen(function (waitFor) { + // If it's not in the cache or it's not a blob, try to get the value from the server + postMessage('IS_NEW_CHANNEL', {channel: channel}, waitFor(function (obj) { + if (obj && obj.error) { error = obj.error; return; } + if (!obj) { error = "INVALID_RESPONSE"; return; } + waitFor.abort(); + cb(undefined, obj.isNew); + })); + }).nThen(function () { + Cache.getChannelCache(channel, function(err, data) { + if (err || !data) { return void cb(error); } + cb(null, false); + }); }); }; diff --git a/www/common/inner/common-mediatag.js b/www/common/inner/common-mediatag.js index 3d28d126a..2ca28bf4c 100644 --- a/www/common/inner/common-mediatag.js +++ b/www/common/inner/common-mediatag.js @@ -76,7 +76,7 @@ define([ MT.displayAvatar = function (common, $container, href, name, _cb) { var cb = Util.once(Util.mkAsync(_cb || function () {})); var displayDefault = function () { - var text = (href && typeof(href) === "string") ? href : Util.getFirstCharacter(name); + var text = Util.getFirstCharacter(name || Messages.anonymous); var $avatar = $('', {'class': 'cp-avatar-default'}).text(text); $container.append($avatar); if (cb) { cb(); } diff --git a/www/common/messenger-ui.js b/www/common/messenger-ui.js index da90db12c..76a756a11 100644 --- a/www/common/messenger-ui.js +++ b/www/common/messenger-ui.js @@ -1037,6 +1037,7 @@ define([ //}); execCommand('GET_MY_INFO', null, function (e, info) { + if (e) { return; } contactsData[info.curvePublic] = info; }); diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index c91106d8c..5715038cc 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -91,7 +91,7 @@ define([ Realtime.whenRealtimeSyncs(s.sharedFolders[k].realtime, waitFor()); } } - }).nThen(function () { console.log('done');cb(); }); + }).nThen(function () { cb(); }); }; Store.get = function (clientId, data, cb) { @@ -1035,9 +1035,6 @@ define([ }); }; Store.setPadTitle = function (clientId, data, cb) { - if (store.offline) { - return void cb({ error: 'OFFLINE' }); - } var title = data.title; var href = data.href; var channel = data.channel; @@ -1110,6 +1107,11 @@ define([ Array.prototype.push.apply(allData, res); }); var contains = allData.length !== 0; + if (store.offline && !contains) { + return void cb({ error: 'OFFLINE' }); + } else if (store.offline) { + return void cb(); + } allData.forEach(function (obj) { var pad = obj.data; pad.atime = +new Date(); @@ -1689,7 +1691,7 @@ define([ noChainPad: true, channel: data.channel, metadata: data.metadata, - network: store.network, + network: store.network || store.networkPromise, //readOnly: data.readOnly, onConnect: function (wc, sendMessage) { channel.sendMessage = function (msg, cId, cb) { diff --git a/www/common/sframe-app-outer.js b/www/common/sframe-app-outer.js index d85266ca7..ae7ee47c3 100644 --- a/www/common/sframe-app-outer.js +++ b/www/common/sframe-app-outer.js @@ -45,6 +45,7 @@ define([ window.addEventListener('message', onMsg); }).nThen(function (/*waitFor*/) { SFCommonO.start({ + cache: true, hash: hash, href: href, useCreationScreen: true, diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index 059dc90e4..4d06b8a1e 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -431,6 +431,10 @@ define([ } if (!stored && !parsed.hashData.password) { // We've received a link without /p/ and it doesn't work without a password: abort + if (e === "ANON_RPC_NOT_READY") { + // We're currently offline and the pad is not in our cache + sframeChan.event('EV_OFFLINE'); + } return void todo(); } // Wrong password or deleted file? diff --git a/www/common/sframe-common.js b/www/common/sframe-common.js index 3eb86ff93..0f823c491 100644 --- a/www/common/sframe-common.js +++ b/www/common/sframe-common.js @@ -15,6 +15,7 @@ define([ '/common/metadata-manager.js', '/customize/application_config.js', + '/common/outer/cache-store.js', '/common/common-realtime.js', '/common/common-util.js', '/common/common-hash.js', @@ -39,6 +40,7 @@ define([ MT, MetadataMgr, AppConfig, + Cache, CommonRealtime, Util, Hash, @@ -167,14 +169,22 @@ define([ }; funcs.getFileSize = function (channelId, cb) { - funcs.sendAnonRpcMsg("GET_FILE_SIZE", channelId, function (data) { - if (!data) { return void cb("No response"); } - if (data.error) { return void cb(data.error); } - if (data.response && data.response.length && typeof(data.response[0]) === 'number') { - return void cb(void 0, data.response[0]); - } else { - cb('INVALID_RESPONSE'); - } + nThen(function (waitFor) { + Cache.getBlobCache(channelId, waitFor(function(err, blob) { + if (err) { return; } + waitFor.abort(); + cb(null, blob.length); + })); + }).nThen(function () { + funcs.sendAnonRpcMsg("GET_FILE_SIZE", channelId, function (data) { + if (!data) { return void cb("No response"); } + if (data.error) { return void cb(data.error); } + if (data.response && data.response.length && typeof(data.response[0]) === 'number') { + return void cb(void 0, data.response[0]); + } else { + cb('INVALID_RESPONSE'); + } + }); }); }; @@ -678,6 +688,10 @@ define([ UI.errorLoadingScreen(Messages.restrictedError); }); + ctx.sframeChan.on("EV_OFFLINE", function () { + UI.errorLoadingScreen("OFFLINE AND NO CACHE"); // XXX + }); + ctx.sframeChan.on("EV_PAD_PASSWORD_ERROR", function () { UI.errorLoadingScreen(Messages.password_error_seed); }); diff --git a/www/common/toolbar.js b/www/common/toolbar.js index 0927cde21..c25f7dfe9 100644 --- a/www/common/toolbar.js +++ b/www/common/toolbar.js @@ -365,6 +365,9 @@ MessengerUI, Messages) { if (!toolbar.connected) { return; } updateUserList(toolbar, config); }); + setTimeout(function () { + updateUserList(toolbar, config, true); + }); } }; @@ -1246,8 +1249,8 @@ MessengerUI, Messages) { if (typeof el !== "string" || !el.trim()) { return; } if (typeof tb[el] === "function") { if (!init && config.displayed.indexOf(el) !== -1) { return; } // Already done - toolbar[el] = tb[el](toolbar, config); if (!init) { config.displayed.push(el); } + toolbar[el] = tb[el](toolbar, config); } }); checkSize();