From 22971a6be49f11955822d23193a281b2bc0c3ec6 Mon Sep 17 00:00:00 2001 From: ed Date: Tue, 6 Jul 2021 21:43:07 +0200 Subject: [PATCH] up2k-cli: add turbo button --- copyparty/web/browser.css | 35 +++++++--- copyparty/web/browser.js | 7 ++ copyparty/web/up2k.js | 138 +++++++++++++++++++++++++++++++++++--- copyparty/web/upload.css | 22 ++++++ copyparty/web/util.js | 4 +- 5 files changed, 185 insertions(+), 21 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 3032deb9..b6c109d5 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -29,10 +29,10 @@ body { position: fixed; max-width: 34em; background: #222; - border: 0 solid #555; + border: 0 solid #777; overflow: hidden; margin-top: 1em; - padding: 0 1em; + padding: 0 1.3em; height: 0; opacity: .1; transition: opacity 0.14s, height 0.14s, padding 0.14s; @@ -40,19 +40,31 @@ body { border-radius: .4em; z-index: 9001; } +#tt.b { + padding: 0 2em; + border-radius: .5em; + box-shadow: 0 .2em 1em #000; +} #tt.show { - padding: 1em; + padding: 1em 1.3em; + border-width: .4em 0; height: auto; - border-width: .2em 0; opacity: 1; } +#tt.show.b { + padding: 1.5em 2em; + border-width: .5em 0; +} #tt code { background: #3c3c3c; - padding: .2em .3em; + padding: .1em .3em; border-top: 1px solid #777; border-radius: .3em; font-family: monospace, monospace; - line-height: 2em; + line-height: 1.7em; +} +#tt em { + color: #f6a; } #path, #path * { @@ -812,11 +824,13 @@ input.eq_gain { border-bottom: 1px solid #555; } #thumbs, -#au_osd_cv { +#au_osd_cv, +#u2tdate { opacity: .3; } #griden.on+#thumbs, -#au_os_ctl.on+#au_osd_cv { +#au_os_ctl.on+#au_osd_cv, +#u2turbo.on+#u2tdate { opacity: 1; } #ghead { @@ -921,13 +935,16 @@ html.light { } html.light #tt { background: #fff; - border-color: #888; + border-color: #888 #000 #777 #000; box-shadow: 0 .3em 1em rgba(0,0,0,0.4); } html.light #tt code { background: #060; color: #fff; } +html.light #tt em { + color: #d38; +} html.light #ops, html.light .opbox, html.light #srch_form { diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 2bbfca51..68ab9e9f 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -133,6 +133,13 @@ ebi('op_cfg').innerHTML = ( (have_zip ? ( '

folder download

\n' ) : '') + + '
\n' + + '

up2k switches

\n' + + '
\n' + + ' turbo\n' + + ' date-chk\n' + + '
\n' + + '
\n' + '

key notation

\n' + '

hidden columns

' ); diff --git a/copyparty/web/up2k.js b/copyparty/web/up2k.js index e08d021d..84432899 100644 --- a/copyparty/web/up2k.js +++ b/copyparty/web/up2k.js @@ -308,6 +308,12 @@ function U2pvis(act, btns) { throw 42; } + //console.log("oldcat %s %d, newcat %s %d, head=%d, tail=%d, file=%d, act.old=%s, act.new=%s, bz_act=%s", + // oldcat, this.ctr[oldcat], + // newcat, this.ctr[newcat], + // this.head, this.tail, nfile, + // this.is_act(oldcat), this.is_act(newcat), bz_act); + fo.in = newcat; this.ctr[oldcat]--; this.ctr[newcat]++; @@ -319,7 +325,7 @@ function U2pvis(act, btns) { this.addrow(nfile); } else if (this.is_act(oldcat)) { - while (this.head < Math.min(this.tab.length, this.tail) && (this.head == nfile || !this.is_act(this.tab[this.head].in))) + while (this.head < Math.min(this.tab.length, this.tail) && this.precard[this.tab[this.head].in]) this.head++; if (!bz_act) { @@ -327,9 +333,10 @@ function U2pvis(act, btns) { tr.parentNode.removeChild(tr); } } - if (bz_act) { + else return; + + if (bz_act) this.bzw(); - } }; this.bzw = function () { @@ -343,7 +350,8 @@ function U2pvis(act, btns) { while (this.head - first > this.wsz) { var obj = ebi('f' + (first++)); - obj.parentNode.removeChild(obj); + if (obj) + obj.parentNode.removeChild(obj); } while (last - this.tail < this.wsz && last < this.tab.length - 2) { var obj = ebi('f' + (++last)); @@ -376,6 +384,8 @@ function U2pvis(act, btns) { this.changecard = function (card) { this.act = card; + this.precard = has(["ok", "ng", "done"], this.act) ? {} : this.act == "bz" ? { "ok": 1, "ng": 1 } : { "ok": 1, "ng": 1, "bz": 1 }; + this.postcard = has(["ok", "ng", "done"], this.act) ? { "bz": 1, "q": 1 } : this.act == "bz" ? { "q": 1 } : {}; this.head = -1; this.tail = -1; var html = []; @@ -390,16 +400,13 @@ function U2pvis(act, btns) { } } if (this.head == -1) { - var precard = has(["ok", "ng", "done"], this.act) ? {} : this.act == "bz" ? { "ok": 1, "ng": 1 } : { "ok": 1, "ng": 1, "bz": 1 }, - postcard = has(["ok", "ng", "done"], this.act) ? { "bz": 1, "q": 1 } : this.act == "bz" ? { "q": 1 } : {}; - for (var a = 0; a < this.tab.length; a++) { var rt = this.tab[a].in; - if (precard[rt]) { + if (this.precard[rt]) { this.head = a + 1; this.tail = a; } - else if (postcard[rt]) { + else if (this.postcard[rt]) { this.head = a; this.tail = a - 1; break; @@ -452,6 +459,8 @@ function U2pvis(act, btns) { that.changecard(newtab); }; } + + this.changecard(this.act); } @@ -548,17 +557,21 @@ function up2k_init(subtle) { ask_up = bcfg_get('ask_up', true), flag_en = bcfg_get('flag_en', false), fsearch = bcfg_get('fsearch', false), + turbo = bcfg_get('u2turbo', false), + datechk = bcfg_get('u2tdate', true), fdom_ctr = 0, min_filebuf = 0; var st = { "files": [], "todo": { + "head": [], "hash": [], "handshake": [], "upload": [] }, "busy": { + "head": [], "hash": [], "handshake": [], "upload": [] @@ -569,6 +582,15 @@ function up2k_init(subtle) { } }; + function push_t(arr, t) { + var sort = arr.length && arr[arr.length - 1].n > t.n; + arr.push(t); + if (sort) + arr.sort(function (a, b) { + return a.n < b.n ? -1 : 1; + }); + } + var pvis = new U2pvis("bz", '#u2cards'); var bobslice = null; @@ -796,7 +818,10 @@ function up2k_init(subtle) { ], fobj.size, draw_each); st.files.push(entry); - st.todo.hash.push(entry); + if (turbo) + push_t(st.todo.head, entry); + else + push_t(st.todo.hash, entry); } if (!draw_each) { pvis.drawcard("q"); @@ -891,9 +916,11 @@ function up2k_init(subtle) { while (window['vis_exh']) { var now = Date.now(), is_busy = 0 != + st.todo.head.length + st.todo.hash.length + st.todo.handshake.length + st.todo.upload.length + + st.busy.head.length + st.busy.hash.length + st.busy.handshake.length + st.busy.upload.length; @@ -943,6 +970,12 @@ function up2k_init(subtle) { } } + if (st.todo.head.length && + st.busy.head.length < parallel_uploads) { + exec_head(); + mou_ikkai = true; + } + if (handshakes_permitted() && st.todo.handshake.length) { exec_handshake(); @@ -1160,6 +1193,53 @@ function up2k_init(subtle) { segm_next(); } + ///// + //// + /// head + // + + function exec_head() { + var t = st.todo.head.shift(); + st.busy.head.push(t); + + var xhr = new XMLHttpRequest(); + xhr.onerror = function () { + console.log('head onerror, retrying', t); + apop(st.busy.head, t); + st.todo.head.unshift(t); + tasker(); + }; + function orz(e) { + var ok = false; + if (xhr.status == 200) { + var srv_sz = xhr.getResponseHeader('Content-Length'), + srv_ts = xhr.getResponseHeader('Last-Modified'); + + ok = t.size == srv_sz; + if (ok && datechk) { + srv_ts = new Date(srv_ts) / 1000; + ok = Math.abs(srv_ts - t.lmod) < 2; + } + } + apop(st.busy.head, t); + if (!ok) + return push_t(st.todo.hash, t); + + t.done = true; + st.bytes.hashed += t.size; + st.bytes.uploaded += t.size; + pvis.seth(t.n, 1, 'YOLO'); + pvis.seth(t.n, 2, "turbo'd"); + pvis.move(t.n, 'ok'); + }; + xhr.onload = function (e) { + try { orz(e); } catch (ex) { vis_exh(ex + '', '', '', '', ex); } + }; + + xhr.open('HEAD', t.purl + t.name, true); + xhr.send(); + } + ///// //// /// handshake @@ -1268,14 +1348,24 @@ function up2k_init(subtle) { msg = '🎷🐛'; if (t.postlist.length) { + var arr = st.todo.upload, + sort = arr.length && arr[arr.length - 1].nfile > t.n; + for (var a = 0; a < t.postlist.length; a++) - st.todo.upload.push({ + arr.push({ 'nfile': t.n, 'npart': t.postlist[a] }); msg = 'uploading'; done = false; + + if (sort) + arr.sort(function (a, b) { + return a.nfile < b.nfile ? -1 : + /* */ a.nfile > b.nfile ? 1 : + a.npart < b.npart ? -1 : 1; + }); } pvis.seth(t.n, 1, msg); apop(st.busy.handshake, t); @@ -1527,6 +1617,30 @@ function up2k_init(subtle) { set_fsearch(!fsearch); } + function tgl_turbo() { + turbo = !turbo; + bcfg_set('u2turbo', turbo); + draw_turbo(); + } + + function tgl_datechk() { + datechk = !datechk; + bcfg_set('u2tdate', datechk); + } + + function draw_turbo() { + var msg = '

WARNING: turbo enabled,  client may not detect and resume incomplete uploads; see turbo-button tooltip

', + html = ebi('u2foot').innerHTML; + + if (turbo && html.indexOf(msg) === -1) + html += msg; + else if (!turbo) + html = html.replace(msg, ''); + + ebi('u2foot').innerHTML = html; + } + draw_turbo(); + function set_fsearch(new_state) { var fixed = false; @@ -1608,6 +1722,8 @@ function up2k_init(subtle) { ebi('multitask').addEventListener('click', tgl_multitask, false); ebi('ask_up').addEventListener('click', tgl_ask_up, false); ebi('flag_en').addEventListener('click', tgl_flag_en, false); + ebi('u2turbo').addEventListener('click', tgl_turbo, false); + ebi('u2tdate').addEventListener('click', tgl_datechk, false); var o = ebi('fsearch'); if (o) o.addEventListener('click', tgl_fsearch, false); diff --git a/copyparty/web/upload.css b/copyparty/web/upload.css index 0ff5edea..d1c25375 100644 --- a/copyparty/web/upload.css +++ b/copyparty/web/upload.css @@ -215,9 +215,31 @@ color: #fff; font-style: italic; } +#u2foot .warn { + font-size: 1.3em; + padding: .5em .8em; + margin: 1em -.6em; + color: #f74; + background: #322; + border: 1px solid #633; + border-width: .1em 0; + text-align: center; +} +#u2foot .warn span { + color: #f86; +} +html.light #u2foot .warn { + color: #b00; + background: #fca; + border-color: #f70; +} +html.light #u2foot .warn span { + color: #930; +} #u2foot span { color: #999; font-size: .9em; + font-weight: normal; } #u2footfoot { margin-bottom: -1em; diff --git a/copyparty/web/util.js b/copyparty/web/util.js index 5464a687..2b0e63a3 100644 --- a/copyparty/web/util.js +++ b/copyparty/web/util.js @@ -514,8 +514,10 @@ var tt = (function () { var pos = this.getBoundingClientRect(), left = pos.left < window.innerWidth / 2, - top = pos.top < window.innerHeight / 2; + top = pos.top < window.innerHeight / 2, + big = this.className.indexOf(' ttb') !== -1; + clmod(r.tt, 'b', big); r.tt.style.top = top ? pos.bottom + 'px' : 'auto'; r.tt.style.bottom = top ? 'auto' : (window.innerHeight - pos.top) + 'px'; r.tt.style.left = left ? pos.left + 'px' : 'auto';