(trunk web) #5013 "WebUI Inspector file tree" -- possible reimplementation.

This commit is contained in:
Jordan Lee
2012-09-23 22:05:21 +00:00
parent 7b7da2d315
commit 53ef843cbd
2 changed files with 187 additions and 238 deletions

View File

@@ -222,18 +222,18 @@ function Inspector(controller) {
else {
d = u = 0;
if(torrents.length == 1) {
d = torrents[0].getDownloadedEver();
u = torrents[0].getUploadedEver();
if (d == 0)
d = torrents[0].getHaveValid();
d = torrents[0].getDownloadedEver();
u = torrents[0].getUploadedEver();
if (d == 0)
d = torrents[0].getHaveValid();
}
else {
for(i=0; t=torrents[i]; ++i) {
d += t.getDownloadedEver();
u += t.getUploadedEver();
}
}
for(i=0; t=torrents[i]; ++i) {
d += t.getDownloadedEver();
u += t.getUploadedEver();
}
}
str = fmt.size(u) + ' (Ratio: ' + fmt.ratioString( Math.ratio(u,d))+')';
}
setTextContent(e.uploaded_lb, str);
@@ -456,183 +456,127 @@ function Inspector(controller) {
***** FILES PAGE
****/
changeFileCommand = function(rows, command) {
changeFileCommand = function(fileIndices, command) {
var torrentId = data.file_torrent.getId();
var rowIndices = $.map(rows.slice(0),function (row) {return row.getIndex();});
data.controller.changeFileCommand(torrentId, rowIndices, command);
data.controller.changeFileCommand(torrentId, fileIndices, command);
},
selectAllFiles = function() {
changeFileCommand([], 'files-wanted');
onFileWantedToggled = function(ev, fileIndices, want) {
changeFileCommand(fileIndices, want?'files-wanted':'files-unwanted');
},
deselectAllFiles = function() {
changeFileCommand([], 'files-unwanted');
},
onFileWantedToggled = function(ev, row, want) {
changeFileCommand([row], want?'files-wanted':'files-unwanted');
},
onFilePriorityToggled = function(ev, row, priority) {
onFilePriorityToggled = function(ev, fileIndices, priority) {
var command;
switch(priority) {
case -1: command = 'priority-low'; break;
case 1: command = 'priority-high'; break;
default: command = 'priority-normal'; break;
}
changeFileCommand([row], command);
changeFileCommand(fileIndices, command);
},
onNameClicked = function(ev, fileRow, fileIndices) {
$(fileRow.getElement()).siblings().slideToggle();
},
clearFileList = function() {
$(data.elements.file_list).empty();
delete data.file_torrent;
delete data.file_torrent_n;
delete data.file_rows;
},
createFileTreeModel = function (tor) {
var i, j, n, name, tokens, walk, tree, token, sub,
leaves = [ ],
tree = { children: { }, file_indices: [ ] };
n = tor.getFileCount();
for (i=0; i<n; ++i) {
name = tor.getFile(i).name;
tokens = name.split('/');
walk = tree;
for (j=0; j<tokens.length; ++j) {
token = tokens[j];
sub = walk.children[token];
if (!sub) {
walk.children[token] = sub = {
name: token,
parent: walk,
children: { },
file_indices: [ ],
depth: j
};
}
walk = sub;
}
walk.file_index = i;
delete walk.children;
leaves.push (walk);
}
for (i=0; i<leaves.length; ++i) {
walk = leaves[i];
j = walk.file_index;
do {
walk.file_indices.push (j);
walk = walk.parent;
} while (walk);
}
return tree;
},
addNodeToView = function (tor, parent, sub, i) {
var row;
row = new FileRow(tor, sub.depth, sub.name, sub.file_indices, i%2);
data.file_rows.push(row);
parent.appendChild(row.getElement());
$(row).bind('wantedToggled',onFileWantedToggled);
$(row).bind('priorityToggled',onFilePriorityToggled);
$(row).bind('nameClicked',onNameClicked);
}
addSubtreeToView = function (tor, parent, sub, i) {
var key, div;
div = document.createElement('div');
if (sub.parent)
addNodeToView (tor, div, sub, i++);
if (sub.children)
for (key in sub.children)
i = addSubtreeToView (tor, div, sub.children[key]);
parent.appendChild(div);
return i;
},
updateFilesPage = function() {
var i, j, n, sel, row, tor, fragment,
box, complete, conn, connections, e, from, heirarchy, item,
matches, parents, parentid, path, sum, subheirarchy, to, inner,
var i, n, tor, fragment, tree,
file_list = data.elements.file_list,
torrents = data.torrents;
// only show one torrent at a time
if (torrents.length !== 1) {
clearFileList();
return;
}
// build the file list
tor = torrents[0];
for (parentid in data.parents) {
data.parents[parentid] = $('#'+parentid).children('li').css('display')
n = tor ? tor.getFileCount() : 0;
if (tor!=data.file_torrent || n==data.file_torrent_n) {
// rebuild the file list...
clearFileList();
data.file_torrent = tor;
data.file_torrent_n = n;
data.file_rows = [ ];
fragment = document.createDocumentFragment();
tree = createFileTreeModel (tor);
addSubtreeToView (tor, fragment, tree, 0);
file_list.appendChild (fragment);
} else {
// ...refresh the already-existing file list
for (i=0, n=data.file_rows.length; i<n; ++i)
data.file_rows[i].refresh();
}
clearFileList();
data.file_torrent = tor;
n = tor.getFileCount();
data.file_rows = [];
fragment = document.createDocumentFragment();
heirarchy = {'/':[]}
for (i=0; i<n; ++i) {
row = data.file_rows[i] = new FileRow(tor, i);
fragment.appendChild(row.getElement());
$(row).bind('wantedToggled',onFileWantedToggled);
$(row).bind('priorityToggled',onFilePriorityToggled);
path = row.getPath();
if (path.length == 1) {
heirarchy['/'].push(path[0]);
} else {
subheirarchy = heirarchy;
for (j=0; j<path.length; j++) {
if (j<(path.length-1)) {
subheirarchy[path[j]] = (subheirarchy[path[j]] == undefined) ? {'/':[]} : subheirarchy[path[j]];
subheirarchy[path[j]]['PARENT'] = (path[j-1] == undefined) ? [undefined] : [path[j-1].replace(/[\[\] ().]/g,'_')]
subheirarchy = subheirarchy[path[j]];
} else {
parentid = (path[j-1] == undefined) ? [undefined] : [path[j-1].replace(/[\[\] ().]/g,'_')]
subheirarchy['/'].push([path[j],parentid]);
}
}
}
}
console.log(heirarchy);
/*
At this point we have a single object containing the whole
torrent heirarchy. The '/' key is file element ids as assigned above
for the current level. Any other keys are array objects which are
directories in the torrent heirarchy, this will also contain a '/'
key and potentially more keys for nested directories.
*/
connections = [];
parents = {};
var recursiveCreate = function(key,val) {
if (key == "PARENT") { return; }
if (typeof(val) == "object" &&! Array.isArray(val)) {
row = document.createElement('li');
row.id = key.replace(/[\[\] ().]/g,'_');
row.classname = 'inspector_torrent_file_list_entry odd';
e = document.createElement('input');
e.type = 'checkbox';
e.className = "file_wanted_control";
e.title = 'Download file';
e.checked = true;
$(e).change(function() { $($(this).parent()).children('li').children('input').click() });
row.appendChild(e);
e = document.createElement('div');
e.className = 'file-priority-radiobox';
box = e;
e = document.createElement('div');
e.className = 'low';
e.title = 'Low Priority';
$(e).click(function(){ $($(this).parent().parent()).children('li').children('div').children('.low').click() });
box.appendChild(e);
e = document.createElement('div');
e.className = 'normal';
e.title = 'Normal Priority';
$(e).click(function(){ $($(this).parent().parent()).children('li').children('div').children('.normal').click() });
box.appendChild(e);
e = document.createElement('div');
e.title = 'High Priority';
e.className = 'high';
$(e).click(function(){ $($(this).parent().parent()).children('li').children('div').children('.high').click() });
box.appendChild(e);
row.appendChild(box);
inner = document.createElement('div');
inner.className = "inspector_torrent_file_list_entry_name";
inner.innerHTML = key;
row.appendChild(inner);
complete = document.createElement('div');
complete.className = "inspector_torrent_file_list_entry_progress";
complete.innerHTML = "&nbsp;"
row.appendChild(complete)
fragment.appendChild(row);
connections.push([key.replace(/[\[\] ().]/g,'_'),val['PARENT'][0]])
} else {
for (item in val) {
parents[val[item][1][0]] = ""
}
connections.push.apply(connections,val)
}
if (!Array.isArray(val)) {
$.each(val,function(key,val) { recursiveCreate(key,val) })
}
}
$.each(heirarchy,function(key,val) { recursiveCreate(key,val) })
file_list.appendChild(fragment);
for (conn in connections) {
from = connections[conn][0];
to = connections[conn][1];
if (to == undefined) { continue; }
$('#'+from).appendTo($('#'+to));
$('#'+from).css('margin-left','20px')
}
for (parentid in parents) {
$($('.inspector_torrent_file_list_entry_name',$('#'+parentid))[0]).click(function() { $($(this).parent()).children('li').toggle(); })
sum = 0;
matches = $('#'+parentid).children('li').text().match(/\([^\.]+\)/g)
if (matches == null) { continue; }
matches.map(function(word) {return parseFloat(word.slice(1,-2)) }).map(function(perc) {sum+=perc})
count = $('#'+parentid).children('li').text().match(/\([^\.]+\)/g).length
totalcomplete = (sum/count).toFixed(1)
$($('.inspector_torrent_file_list_entry_progress',$('#'+parentid))[0]).text('('+totalcomplete+'%)')
}
for (parentid in data.parents) {
$('#'+parentid).children('li').css('display',data.parents[parentid])
}
data.parents = parents;
},
/****
@@ -830,27 +774,23 @@ function Inspector(controller) {
data.elements.peers_list = $('#inspector_peers_list')[0];
data.elements.trackers_list = $('#inspector_trackers_list')[0];
data.elements.have_lb = $('#inspector-info-have')[0];
data.elements.availability_lb = $('#inspector-info-availability')[0];
data.elements.downloaded_lb = $('#inspector-info-downloaded')[0];
data.elements.uploaded_lb = $('#inspector-info-uploaded')[0];
data.elements.state_lb = $('#inspector-info-state')[0];
data.elements.running_time_lb = $('#inspector-info-running-time')[0];
data.elements.remaining_time_lb = $('#inspector-info-remaining-time')[0];
data.elements.last_activity_lb = $('#inspector-info-last-activity')[0];
data.elements.error_lb = $('#inspector-info-error')[0];
data.elements.size_lb = $('#inspector-info-size')[0];
data.elements.foldername_lb = $('#inspector-info-location')[0];
data.elements.hash_lb = $('#inspector-info-hash')[0];
data.elements.privacy_lb = $('#inspector-info-privacy')[0];
data.elements.origin_lb = $('#inspector-info-origin')[0];
data.elements.comment_lb = $('#inspector-info-comment')[0];
data.elements.have_lb = $('#inspector-info-have')[0];
data.elements.availability_lb = $('#inspector-info-availability')[0];
data.elements.downloaded_lb = $('#inspector-info-downloaded')[0];
data.elements.uploaded_lb = $('#inspector-info-uploaded')[0];
data.elements.state_lb = $('#inspector-info-state')[0];
data.elements.running_time_lb = $('#inspector-info-running-time')[0];
data.elements.remaining_time_lb = $('#inspector-info-remaining-time')[0];
data.elements.last_activity_lb = $('#inspector-info-last-activity')[0];
data.elements.error_lb = $('#inspector-info-error')[0];
data.elements.size_lb = $('#inspector-info-size')[0];
data.elements.foldername_lb = $('#inspector-info-location')[0];
data.elements.hash_lb = $('#inspector-info-hash')[0];
data.elements.privacy_lb = $('#inspector-info-privacy')[0];
data.elements.origin_lb = $('#inspector-info-origin')[0];
data.elements.comment_lb = $('#inspector-info-comment')[0];
data.elements.name_lb = $('#torrent_inspector_name')[0];
// file page's buttons
$('#select-all-files').click(selectAllFiles);
$('#deselect-all-files').click(deselectAllFiles);
// force initial 'N/A' updates on all the pages
updateInspector();
updateInfoPage();