Fix migration race condition and handle readonly users

pull/1/head
yflory 4 years ago
parent 800eb67934
commit a0b7f39fd3

@ -56,7 +56,7 @@ define([
var DISPLAY_RESTORE_BUTTON = false; var DISPLAY_RESTORE_BUTTON = false;
var NEW_VERSION = 3; var NEW_VERSION = 3;
var PENDING_TIMEOUT = 30000; var PENDING_TIMEOUT = 30000;
var READ_ONLY_REFRESH_DATA_DELAY = 15000; var READONLY_REFRESH_TO = 15000;
var debug = function (x) { var debug = function (x) {
if (!window.CP_DEV_MODE) { return; } if (!window.CP_DEV_MODE) { return; }
@ -112,7 +112,7 @@ define([
return window.frames[0].editor || window.frames[0].editorCell; return window.frames[0].editor || window.frames[0].editorCell;
}; };
var setEditable = function (state) { var setEditable = function (state, force) {
$('#cp-app-oo-editor').find('#cp-app-oo-offline').remove(); $('#cp-app-oo-editor').find('#cp-app-oo-offline').remove();
/* /*
try { try {
@ -120,7 +120,7 @@ define([
//window.frames[0].editor.setViewModeDisconnect(true); //window.frames[0].editor.setViewModeDisconnect(true);
} catch (e) {} } catch (e) {}
*/ */
if (!state && !readOnly) { if (!state && (!readOnly || force)) {
$('#cp-app-oo-editor').append(h('div#cp-app-oo-offline')); $('#cp-app-oo-editor').append(h('div#cp-app-oo-offline'));
} }
}; };
@ -272,6 +272,7 @@ define([
} }
}; };
/*
var checkDrawings = function () { var checkDrawings = function () {
var editor = getEditor(); var editor = getEditor();
if (!editor || !editor.GetSheets) { return false; } if (!editor || !editor.GetSheets) { return false; }
@ -280,6 +281,7 @@ define([
return obj.worksheet.Drawings.length; return obj.worksheet.Drawings.length;
}); });
}; };
*/
// DEPRECATED from version 3 // DEPRECATED from version 3
// Loading a checkpoint reorder the sheet starting from ID "5". // Loading a checkpoint reorder the sheet starting from ID "5".
@ -328,11 +330,8 @@ define([
index: ev.index index: ev.index
}; };
oldHashes = JSON.parse(JSON.stringify(content.hashes)); oldHashes = JSON.parse(JSON.stringify(content.hashes));
var hasDrawings = checkDrawings(); content.locks = {};
if (hasDrawings) { content.ids = {};
content.locks = {};
content.ids = {};
}
// If this is a migration, set the new version // If this is a migration, set the new version
if (APP.migrate) { if (APP.migrate) {
delete content.migration; delete content.migration;
@ -388,6 +387,9 @@ define([
}; };
var resetData = function (blob, type) { var resetData = function (blob, type) {
// If a read-only refresh popup was planned, abort it
clearTimeout(APP.refreshRoTo);
if (!isLockedModal.modal) { if (!isLockedModal.modal) {
isLockedModal.modal = UI.openCustomModal(isLockedModal.content); isLockedModal.modal = UI.openCustomModal(isLockedModal.content);
} }
@ -415,14 +417,11 @@ define([
}; };
fixSheets(); fixSheets();
var hasDrawings = checkDrawings(); ooChannel.ready = false;
if (hasDrawings) { ooChannel.queue = [];
ooChannel.ready = false; data.callback = function () {
ooChannel.queue = []; resetData(blob, file);
data.callback = function () { };
resetData(blob, file);
};
}
APP.FM.handleFile(blob, data); APP.FM.handleFile(blob, data);
}; };
@ -612,6 +611,7 @@ define([
sframeChan.on('EV_OO_EVENT', function (obj) { sframeChan.on('EV_OO_EVENT', function (obj) {
switch (obj.ev) { switch (obj.ev) {
case 'READY': case 'READY':
cb();
break; break;
case 'LEAVE': case 'LEAVE':
removeClient(obj.data); removeClient(obj.data);
@ -627,7 +627,7 @@ define([
// Don't "spam" the user instantly and no more than // Don't "spam" the user instantly and no more than
// 1 popup every 15s // 1 popup every 15s
setTimeout(refreshReadOnly, READ_ONLY_REFRESH_DATA_DELAY); APP.refreshRoTo = setTimeout(refreshReadOnly, READONLY_REFRESH_TO);
return; return;
} }
ooChannel.send(obj.data.msg); ooChannel.send(obj.data.msg);
@ -639,7 +639,6 @@ define([
break; break;
} }
}); });
cb();
}; };
var getParticipants = function () { var getParticipants = function () {
@ -762,6 +761,8 @@ define([
ooChannel.cpIndex += ooChannel.queue.length; ooChannel.cpIndex += ooChannel.queue.length;
var last = ooChannel.queue.pop(); var last = ooChannel.queue.pop();
if (last) { ooChannel.lastHash = last.hash; } if (last) { ooChannel.lastHash = last.hash; }
} else {
setEditable(false, true);
} }
send({ send({
type: "authChanges", type: "authChanges",
@ -1015,6 +1016,10 @@ define([
index: -1 index: -1
}); });
} }
if (APP.onDocumentUnlock) {
APP.onDocumentUnlock();
APP.onDocumentUnlock = undefined;
}
break; break;
} }
}); });
@ -1095,35 +1100,65 @@ define([
} }
}, },
"onDocumentReady": function () { "onDocumentReady": function () {
var onMigrateRdy = Util.mkEvent();
onMigrateRdy.reg(function () {
var div = h('div.cp-oo-x2tXls', [
h('span.fa.fa-spin.fa-spinner'),
h('span', Messages.oo_sheetMigration_loading) // XXX tell them that it will take ~ 1min)
]);
UI.openCustomModal(UI.dialog.customModal(div, {buttons: []}));
makeCheckpoint(true);
});
// DEPRECATED: from version 3, the queue is sent again during init // DEPRECATED: from version 3, the queue is sent again during init
if (APP.migrate && ((content.version || 1) <= 2)) { if (APP.migrate && ((content.version || 1) <= 2)) {
// The doc is ready, fix the worksheets IDs and push the queue // The doc is ready, fix the worksheets IDs and push the queue
fixSheets(); fixSheets();
// Push changes since last cp // Push changes since last cp
ooChannel.ready = true; ooChannel.ready = true;
var changes = [];
var changesIndex;
ooChannel.queue.forEach(function (data) { ooChannel.queue.forEach(function (data) {
ooChannel.send(data.msg); Array.prototype.push.apply(changes, data.msg.changes);
changesIndex = data.msg.changesIndex;
//ooChannel.send(data.msg);
}); });
if (!readOnly) {
var last = ooChannel.queue.pop();
if (last) { ooChannel.lastHash = last.hash; }
}
ooChannel.cpIndex += ooChannel.queue.length; ooChannel.cpIndex += ooChannel.queue.length;
var last = ooChannel.queue.pop();
if (last) { ooChannel.lastHash = last.hash; }
// Apply existing locks var onDocUnlock = function () {
deleteOfflineLocks(); // Migration required but read-only: continue...
APP.onLocal(); if (readOnly) {
handleNewLocks(oldLocks, content.locks || {});
// Allow edition
if (lock) {
setTimeout(function () {
setEditable(true); setEditable(true);
getEditor().setViewModeDisconnect(); getEditor().setViewModeDisconnect();
}, 60000); } else {
} else { // No changes after the cp: migrate now
setEditable(true); onMigrateRdy.fire();
}
};
// Send the changes all at once
if (changes.length) {
setTimeout(function () {
ooChannel.send({
type: 'saveChanges',
changesIndex: changesIndex,
changes: changes,
locks: []
});
APP.onDocumentUnlock = onDocUnlock;
}, 5000);
return;
} }
onDocUnlock();
return;
}
if (lock) {
getEditor().setViewModeDisconnect();
} else {
setEditable(true);
} }
if (isLockedModal.modal && force) { if (isLockedModal.modal && force) {
@ -1133,14 +1168,7 @@ define([
} }
if (APP.migrate && !readOnly) { if (APP.migrate && !readOnly) {
var div = h('div.cp-oo-x2tXls', [ onMigrateRdy.fire();
h('span.fa.fa-spin.fa-spinner'),
h('span', Messages.oo_sheetMigration_loading) // XXX tell them that it will take ~ 1min)
]);
UI.openCustomModal(UI.dialog.customModal(div, {buttons: []}));
setTimeout(function () {
makeCheckpoint(true);
}, 60000);
} }
} }
} }
@ -1791,19 +1819,19 @@ define([
} else if (content && (!content.version || content.version === 1)) { } else if (content && (!content.version || content.version === 1)) {
version = 'v1/'; version = 'v1/';
APP.migrate = true; APP.migrate = true;
// Registedred users can start the migration // Registedred ~~users~~ editors can start the migration
if (common.isLoggedIn()) { if (common.isLoggedIn() && !readOnly) {
content.migration = true; content.migration = true;
APP.onLocal(); APP.onLocal();
} else { } else {
var msg = h('div.alert.alert-warning.cp-burn-after-reading', Messages.oo_sheetMigration_anonymousEditor); var msg = h('div.alert.alert-warning.cp-burn-after-reading', Messages.oo_sheetMigration_anonymousEditor); // XXX update: "anonymous users or viewers"
$(APP.helpMenu.menu).after(msg); $(APP.helpMenu.menu).after(msg);
readOnly = true; readOnly = true;
} }
} else if (content && content.version === 2) { } else if (content && content.version === 2) {
APP.migrate = true; APP.migrate = true;
// Registedred users can start the migration // Registedred ~~users~~ editors can start the migration
if (common.isLoggedIn()) { if (common.isLoggedIn() && !readOnly) {
content.migration = true; content.migration = true;
APP.onLocal(); APP.onLocal();
} else { } else {
@ -1854,15 +1882,12 @@ define([
var reloadPopup = false; var reloadPopup = false;
var checkNewCheckpoint = function () { var checkNewCheckpoint = function () {
var hasDrawings = checkDrawings(); var lastCp = getLastCp();
if (hasDrawings) { loadLastDocument(lastCp, function () {
var lastCp = getLastCp(); // On error, do nothing
loadLastDocument(lastCp, function () { }, function (blob, type) {
// On error, do nothing resetData(blob, type);
}, function (blob, type) { });
resetData(blob, type);
});
}
}; };
config.onRemote = function () { config.onRemote = function () {
@ -1891,10 +1916,7 @@ define([
var newLatest = getLastCp(); var newLatest = getLastCp();
if (newLatest.index > latest.index) { if (newLatest.index > latest.index) {
ooChannel.queue = []; ooChannel.queue = [];
var hasDrawings = checkDrawings(); ooChannel.ready = false;
if (hasDrawings) {
ooChannel.ready = false;
}
// New checkpoint // New checkpoint
sframeChan.query('Q_OO_SAVE', { sframeChan.query('Q_OO_SAVE', {
hash: newLatest.hash, hash: newLatest.hash,

Loading…
Cancel
Save