make browser columns compactable

This commit is contained in:
ed 2021-03-02 00:07:04 +01:00
parent 46e10b0e9f
commit 61a6bc3a65
9 changed files with 243 additions and 61 deletions

5
.vscode/launch.json vendored
View file

@ -13,10 +13,13 @@
"-ed", "-ed",
"-emp", "-emp",
"-e2dsa", "-e2dsa",
"-e2ts",
"-a", "-a",
"ed:wark", "ed:wark",
"-v", "-v",
"srv::r:aed:cnodupe" "srv::r:aed:cnodupe",
"-v",
"dist:dist:r"
] ]
}, },
{ {

2
.vscode/tasks.json vendored
View file

@ -8,7 +8,7 @@
}, },
{ {
"label": "no_dbg", "label": "no_dbg",
"command": "${config:python.pythonPath} -m copyparty -ed -emp -e2dsa -a ed:wark -v srv::r:aed:cnodupe ;exit 1", "command": "${config:python.pythonPath} -m copyparty -ed -emp -e2dsa -e2ts -a ed:wark -v srv::r:aed:cnodupe -v dist:dist:r ;exit 1",
"type": "shell" "type": "shell"
} }
] ]

View file

@ -257,7 +257,7 @@ def main():
ap2.add_argument("--no-mutagen", action="store_true", help="use ffprobe for tags instead") ap2.add_argument("--no-mutagen", action="store_true", help="use ffprobe for tags instead")
ap2.add_argument("-mtm", metavar="M=t,t,t", action="append", type=str, help="add/replace metadata mapping") ap2.add_argument("-mtm", metavar="M=t,t,t", action="append", type=str, help="add/replace metadata mapping")
ap2.add_argument("-mte", metavar="M,M,M", type=str, help="tags to index/display (comma-sep.)", ap2.add_argument("-mte", metavar="M,M,M", type=str, help="tags to index/display (comma-sep.)",
default="circle,album,.tn,artist,title,.dur,.q") default="circle,album,.tn,artist,title,.bpm,key,.dur,.q")
ap2 = ap.add_argument_group('SSL/TLS options') ap2 = ap.add_argument_group('SSL/TLS options')
ap2.add_argument("--http-only", action="store_true", help="disable ssl/tls") ap2.add_argument("--http-only", action="store_true", help="disable ssl/tls")

View file

@ -96,7 +96,10 @@ a,
} }
#files td { #files td {
border-bottom: 1px solid #111; border-bottom: 1px solid #111;
}
#files td+td+td {
max-width: 30em; max-width: 30em;
overflow: hidden;
} }
#files tr+tr td { #files tr+tr td {
border-top: 1px solid #383838; border-top: 1px solid #383838;
@ -168,7 +171,8 @@ a,
margin: -.2em; margin: -.2em;
} }
#files tbody a.play.act { #files tbody a.play.act {
color: #af0; color: #840;
text-shadow: 0 0 .3em #b80;
} }
#blocked { #blocked {
position: fixed; position: fixed;
@ -299,6 +303,20 @@ a,
width: calc(100% - 10.5em); width: calc(100% - 10.5em);
background: rgba(0,0,0,0.2); background: rgba(0,0,0,0.2);
} }
@media (min-width: 100em) {
#barpos,
#barbuf {
width: calc(100% - 24em);
left: 10em;
top: .7em;
height: 1.6em;
bottom: auto;
}
#widget {
bottom: -3.2em;
height: 3.2em;
}
}
@ -496,3 +514,42 @@ input[type="checkbox"]:checked+label {
position: absolute; position: absolute;
z-index: 9; z-index: 9;
} }
#files .cfg {
display: none;
font-size: 2em;
white-space: nowrap;
}
#files th:hover .cfg,
#files th.min .cfg {
display: block;
width: 1em;
border-radius: .2em;
margin: -1.3em auto 0 auto;
background: #444;
}
#files th.min .cfg {
margin: -.6em;
}
#files>thead>tr>th.min span {
position: absolute;
transform: rotate(270deg);
background: linear-gradient(90deg, #222, #444);
margin-left: -4.6em;
padding: .4em;
top: 5.4em;
width: 8em;
text-align: right;
letter-spacing: .04em;
}
#files td:nth-child(2n) {
color: #f5a;
}
#files td.min a {
display: none;
}
#files tr.play td {
background: #fc4;
border-color: transparent;
color: #400;
text-shadow: none;
}

View file

