diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css
index 3a3a8aa5..35acaf75 100644
--- a/copyparty/web/browser.css
+++ b/copyparty/web/browser.css
@@ -42,12 +42,8 @@ body {
#path #entree {
margin-left: -.7em;
}
-#treetab {
- display: none;
-}
#files {
border-spacing: 0;
- margin-top: 2em;
z-index: 1;
position: relative;
}
@@ -157,6 +153,15 @@ a, #files tbody div a:last-child {
.logue {
padding: .2em 1.5em;
}
+.logue:empty {
+ display: none;
+}
+#pro.logue {
+ margin-bottom: .8em;
+}
+#epi.logue {
+ margin: .8em 0;
+}
#srv_info {
opacity: .5;
font-size: .8em;
@@ -442,12 +447,40 @@ input[type="checkbox"]:checked+label {
#files td div a:last-child {
width: 100%;
}
-#tree,
-#treefiles {
- vertical-align: top;
+#wrap {
+ margin-top: 2em;
}
#tree {
- padding-top: 2em;
+ display: none;
+ position: fixed;
+ left: 0;
+ bottom: 0;
+ top: 7em;
+ padding-top: .2em;
+ overflow-y: auto;
+ -ms-scroll-chaining: none;
+ overscroll-behavior-y: none;
+ scrollbar-color: #eb0 #333;
+}
+#thx_ff {
+ padding: 5em 0;
+}
+#tree::-webkit-scrollbar-track {
+ background: #333;
+}
+#tree::-webkit-scrollbar {
+ background: #333;
+}
+#tree::-webkit-scrollbar-thumb {
+ background: #eb0;
+}
+#tree:hover {
+ z-index: 2;
+}
+#treeul {
+ position: relative;
+ left: -1.7em;
+ width: calc(100% + 1.3em);
}
#tree>a+a {
padding: .2em .4em;
@@ -471,12 +504,6 @@ input[type="checkbox"]:checked+label {
padding: .3em .5em;
font-size: 1.5em;
}
-#treefiles #files tbody {
- border-radius: 0 .7em 0 .7em;
-}
-#treefiles #files thead th:nth-child(1) {
- border-radius: .7em 0 0 0;
-}
#tree ul,
#tree li {
padding: 0;
@@ -488,7 +515,11 @@ input[type="checkbox"]:checked+label {
#tree li {
margin-left: 1em;
list-style: none;
- white-space: nowrap;
+ border-top: 1px solid #4c4c4c;
+ border-bottom: 1px solid #111;
+}
+#tree li:last-child {
+ border-bottom: none;
}
#treeul a.hl {
color: #400;
@@ -502,24 +533,12 @@ input[type="checkbox"]:checked+label {
#treeul a+a {
width: calc(100% - 2em);
background: #333;
+ line-height: 1em;
}
#treeul a+a:hover {
background: #222;
color: #fff;
}
-#treeul {
- position: relative;
- overflow: hidden;
- left: -1.7em;
-}
-#treeul:hover {
- z-index: 2;
- overflow: visible;
-}
-#treeul:hover a+a {
- width: auto;
- min-width: calc(100% - 2em);
-}
#treeul a:first-child {
font-family: monospace, monospace;
}
diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html
index 904e08ac..61e247f7 100644
--- a/copyparty/web/browser.html
+++ b/copyparty/web/browser.html
@@ -50,20 +50,18 @@
{%- endfor %}
-
{{ logues[0] }}
+
-
+
+
+
{{ logues[0] }}
@@ -101,6 +99,8 @@
+
+
{%- if srv_info %}
{{ srv_info }}
{%- endif %}
diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js
index 67e92969..902ec30f 100644
--- a/copyparty/web/browser.js
+++ b/copyparty/web/browser.js
@@ -586,6 +586,7 @@ function autoplay_blocked() {
["name", "name", "name contains (negate with -nope)", "46"]
]
];
+ var oldcfg = [];
if (document.querySelector('#srch_form.tags'))
sconf.push(["tags",
@@ -664,8 +665,16 @@ function autoplay_blocked() {
if (ofiles.getAttribute('ts') > this.ts)
return;
- ebi('path').style.display = 'none';
- ebi('tree').style.display = 'none';
+ if (!oldcfg.length) {
+ oldcfg = [
+ ebi('path').style.display,
+ ebi('tree').style.display,
+ ebi('wrap').style.marginLeft
+ ];
+ ebi('path').style.display = 'none';
+ ebi('tree').style.display = 'none';
+ ebi('wrap').style.marginLeft = '0';
+ }
var html = mk_files_header(tagord);
html.push('');
@@ -714,8 +723,10 @@ function autoplay_blocked() {
function unsearch(e) {
ev(e);
- ebi('path').style.display = 'inline-block';
- ebi('tree').style.display = 'block';
+ ebi('path').style.display = oldcfg[0];
+ ebi('tree').style.display = oldcfg[1];
+ ebi('wrap').style.marginLeft = oldcfg[2];
+ oldcfg = [];
ebi('files').innerHTML = orig_html;
orig_html = null;
reload_browser();
@@ -723,8 +734,7 @@ function autoplay_blocked() {
})();
-// tree
-(function () {
+var treectl = (function () {
var dyn = bcfg_get('dyntree', true);
var treesz = icfg_get('treesz', 16);
treesz = Math.min(Math.max(treesz, 4), 50);
@@ -734,19 +744,50 @@ function autoplay_blocked() {
ev(e);
ebi('path').style.display = 'none';
- var treetab = ebi('treetab');
- var treefiles = ebi('treefiles');
-
- treetab.style.display = 'table';
-
- treefiles.appendChild(ebi('pro'));
- treefiles.appendChild(ebi('files'));
- treefiles.appendChild(ebi('epi'));
+ var tree = ebi('tree');
+ tree.style.display = 'block';
swrite('entreed', 'tree');
get_tree("", get_evpath(), true);
+ onresize();
}
+ function detree(e) {
+ ev(e);
+ ebi('tree').style.display = 'none';
+ ebi('path').style.display = 'inline-block';
+ ebi('wrap').style.marginLeft = '0';
+ swrite('entreed', 'na');
+ }
+
+ function onscroll() {
+ var top = ebi('wrap').getBoundingClientRect().top;
+ ebi('tree').style.top = Math.max(0, parseInt(top)) + 'px';
+ }
+ window.addEventListener('scroll', onscroll);
+
+ function periodic() {
+ onscroll();
+ setTimeout(periodic, document.visibilityState ? 200 : 5000);
+ }
+ periodic();
+
+ function onresize(e) {
+ var q = '#tree';
+ var nq = 0;
+ while (dyn) {
+ nq++;
+ q += '>ul>li';
+ if (!document.querySelector(q))
+ break;
+ }
+ var w = treesz + nq;
+ ebi('tree').style.width = w + 'em';
+ ebi('wrap').style.marginLeft = w + 'em';
+ onscroll();
+ }
+ window.addEventListener('resize', onresize);
+
function get_tree(top, dst, rst) {
var xhr = new XMLHttpRequest();
xhr.top = top;
@@ -810,20 +851,7 @@ function autoplay_blocked() {
document.querySelector('#treeul>li>a+a').textContent = '[root]';
despin('#tree');
reload_tree();
- rescale_tree();
- }
-
- function rescale_tree() {
- var q = '#tree';
- var nq = 0;
- while (true) {
- nq++;
- q += '>ul>li';
- if (!document.querySelector(q))
- break;
- }
- var w = treesz + (dyn ? nq : 0);
- ebi('treeul').style.width = w + 'em';
+ onresize();
}
function reload_tree() {
@@ -873,7 +901,7 @@ function autoplay_blocked() {
rm.parentNode.removeChild(rm);
}
this.textContent = '+';
- rescale_tree();
+ onresize();
return;
}
var dst = this.getAttribute('dst');
@@ -981,25 +1009,11 @@ function autoplay_blocked() {
return ret;
}
- function detree(e) {
- ev(e);
- var treetab = ebi('treetab');
-
- treetab.parentNode.insertBefore(ebi('pro'), treetab);
- treetab.parentNode.insertBefore(ebi('files'), treetab.nextSibling);
- treetab.parentNode.insertBefore(ebi('epi'), ebi('files').nextSibling);
-
- ebi('path').style.display = 'inline-block';
- treetab.style.display = 'none';
-
- swrite('entreed', 'na');
- }
-
function dyntree(e) {
ev(e);
dyn = !dyn;
bcfg_set('dyntree', dyn);
- rescale_tree();
+ onresize();
}
function scaletree(e) {
@@ -1009,7 +1023,7 @@ function autoplay_blocked() {
treesz = 16;
swrite('treesz', treesz);
- rescale_tree();
+ onresize();
}
ebi('entree').onclick = entree;
@@ -1034,6 +1048,10 @@ function autoplay_blocked() {
if (window.history && history.pushState) {
hist_replace(get_evpath() + window.location.hash);
}
+
+ return {
+ "onscroll": onscroll
+ }
})();
diff --git a/copyparty/web/up2k.js b/copyparty/web/up2k.js
index 4afda02a..c9464c6b 100644
--- a/copyparty/web/up2k.js
+++ b/copyparty/web/up2k.js
@@ -46,9 +46,9 @@ function up2k_flagbus() {
var dbg = function (who, msg) {
console.log('flagbus(' + flag.id + '): [' + who + '] ' + msg);
};
- flag.ch.onmessage = function (ev) {
- var who = ev.data[0],
- what = ev.data[1];
+ flag.ch.onmessage = function (e) {
+ var who = e.data[0],
+ what = e.data[1];
if (who == flag.id) {
dbg(who, 'hi me (??)');
@@ -83,7 +83,7 @@ function up2k_flagbus() {
flag.ch.postMessage([flag.id, "hey"]);
}
else {
- dbg('?', ev.data);
+ dbg('?', e.data);
}
};
var tx = function (now, msg) {
@@ -194,7 +194,7 @@ function up2k_init(have_crypto) {
// handle user intent to use the basic uploader instead
ebi('u2nope').onclick = function (e) {
- e.preventDefault();
+ ev(e);
setmsg();
goto('bup');
};
@@ -254,29 +254,29 @@ function up2k_init(have_crypto) {
}
ebi('u2btn').addEventListener('click', nav, false);
- function ondrag(ev) {
- ev.stopPropagation();
- ev.preventDefault();
- ev.dataTransfer.dropEffect = 'copy';
- ev.dataTransfer.effectAllowed = 'copy';
+ function ondrag(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ e.dataTransfer.dropEffect = 'copy';
+ e.dataTransfer.effectAllowed = 'copy';
}
ebi('u2btn').addEventListener('dragover', ondrag, false);
ebi('u2btn').addEventListener('dragenter', ondrag, false);
- function gotfile(ev) {
- ev.stopPropagation();
- ev.preventDefault();
+ function gotfile(e) {
+ e.stopPropagation();
+ e.preventDefault();
var files;
var is_itemlist = false;
- if (ev.dataTransfer) {
- if (ev.dataTransfer.items) {
- files = ev.dataTransfer.items; // DataTransferItemList
+ if (e.dataTransfer) {
+ if (e.dataTransfer.items) {
+ files = e.dataTransfer.items; // DataTransferItemList
is_itemlist = true;
}
- else files = ev.dataTransfer.files; // FileList
+ else files = e.dataTransfer.files; // FileList
}
- else files = ev.target.files;
+ else files = e.target.files;
if (files.length == 0)
return alert('no files selected??');
@@ -655,8 +655,8 @@ function up2k_init(have_crypto) {
prog(t.n, nchunk, col_hashing);
};
- var segm_load = function (ev) {
- cache_buf = ev.target.result;
+ var segm_load = function (e) {
+ cache_buf = e.target.result;
cache_ofs = 0;
hash_calc();
};
@@ -730,7 +730,7 @@ function up2k_init(have_crypto) {
st.busy.handshake.push(t);
var xhr = new XMLHttpRequest();
- xhr.onload = function (ev) {
+ xhr.onload = function (e) {
if (xhr.status == 200) {
var response = JSON.parse(xhr.responseText);
@@ -881,7 +881,7 @@ function up2k_init(have_crypto) {
alert('y o u b r o k e i t\n\n(was that a folder? just files please)');
};
- reader.onload = function (ev) {
+ reader.onload = function (e) {
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function (xev) {
var perc = xev.loaded / (cdr - car) * 100;
@@ -915,7 +915,7 @@ function up2k_init(have_crypto) {
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
xhr.overrideMimeType('Content-Type', 'application/octet-stream');
xhr.responseType = 'text';
- xhr.send(ev.target.result);
+ xhr.send(e.target.result);
};
reader.readAsArrayBuffer(bobslice.call(t.fobj, car, cdr));
@@ -944,7 +944,7 @@ function up2k_init(have_crypto) {
/// config ui
//
- function onresize(ev) {
+ function onresize(e) {
var bar = ebi('ops'),
wpx = innerWidth,
fpx = parseInt(getComputedStyle(bar)['font-size']),
@@ -959,17 +959,17 @@ function up2k_init(have_crypto) {
ebi('u2conf').setAttribute('class', wide ? 'has_btn' : '');
}
}
- window.onresize = onresize;
+ window.addEventListener('resize', onresize);
onresize();
- function desc_show(ev) {
+ function desc_show(e) {
var msg = this.getAttribute('alt');
msg = msg.replace(/\$N/g, "
");
var cdesc = ebi('u2cdesc');
cdesc.innerHTML = msg;
cdesc.setAttribute('class', 'show');
}
- function desc_hide(ev) {
+ function desc_hide(e) {
ebi('u2cdesc').setAttribute('class', '');
}
var o = document.querySelectorAll('#u2conf *[alt]');
@@ -1084,17 +1084,17 @@ function up2k_init(have_crypto) {
}
}
- function nop(ev) {
- ev.preventDefault();
+ function nop(e) {
+ ev(e);
this.click();
}
- ebi('nthread_add').onclick = function (ev) {
- ev.preventDefault();
+ ebi('nthread_add').onclick = function (e) {
+ ev(e);
bumpthread(1);
};
- ebi('nthread_sub').onclick = function (ev) {
- ev.preventDefault();
+ ebi('nthread_sub').onclick = function (e) {
+ ev(e);
bumpthread(-1);
};
diff --git a/copyparty/web/upload.css b/copyparty/web/upload.css
index caa8004e..32635e9b 100644
--- a/copyparty/web/upload.css
+++ b/copyparty/web/upload.css
@@ -62,7 +62,7 @@
width: calc(100% - 2em);
max-width: 100em;
}
-#u2form.srch #u2tab {
+#op_up2k.srch #u2tab {
max-width: none;
}
#u2tab td {
@@ -76,7 +76,7 @@
#u2tab td:nth-child(3) {
width: 40%;
}
-#u2form.srch #u2tab td:nth-child(3) {
+#op_up2k.srch #u2tab td:nth-child(3) {
font-family: sans-serif;
width: auto;
}
diff --git a/copyparty/web/util.js b/copyparty/web/util.js
index 9e49f527..d6f58f94 100644
--- a/copyparty/web/util.js
+++ b/copyparty/web/util.js
@@ -183,6 +183,9 @@ function goto(dest) {
if (fn)
fn();
}
+
+ if (window['treectl'])
+ treectl.onscroll();
}