diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 4ad9e57b..6e688190 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -629,6 +629,9 @@ input.eq_gain { margin-top: .5em; padding: 1.3em .3em; } +#ico1 { + cursor: pointer; +} @@ -1076,7 +1079,8 @@ a.btn, #rui label, #modal-ok, #modal-ng, -#ops { +#ops, +#ico1 { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index c3392e37..6e793c34 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -168,6 +168,15 @@ ebi('op_cfg').innerHTML = ( ' \n' + ' \n' + '\n' + + '
\n' + + '

favicon 🎉

\n' + + '
\n' + + ' ' + + ' ' + + ' ' + + ' \n' + + '
\n' + + '
\n' + '

key notation

\n' + '

hidden columns

' ); diff --git a/copyparty/web/up2k.js b/copyparty/web/up2k.js index cdcd771d..0f5f3c85 100644 --- a/copyparty/web/up2k.js +++ b/copyparty/web/up2k.js @@ -2012,6 +2012,15 @@ function warn_uploader_busy(e) { tt.init(); +favico.init(); +ebi('ico1').onclick = function () { + var a = favico.txt == this.textContent; + swrite('icot', a ? 'c' : this.textContent); + swrite('icof', a ? null : '000'); + swrite('icob', a ? null : ''); + favico.init(); +}; + if (QS('#op_up2k.act')) goto_up2k(); diff --git a/copyparty/web/util.js b/copyparty/web/util.js index a5c927c8..6fb3512f 100644 --- a/copyparty/web/util.js +++ b/copyparty/web/util.js @@ -621,9 +621,9 @@ function icfg_get(name, defval) { } function fcfg_get(name, defval) { - var o = ebi(name); + var o = ebi(name), + val = parseFloat(sread(name)); - var val = parseFloat(sread(name)); if (isNaN(val)) return parseFloat(o ? o.value : defval); @@ -633,6 +633,19 @@ function fcfg_get(name, defval) { return val; } +function scfg_get(name, defval) { + var o = ebi(name), + val = sread(name); + + if (val === null) + val = defval; + + if (o) + o.value = val; + + return val; +} + function bcfg_get(name, defval) { var o = ebi(name); if (!o) @@ -684,6 +697,21 @@ function bcfg_bind(obj, oname, cname, defval, cb, un_ev) { return v; } +function scfg_bind(obj, oname, cname, defval, cb) { + var v = scfg_get(cname, defval), + el = ebi(cname); + + obj[oname] = v; + if (el) + el.oninput = function (e) { + swrite(cname, obj[oname] = this.value); + if (cb) + cb(obj[oname]); + }; + + return v; +} + function hist_push(url) { console.log("h-push " + url); @@ -849,16 +877,7 @@ var tt = (function () { } r.init = function () { - var ttb = ebi('tooltips'); - if (ttb) { - ttb.onclick = function (e) { - ev(e); - r.en = !r.en; - bcfg_set('tooltips', r.en); - r.init(); - }; - r.en = bcfg_get('tooltips', true) - } + bcfg_bind(r, 'en', 'tooltips', r.en, r.init); r.att(document); }; @@ -1181,3 +1200,54 @@ function repl(e) { } if (ebi('repl')) ebi('repl').onclick = repl; + + +var favico = (function () { + var r = {}; + r.en = true; + + function gx(txt) { + return ( + '\n' + + '\n' + + (r.bg ? '\n' : '') + + '' + txt + '' + ); + } + + r.upd = function () { + var i = QS('link[rel="icon"]'), b64; + if (!r.txt) + return; + + try { + b64 = btoa(gx(r.txt)); + } + catch (ex) { + b64 = encodeURIComponent(r.txt).replace(/%([0-9A-F]{2})/g, + function x(m, v) { return String.fromCharCode('0x' + v); }); + + b64 = btoa(gx(unescape(encodeURIComponent(r.txt)))); + } + + if (!i) { + i = mknod('link'); + i.rel = 'icon'; + document.head.appendChild(i); + } + i.href = 'data:image/svg+xml;base64,' + b64; + }; + + r.init = function () { + clearTimeout(r.to); + scfg_bind(r, 'txt', 'icot', '', r.upd); + scfg_bind(r, 'fg', 'icof', 'fc5', r.upd); + scfg_bind(r, 'bg', 'icob', '333', r.upd); + r.upd(); + }; + + r.to = setTimeout(r.init, 100); + return r; +})();