Get the channel history
This commit is contained in:
parent
525d35c9ec
commit
43c045721c
@ -409,6 +409,20 @@
|
|||||||
.cryptpad-toolbar-rightside {
|
.cryptpad-toolbar-rightside {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
.cryptpad-toolbar-history {
|
||||||
|
display: none;
|
||||||
|
text-align: center;
|
||||||
|
.next {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.previous {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.goto {
|
||||||
|
display: inline-block;
|
||||||
|
input { width: 50px; }
|
||||||
|
}
|
||||||
|
}
|
||||||
.cryptpad-spinner {
|
.cryptpad-spinner {
|
||||||
height: 16px;
|
height: 16px;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
|
|||||||
@ -472,6 +472,22 @@
|
|||||||
.cryptpad-toolbar-rightside {
|
.cryptpad-toolbar-rightside {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
.cryptpad-toolbar-history {
|
||||||
|
display: none;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.cryptpad-toolbar-history .next {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.cryptpad-toolbar-history .previous {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.cryptpad-toolbar-history .goto {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.cryptpad-toolbar-history .goto input {
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
.cryptpad-spinner {
|
.cryptpad-spinner {
|
||||||
height: 16px;
|
height: 16px;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
|
|||||||
@ -402,6 +402,21 @@ define([
|
|||||||
editHash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys);
|
editHash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* add an export button */
|
||||||
|
var $hist = Cryptpad.createButton();
|
||||||
|
var historyRender = function () {};
|
||||||
|
var historyClose = function () {
|
||||||
|
// TODO: enable onlocal, onremote... (or at least the display part)
|
||||||
|
};
|
||||||
|
var historyTodo = function (hist) {
|
||||||
|
hist.display($bar, historyRender, historyClose);
|
||||||
|
};
|
||||||
|
$hist.removeClass('fa-question').addClass('fa-history').click(function () {
|
||||||
|
// TODO: disable onlocal, onremote...
|
||||||
|
Cryptpad.getHistory(historyTodo);
|
||||||
|
});
|
||||||
|
$rightside.append($hist);
|
||||||
|
|
||||||
/* save as template */
|
/* save as template */
|
||||||
if (!Cryptpad.isTemplate(window.location.href)) {
|
if (!Cryptpad.isTemplate(window.location.href)) {
|
||||||
var templateObj = {
|
var templateObj = {
|
||||||
|
|||||||
156
www/common/common-history.js
Normal file
156
www/common/common-history.js
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
define([
|
||||||
|
'/bower_components/chainpad-json-validator/json-ot.js',
|
||||||
|
'/bower_components/chainpad-crypto/crypto.js',
|
||||||
|
'/bower_components/jquery/dist/jquery.min.js',
|
||||||
|
'/bower_components/chainpad/chainpad.dist.js',
|
||||||
|
], function (JsonOT, Crypto) {
|
||||||
|
var $ = window.jQuery;
|
||||||
|
var ChainPad = window.ChainPad;
|
||||||
|
var History = {};
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO
|
||||||
|
* Implement GET_FULL_HISTORY serverside
|
||||||
|
* All the history messages should be ['FULL_HISTORY', wc.id, msg]
|
||||||
|
* Send [FULL_HISTORY_END, wc.id]
|
||||||
|
*
|
||||||
|
* We also need a chainpad without pruning and with the ability to get old messages
|
||||||
|
*/
|
||||||
|
var loadHistory = function (common, cb) {
|
||||||
|
var network = common.getNetwork();
|
||||||
|
var hkn = network.historyKeeper;
|
||||||
|
|
||||||
|
var wcId = common.hrefToHexChannelId(window.location.href);
|
||||||
|
|
||||||
|
var createRealtime = function(chan) {
|
||||||
|
console.log(ChainPad);
|
||||||
|
return ChainPad.create({
|
||||||
|
userName: 'history',
|
||||||
|
initialState: '',
|
||||||
|
transformFunction: JsonOT.validate,
|
||||||
|
logLevel: 0
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var realtime = createRealtime();
|
||||||
|
|
||||||
|
var secret = Cryptpad.getSecrets();
|
||||||
|
var crypto = Crypto.createEncryptor(secret.keys);
|
||||||
|
|
||||||
|
var to = window.setTimeout(function () {
|
||||||
|
cb('[GET_FULL_HISTORY_TIMEOUT]');
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
|
var parse = function (msg) {
|
||||||
|
try {
|
||||||
|
return JSON.parse(msg);
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var onMsg = function (msg) {
|
||||||
|
var parsed = parse(msg);
|
||||||
|
if (parsed[0] === 'FULL_HISTORY_END') {
|
||||||
|
window.clearTimeout(to);
|
||||||
|
cb(null, realtime);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (parsed[0] !== 'FULL_HISTORY') { return; }
|
||||||
|
var msg = parsed[1];
|
||||||
|
var decryptedMsg = crypto.decrypt(msg, secret.keys.validateKey);
|
||||||
|
realtime.message(decryptedMsg);
|
||||||
|
};
|
||||||
|
|
||||||
|
network.on('message', function (msg, sender) {
|
||||||
|
onMsg(msg);
|
||||||
|
});
|
||||||
|
|
||||||
|
network.sendto(hkn, JSON.stringify(['GET_FULL_HISTORY', wcId]));
|
||||||
|
};
|
||||||
|
|
||||||
|
var create = History.create = function (common, cb) {
|
||||||
|
var exp = {};
|
||||||
|
|
||||||
|
var states = exp.states = ['a', 'b', 'c'];
|
||||||
|
var c = exp.current = states.length - 1;
|
||||||
|
console.log(c);
|
||||||
|
|
||||||
|
var onUpdate;
|
||||||
|
|
||||||
|
var update = exp.update = function () {
|
||||||
|
states = [];
|
||||||
|
if (typeof onUpdate === "function") { onUpdate(); }
|
||||||
|
return states;
|
||||||
|
};
|
||||||
|
|
||||||
|
var get = exp.get = function (i) {
|
||||||
|
i = parseInt(i);
|
||||||
|
console.log('getting', i);
|
||||||
|
if (typeof(i) !== "number" || i < 0 || i > states.length - 1) { return; }
|
||||||
|
var hash = states[i];
|
||||||
|
c = i;
|
||||||
|
if (typeof onUpdate === "function") { onUpdate(); }
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
|
||||||
|
var getNext = exp.getNext = function () {
|
||||||
|
if (c < states.length - 1) { return get(++c); }
|
||||||
|
};
|
||||||
|
var getPrevious = exp.getPrevious = function () {
|
||||||
|
if (c > 0) { return get(--c); }
|
||||||
|
};
|
||||||
|
|
||||||
|
var display = exp.display = function ($toolbar, render, onClose) {
|
||||||
|
var $hist = $toolbar.find('.cryptpad-toolbar-history').html('').show();
|
||||||
|
var $left = $toolbar.find('.cryptpad-toolbar-leftside').hide();
|
||||||
|
var $right = $toolbar.find('.cryptpad-toolbar-rightside').hide();
|
||||||
|
|
||||||
|
var $prev =$('<button>', {'class': 'previous'}).text('<<').appendTo($hist);
|
||||||
|
var $next = $('<button>', {'class': 'next'}).text('>>').appendTo($hist);
|
||||||
|
|
||||||
|
var $nav = $('<div>', {'class': 'goto'}).appendTo($hist);
|
||||||
|
var $cur = $('<input>', {
|
||||||
|
'type' : 'number',
|
||||||
|
'min' : '1',
|
||||||
|
'max' : states.length
|
||||||
|
}).val(c + 1).appendTo($nav);
|
||||||
|
var $label = $('<label>').text(' / '+ states.length).appendTo($nav);
|
||||||
|
var $goTo = $('<button>').text('V').appendTo($nav);
|
||||||
|
$('<br>').appendTo($nav);
|
||||||
|
var $rev = $('<button>', {'class':'revertHistory'}).text('TODO: revert').appendTo($nav);
|
||||||
|
var $close = $('<button>', {'class':'closeHistory'}).text('TODO: close').appendTo($nav);
|
||||||
|
|
||||||
|
onUpdate = function () {
|
||||||
|
$cur.attr('max', exp.states.length);
|
||||||
|
$cur.val(c+1);
|
||||||
|
};
|
||||||
|
|
||||||
|
var toRender = function (getter) {
|
||||||
|
return function () { render(getter()) };
|
||||||
|
};
|
||||||
|
|
||||||
|
$prev.click(toRender(getPrevious));
|
||||||
|
$next.click(toRender(getNext));
|
||||||
|
$goTo.click(function () {
|
||||||
|
render( get($cur.val() - 1) )
|
||||||
|
});
|
||||||
|
|
||||||
|
$close.click(function () {
|
||||||
|
$hist.hide();
|
||||||
|
$left.show();
|
||||||
|
$right.show();
|
||||||
|
onClose();
|
||||||
|
});
|
||||||
|
|
||||||
|
render(get(c));
|
||||||
|
};
|
||||||
|
|
||||||
|
loadHistory(common, function (err, newRt) {
|
||||||
|
if (err) { throw new Error(err); }
|
||||||
|
realtime = exp.realtime = newRt;
|
||||||
|
cb(exp);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return History;
|
||||||
|
});
|
||||||
|
|
||||||
@ -5,13 +5,14 @@ define([
|
|||||||
'/common/common-util.js',
|
'/common/common-util.js',
|
||||||
'/common/common-hash.js',
|
'/common/common-hash.js',
|
||||||
'/common/common-interface.js',
|
'/common/common-interface.js',
|
||||||
|
'/common/common-history.js',
|
||||||
|
|
||||||
'/common/clipboard.js',
|
'/common/clipboard.js',
|
||||||
'/common/pinpad.js',
|
'/common/pinpad.js',
|
||||||
'/customize/application_config.js',
|
'/customize/application_config.js',
|
||||||
|
|
||||||
'/bower_components/jquery/dist/jquery.min.js',
|
'/bower_components/jquery/dist/jquery.min.js',
|
||||||
], function (Config, Messages, Store, Util, Hash, UI, Clipboard, Pinpad, AppConfig) {
|
], function (Config, Messages, Store, Util, Hash, UI, History, Clipboard, Pinpad, AppConfig) {
|
||||||
/* This file exposes functionality which is specific to Cryptpad, but not to
|
/* This file exposes functionality which is specific to Cryptpad, but not to
|
||||||
any particular pad type. This includes functions for committing metadata
|
any particular pad type. This includes functions for committing metadata
|
||||||
about pads to your local storage for future use and improved usability.
|
about pads to your local storage for future use and improved usability.
|
||||||
@ -81,6 +82,11 @@ define([
|
|||||||
common.findWeaker = Hash.findWeaker;
|
common.findWeaker = Hash.findWeaker;
|
||||||
common.findStronger = Hash.findStronger;
|
common.findStronger = Hash.findStronger;
|
||||||
|
|
||||||
|
// History
|
||||||
|
common.getHistory = function (cb) {
|
||||||
|
return History.create(common, cb);
|
||||||
|
};
|
||||||
|
|
||||||
var getStore = common.getStore = function () {
|
var getStore = common.getStore = function () {
|
||||||
if (store) { return store; }
|
if (store) { return store; }
|
||||||
throw new Error("Store is not ready!");
|
throw new Error("Store is not ready!");
|
||||||
|
|||||||
@ -23,6 +23,7 @@ define([
|
|||||||
var TOP_CLS = Bar.constants.top = 'cryptpad-toolbar-top';
|
var TOP_CLS = Bar.constants.top = 'cryptpad-toolbar-top';
|
||||||
var LEFTSIDE_CLS = Bar.constants.leftside = 'cryptpad-toolbar-leftside';
|
var LEFTSIDE_CLS = Bar.constants.leftside = 'cryptpad-toolbar-leftside';
|
||||||
var RIGHTSIDE_CLS = Bar.constants.rightside = 'cryptpad-toolbar-rightside';
|
var RIGHTSIDE_CLS = Bar.constants.rightside = 'cryptpad-toolbar-rightside';
|
||||||
|
var HISTORY_CLS = Bar.constants.history = 'cryptpad-toolbar-history';
|
||||||
|
|
||||||
var SPINNER_CLS = Bar.constants.spinner = 'cryptpad-spinner';
|
var SPINNER_CLS = Bar.constants.spinner = 'cryptpad-spinner';
|
||||||
|
|
||||||
@ -74,7 +75,8 @@ define([
|
|||||||
})
|
})
|
||||||
.append($('<div>', {'class': TOP_CLS}))
|
.append($('<div>', {'class': TOP_CLS}))
|
||||||
.append($('<div>', {'class': LEFTSIDE_CLS}))
|
.append($('<div>', {'class': LEFTSIDE_CLS}))
|
||||||
.append($('<div>', {'class': RIGHTSIDE_CLS}));
|
.append($('<div>', {'class': RIGHTSIDE_CLS}))
|
||||||
|
.append($('<div>', {'class': HISTORY_CLS}));
|
||||||
|
|
||||||
// The 'notitle' class removes the line added for the title with a small screen
|
// The 'notitle' class removes the line added for the title with a small screen
|
||||||
if (!config || typeof config !== "object") {
|
if (!config || typeof config !== "object") {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user