@ -58,17 +58,17 @@
<thead> <thead>
<tr> <tr>
<th></th> <th></th>
<th>File Name</th> <th><span>File Name</span></th>
<th sort="int">Size</th> <th sort="int"><span>Size</span></th>
{%- for k in taglist %} {%- for k in taglist %}
{%- if k.startswith('.') %} {%- if k.startswith('.') %}
<td sort="int">{{ k[1:] }}</td> <th sort="int"><span>{{ k[1:] }}</span></th>
{%- else %} {%- else %}
<td>{{ k[0]|upper }}{{ k[1:] }}</td> <th><span>{{ k[0]|upper }}{{ k[1:] }}</span></th>
{%- endif %} {%- endif %}
{%- endfor %} {%- endfor %}
<th>T</th> <th><span>T</span></th>
<th>Date</th> <th><span>Date</span></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View file

@ -6,21 +6,6 @@ function dbg(msg) {
ebi('path').innerHTML = msg; ebi('path').innerHTML = msg;
} }
function ev(e) {
e = e || window.event;
if (!e)
return;
if (e.preventDefault)
e.preventDefault()
if (e.stopPropagation)
e.stopPropagation();
e.returnValue = false;
return e;
}
makeSortable(ebi('files')); makeSortable(ebi('files'));
@ -55,7 +40,7 @@ function init_mp() {
for (var a = 0, aa = tracks.length; a < aa; a++) for (var a = 0, aa = tracks.length; a < aa; a++)
ebi('trk' + a).onclick = ev_play; ebi('trk' + a).onclick = ev_play;
ret.vol = localStorage.getItem('vol'); ret.vol = sread('vol');
if (ret.vol !== null) if (ret.vol !== null)
ret.vol = parseFloat(ret.vol); ret.vol = parseFloat(ret.vol);
else else
@ -67,7 +52,7 @@ function init_mp() {
ret.setvol = function (vol) { ret.setvol = function (vol) {
ret.vol = Math.max(Math.min(vol, 1), 0); ret.vol = Math.max(Math.min(vol, 1), 0);
localStorage.setItem('vol', vol); swrite('vol', vol);
if (ret.au) if (ret.au)
ret.au.volume = ret.expvol(); ret.au.volume = ret.expvol();
@ -460,6 +445,11 @@ function play(tid, call_depth) {
mp.au.volume = mp.expvol(); mp.au.volume = mp.expvol();
var oid = 'trk' + tid; var oid = 'trk' + tid;
setclass(oid, 'play act'); setclass(oid, 'play act');
var trs = ebi('files').getElementsByTagName('tbody')[0].getElementsByTagName('tr');
for (var a = 0, aa = trs.length; a < aa; a++) {
trs[a].className = trs[a].className.replace(/ *play */, "");
}
ebi(oid).parentElement.parentElement.className += ' play';
try { try {
if (hack_attempt_play) if (hack_attempt_play)
@ -708,6 +698,7 @@ function autoplay_blocked() {
ofiles.innerHTML = html.join('\n'); ofiles.innerHTML = html.join('\n');
ofiles.setAttribute("ts", this.ts); ofiles.setAttribute("ts", this.ts);
filecols.set_style();
reload_browser(); reload_browser();
ebi('unsearch').onclick = unsearch; ebi('unsearch').onclick = unsearch;
@ -741,7 +732,7 @@ function autoplay_blocked() {
treefiles.appendChild(ebi('files')); treefiles.appendChild(ebi('files'));
treefiles.appendChild(ebi('epi')); treefiles.appendChild(ebi('epi'));
localStorage.setItem('entreed', 'tree'); swrite('entreed', 'tree');
get_tree("", get_vpath()); get_tree("", get_vpath());
} }
@ -911,6 +902,7 @@ function autoplay_blocked() {
ebi('pro').innerHTML = res.logues ? res.logues[0] || "" : ""; ebi('pro').innerHTML = res.logues ? res.logues[0] || "" : "";
ebi('epi').innerHTML = res.logues ? res.logues[1] || "" : ""; ebi('epi').innerHTML = res.logues ? res.logues[1] || "" : "";
filecols.set_style();
reload_tree(); reload_tree();
reload_browser(); reload_browser();
} }
@ -955,12 +947,12 @@ function autoplay_blocked() {
ebi('path').style.display = 'inline-block'; ebi('path').style.display = 'inline-block';
treetab.style.display = 'none'; treetab.style.display = 'none';
localStorage.setItem('entreed', 'na'); swrite('entreed', 'na');
} }
ebi('entree').onclick = entree; ebi('entree').onclick = entree;
ebi('detree').onclick = detree; ebi('detree').onclick = detree;
if (window.localStorage && localStorage.getItem('entreed') == 'tree') if (sread('entreed') == 'tree')
entree(); entree();
window.onpopstate = function (e) { window.onpopstate = function (e) {
@ -973,7 +965,7 @@ function autoplay_blocked() {
}; };
if (window.history && history.pushState) { if (window.history && history.pushState) {
var u = get_vpath(); var u = get_vpath() + window.location.hash;
history.replaceState(ebi('files').innerHTML, u, u); history.replaceState(ebi('files').innerHTML, u, u);
} }
})(); })();
@ -1032,28 +1024,118 @@ function apply_perms(perms) {
function mk_files_header(taglist) { function mk_files_header(taglist) {
var html = ['<thead>', '<th></th>', '<th>File Name</th>', '<th sort="int">Size</th>']; var html = [
'<thead>',
'<th></th>',
'<th><span>File Name</span></th>',
'<th sort="int"><span>Size</span></th>'
];
for (var a = 0; a < taglist.length; a++) { for (var a = 0; a < taglist.length; a++) {
var tag = taglist[a]; var tag = taglist[a];
var c1 = tag.slice(0, 1).toUpperCase(); var c1 = tag.slice(0, 1).toUpperCase();
tag = c1 + tag.slice(1); tag = c1 + tag.slice(1);
if (c1 == '.') if (c1 == '.')
tag = '<th sort="int">' + tag.slice(1); tag = '<th sort="int"><span>' + tag.slice(1);
else else
tag = '<th>' + tag; tag = '<th><span>' + tag;
html.push(tag + '</th>'); html.push(tag + '</span></th>');
} }
html = html.concat([ html = html.concat([
'<th>T</th>', '<th><span>T</span></th>',
'<th>Date</th>', '<th><span>Date</span></th>',
'</thead>', '</thead>',
]); ]);
return html; return html;
} }
var filecols = (function () {
var hidden = jread('filecols', []);
var add_btns = function () {
var ths = document.querySelectorAll('#files th>span');
for (var a = 0, aa = ths.length; a < aa; a++) {
var th = ths[a].parentElement;
var is_hidden = has(hidden, ths[a].textContent);
th.innerHTML = '<div class="cfg"><a href="#">' +
(is_hidden ? '+' : '-') + '</a></div>' + ths[a].outerHTML;
th.getElementsByTagName('a')[0].onclick = ev_row_tgl;
}
};
var set_style = function () {
add_btns();
var ohidden = [],
ths = document.querySelectorAll('#files th'),
ncols = ths.length;
for (var a = 0; a < ncols; a++) {
var span = ths[a].getElementsByTagName('span');
if (span.length <= 0)
continue;
var name = span[0].textContent,
cls = '';
if (has(hidden, name)) {
ohidden.push(a);
cls = ' min';
}
ths[a].className = ths[a].className.replace(/ *min */, " ") + cls;
}
for (var a = 0; a < ncols; a++) {
var cls = has(ohidden, a) ? 'min' : '';
var tds = document.querySelectorAll('#files>tbody>tr>td:nth-child(' + (a + 1) + ')');
for (var b = 0, bb = tds.length; b < bb; b++) {
tds[b].setAttribute('class', cls);
if (a < 2)
continue;
if (cls) {
if (!tds[b].hasAttribute('html')) {
tds[b].setAttribute('html', tds[b].innerHTML);
tds[b].innerHTML = '...';
}
}
else if (tds[b].hasAttribute('html')) {
tds[b].innerHTML = tds[b].getAttribute('html');
tds[b].removeAttribute('html');
}
}
}
};
set_style();
var toggle = function (name) {
var ofs = hidden.indexOf(name);
if (ofs !== -1)
hidden.splice(ofs, 1);
else
hidden.push(name);
jwrite("filecols", hidden);
set_style();
};
return {
"add_btns": add_btns,
"set_style": set_style,
"toggle": toggle,
};
})();
function ev_row_tgl(e) {
ev(e);
filecols.toggle(this.parentElement.parentElement.getElementsByTagName('span')[0].textContent);
}
function reload_browser(not_mp) { function reload_browser(not_mp) {
filecols.set_style();
makeSortable(ebi('files')); makeSortable(ebi('files'));
var parts = get_vpath().split('/'); var parts = get_vpath().split('/');

View file

@ -524,11 +524,9 @@ dom_navtgl.onclick = function () {
dom_navtgl.innerHTML = hidden ? 'show nav' : 'hide nav'; dom_navtgl.innerHTML = hidden ? 'show nav' : 'hide nav';
dom_nav.style.display = hidden ? 'none' : 'block'; dom_nav.style.display = hidden ? 'none' : 'block';
if (window.localStorage) swrite('hidenav', hidden ? 1 : 0);
localStorage.setItem('hidenav', hidden ? 1 : 0);
redraw(); redraw();
}; };
if (window.localStorage && localStorage.getItem('hidenav') == 1) if (sread('hidenav') == 1)
dom_navtgl.onclick(); dom_navtgl.onclick();

View file

@ -210,7 +210,7 @@ function up2k_init(have_crypto) {
} }
function cfg_get(name) { function cfg_get(name) {
var val = localStorage.getItem(name); var val = sread(name);
if (val === null) if (val === null)
return parseInt(ebi(name).value); return parseInt(ebi(name).value);
@ -223,7 +223,7 @@ function up2k_init(have_crypto) {
if (!o) if (!o)
return defval; return defval;
var val = localStorage.getItem(name); var val = sread(name);
if (val === null) if (val === null)
val = defval; val = defval;
else else
@ -234,8 +234,7 @@ function up2k_init(have_crypto) {
} }
function bcfg_set(name, val) { function bcfg_set(name, val) {
localStorage.setItem( swrite(name, val ? '1' : '0');
name, val ? '1' : '0');
var o = ebi(name); var o = ebi(name);
if (o) if (o)
@ -1033,7 +1032,7 @@ function up2k_init(have_crypto) {
return; return;
parallel_uploads = v; parallel_uploads = v;
localStorage.setItem('nthread', v); swrite('nthread', v);
obj.style.background = '#444'; obj.style.background = '#444';
return; return;
} }

View file

@ -43,6 +43,21 @@ function ebi(id) {
return document.getElementById(id); return document.getElementById(id);
} }
function ev(e) {
e = e || window.event;
if (!e)
return;
if (e.preventDefault)
e.preventDefault()
if (e.stopPropagation)
e.stopPropagation();
e.returnValue = false;
return e;
}
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
if (!String.prototype.endsWith) { if (!String.prototype.endsWith) {
@ -79,10 +94,10 @@ function sortTable(table, col) {
var tb = table.tBodies[0], var tb = table.tBodies[0],
th = table.tHead.rows[0].cells, th = table.tHead.rows[0].cells,
tr = Array.prototype.slice.call(tb.rows, 0), tr = Array.prototype.slice.call(tb.rows, 0),
i, reverse = th[col].className == 'sort1' ? -1 : 1; i, reverse = th[col].className.indexOf('sort1') !== -1 ? -1 : 1;
for (var a = 0, thl = th.length; a < thl; a++) for (var a = 0, thl = th.length; a < thl; a++)
th[a].className = ''; th[a].className = th[a].className.replace(/ *sort-?1 */, " ");
th[col].className = 'sort' + reverse; th[col].className += ' sort' + reverse;
var stype = th[col].getAttribute('sort'); var stype = th[col].getAttribute('sort');
tr = tr.sort(function (a, b) { tr = tr.sort(function (a, b) {
if (!a.cells[col]) if (!a.cells[col])
@ -107,7 +122,8 @@ function makeSortable(table) {
if (th) i = th.length; if (th) i = th.length;
else return; // if no `<thead>` then do nothing else return; // if no `<thead>` then do nothing
while (--i >= 0) (function (i) { while (--i >= 0) (function (i) {
th[i].onclick = function () { th[i].onclick = function (e) {
ev(e);
sortTable(table, i); sortTable(table, i);
}; };
}(i)); }(i));
@ -123,16 +139,13 @@ function makeSortable(table) {
})(); })();
function opclick(ev) { function opclick(e) {
if (ev) //ie ev(e);
ev.preventDefault();
var dest = this.getAttribute('data-dest'); var dest = this.getAttribute('data-dest');
goto(dest); goto(dest);
// writing a blank value makes ie8 segfault w swrite('opmode', dest || undefined);
if (window.localStorage)
localStorage.setItem('opmode', dest || '.');
var input = document.querySelector('.opview.act input:not([type="hidden"])') var input = document.querySelector('.opview.act input:not([type="hidden"])')
if (input) if (input)
@ -167,11 +180,9 @@ function goto(dest) {
(function () { (function () {
goto(); goto();
if (window.localStorage) { var op = sread('opmode');
var op = localStorage.getItem('opmode');
if (op !== null && op !== '.') if (op !== null && op !== '.')
goto(op); goto(op);
}
})(); })();
@ -238,3 +249,35 @@ function has(haystack, needle) {
return false; return false;
} }
function sread(key) {
if (window.localStorage)
return localStorage.getItem(key);
return '';
}
function swrite(key, val) {
if (window.localStorage) {
if (val === undefined)
localStorage.removeItem(key);
else
localStorage.setItem(key, val);
}
}
function jread(key, fb) {
var str = sread(key);
if (!str)
return fb;
return JSON.parse(str);
}
function jwrite(key, val) {
if (!val)
swrite(key);
else
swrite(key, JSON.stringify(val));
}