Skip to content

Commit

Permalink
display custom label paths as tree
Browse files Browse the repository at this point in the history
  • Loading branch information
TrimmingFool committed Feb 14, 2022
1 parent a65e307 commit 49f6623
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 58 deletions.
29 changes: 17 additions & 12 deletions css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -86,19 +86,24 @@ table#maincont {margin: 5px 0 0 0}
table#maincont td.uicell {vertical-align: top; padding: 0 }

div#CatList {width: 0px; border: 1px solid #A0A0A0; background-color: #FFFFFF; overflow-y: auto; overflow-x: hidden}
div#CatList ul {padding: 0; margin: 0; list-style: none; white-space: nowrap}
div#CatList ul li {padding: 2px 25px; margin: 0; line-height: 14px; font-size: 11px; cursor: pointer; border: 1px solid #FFFFFF; background-repeat: no-repeat}
div#CatList ul { margin: 0; padding: 0; list-style: none; white-space: nowrap}
div#CatList ul li { display: flex; padding: 3px; flex-flow: row nowrap; align-items: center; height: 16px; font-size: 11px; cursor: pointer; border: 0px solid #FFFFFF; overflow: hidden;}
div#CatList ul li.sel {background-color: #CFDEEF; border-color: #CFDEEF }
.-_-_-all-_-_-, #-_-_-all-_-_-, #-_-_-dls-_-_-, #-_-_-com-_-_-, #-_-_-act-_-_-, #-_-_-iac-_-_-, #-_-_-err-_-_- {background-image: url(../images/tstatus.png)}
.-_-_-all-_-_-, #-_-_-all-_-_- {background-position: 4px -174px;}
#-_-_-dls-_-_- {background-position: 4px 2px;}
#-_-_-com-_-_- {background-position: 4px -14px;}
#-_-_-act-_-_- {background-position: 4px -158px;}
#-_-_-iac-_-_- {background-position: 4px -30px;}
#-_-_-err-_-_- {background-position: 4px -94px;}
span.label-count,span.label-size { background-color: #F0F0F0; padding: 0.1em 0.3em 0.1em 0.3em; margin-left: 0.3em; border-radius: 0.8em; }
div#CatList ul li.RSS {background-image: url(../images/tstatus.png); background-position: 4px -206px}
div#CatList ul li.disRSS {background-image: url(../images/tstatus.png); background-position: 4px -190px}
div#CatList ul li div { margin-right: 0.5em; }
div#CatList .label-prefix { flex: 0 0 auto; display: flex; flex-flow: row nowrap; opacity: 0.1; font-family: monospace; font-size: 19px; margin-left: -2px; margin-right: 2px; }
div#CatList .label-prefix div { margin-right: 0px; width: 12px; }
.label-icon { min-width: 16px; min-height: 16px; background-image: url(../images/tstatus.png); background-repeat: no-repeat; }
.label-icon img { width: 16px; }
.-_-_-all-_-_- .label-icon, #-_-_-all-_-_- .label-icon {background-position: 0px -176px;}
#-_-_-dls-_-_- .label-icon {background-position: 0px 0px;}
#-_-_-com-_-_- .label-icon {background-position: 0px -16px;}
#-_-_-act-_-_- .label-icon {background-position: 0px -160px;}
#-_-_-iac-_-_- .label-icon {background-position: 0px -32px;}
#-_-_-err-_-_- .label-icon {background-position: 0px -96px;}
.label-count,.label-size { background-color: #F0F0F0; padding: 0.1em 0.3em 0.1em 0.3em; border-radius: 0.8em; }
div#CatList ul li.RSS .label-icon { background-position: 0px -208px}
div#CatList ul li.disRSS .label-icon { background-position: 0px -192px}
#flabel_cont li:not(.-_-_-all-_-_-) .label-icon { background-position: 0px -32px; }

.stable-icon {background-image: url(../images/tstatus.png); background-repeat: no-repeat}
.Status_Down {background-position: 0px 0px}
Expand Down
18 changes: 9 additions & 9 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -96,32 +96,32 @@
<div class="catpanel" id="pstate" onclick="theWebUI.togglePanel(this); return(false);"><script type="text/javascript"> document.write(theUILang.pnlState); </script></div>
<ul id="pstate_cont" class="catpanel_cont">
<li class="-_-_-all-_-_- sel cat">
<span class="label-text"><script type="text/javascript"> document.write(theUILang.All); </script></span><span class="label-count">0</span><span class="label-size" style="display: none"></span>
<div class="label-prefix"></div><div class="label-icon"></div><div class="label-text"><script type="text/javascript"> document.write(theUILang.All); </script></div><div class="label-count">0</div><div class="label-size" style="display: none"></div>
</li>
<li id="-_-_-dls-_-_-" class="cat">
<span class="label-text"><script type="text/javascript"> document.write(theUILang.Downloading); </script></span><span class="label-count">0</span><span class="label-size" style="display: none"></span>
<div class="label-prefix"></div><div class="label-icon"></div><div class="label-text"><script type="text/javascript"> document.write(theUILang.Downloading); </script></div><div class="label-count">0</div><div class="label-size" style="display: none"></div>
</li>
<li id="-_-_-com-_-_-" class="cat">
<span class="label-text"><script type="text/javascript"> document.write(theUILang.Finished); </script></span><span class="label-count">0</span><span class="label-size" style="display: none"></span>
<div class="label-prefix"></div><div class="label-icon"></div><div class="label-text"><script type="text/javascript"> document.write(theUILang.Finished); </script></div><div class="label-count">0</div><div class="label-size" style="display: none"></div>
</li>
<li id="-_-_-act-_-_-" class="cat">
<span class="label-text"><script type="text/javascript"> document.write(theUILang.Active); </script></span><span class="label-count">0</span><span class="label-size" style="display: none"></span>
<div class="label-prefix"></div><div class="label-icon"></div><div class="label-text"><script type="text/javascript"> document.write(theUILang.Active); </script></div><div class="label-count">0</div><div class="label-size" style="display: none"></div>
</li>
<li id="-_-_-iac-_-_-" class="cat">
<span class="label-text"><script type="text/javascript"> document.write(theUILang.Inactive); </script></span><span class="label-count">0</span><span class="label-size" style="display: none"></span>
<div class="label-prefix"></div><div class="label-icon"></div><div class="label-text"><script type="text/javascript"> document.write(theUILang.Inactive); </script></div><div class="label-count">0</div><div class="label-size" style="display: none"></div>
</li>
<li id="-_-_-err-_-_-" class="cat">
<span class="label-text"><script type="text/javascript"> document.write(theUILang.Error); </script></span><span class="label-count">0</span><span class="label-size" style="display: none"></span>
<div class="label-prefix"></div><div class="label-icon"></div><div class="label-text"><script type="text/javascript"> document.write(theUILang.Error); </script></div><div class="label-count">0</div><div class="label-size" style="display: none"></div>
</li>
</ul>
<div class="catpanel" id="plabel" onclick="theWebUI.togglePanel(this); return(false);"><script type="text/javascript"> document.write(theUILang.Labels); </script></div>
<div class="catpanel_cont" id="plabel_cont">
<ul id="clabel_cont">
<li class="-_-_-all-_-_- sel cat">
<span class="label-text"><script type="text/javascript"> document.write(theUILang.All); </script></span><span class="label-count">0</span><span class="label-size" style="display: none"></span>
<div class="label-prefix"></div><div class="label-icon"></div><div class="label-text"><script type="text/javascript"> document.write(theUILang.All); </script></div><div class="label-count">0</div><div class="label-size" style="display: none"></div>
</li>
<li id="-_-_-nlb-_-_-" class="cat">
<span class="label-text"><script type="text/javascript"> document.write(theUILang.No_label); </script></span><span class="label-count">0</span><span class="label-size" style="display: none"></span>
<div class="label-prefix"></div><div class="label-icon"></div><div class="label-text"><script type="text/javascript"> document.write(theUILang.No_label); </script></div><div class="label-count">0</div><div class="label-size" style="display: none"></div>
</li>
</ul>
<ul id="lbll">
Expand All @@ -131,7 +131,7 @@
<div class="catpanel_cont" id="flabel_cont">
<ul id="lblf">
<li class="-_-_-all-_-_- sel cat">
<span class="label-text"><script type="text/javascript"> document.write(theUILang.All); </script></span><span class="label-count">0</span><span class="label-size" style="display: none"></span>
<div class="label-prefix"></div><div class="label-icon"></div><div class="label-text"><script type="text/javascript"> document.write(theUILang.All); </script></div><div class="label-count">0</div><div class="label-size" style="display: none"></div>
</li>
</ul>
</div>
Expand Down
10 changes: 10 additions & 0 deletions js/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,16 @@ var theFormatter =
}
}
return(arr);
},
treePrefix: function({hasNext, level})
{
const prefix = [];
for (let l = 1; l < level+1; l++) {
prefix.push(hasNext[l] ?
(l === level ? '├' : '│') :
(l === level ? '└' : ' '));
}
return prefix;
}
};

