From 4f147d4fd2fb3bf24a8a57ab167f1b352a169dcb Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 18 Sep 2020 17:54:57 +0200 Subject: [PATCH] Add support for onlyoffice history --- lib/workers/db-worker.js | 2 +- www/common/onlyoffice/history.js | 340 ++++++++++++++++++++++++++++++ www/common/onlyoffice/inner.js | 111 +++++++--- www/common/outer/async-store.js | 2 + www/common/outer/onlyoffice.js | 24 ++- www/common/sframe-common-outer.js | 2 +- 6 files changed, 439 insertions(+), 42 deletions(-) create mode 100644 www/common/onlyoffice/history.js diff --git a/lib/workers/db-worker.js b/lib/workers/db-worker.js index 87b8fe93a..681988ad0 100644 --- a/lib/workers/db-worker.js +++ b/lib/workers/db-worker.js @@ -255,7 +255,7 @@ const getOlderHistory = function (data, cb) { } else if (untilHash) { for (var i = messages.length - 1; i >= 0; i--) { toSend.unshift(messages[i]); - if (Array.isArray(messages[i]) && HK.getHash(messages[i][4], Log) === untilHash) { + if (Array.isArray(messages[i]) && HK.getHash(messages[i][4]) === untilHash) { break; } } diff --git a/www/common/onlyoffice/history.js b/www/common/onlyoffice/history.js new file mode 100644 index 000000000..e9f361f36 --- /dev/null +++ b/www/common/onlyoffice/history.js @@ -0,0 +1,340 @@ +define([ + 'jquery', + '/common/common-interface.js', + '/bower_components/nthen/index.js', + //'/bower_components/chainpad-json-validator/json-ot.js', +], function ($, UI, nThen, /* JsonOT */) { + //var ChainPad = window.ChainPad; + var History = {}; + + History.create = function (common, config) { + if (!config.$toolbar) { return void console.error("config.$toolbar is undefined");} + if (History.loading) { return void console.error("History is already being loaded..."); } + History.loading = true; + var $toolbar = config.$toolbar; + var sframeChan = common.getSframeChannel(); + + if (!config.onlyoffice || !config.setHistory || !config.onCheckpoint || !config.onPatch) { + throw new Error("Missing config element"); + } + + var cpIndex = -1; + var msgIndex = 0; + var sortedCp; + var ooMessages = {}; + var loading = false; + var update = function () {}; + + // Get an array of the checkpoint IDs sorted their patch index + var hashes = config.onlyoffice.hashes; + var sortedCp = Object.keys(hashes).map(Number).sort(function (a, b) { + return hashes[a].index - hashes[b].index; + }); + + var fillOO = function (id, messages) { + if (!id) { return; } + if (ooMessages[id]) { return; } + ooMessages[id] = messages; + update(); + }; + + // We want to load a checkpoint (or initial state) + var loadMoreOOHistory = function () { + if (!Array.isArray(sortedCp)) { return void console.error("Wrong type"); } + + var cp = {}; + + // Get the checkpoint ID + var id = -1; + if (cpIndex < sortedCp.length) { + id = sortedCp[sortedCp.length - 1 - cpIndex]; + cp = hashes[id]; + } + var nextId = sortedCp[sortedCp.length - cpIndex]; + + // Get the history between "toHash" and "fromHash". This function is using + // "getOlderHistory", that's why we start from the more recent hash + // and we go back in time to an older hash + + // We need to get all the patches between the current cp hash and the next cp hash + + // Current cp or initial hash (invalid hash ==> initial hash) + var toHash = cp.hash || 'NONE'; + // Next cp or last hash + var fromHash = nextId ? hashes[nextId].hash : config.onlyoffice.lastHash; + + msgIndex = 0; + if (ooMessages[id]) { + // Cp already loaded: reload OO + loading = false; + return void config.onCheckpoint(cp); + } + + sframeChan.query('Q_GET_HISTORY_RANGE', { + channel: config.onlyoffice.channel, + lastKnownHash: fromHash, + toHash: toHash, + }, function (err, data) { + if (err) { return void console.error(err); } + if (!Array.isArray(data.messages)) { return void console.error('Not an array!'); } + + var messages = (data.messages || []).slice(1); + + if (config.debug) { console.log(data.messages); } + fillOO(id, messages); + loading = false; + config.onCheckpoint(cp); + }); + }; + + // config.setHistory(bool, bool) + // - bool1: history value + // - bool2: reset old content? + var render = function (val) { + if (typeof val === "undefined") { return; } + try { + config.applyVal(val); + } catch (e) { + // Probably a parse error + console.error(e); + } + }; + var onClose = function () { config.setHistory(false); }; + var onRevert = function () { + config.onRevert(); + }; + + config.setHistory(true); + + var Messages = common.Messages; + + var realtime; + + var states = []; + var c = 0;//states.length - 1; + + var $hist = $toolbar.find('.cp-toolbar-history'); + var $bottom = $toolbar.find('.cp-toolbar-bottom'); + + $hist.html('').css('display', 'flex'); + $bottom.hide(); + + UI.spinner($hist).get().show(); + + var $loadMore, $version, get; + + var $fastPrev = $('