diff --git a/customize.dist/loading.js b/customize.dist/loading.js index 733b3fff0..85a4a0b7e 100644 --- a/customize.dist/loading.js +++ b/customize.dist/loading.js @@ -317,9 +317,12 @@ button.primary:hover{ var c = types.indexOf(data.type); if (c < current) { return console.error(data); } try { - document.querySelector('.cp-loading-spinner-container').style.display = 'none'; - document.querySelector('.cp-loading-progress-list').innerHTML = makeList(data); - document.querySelector('.cp-loading-progress-container').innerHTML = makeBar(data); + var a = document.querySelector('.cp-loading-spinner-container'); + if (a) { a.style.display = 'none'; } + var b = document.querySelector('.cp-loading-progress-list'); + if (b) { b.innerHTML = makeList(data); } + var c = document.querySelector('.cp-loading-progress-container'); + if (c) { c.innerHTML = makeBar(data); } } catch (e) { console.error(e); } }; window.CryptPad_updateLoadingProgress = updateLoadingProgress; diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 4886b213e..f97855105 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -42,7 +42,7 @@ define([ var APP = window.APP = { editable: false, - online: true, + online: false, mobile: function () { if (window.matchMedia) { return !window.matchMedia('(any-pointer:fine)').matches; } else { return $('body').width() <= 600; } @@ -4361,8 +4361,12 @@ define([ var anonDrive = manager.isPathIn(currentPath, [FILES_DATA]) && !APP.loggedIn; if (manager.isFolder(el) && !manager.isSharedFolder(el) && !anonDrive) { // Folder + // disconnected + if (!APP.editable) { + return void UI.warn(Messages.error); // XXX + } // if folder is inside SF - if (manager.isInSharedFolder(paths[0].path)) { + else if (manager.isInSharedFolder(paths[0].path)) { return void UI.alert(Messages.convertFolderToSF_SFParent); } // if folder already contains SF diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 7066d3921..89ed1dbbf 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -89,7 +89,7 @@ define([ Realtime.whenRealtimeSyncs(s.sharedFolders[k].realtime, waitFor()); } } - }).nThen(function () { cb(); }); + }).nThen(function () { console.log('done');cb(); }); }; Store.get = function (clientId, data, cb) { @@ -2162,7 +2162,7 @@ define([ if (!s) { return void cb({ error: 'ENOTFOUND' }); } SF.load({ isNew: isNew, - network: store.network, + network: store.network || store.networkPromise, store: s, isNewChannel: Store.isNewChannel }, id, data, cb); @@ -2465,8 +2465,45 @@ define([ }); }; + var onCacheReady = function (clientId, cb) { + var proxy = store.proxy; + if (!proxy.settings) { proxy.settings = NEW_USER_SETTINGS; } + if (!proxy.friends_pending) { proxy.friends_pending = {}; } + var unpin = function (data, cb) { + if (!store.loggedIn) { return void cb(); } + Store.unpinPads(null, data, cb); + }; + var pin = function (data, cb) { + if (!store.loggedIn) { return void cb(); } + Store.pinPads(null, data, cb); + }; + var manager = store.manager = ProxyManager.create(proxy.drive, { + onSync: function (cb) { onSync(null, cb); }, + edPublic: proxy.edPublic, + pin: pin, + unpin: unpin, + loadSharedFolder: loadSharedFolder, + settings: proxy.settings, + removeOwnedChannel: function (channel, cb) { Store.removeOwnedChannel('', channel, cb); }, + Store: Store + }, { + outer: true, + edPublic: store.proxy.edPublic, + loggedIn: store.loggedIn, + log: function (msg) { + // broadcast to all drive apps + sendDriveEvent("DRIVE_LOG", msg); + }, + rt: store.realtime + }); + var userObject = store.userObject = manager.user.userObject; + addSharedFolderHandler(); + userObject.migrate(cb); + }; var onReady = function (clientId, returned, cb) { + console.error('READY'); var proxy = store.proxy; + /* var unpin = function (data, cb) { if (!store.loggedIn) { return void cb(); } Store.unpinPads(null, data, cb); @@ -2498,9 +2535,16 @@ define([ }); var userObject = store.userObject = manager.user.userObject; addSharedFolderHandler(); + */ + store.ready = true; + var manager = store.manager; + var userObject = store.userObject; nThen(function (waitFor) { - userObject.migrate(waitFor()); + if (manager) { return; } + onCacheReady(clientId, waitFor); + manager = store.manager; + userObject = store.userObject; }).nThen(function (waitFor) { initAnonRpc(null, null, waitFor()); initRpc(null, null, waitFor()); @@ -2533,12 +2577,12 @@ define([ loadUniversal(Messenger, 'messenger', waitFor); store.messenger = store.modules['messenger']; loadUniversal(Profile, 'profile', waitFor); - loadUniversal(Team, 'team', waitFor, clientId); + loadUniversal(Team, 'team', waitFor, clientId); // XXX load teams offline? loadUniversal(History, 'history', waitFor); cleanFriendRequests(); }).nThen(function () { - var requestLogin = function () { - broadcast([], "REQUEST_LOGIN"); + var requestLogin = function () { + broadcast([], "REQUEST_LOGIN"); }; if (store.loggedIn) { @@ -2571,7 +2615,10 @@ define([ returned.feedback = Util.find(proxy, ['settings', 'general', 'allowUserFeedback']); Feedback.init(returned.feedback); - if (typeof(cb) === 'function') { cb(returned); } + // XXX send feedback and logintoken to outer... + //if (typeof(cb) === 'function') { cb(returned); } + store.offline = false; + sendDriveEvent('NETWORK_RECONNECT'); if (typeof(proxy.uid) !== 'string' || proxy.uid.length !== 32) { // even anonymous users should have a persistent, unique-ish id @@ -2670,8 +2717,17 @@ define([ if (!data.userHash) { returned.anonHash = Hash.getEditHashFromKeys(secret); } + if (typeof(cb) === "function") { cb(returned); } + }).on('cacheready', function (info) { + store.offline = true; + store.realtime = info.realtime; + store.networkPromise = info.networkPromise; + // XXX make sure we have a valid drive available + onCacheReady(clientId, function () { + if (typeof(cb) === "function") { cb(returned); } + }); }).on('ready', function (info) { - if (store.userObject) { return; } // the store is already ready, it is a reconnection + if (store.ready) { return; } // the store is already ready, it is a reconnection store.driveMetadata = info.metadata; if (!rt.proxy.drive || typeof(rt.proxy.drive) !== 'object') { rt.proxy.drive = {}; } var drive = rt.proxy.drive; diff --git a/www/common/outer/sharedfolder.js b/www/common/outer/sharedfolder.js index 3c1c8632d..830bef05b 100644 --- a/www/common/outer/sharedfolder.js +++ b/www/common/outer/sharedfolder.js @@ -128,11 +128,11 @@ define([ var uo = store.manager.addProxy(id, sf.rt, leave, secondaryKey); // NOTE: Shared folder migration, disable for now SF.checkMigration(secondaryKey, sf.rt.proxy, uo, function () { - cb(sf.rt, sf.metadata); + cb(sf.rt); }); */ store.manager.addProxy(id, sf.rt, leave, secondaryKey); - cb(sf.rt, sf.metadata); + cb(sf.rt); }); sf.teams.push({ cb: cb, @@ -182,6 +182,26 @@ define([ } }; var rt = sf.rt = Listmap.create(listmapConfig); + rt.proxy.on('cacheready', function (info) { + if (isNew && !Object.keys(rt.proxy).length) { + // New Shared folder: no migration required + rt.proxy.version = 2; + } + if (!sf.teams) { + return; + } + sf.teams.forEach(function (obj) { + var leave = function () { SF.leave(secret.channel, obj.store.id); }; + + // We can safely call addProxy and obj.cb here because + // 1. addProxy won't re-add the same folder twice on 'ready' + // 2. obj.cb is using Util.once + rt.cache = true; + obj.store.manager.addProxy(obj.id, rt, leave, obj.secondaryKey); + obj.cb(sf.rt); + }); + sf.ready = true; + }); rt.proxy.on('ready', function (info) { if (isNew && !Object.keys(rt.proxy).length) { // New Shared folder: no migration required @@ -196,13 +216,13 @@ define([ var uo = obj.store.manager.addProxy(obj.id, rt, leave, obj.secondaryKey); // NOTE: Shared folder migration, disable for now SF.checkMigration(secondaryKey, rt.proxy, uo, function () { - obj.cb(sf.rt, info.metadata); + obj.cb(sf.rt); }); */ + rt.cache = false; obj.store.manager.addProxy(obj.id, rt, leave, obj.secondaryKey); - obj.cb(sf.rt, info.metadata); + obj.cb(sf.rt); }); - sf.metadata = info.metadata; sf.ready = true; }); rt.proxy.on('error', function (info) { diff --git a/www/common/proxy-manager.js b/www/common/proxy-manager.js index 74bfcd890..17b4fec55 100644 --- a/www/common/proxy-manager.js +++ b/www/common/proxy-manager.js @@ -17,6 +17,15 @@ define([ // Add a shared folder to the list var addProxy = function (Env, id, lm, leave, editKey) { + if (Env.folders[id]) { + // Shared folder already added to the proxy-manager, probably + // a cached version + if (Env.folders[id].offline && !lm.cache) { + Env.folders[id].offline = false; + Env.Store.refreshDriveUI(); + } + return; + } var cfg = getConfig(Env); cfg.sharedFolder = true; cfg.id = id; @@ -38,14 +47,15 @@ define([ Env.folders[id] = { proxy: lm.proxy, userObject: userObject, - leave: leave + leave: leave, + offline: Boolean(lm.cache) }; if (proxy.on) { proxy.on('disconnect', function () { Env.folders[id].offline = true; }); proxy.on('reconnect', function () { - Env.folders[id].online = true; + Env.folders[id].offline = false; }); } return userObject; @@ -537,7 +547,7 @@ define([ Env.user.userObject.add(id, resolved.path); // 2b. load the proxy - Env.loadSharedFolder(id, folderData, waitFor(function (rt, metadata) { + Env.loadSharedFolder(id, folderData, waitFor(function (rt) { if (!rt) { waitFor.abort(); return void cb({ error: 'EDELETED' }); @@ -546,11 +556,13 @@ define([ if (!rt.proxy.metadata) { // Creating a new shared folder rt.proxy.metadata = { title: data.name || Messages.fm_newFolder }; } - // If we're importing a folder, check its serverside metadata - if (data.folderData && metadata) { - var fData = Env.user.proxy[UserObject.SHARED_FOLDERS][id]; - if (metadata.owners) { fData.owners = metadata.owners; } - if (metadata.expire) { fData.expire = +metadata.expire; } + if (data.folderData) { + // If we're importing a folder, check its serverside metadata + Env.Store.getPadMetadata(null, { channel: folderData.channel }, function (md) { + var fData = Env.user.proxy[UserObject.SHARED_FOLDERS][id]; + if (md.owners) { fData.owners = md.owners; } + if (md.expire) { fData.expire = +md.expire; } + }); } }), !Boolean(data.folderData)); }).nThen(function () {