Expand Down
6 changes: 6 additions & 0 deletions js/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,12 @@ function makeContent()
"<div class=\"op100l\"><input type=\"checkbox\" id=\"webui.show_searchlabelsize\"/>"+
"<label for=\"webui.show_searchlabelsize\" id=\"lbl_webui.show_searchlabelsize\" >"+theUILang.showSearchLabelSize+"</label>"+
"</div>"+
"<div class=\"op100l\"><input type=\"checkbox\" id=\"webui.show_label_path_tree\"/>"+
"<label for=\"webui.show_label_path_tree\" id=\"lbl_webui.show_label_path_tree\" >"+theUILang.showCustomLabelTree+"</label>"+
"</div>"+
"<div class=\"op100l\"><input type=\"checkbox\" id=\"webui.show_empty_path_labels\"/>"+
"<label for=\"webui.show_empty_path_labels\" id=\"lbl_webui.show_empty_path_labels\" >"+theUILang.showEmptyPathLabel+"</label>"+
"</div>"+
"<div class=\"op100l\"><input type=\"checkbox\" id=\"webui.register_magnet\"/>"+
"<label for=\"webui.register_magnet\" id=\"lbl_webui.register_magnet\" >"+theUILang.registerMagnet+"</label>"+
"</div>"+
Expand Down
133 changes: 110 additions & 23 deletions js/webui.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ var theWebUI =
"webui.show_labelsize": 1,
"webui.show_searchlabelsize": 0,
"webui.show_statelabelsize": 0,
"webui.show_label_path_tree": 1,
"webui.show_empty_path_labels": 0,
"webui.register_magnet": 0
},
showFlags: 0,
Expand Down Expand Up @@ -1442,12 +1444,15 @@ var theWebUI =
_bf.push([theUILang.Remove_label, (table.selCount > 1) || this.isTorrentCommandEnabled("setlabel",id) ? "theWebUI.removeLabel()" : null]);
_bf.push([CMENU_SEP]);
for(var lbl in this.cLabels)
{
if((table.selCount == 1) && (this.torrents[id].label == lbl))
_bf.push([CMENU_SEL, lbl+" "]);
else
_bf.push([lbl+" ", (table.selCount > 1) || this.isTorrentCommandEnabled("setlabel",id) ? "theWebUI.setLabel('" + addslashes(lbl) + "')" : null]);
}
{
var lblText = this.settings['webui.show_label_path_tree'] ?
'│'.repeat(this.cLabels[lbl].level) + this.cLabelText(lbl):
lbl;
if((table.selCount == 1) && (this.torrents[id].label == lbl))
_bf.push([CMENU_SEL, lblText]);
else
_bf.push([lblText, (table.selCount > 1) || this.isTorrentCommandEnabled("setlabel",id) ? "theWebUI.setLabel('" + addslashes(lbl) + "')" : null]);
}
theContextMenu.add([CMENU_CHILD, theUILang.Labels, _bf]);
theContextMenu.add([CMENU_SEP]);
var _c0 = [];
Expand Down Expand Up @@ -2007,6 +2012,11 @@ var theWebUI =
return(false);
},

