merge offlineCache and soon

pull/1/head
ansuz 4 years ago
commit beb74b46d5

@ -229,6 +229,7 @@ define([
}; };
}; };
UIElements.noContactsMessage = function (common) { UIElements.noContactsMessage = function (common) {
var metadataMgr = common.getMetadataMgr(); var metadataMgr = common.getMetadataMgr();
var data = metadataMgr.getUserData(); var data = metadataMgr.getUserData();

@ -12,11 +12,13 @@ define([
'/common/outer/local-store.js', '/common/outer/local-store.js',
'/common/outer/worker-channel.js', '/common/outer/worker-channel.js',
'/common/outer/login-block.js', '/common/outer/login-block.js',
'/common/outer/cache-store.js',
'/customize/application_config.js', '/customize/application_config.js',
'/bower_components/nthen/index.js', '/bower_components/nthen/index.js',
], function (Config, Messages, Util, Hash, Cache, ], function (Config, Messages, Util, Hash, Cache,
Messaging, Constants, Feedback, Visible, UserObject, LocalStore, Channel, Block, Messaging, Constants, Feedback, Visible, UserObject, LocalStore, Channel, Block,
Cache,
AppConfig, Nthen) { AppConfig, Nthen) {
/* This file exposes functionality which is specific to Cryptpad, but not to /* This file exposes functionality which is specific to Cryptpad, but not to
@ -453,10 +455,35 @@ define([
}); });
}; };
common.getFileSize = function (href, password, cb) { common.getFileSize = function (href, password, _cb) {
postMessage("GET_FILE_SIZE", {href: href, password: password}, function (obj) { var cb = Util.once(Util.mkAsync(_cb));
if (obj && obj.error) { return void cb(obj.error); } var channel = Hash.hrefToHexChannelId(href, password);
cb(undefined, obj.size); 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);
});
}); });
}; };
@ -467,11 +494,23 @@ define([
}); });
}; };
common.isNewChannel = function (href, password, cb) { common.isNewChannel = function (href, password, _cb) {
postMessage('IS_NEW_CHANNEL', {href: href, password: password}, function (obj) { var cb = Util.once(Util.mkAsync(_cb));
if (obj.error) { return void cb(obj.error); } var channel = Hash.hrefToHexChannelId(href, password);
if (!obj) { return void cb('INVALID_RESPONSE'); } var error;
cb(undefined, obj.isNew); 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);
});
}); });
}; };
@ -2158,6 +2197,7 @@ define([
anonHash: LocalStore.getFSHash(), anonHash: LocalStore.getFSHash(),
localToken: tryParsing(localStorage.getItem(Constants.tokenKey)), // TODO move this to LocalStore ? localToken: tryParsing(localStorage.getItem(Constants.tokenKey)), // TODO move this to LocalStore ?
language: common.getLanguage(), language: common.getLanguage(),
cache: rdyCfg.cache,
driveEvents: true //rdyCfg.driveEvents // Boolean driveEvents: true //rdyCfg.driveEvents // Boolean
}; };

@ -42,7 +42,7 @@ define([
var APP = window.APP = { var APP = window.APP = {
editable: false, editable: false,
online: true, online: false,
mobile: function () { mobile: function () {
if (window.matchMedia) { return !window.matchMedia('(any-pointer:fine)').matches; } if (window.matchMedia) { return !window.matchMedia('(any-pointer:fine)').matches; }
else { return $('body').width() <= 600; } else { return $('body').width() <= 600; }
@ -4372,8 +4372,12 @@ define([
var anonDrive = manager.isPathIn(currentPath, [FILES_DATA]) && !APP.loggedIn; var anonDrive = manager.isPathIn(currentPath, [FILES_DATA]) && !APP.loggedIn;
if (manager.isFolder(el) && !manager.isSharedFolder(el) && !anonDrive) { // Folder 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 folder is inside SF
if (manager.isInSharedFolder(paths[0].path)) { else if (manager.isInSharedFolder(paths[0].path)) {
return void UI.alert(Messages.convertFolderToSF_SFParent); return void UI.alert(Messages.convertFolderToSF_SFParent);
} }
// if folder already contains SF // if folder already contains SF

@ -769,6 +769,7 @@ define([
}, function () {}); }, function () {});
}; };
Messages.access_offline = "You're currently offline. Access management is not available"; // XXX
var getAccessTab = function (Env, data, opts, _cb) { var getAccessTab = function (Env, data, opts, _cb) {
var cb = Util.once(Util.mkAsync(_cb)); var cb = Util.once(Util.mkAsync(_cb));
var common = Env.common; var common = Env.common;
@ -776,8 +777,14 @@ define([
var sframeChan = common.getSframeChannel(); var sframeChan = common.getSframeChannel();
var metadataMgr = common.getMetadataMgr(); var metadataMgr = common.getMetadataMgr();
var priv = metadataMgr.getPrivateData();
var $div = $(h('div.cp-share-columns')); var $div = $(h('div.cp-share-columns'));
if (priv.offline) {
$div.append(h('p', Messages.access_offline));
return void cb(void 0, $div);
}
if (!data) { return void cb(void 0, $div); } if (!data) { return void cb(void 0, $div); }
var div1 = h('div.cp-usergrid-user.cp-share-column.cp-access'); var div1 = h('div.cp-usergrid-user.cp-share-column.cp-access');

@ -82,7 +82,7 @@ define([
MT.displayAvatar = function (common, $container, href, name, _cb) { MT.displayAvatar = function (common, $container, href, name, _cb) {
var cb = Util.once(Util.mkAsync(_cb || function () {})); var cb = Util.once(Util.mkAsync(_cb || function () {}));
var displayDefault = function () { var displayDefault = function () {
var text = (href && typeof(href) === "string") ? href : Util.getFirstCharacter(name); var text = Util.getFirstCharacter(name || Messages.anonymous);
var $avatar = $('<span>', {'class': 'cp-avatar-default'}).text(text); var $avatar = $('<span>', {'class': 'cp-avatar-default'}).text(text);
$container.append($avatar); $container.append($avatar);
if (cb) { cb(); } if (cb) { cb(); }

@ -54,6 +54,9 @@ define([
if (!common.isLoggedIn()) { return void cb(void 0, $d); } if (!common.isLoggedIn()) { return void cb(void 0, $d); }
var privateData = common.getMetadataMgr().getPrivateData();
if (privateData.offline) { return void cb(void 0, $d); }
// File and history size... // File and history size...
var owned = Modal.isOwned(Env, data); var owned = Modal.isOwned(Env, data);

@ -273,6 +273,21 @@ define([
var hasFriends = opts.hasFriends; var hasFriends = opts.hasFriends;
var onFriendShare = Util.mkEvent(); var onFriendShare = Util.mkEvent();
Messages.share_noContactsOffline = "OFFLINE"; // XXX
var metadataMgr = common.getMetadataMgr();
var priv = metadataMgr.getPrivateData();
if (priv.offline) {
return void cb(void 0, {
content: h('p', Messages.share_noContactsOffline),
buttons: [{
className: 'cancel',
name: Messages.filePicker_close,
onClick: function () {},
keys: [27]
}]
});
}
var friendsObject = hasFriends ? createShareWithFriends(opts, onFriendShare, opts.getLinkValue) : UIElements.noContactsMessage(common); var friendsObject = hasFriends ? createShareWithFriends(opts, onFriendShare, opts.getLinkValue) : UIElements.noContactsMessage(common);
var friendsList = friendsObject.content; var friendsList = friendsObject.content;
@ -642,6 +657,8 @@ define([
opts.teams = teams; opts.teams = teams;
var hasFriends = opts.hasFriends = Object.keys(opts.friends || {}).length || var hasFriends = opts.hasFriends = Object.keys(opts.friends || {}).length ||
Object.keys(teams).length; Object.keys(teams).length;
var metadataMgr = common.getMetadataMgr();
var priv = metadataMgr.getPrivateData();
// check if the pad is password protected // check if the pad is password protected
var pathname = opts.pathname; var pathname = opts.pathname;
@ -662,23 +679,24 @@ define([
$rights.find('input[type="radio"]').trigger('change'); $rights.find('input[type="radio"]').trigger('change');
}; };
var onShowContacts = function () { var onShowContacts = function () {
if (!hasFriends) { if (!hasFriends || priv.offline) {
$rights.hide(); $rights.hide();
} }
}; };
var contactsActive = hasFriends && !priv.offline;
var tabs = [{ var tabs = [{
getTab: getContactsTab, getTab: getContactsTab,
title: Messages.share_contactCategory, title: Messages.share_contactCategory,
icon: "fa fa-address-book", icon: "fa fa-address-book",
active: hasFriends, active: contactsActive,
onShow: onShowContacts, onShow: onShowContacts,
onHide: resetTab onHide: resetTab
}, { }, {
getTab: getLinkTab, getTab: getLinkTab,
title: Messages.share_linkCategory, title: Messages.share_linkCategory,
icon: "fa fa-link", icon: "fa fa-link",
active: !hasFriends, active: !contactsActive,
}, { }, {
getTab: getEmbedTab, getTab: getEmbedTab,
title: Messages.share_embedCategory, title: Messages.share_embedCategory,

@ -1037,6 +1037,7 @@ define([
//}); //});
execCommand('GET_MY_INFO', null, function (e, info) { execCommand('GET_MY_INFO', null, function (e, info) {
if (e) { return; }
contactsData[info.curvePublic] = info; contactsData[info.curvePublic] = info;
}); });

@ -34,6 +34,8 @@ define([
NetConfig, AppConfig, NetConfig, AppConfig,
Crypto, ChainPad, CpNetflux, Listmap, nThen, Saferphore) { Crypto, ChainPad, CpNetflux, Listmap, nThen, Saferphore) {
var onReadyEvt = Util.mkEvent(true);
// Default settings for new users // Default settings for new users
var NEW_USER_SETTINGS = { var NEW_USER_SETTINGS = {
drive: { drive: {
@ -598,6 +600,7 @@ define([
pendingFriends: store.proxy.friends_pending || {}, pendingFriends: store.proxy.friends_pending || {},
supportPrivateKey: Util.find(store.proxy, ['mailboxes', 'supportadmin', 'keys', 'curvePrivate']), supportPrivateKey: Util.find(store.proxy, ['mailboxes', 'supportadmin', 'keys', 'curvePrivate']),
accountName: store.proxy.login_name || '', accountName: store.proxy.login_name || '',
offline: store.offline,
teams: teams, teams: teams,
plan: account.plan plan: account.plan
} }
@ -1035,9 +1038,6 @@ define([
}); });
}; };
Store.setPadTitle = function (clientId, data, cb) { Store.setPadTitle = function (clientId, data, cb) {
if (store.offline) {
return void cb({ error: 'OFFLINE' });
}
var title = data.title; var title = data.title;
var href = data.href; var href = data.href;
var channel = data.channel; var channel = data.channel;
@ -1110,6 +1110,11 @@ define([
Array.prototype.push.apply(allData, res); Array.prototype.push.apply(allData, res);
}); });
var contains = allData.length !== 0; 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) { allData.forEach(function (obj) {
var pad = obj.data; var pad = obj.data;
pad.atime = +new Date(); pad.atime = +new Date();
@ -1410,13 +1415,15 @@ define([
// Universal // Universal
Store.universal = { Store.universal = {
execCommand: function (clientId, obj, cb) { execCommand: function (clientId, obj, cb) {
var type = obj.type; onReadyEvt.reg(function () {
var data = obj.data; var type = obj.type;
if (store.modules[type]) { var data = obj.data;
store.modules[type].execCommand(clientId, data, cb); if (store.modules[type]) {
} else { store.modules[type].execCommand(clientId, data, cb);
return void cb({error: type + ' is disabled'}); } else {
} return void cb({error: type + ' is disabled'});
}
});
} }
}; };
var loadUniversal = function (Module, type, waitFor, clientId) { var loadUniversal = function (Module, type, waitFor, clientId) {
@ -1456,17 +1463,23 @@ define([
// Cursor // Cursor
Store.cursor = { Store.cursor = {
execCommand: function (clientId, data, cb) { execCommand: function (clientId, data, cb) {
if (!store.cursor) { return void cb ({error: 'Cursor channel is disabled'}); } // The cursor module can only be used when the store is ready
store.cursor.execCommand(clientId, data, cb); onReadyEvt.reg(function () {
if (!store.cursor) { return void cb ({error: 'Cursor channel is disabled'}); }
store.cursor.execCommand(clientId, data, cb);
});
} }
}; };
// Mailbox // Mailbox
Store.mailbox = { Store.mailbox = {
execCommand: function (clientId, data, cb) { execCommand: function (clientId, data, cb) {
if (!store.loggedIn) { return void cb(); } // The mailbox can only be used when the store is ready
if (!store.mailbox) { return void cb ({error: 'Mailbox is disabled'}); } onReadyEvt.reg(function () {
store.mailbox.execCommand(clientId, data, cb); if (!store.loggedIn) { return void cb(); }
if (!store.mailbox) { return void cb ({error: 'Mailbox is disabled'}); }
store.mailbox.execCommand(clientId, data, cb);
});
} }
}; };
@ -1723,7 +1736,7 @@ define([
noChainPad: true, noChainPad: true,
channel: data.channel, channel: data.channel,
metadata: data.metadata, metadata: data.metadata,
network: store.network, network: store.network || store.networkPromise,
//readOnly: data.readOnly, //readOnly: data.readOnly,
onConnect: function (wc, sendMessage) { onConnect: function (wc, sendMessage) {
channel.sendMessage = function (msg, cId, cb) { channel.sendMessage = function (msg, cId, cb) {
@ -1956,6 +1969,7 @@ define([
Store.getPadMetadata = function (clientId, data, _cb) { Store.getPadMetadata = function (clientId, data, _cb) {
var cb = Util.once(Util.mkAsync(_cb)); var cb = Util.once(Util.mkAsync(_cb));
if (store.offline || !store.anon_rpc) { return void cb({ error: 'OFFLINE' }); }
if (!data.channel) { return void cb({ error: 'ENOTFOUND'}); } if (!data.channel) { return void cb({ error: 'ENOTFOUND'}); }
if (data.channel.length !== 32) { return void cb({ error: 'EINVAL'}); } if (data.channel.length !== 32) { return void cb({ error: 'EINVAL'}); }
store.anon_rpc.send('GET_METADATA', data.channel, function (err, obj) { store.anon_rpc.send('GET_METADATA', data.channel, function (err, obj) {
@ -2207,7 +2221,7 @@ define([
if (!s) { return void cb({ error: 'ENOTFOUND' }); } if (!s) { return void cb({ error: 'ENOTFOUND' }); }
SF.load({ SF.load({
isNew: isNew, isNew: isNew,
network: store.network, network: store.network || store.networkPromise,
store: s, store: s,
isNewChannel: Store.isNewChannel isNewChannel: Store.isNewChannel
}, id, data, cb); }, id, data, cb);
@ -2223,16 +2237,18 @@ define([
}); });
}; };
Store.addSharedFolder = function (clientId, data, cb) { Store.addSharedFolder = function (clientId, data, cb) {
var s = getStore(data.teamId); onReadyEvt.reg(function () {
s.manager.addSharedFolder(data, function (id) { var s = getStore(data.teamId);
if (id && typeof(id) === "object" && id.error) { s.manager.addSharedFolder(data, function (id) {
return void cb(id); if (id && typeof(id) === "object" && id.error) {
} return void cb(id);
var send = data.teamId ? s.sendEvent : sendDriveEvent; }
send('DRIVE_CHANGE', { var send = data.teamId ? s.sendEvent : sendDriveEvent;
path: ['drive', UserObject.FILES_DATA] send('DRIVE_CHANGE', {
}, clientId); path: ['drive', UserObject.FILES_DATA]
cb(id); }, clientId);
cb(id);
});
}); });
}; };
Store.updateSharedFolderPassword = function (clientId, data, cb) { Store.updateSharedFolderPassword = function (clientId, data, cb) {
@ -2501,8 +2517,10 @@ define([
}); });
}; };
var onReady = function (clientId, returned, cb) { var onCacheReady = function (clientId, cb) {
var proxy = store.proxy; var proxy = store.proxy;
if (!proxy.settings) { proxy.settings = NEW_USER_SETTINGS; }
if (!proxy.friends_pending) { proxy.friends_pending = {}; }
var unpin = function (data, cb) { var unpin = function (data, cb) {
if (!store.loggedIn) { return void cb(); } if (!store.loggedIn) { return void cb(); }
Store.unpinPads(null, data, cb); Store.unpinPads(null, data, cb);
@ -2511,8 +2529,6 @@ define([
if (!store.loggedIn) { return void cb(); } if (!store.loggedIn) { return void cb(); }
Store.pinPads(null, data, cb); Store.pinPads(null, data, cb);
}; };
if (!proxy.settings) { proxy.settings = NEW_USER_SETTINGS; }
if (!proxy.friends_pending) { proxy.friends_pending = {}; }
var manager = store.manager = ProxyManager.create(proxy.drive, { var manager = store.manager = ProxyManager.create(proxy.drive, {
onSync: function (cb) { onSync(null, cb); }, onSync: function (cb) { onSync(null, cb); },
edPublic: proxy.edPublic, edPublic: proxy.edPublic,
@ -2534,9 +2550,24 @@ define([
}); });
var userObject = store.userObject = manager.user.userObject; var userObject = store.userObject = manager.user.userObject;
addSharedFolderHandler(); addSharedFolderHandler();
userObject.migrate(cb);
};
// onReady: called when the drive is synced (not using the cache anymore)
// "cb" is wrapped in Util.once() and may have already been called
// if we have a local cache
var onReady = function (clientId, returned, cb) {
console.error('READY');
store.ready = true;
var proxy = store.proxy;
var manager = store.manager;
var userObject = store.userObject;
nThen(function (waitFor) { nThen(function (waitFor) {
userObject.migrate(waitFor()); if (manager) { return; }
onCacheReady(clientId, waitFor());
manager = store.manager;
userObject = store.userObject;
}).nThen(function (waitFor) { }).nThen(function (waitFor) {
initAnonRpc(null, null, waitFor()); initAnonRpc(null, null, waitFor());
initRpc(null, null, waitFor()); initRpc(null, null, waitFor());
@ -2569,7 +2600,7 @@ define([
loadUniversal(Messenger, 'messenger', waitFor); loadUniversal(Messenger, 'messenger', waitFor);
store.messenger = store.modules['messenger']; store.messenger = store.modules['messenger'];
loadUniversal(Profile, 'profile', waitFor); loadUniversal(Profile, 'profile', waitFor);
loadUniversal(Team, 'team', waitFor, clientId); loadUniversal(Team, 'team', waitFor, clientId); // XXX load teams offline?
loadUniversal(History, 'history', waitFor); loadUniversal(History, 'history', waitFor);
}).nThen(function () { }).nThen(function () {
var requestLogin = function () { var requestLogin = function () {
@ -2606,7 +2637,14 @@ define([
returned.feedback = Util.find(proxy, ['settings', 'general', 'allowUserFeedback']); returned.feedback = Util.find(proxy, ['settings', 'general', 'allowUserFeedback']);
Feedback.init(returned.feedback); Feedback.init(returned.feedback);
// XXX send feedback and logintoken to outer...
// "cb" may have already been called by onCacheReady
if (typeof(cb) === 'function') { cb(returned); } if (typeof(cb) === 'function') { cb(returned); }
sendDriveEvent('NETWORK_RECONNECT');
broadcast([], "UPDATE_METADATA");
store.offline = false;
// XXX broadcast READY event with the missing data
// XXX we can improve feedback to queue the queries and send them when coming back online
if (typeof(proxy.uid) !== 'string' || proxy.uid.length !== 32) { if (typeof(proxy.uid) !== 'string' || proxy.uid.length !== 32) {
// even anonymous users should have a persistent, unique-ish id // even anonymous users should have a persistent, unique-ish id
@ -2662,6 +2700,8 @@ define([
}); });
loadMailbox(); loadMailbox();
onReadyEvt.fire();
}); });
}; };
@ -2705,8 +2745,17 @@ define([
if (!data.userHash) { if (!data.userHash) {
returned.anonHash = Hash.getEditHashFromKeys(secret); returned.anonHash = Hash.getEditHashFromKeys(secret);
} }
}).on('cacheready', function (info) {
if (!data.cache) { return; }
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) { }).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; store.driveMetadata = info.metadata;
if (!rt.proxy.drive || typeof(rt.proxy.drive) !== 'object') { rt.proxy.drive = {}; } if (!rt.proxy.drive || typeof(rt.proxy.drive) !== 'object') { rt.proxy.drive = {}; }
var drive = rt.proxy.drive; var drive = rt.proxy.drive;
@ -2732,10 +2781,12 @@ define([
rt.proxy.on('disconnect', function () { rt.proxy.on('disconnect', function () {
store.offline = true; store.offline = true;
sendDriveEvent('NETWORK_DISCONNECT'); sendDriveEvent('NETWORK_DISCONNECT');
broadcast([], "UPDATE_METADATA");
}); });
rt.proxy.on('reconnect', function () { rt.proxy.on('reconnect', function () {
store.offline = false; store.offline = false;
sendDriveEvent('NETWORK_RECONNECT'); sendDriveEvent('NETWORK_RECONNECT');
broadcast([], "UPDATE_METADATA");
}); });
// Ping clients regularly to make sure one tab was not closed without sending a removeClient() // Ping clients regularly to make sure one tab was not closed without sending a removeClient()

@ -128,11 +128,11 @@ define([
var uo = store.manager.addProxy(id, sf.rt, leave, secondaryKey); var uo = store.manager.addProxy(id, sf.rt, leave, secondaryKey);
// NOTE: Shared folder migration, disable for now // NOTE: Shared folder migration, disable for now
SF.checkMigration(secondaryKey, sf.rt.proxy, uo, function () { SF.checkMigration(secondaryKey, sf.rt.proxy, uo, function () {
cb(sf.rt, sf.metadata); cb(sf.rt);
}); });
*/ */
store.manager.addProxy(id, sf.rt, leave, secondaryKey); store.manager.addProxy(id, sf.rt, leave, secondaryKey);
cb(sf.rt, sf.metadata); cb(sf.rt);
}); });
sf.teams.push({ sf.teams.push({
cb: cb, cb: cb,
@ -182,7 +182,27 @@ define([
} }
}; };
var rt = sf.rt = Listmap.create(listmapConfig); var rt = sf.rt = Listmap.create(listmapConfig);
rt.proxy.on('ready', function (info) { rt.proxy.on('cacheready', function () {
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 () {
if (isNew && !Object.keys(rt.proxy).length) { if (isNew && !Object.keys(rt.proxy).length) {
// New Shared folder: no migration required // New Shared folder: no migration required
rt.proxy.version = 2; rt.proxy.version = 2;
@ -196,13 +216,13 @@ define([
var uo = obj.store.manager.addProxy(obj.id, rt, leave, obj.secondaryKey); var uo = obj.store.manager.addProxy(obj.id, rt, leave, obj.secondaryKey);
// NOTE: Shared folder migration, disable for now // NOTE: Shared folder migration, disable for now
SF.checkMigration(secondaryKey, rt.proxy, uo, function () { 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.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; sf.ready = true;
}); });
rt.proxy.on('error', function (info) { rt.proxy.on('error', function (info) {

@ -17,6 +17,15 @@ define([
// Add a shared folder to the list // Add a shared folder to the list
var addProxy = function (Env, id, lm, leave, editKey) { 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); var cfg = getConfig(Env);
cfg.sharedFolder = true; cfg.sharedFolder = true;
cfg.id = id; cfg.id = id;
@ -38,7 +47,8 @@ define([
Env.folders[id] = { Env.folders[id] = {
proxy: lm.proxy, proxy: lm.proxy,
userObject: userObject, userObject: userObject,
leave: leave leave: leave,
offline: Boolean(lm.cache)
}; };
if (proxy.on) { if (proxy.on) {
proxy.on('disconnect', function () { proxy.on('disconnect', function () {
@ -537,7 +547,7 @@ define([
Env.user.userObject.add(id, resolved.path); Env.user.userObject.add(id, resolved.path);
// 2b. load the proxy // 2b. load the proxy
Env.loadSharedFolder(id, folderData, waitFor(function (rt, metadata) { Env.loadSharedFolder(id, folderData, waitFor(function (rt) {
if (!rt) { if (!rt) {
waitFor.abort(); waitFor.abort();
return void cb({ error: 'EDELETED' }); return void cb({ error: 'EDELETED' });
@ -546,11 +556,13 @@ define([
if (!rt.proxy.metadata) { // Creating a new shared folder if (!rt.proxy.metadata) { // Creating a new shared folder
rt.proxy.metadata = { title: data.name || Messages.fm_newFolder }; rt.proxy.metadata = { title: data.name || Messages.fm_newFolder };
} }
// If we're importing a folder, check its serverside metadata if (data.folderData) {
if (data.folderData && metadata) { // If we're importing a folder, check its serverside metadata
var fData = Env.user.proxy[UserObject.SHARED_FOLDERS][id]; Env.Store.getPadMetadata(null, { channel: folderData.channel }, function (md) {
if (metadata.owners) { fData.owners = metadata.owners; } var fData = Env.user.proxy[UserObject.SHARED_FOLDERS][id];
if (metadata.expire) { fData.expire = +metadata.expire; } if (md.owners) { fData.owners = md.owners; }
if (md.expire) { fData.expire = +md.expire; }
});
} }
}), !Boolean(data.folderData)); }), !Boolean(data.folderData));
}).nThen(function () { }).nThen(function () {

@ -15,6 +15,7 @@ define([
hash = obj.hash; hash = obj.hash;
}).nThen(function (/*waitFor*/) { }).nThen(function (/*waitFor*/) {
SFCommonO.start({ SFCommonO.start({
cache: true,
hash: hash, hash: hash,
href: href, href: href,
useCreationScreen: true, useCreationScreen: true,

@ -218,6 +218,7 @@ define([
Cryptpad.ready(waitFor(), { Cryptpad.ready(waitFor(), {
driveEvents: cfg.driveEvents, driveEvents: cfg.driveEvents,
cache: Boolean(cfg.cache),
currentPad: currentPad currentPad: currentPad
}); });
@ -497,7 +498,11 @@ define([
// We've received a link without /p/ and it doesn't work without a password: abort // We've received a link without /p/ and it doesn't work without a password: abort
return void todo(); return void todo();
} }
if (e === "ANON_RPC_NOT_READY") {
// We're currently offline and the pad is not in our cache
w.abort();
return void sframeChan.event('EV_OFFLINE');
}
// Wrong password or deleted file? // Wrong password or deleted file?
askPassword(true, passwordCfg); askPassword(true, passwordCfg);
})); }));

@ -16,6 +16,7 @@ define([
'/common/metadata-manager.js', '/common/metadata-manager.js',
'/customize/application_config.js', '/customize/application_config.js',
'/common/outer/cache-store.js',
'/common/common-realtime.js', '/common/common-realtime.js',
'/common/common-util.js', '/common/common-util.js',
'/common/common-hash.js', '/common/common-hash.js',
@ -41,6 +42,7 @@ define([
MT, MT,
MetadataMgr, MetadataMgr,
AppConfig, AppConfig,
Cache,
CommonRealtime, CommonRealtime,
Util, Util,
Hash, Hash,
@ -186,14 +188,22 @@ define([
}; };
funcs.getFileSize = function (channelId, cb) { funcs.getFileSize = function (channelId, cb) {
funcs.sendAnonRpcMsg("GET_FILE_SIZE", channelId, function (data) { nThen(function (waitFor) {
if (!data) { return void cb("No response"); } Cache.getBlobCache(channelId, waitFor(function(err, blob) {
if (data.error) { return void cb(data.error); } if (err) { return; }
if (data.response && data.response.length && typeof(data.response[0]) === 'number') { waitFor.abort();
return void cb(void 0, data.response[0]); cb(null, blob.length);
} else { }));
cb('INVALID_RESPONSE'); }).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');
}
});
}); });
}; };
@ -764,6 +774,10 @@ define([
UI.errorLoadingScreen(Messages.restrictedError); 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 () { ctx.sframeChan.on("EV_PAD_PASSWORD_ERROR", function () {
UI.errorLoadingScreen(Messages.password_error_seed); UI.errorLoadingScreen(Messages.password_error_seed);
}); });

@ -367,6 +367,9 @@ MessengerUI, Messages) {
if (!toolbar.connected) { return; } if (!toolbar.connected) { return; }
updateUserList(toolbar, config); updateUserList(toolbar, config);
}); });
setTimeout(function () {
updateUserList(toolbar, config, true);
});
} }
}; };
@ -1288,8 +1291,8 @@ MessengerUI, Messages) {
if (typeof el !== "string" || !el.trim()) { return; } if (typeof el !== "string" || !el.trim()) { return; }
if (typeof tb[el] === "function") { if (typeof tb[el] === "function") {
if (!init && config.displayed.indexOf(el) !== -1) { return; } // Already done if (!init && config.displayed.indexOf(el) !== -1) { return; } // Already done
toolbar[el] = tb[el](toolbar, config);
if (!init) { config.displayed.push(el); } if (!init) { config.displayed.push(el); }
toolbar[el] = tb[el](toolbar, config);
} }
}); });
checkSize(); checkSize();

@ -278,6 +278,7 @@ define([
if (!proxy.drive || typeof(proxy.drive) !== 'object') { if (!proxy.drive || typeof(proxy.drive) !== 'object') {
throw new Error("Corrupted drive"); throw new Error("Corrupted drive");
} }
APP.online = !privateData.offline;
var drive = DriveUI.create(common, { var drive = DriveUI.create(common, {
$limit: usageBar && usageBar.$container, $limit: usageBar && usageBar.$container,
proxy: proxy, proxy: proxy,

@ -105,6 +105,7 @@ define([
hash: hash, hash: hash,
href: href, href: href,
afterSecrets: afterSecrets, afterSecrets: afterSecrets,
cache: true,
noHash: true, noHash: true,
noRealtime: true, noRealtime: true,
driveEvents: true, driveEvents: true,

@ -328,6 +328,7 @@ define([
}, true); }, true);
} }
driveAPP.online = !teamData.offline;
var drive = DriveUI.create(common, { var drive = DriveUI.create(common, {
proxy: proxy, proxy: proxy,
folders: folders, folders: folders,

Loading…
Cancel
Save