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; showVersion(); 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 showVersion = function () { var major = sortedCp.length - cpIndex; var v = major + '.' + msgIndex; $version.text("Version " + v); // XXX var $pos = $hist.find('.cp-toolbar-history-pos'); var cps = sortedCp.length; var id = sortedCp[cps - cpIndex -1] || -1; if (!ooMessages[id]) { return; } var msgs = ooMessages[id]; var p = 100*(msgIndex / (msgs.length-1)); $pos.css('margin-left', p+'%'); }; var $fastPrev = $('