cLabelText: function(lbl) {
const l = this.cLabels[lbl];
return l.path.slice(l.level).join('/');
},

/**
*
* @param {Object.<string, number>} c - <label_name, count>
Expand All @@ -2019,26 +2029,78 @@ var theWebUI =
lbls.sort();

this.cLabels = {};
let prevCustomEle = null;
for(var lbl of lbls)
{
var id = "-_-_-" + lbl + "-_-_-";
this.labels[id] = { cnt: c[lbl], size: s[lbl] };
if (!this.staticLabels.includes(lbl))
{
// use custom label
this.cLabels[lbl] = 1;
if(!$$(id))
{
p.append( this.createSelectableLabelElement(id, lbl, theWebUI.labelContextMenu));
let path = [];
for(const nodeText of lbl.split('/')) {
path.push(nodeText);
const clbl = path.join('/');
const cid = '-_-_-' + clbl + '-_-_-';
if (this.settings['webui.show_empty_path_labels'])
{
// add empty non-leaf labels
if (!(cid in this.labels))
this.labels[cid] = { cnt: 0, size: 0 };
}
else if (cid in this.labels && this.labels[cid].cnt === 0 && cid !== id)
{
// delete empty non-leaf labels
// (keep empty leaf labels since they can not be recovered with show_empty_path_labels = true)
delete this.labels[cid];
}
if (!(clbl in this.cLabels) && cid in this.labels)
{
this.cLabels[clbl] = {
path: path.slice(),
level: path.length-1,
};
let ele = $$(cid);
if(!ele) {
ele = this.createSelectableLabelElement(cid, clbl, theWebUI.labelContextMenu);
if (prevCustomEle) {
ele.insertAfter(prevCustomEle);
} else {
p.append(ele);
}
}
prevCustomEle = ele;
}
}
}
}
if ( !this.settings['webui.show_empty_path_labels'] ) {
// flatten tree where parent nodes are missing
for (const lbl in this.cLabels) {
while (true) {
const label = this.cLabels[lbl];
const omittedPath = label.path.slice(0, label.level);
if ( !omittedPath.length || (omittedPath.join('/') in this.cLabels))
break;
$($$('-_-_-' + omittedPath.join('/') + '-_-_-')).remove();
this.cLabels[lbl].level--;
}
}
this.labels[id] = { cnt: c[lbl], size: s[lbl] };
}
// determine for each cLabel if it has a next sibling
let hasNext = [];
for (const lbl of Object.keys(this.cLabels).reverse()) {
let label = this.cLabels[lbl];
hasNext = hasNext.slice(0, label.level+1);
label.hasNext = [...hasNext];
hasNext[label.level] = true;
}
var actDeleted = false;
var pLabels = ['nlb'].concat(Object.keys(this.cLabels));
p.children().each(function(ndx,val)
{
var id = val.id;
var lbl = (id&&id.substr(5, id.length - 10))||'nlb';
var lbl = (id&&theWebUI.idToLbl(id))||'nlb';
if (!pLabels.includes(lbl)) {
$(val).remove();
if(theWebUI.actLbls["plabel_cont"] == id)
Expand All @@ -2049,7 +2111,7 @@ var theWebUI =
{
this.switchLabel($("#plabel_cont .-_-_-all-_-_-").get(0))
}
},
},

/**
*
Expand Down Expand Up @@ -2125,32 +2187,51 @@ var theWebUI =

createSelectableLabelElement: function(id, text, onClick) {
return( $("<LI>").attr("id",id)
.append($('<span>').addClass('label-text').text(text))
.append($('<span>').addClass('label-count').text(0))
.append($('<span>').addClass('label-size'))
.append($('<div>').addClass('label-prefix').hide())
.append($('<div>').addClass('label-icon'))
.append($('<div>').addClass('label-text').text(text))
.append($('<div>').addClass('label-count').text(0))
.append($('<div>').addClass('label-size').hide())
.attr("title",text+" (0)")
.mouseclick(onClick))
.addClass("cat");
},

updateLabel: function(label, count, size, showSize) {
updateLabel: function(label, count, size, showSize, text, prefix, titleText) {
var li = $(label);
var pfx = li.children('.label-prefix');
if (!prefix || prefix === '') {
pfx.hide();
} else {
if (prefix !== pfx.text()) {
pfx.empty();
for (var c of prefix) {
pfx.append($('<div>').text(c));
}
}
pfx.show();
}
var txt = li.children('.label-text');
if (text)
txt.text(text);
var lblSize = theConverter.bytes(size, 2);
li.children('.label-count').text(count);
var txt = li.children('.label-text');
li.attr('title',
txt.contents().not(txt.children('script')).text() +
(titleText||text||txt.contents().not(txt.children('script')).text()) +
' ('+ count + ( showSize ? ' ; '+ lblSize : '') +')');
var sizeSpan = li.children('.label-size');
sizeSpan.text(lblSize);
if (showSize)
{
if (size && showSize) {
sizeSpan.show();
} else {
sizeSpan.hide();
}
},

idToLbl: function(id) {
return(id.substr(5, id.length - 10));
},

updateLabels: function(wasRemoved)
{
this.updateAllFilterLabel('pstate_cont', this.settings["webui.show_statelabelsize"]);
Expand All @@ -2159,12 +2240,18 @@ var theWebUI =

for(var k in this.labels)
if(k.substr(0, 5) == "-_-_-") {
var lbl = k.substr(5, k.length - 10);
const lbl = this.idToLbl(k);
const customLabel = lbl in this.cLabels && lbl;
const showTree = customLabel && this.settings['webui.show_label_path_tree'];
this.updateLabel(
$$(k),
this.labels[k].cnt,
this.labels[k].size,
this.staticLabels.includes(lbl) && lbl != 'nlb' ? this.settings["webui.show_statelabelsize"] : this.settings["webui.show_labelsize"]);
this.staticLabels.includes(lbl) && lbl != 'nlb' ? this.settings["webui.show_statelabelsize"] : this.settings["webui.show_labelsize"],
(showTree && this.cLabelText(lbl))||customLabel,
showTree && theFormatter.treePrefix(this.cLabels[lbl]),
customLabel,
);
}
},

Expand Down
2 changes: 2 additions & 0 deletions lang/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,8 @@ var theUILang =
showStateLabelSize : "Show state size",
showLabelSize : "Show label size",
showSearchLabelSize : "Show search size",
showCustomLabelTree : "Show label path tree",
showEmptyPathLabel : "Show empty path labels",
phpParameterUnavailable : "PHP directive register_argc_argv is set to OFF. Change to ON, otherwise some plugins won't work correctly.",
addTorrentFailedURL : "Failed to add torrent. Can't retrieve URL.",
addTorrentFailedFile : "Failed to add torrent. The retrieved content is not a valid torrent file.",
Expand Down

0 comments on commit 49f6623

Please sign in to comment.