diff --git a/www/common/sframe-app-framework.js b/www/common/sframe-app-framework.js index 88a81f90f..b66294416 100644 --- a/www/common/sframe-app-framework.js +++ b/www/common/sframe-app-framework.js @@ -339,6 +339,34 @@ define([ }); }; + // Get the realtime metadata when in history mode + var getLastMetadata = function () { + if (!unsyncMode) { return; } + var newContentStr = cpNfInner.chainpad.getUserDoc(); + var newContent = JSON.parse(newContentStr); + var meta = extractMetadata(newContent); + return meta; + }; + var setLastMetadata = function (md) { + if (!unsyncMode) { return; } + var newContentStr = cpNfInner.chainpad.getAuthDoc(); + var newContent = JSON.parse(newContentStr); + if (Array.isArray(newContent)) { + newContent[3] = { + metadata: md + }; + } else { + newContent.metadata = md; + } + try { + cpNfInner.chainpad.contentUpdate(JSONSortify(newContent)); + return true; + } catch (e) { + console.error(e); + return false; + } + }; + /* var hasChanged = function (content) { try { @@ -767,7 +795,9 @@ define([ onLocal: onLocal, onRemote: onRemote, setHistory: setHistoryMode, - extractMetadata: extractMetadata, + extractMetadata: extractMetadata, // extract from current version + getLastMetadata: getLastMetadata, // get from authdoc + setLastMetadata: setLastMetadata, // set to userdoc/authdoc applyVal: function (val) { var newContent = JSON.parse(val); var meta = extractMetadata(newContent); diff --git a/www/common/sframe-common-history.js b/www/common/sframe-common-history.js index c97ccd633..865b7fb3b 100644 --- a/www/common/sframe-common-history.js +++ b/www/common/sframe-common-history.js @@ -1,13 +1,14 @@ define([ 'jquery', '/common/common-interface.js', + '/common/common-util.js', '/common/hyperscript.js', '/customize/messages.js', '/bower_components/nthen/index.js', //'/bower_components/chainpad-json-validator/json-ot.js', '/bower_components/chainpad/chainpad.dist.js', -], function ($, UI, h, Messages, nThen, ChainPad /* JsonOT */) { +], function ($, UI, Util, h, Messages, nThen, ChainPad /* JsonOT */) { //var ChainPad = window.ChainPad; var History = {}; @@ -103,9 +104,9 @@ define([ }; // Refresh the timeline UI with the block states - var refreshBar = function () { + var refreshBar = function (snapshotsOnly) { var $pos = $hist.find('.cp-history-timeline-pos'); - var $bar = $(bar).html(''); + var $bar = $(bar); var users = { list: [], author: '', @@ -121,20 +122,23 @@ define([ var snapshotsData = {}; var snapshots = []; - try { - if (config.extractMetadata) { - var idx = states.length - 1; - var val = JSON.parse(states[idx].getContent().doc); - var md = config.extractMetadata(val); + if (config.getLastMetadata) { + try { + var md = config.getLastMetadata(); if (md.snapshots) { snapshotsData = md.snapshots; snapshots = Object.keys(md.snapshots); } - } - } catch (e) { console.error(e); } + } catch (e) { console.error(e); } + } var max = states.length - 1; + var snapshotsEl = []; + patchWidth = 100 / max; + + // Check if we need a new block on the index i for the "obj" type (user or users) var check = function (obj, author, i) { + if (snapshotsOnly) { return; } if (obj.author !== author) { obj.author = author; if (obj.el) { @@ -146,9 +150,6 @@ define([ } }; - var snapshotsEl = []; - patchWidth = 100 / max; - var hash; for (var i = 1; i < states.length; i++) { hash = states[i].serverHash; @@ -161,17 +162,26 @@ define([ check(user, getAuthor(i, 1), i); check(users, getAuthor(i, 2), i); } - $(user.el).css('width', (100*(max + 1 - user.i)/max)+'%'); - $(users.el).css('width', (100*(max + 1 - users.i)/max)+'%'); - - $bar.append([ - h('span.cp-history-timeline-users', users.list), - h('span.cp-history-timeline-user', user.list), - h('div.cp-history-snapshots', [ - $pos[0], + + if (snapshotsOnly) { + // We only want to redraw the snapshots + $bar.find('.cp-history-snapshotsi').html('').append([ + $pos, snapshotsEl - ]), - ]); + ]); + } else { + $(user.el).css('width', (100*(max + 1 - user.i)/max)+'%'); + $(users.el).css('width', (100*(max + 1 - users.i)/max)+'%'); + + $bar.html('').append([ + h('span.cp-history-timeline-users', users.list), + h('span.cp-history-timeline-user', user.list), + h('div.cp-history-snapshots', [ + $pos[0], + snapshotsEl + ]), + ]); + } onResize(); }; @@ -220,6 +230,20 @@ define([ Messages.history_cantRestore = "Can't restore now. Disconnected."; // XXX var onRevert = function () { + // Before we can restore the current version, we need to update metadataMgr + // so that it will uses the snapshots from the realtime version! + // Restoring the snapshots to their old version would go against the + // goal of having snapshots + if (config.getLastMetadata) { + var metadataMgr = common.getMetadataMgr(); + var lastMd = config.getLastMetadata(); + var _snapshots = lastMd.snapshots; + var md = Util.clone(metadataMgr.getMetadata()); + md.snapshots = _snapshots; + metadataMgr.updateMetadata(md); + } + + // And now we can properly restore the content var closed = config.setHistory(false, false); if (!closed) { return void UI.alert(Messages.history_cantRestore); @@ -350,6 +374,27 @@ define([ }; */ + var makeSnapshot = function (title) { + var idx = getIndex(c); + if (!config.getLastMetadata || !config.setLastMetadata) { return; } + try { + var block = states[idx]; + var hash = block.serverHash; + var md = config.getLastMetadata(); + md.snapshots = md.snapshots || {}; + if (md.snapshots[hash]) { return; } + md.snapshots[hash] = { + title: title, + time: block.time ? (+new Date(block.time)) : +new Date() + }; + var sent = config.setLastMetadata(md); + if (!sent) { return void UI.warn(Messages.error); } + refreshBar(); + } catch (e) { + console.error(e); + } + }; + Messages.history_fastPrev = "Previous editing session"; // XXX Messages.history_userPrev = "Previous user"; // XXX Messages.history_fastNext = "Next editing session"; // XXX @@ -428,7 +473,6 @@ define([ Messages.history_shareTitle = "Share a link to this version"; // XXX var snapshot = h('button', { title: Messages.snapshots_new, - disabled: History.readOnly ? 'disabled' : undefined }, [ h('i.fa.fa-camera') ]); @@ -438,7 +482,6 @@ define([ ]); var restore = h('button', { title: Messages.history_restoreTitle, - disabled: History.readOnly ? 'disabled' : undefined }, [ h('i.fa.fa-check'), h('span', Messages.history_restore) @@ -458,78 +501,19 @@ define([ ]) ]); + if (History.readOnly) { + snapshot.disabled = true; + restore.disabled = true; + } + if (config.drive) { + snapshot.disabled = true; + share.disabled = true; + } + $hist.append([timeline, actions]); onResize(); $(window).on('resize', onResize); - /* - var $rev = $('