Get the channel history

pull/1/head
yflory 8 years ago
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 = {

@ -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…
Cancel
Save