Better performances and UI for the debug tools

pull/1/head
yflory 6 years ago
parent ec33084226
commit 98bf773221

@ -524,7 +524,7 @@ define([
decryptedMsgs.push(crypto.decrypt(msg, true, true)); decryptedMsgs.push(crypto.decrypt(msg, true, true));
setTimeout(waitFor(function () { setTimeout(waitFor(function () {
sframeChan.event('EV_FULL_HISTORY_STATUS', (i+1)/total); sframeChan.event('EV_FULL_HISTORY_STATUS', (i+1)/total);
}), 5); }));
}).nThen; }).nThen;
}); });
nt(function () { nt(function () {

@ -22,6 +22,7 @@
display: none; display: none;
} }
#cp-app-debug-content { #cp-app-debug-content {
margin: 50px;
flex-flow: column; flex-flow: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -29,24 +30,33 @@
flex: 1; flex: 1;
min-height: 0; min-height: 0;
} }
.cp-app-debug-progress { .cp-app-debug-progress, .cp-app-debug-init {
width: 80%;
}
.cp-loading-progress-bar {
position: relative;
border: 1px solid #eee;
height: 36px;
}
#cp-app-debug-progres-bar-text {
position: absolute;
width: 100%;
text-align: center; text-align: center;
height: 100%;
line-height: 36px;
} }
#cp-app-debug-loading { #cp-app-debug-loading {
text-align: center; text-align: center;
} }
.cp-app-debug-content-hrefs {
td, th {
max-width: 300px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 0 20px;
}
td:nth-child(3) {
max-width: 500px;
}
.cp-debug-ok {
background-color: #eeffee;
}
.cp-debug-nok {
background-color: #ffeeee;
}
tr:not(:first-child):hover {
background-color: rgba(0,0,0,0.1);
}
}
} }
} }

@ -1759,21 +1759,23 @@ var getDepthOfState = function (content, minDepth, realtime) {
return -1; return -1;
}; };
var getContentAtState = function (realtime, msg) { var getContentAtState = function (realtime, msg, previousDoc) {
var patches = [ msg ]; var patches = [ msg ];
while (patches[0] !== realtime.rootMessage) { var doc = previousDoc || '';
var parent = getParent(realtime, patches[0]); if (!previousDoc) {
if (!parent) { while (patches[0] !== realtime.rootMessage) {
return { error: 'not connected to root', doc: undefined }; var parent = getParent(realtime, patches[0]);
if (!parent) {
return { error: 'not connected to root', doc: undefined };
}
patches.unshift(parent);
}
if (realtime.rootMessage.content.operations.length) {
Common.assert(realtime.rootMessage.content.operations.length === 1);
doc = realtime.rootMessage.content.operations[0].toInsert;
} }
patches.unshift(parent);
}
var doc = '';
if (realtime.rootMessage.content.operations.length) {
Common.assert(realtime.rootMessage.content.operations.length === 1);
doc = realtime.rootMessage.content.operations[0].toInsert;
} }
for (var i = 1; i < patches.length; i++) { for (var i = previousDoc?0:1; i < patches.length; i++) {
doc = Patch.apply(patches[i].content, doc); doc = Patch.apply(patches[i].content, doc);
} }
return { error: undefined, doc: doc }; return { error: undefined, doc: doc };
@ -1795,7 +1797,7 @@ export type ChainPad_Block_t = {
parentCount: number, parentCount: number,
getParent: ()=>?ChainPad_Block_t, getParent: ()=>?ChainPad_Block_t,
getChildren: ()=>Array<ChainPad_Block_t>, getChildren: ()=>Array<ChainPad_Block_t>,
getContent: ()=>{ getContent: (?string)=>{
error: ?string, error: ?string,
doc: ?string doc: ?string
}, },
@ -1825,7 +1827,7 @@ var wrapMessage = function (realtime, msg) /*:ChainPad_Block_t*/ {
return wrapMessage(realtime, x); return wrapMessage(realtime, x);
}); });
}, },
getContent: function () { return getContentAtState(realtime, msg); }, getContent: function (previous) { return getContentAtState(realtime, msg, previous); },
getPatch: function () { return Patch.clone(msg.content); }, getPatch: function () { return Patch.clone(msg.content); },
getInversePatch: function () { return Patch.clone(inversePatch(msg.content)); }, getInversePatch: function () { return Patch.clone(inversePatch(msg.content)); },
equals: function (block, msgOpt) { equals: function (block, msgOpt) {

@ -66,19 +66,24 @@ define([
var getHrefsTable = function (chainpad, length, cb, progress) { var getHrefsTable = function (chainpad, length, cb, progress) {
var priv = metadataMgr.getPrivateData(); var priv = metadataMgr.getPrivateData();
var origin = priv.origin;
var edPublic = priv.edPublic; var edPublic = priv.edPublic;
var pads = {}; var pads = {};
var channelByHref = {};
var isOwned = function (data) { var isOwned = function (data) {
data = data || {}; data = data || {};
return data && data.owners && Array.isArray(data.owners) && data.owners.indexOf(edPublic) !== -1; return data && data.owners && Array.isArray(data.owners) && data.owners.indexOf(edPublic) !== -1;
}; };
var parseBlock = function (block) { var parseBlock = function (block, doc) {
var c = block.getContent().doc; var c = block.getContent(doc).doc;
if (!c) { return void console.error(block); } if (!c) { return void console.error(block); }
var p; var p;
try { try {
p = JSON.parse(c).drive || {}; p = JSON.parse(c);
if (!p.metadata) {
p = p.drive || {};
}
} catch (e) { } catch (e) {
console.error(e); console.error(e);
p = {}; p = {};
@ -93,18 +98,20 @@ define([
try { try {
pad = old[i]; pad = old[i];
href = pad.href || pad.roHref; href = pad.href || pad.roHref;
if (href) { chan = channelByHref[href];
if (!chan && href) {
parsed = Hash.parsePadUrl(href); parsed = Hash.parsePadUrl(href);
chan = (Hash.getSecrets(parsed.type, parsed.hash) || {}).channel; chan = parsed.hashData && Util.base64ToHex(parsed.hashData.channel || '');
if (chan && (!pads[chan] || pads[chan].atime < pad.atime)) { channelByHref[href] = chan;
pads[chan] = { }
atime: +new Date(pad.atime), if (chan && (!pads[chan] || pads[chan].atime < pad.atime)) {
href: href, pads[chan] = {
title: pad.title, atime: +new Date(pad.atime),
owned: isOwned(pad), href: href,
expired: pad.expire && pad.expire < (+new Date()) title: pad.title,
}; owned: isOwned(pad),
} expired: pad.expire && pad.expire < (+new Date())
};
} }
} catch (e) {} } catch (e) {}
} }
@ -114,12 +121,14 @@ define([
for (var id in ids) { for (var id in ids) {
try { try {
pad = ids[id]; pad = ids[id];
chan = pad.channel;
href = pad.href || pad.roHref; href = pad.href || pad.roHref;
chan = pad.channel || channelByHref[href];
if (!chan) { if (!chan) {
if (href) { if (href) {
parsed = Hash.parsePadUrl(href); parsed = Hash.parsePadUrl(href);
chan = (Hash.getSecrets(parsed.type, parsed.hash, pad.password) || {}).channel; chan = (parsed.hashData && Util.base64ToHex(parsed.hashData.channel || '')) ||
(Hash.getSecrets(parsed.type, parsed.hash, pad.password) || {}).channel;
channelByHref[href] = chan;
} }
} }
if (chan && (!pads[chan] || pads[chan].atime < pad.atime)) { if (chan && (!pads[chan] || pads[chan].atime < pad.atime)) {
@ -134,30 +143,33 @@ define([
} catch (e) {} } catch (e) {}
} }
} }
return c;
}; };
var nt = nThen;
// Safely get all the pads from all the states
var i = 0;
var next = function (block) {
nt = nt(function (waitFor) {
i++;
parseBlock(block);
progress(Math.min(i/length, 1));
setTimeout(waitFor(), 1);
}).nThen;
var c = block.getChildren();
c.forEach(next);
};
var root = chainpad.getRootBlock();
next(root);
// Make the table
var allChannels; var allChannels;
var deleted; var deleted;
nt(function (waitFor) {
nThen(function (W) {
var nt = nThen;
// Safely get all the pads from all the states
var i = 0;
var next = function (block, doc) {
nt = nt(W(function (waitFor) {
i++;
var doc2 = parseBlock(block, doc);
progress(Math.min(i/length, 1));
var c = block.getChildren();
setTimeout(waitFor(), 1);
c.forEach(function (b) {
next(b, doc2);
});
})).nThen;
};
var root = chainpad.getRootBlock();
next(root);
}).nThen(function (waitFor) {
// Make the table
allChannels = Object.keys(pads); allChannels = Object.keys(pads);
sframeChan.query('Q_DRIVE_GETDELETED', {list:allChannels}, waitFor(function (err, data) { sframeChan.query('Q_DRIVE_GETDELETED', {list:allChannels}, waitFor(function (err, data) {
deleted = data; deleted = data;
@ -166,15 +178,16 @@ define([
// Current status // Current status
try { try {
var parsed = JSON.parse(chainpad.getUserDoc()); var parsed = JSON.parse(chainpad.getUserDoc());
var channels = Object.keys(parsed.drive[Constants.storageKey] || {}).map(function (id) { var drive = parsed.metadata ? parsed : parsed.drive;
return parsed.drive[Constants.storageKey][id].channel; var channels = Object.keys(drive[Constants.storageKey] || {}).map(function (id) {
return drive[Constants.storageKey][id].channel;
}); });
} catch (e) { } catch (e) {
console.error(e); console.error(e);
} }
// Header // Header
var rows = [h('tr', [ // XXX var rows = [h('tr', [// TODO
h('th', '#'), h('th', '#'),
h('th', 'Title'), h('th', 'Title'),
h('th', 'URL'), h('th', 'URL'),
@ -190,14 +203,23 @@ define([
}); });
body.forEach(function (id, i) { body.forEach(function (id, i) {
var p = pads[id]; var p = pads[id];
var del = deleted.indexOf(id) !== -1;
var removed = channels.indexOf(id) === -1;
rows.push(h('tr', [ rows.push(h('tr', [
h('td', String(i+1)), h('td', String(i+1)),
h('td', p.title), h('td', {
h('td', p.href), title: p.title
}, p.title),
h('td', h('a', {
href: origin+p.href,
target: '_blank'
}, p.href)),
h('td', new Date(p.atime).toLocaleString()), h('td', new Date(p.atime).toLocaleString()),
h('td', p.owned ? 'Yes' : ''), h('td', p.owned ? 'Yes' : 'No'),
h('td', p.expired ? 'Expired' : (channels.indexOf(id) !== -1 ? 'Stored' : 'Deleted')), // XXX h('td'+(p.expired || removed ?'.cp-debug-nok':'.cp-debug-ok'),
h('td', deleted.indexOf(id) !== -1 ? 'Missing' : 'OK'), // XXX p.expired ? 'Expired' :
(!removed ? 'Stored' : 'Deleted')),// TODO
h('td'+(del?'.cp-debug-nok':'.cp-debug-ok'), del ? 'Missing' : 'Available'),// TODO
])); ]));
}); });
// Table // Table
@ -257,7 +279,7 @@ define([
nt = nt(function (waitFor) { nt = nt(function (waitFor) {
chainpad.message(msg); chainpad.message(msg);
progress(Math.min(i/length, 1)); progress(Math.min(i/length, 1));
setTimeout(waitFor(), 1); setTimeout(waitFor());
}).nThen; }).nThen;
}); });
nt(function () { nt(function () {
@ -273,6 +295,7 @@ define([
// Set spinner // Set spinner
var content = h('div#cp-app-debug-loading', [ var content = h('div#cp-app-debug-loading', [
h('h2', 'Step 1/3'),
h('p', 'Loading history from the server...'), h('p', 'Loading history from the server...'),
h('span.fa.fa-circle-o-notch.fa-spin.fa-3x.fa-fw') h('span.fa.fa-circle-o-notch.fa-spin.fa-3x.fa-fw')
]); ]);
@ -281,25 +304,22 @@ define([
// Update progress bar // Update progress bar
var decrypting = false; var decrypting = false;
var length = 0; var length = 0;
var decryptProgress = h('span', '0%');
sframeChan.on('EV_FULL_HISTORY_STATUS', function (progress) { sframeChan.on('EV_FULL_HISTORY_STATUS', function (progress) {
if (!decrypting) { if (!decrypting) {
// Add the progress bar the first time // Add the progress bar the first time
decrypting = true; decrypting = true;
var content = h('div.cp-app-debug-progress.cp-loading-progress', [ var content = h('div.cp-app-debug-progress.cp-loading-progress', [
h('h2', 'Step 2/3'),
h('p', 'Decrypting your history...'), h('p', 'Decrypting your history...'),
h('div.cp-loading-progress-bar', [ h('span.fa.fa-circle-o-notch.fa-spin.fa-3x.fa-fw'),
h('div.cp-loading-progress-bar-value#cp-app-debug-progress-bar'), h('br'),
h('span#cp-app-debug-progress-bar-text'), decryptProgress
])
]); ]);
$('#cp-app-debug-content').html('').append(content); $('#cp-app-debug-content').html('').append(content);
} }
length++; length++;
var progress = progress*100; decryptProgress.innerHTML = (progress*100).toFixed(2) + '%'
var $bar = $('#cp-app-debug-progress-bar');
var $barText = $('#cp-app-debug-progress-bar-text');
$bar.css('width', progress+'%');
$barText.text((Math.round(progress * 100) / 100) + '%');
}); });
// Get full history // Get full history
@ -310,14 +330,15 @@ define([
// Graph // Graph
var graph = h('div.cp-app-debug-content-graph'); var graph = h('div.cp-app-debug-content-graph');
var seeAllButton = h('button', 'Get the list'); var seeAllButton = h('button.btn.btn-success', 'Get the list');
var hrefs = h('div.cp-app-debug-content-hrefs', [ var hrefs = h('div.cp-app-debug-content-hrefs', [
h('h2', 'List all the pads ever stored in your CryptDrive'), // XXX h('h2', 'List all the pads ever stored in your CryptDrive'), // TODO
]); ]);
var parseProgress = h('span', '0%'); var parseProgress = h('span', '0%');
var content = h('div#cp-app-debug-loading', [ var content = h('div#cp-app-debug-loading', [
h('p', 'Parsing history...'),// XXX h('h2', 'Step 3/3'),
h('p', 'Parsing history...'),// TODO
h('span.fa.fa-circle-o-notch.fa-spin.fa-3x.fa-fw'), h('span.fa.fa-circle-o-notch.fa-spin.fa-3x.fa-fw'),
h('br'), h('br'),
parseProgress parseProgress
@ -338,8 +359,7 @@ define([
if (clicked) { return; } if (clicked) { return; }
clicked = true; clicked = true;
$(seeAllButton).remove(); $(seeAllButton).remove();
// XXX // Make the table
// Make table
var progress = h('span', '0%'); var progress = h('span', '0%');
var loading = h('div', [ var loading = h('div', [
'Loading data...', 'Loading data...',
@ -351,7 +371,7 @@ define([
loading.innerHTML = ''; loading.innerHTML = '';
hrefs.append(table); hrefs.append(table);
}, function (p) { }, function (p) {
progress.innerHTML = (Math.round(p*100*100)/100) + '%' progress.innerHTML = (p*100).toFixed(2) + '%'
}); });
}).appendTo(hrefs); }).appendTo(hrefs);
} }
@ -360,11 +380,11 @@ define([
var code = h('code'); var code = h('code');
getGraph(chainpad, function (graphVal) { getGraph(chainpad, function (graphVal) {
code.innerHTML = graphVal; code.innerHTML = graphVal;
$(graph).append(h('h2', 'Graph')); // XXX $(graph).append(h('h2', 'Graph')); // TODO
$(graph).append(code); $(graph).append(code);
}); });
}, function (p) { }, function (p) {
parseProgress.innerHTML = (Math.round(p*100*100)/100) + '%' parseProgress.innerHTML = (p*100).toFixed(2) + '%'
}); });
}, {timeout: 2147483647}); // Max 32-bit integer }, {timeout: 2147483647}); // Max 32-bit integer
}; };
@ -381,10 +401,10 @@ define([
$('#cp-app-debug-get-content').addClass('cp-toolbar-button-active'); $('#cp-app-debug-get-content').addClass('cp-toolbar-button-active');
}; };
var setInitContent = function () { var setInitContent = function () {
var button = h('button.btn.btn-primary', 'Load history'); var button = h('button.btn.btn-success', 'Load history');
$(button).click(getFullHistory); $(button).click(getFullHistory);
var content = h('p', [ var content = h('p.cp-app-debug-init', [
'To get better debugging tools, we need to load the entire history of the document. This make take some time.', // XXX 'To get better debugging tools, we need to load the entire history of the document. This make take some time.', // TODO
h('br'), h('br'),
button button
]); ]);
@ -454,7 +474,7 @@ define([
var $content = common.createButton(null, true, { var $content = common.createButton(null, true, {
icon: 'fa-question', icon: 'fa-question',
title: 'Get debugging graph', // XXX title: 'Get debugging graph', // TODO
name: 'graph', name: 'graph',
id: 'cp-app-debug-get-content' id: 'cp-app-debug-get-content'
}); });

@ -63,6 +63,11 @@ define([
} }
drive = true; drive = true;
window.location.hash = hash; window.location.hash = hash;
} else {
var p = Hash.parsePadUrl('/debug/'+window.location.hash);
if (p && p.hashData && p.hashData.app === 'drive') {
drive = true;
}
} }
var addData = function (meta) { var addData = function (meta) {
meta.debugDrive = drive; meta.debugDrive = drive;

Loading…
Cancel
Save