diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css
index c2e40414..13a0835a 100644
--- a/copyparty/web/browser.css
+++ b/copyparty/web/browser.css
@@ -1265,6 +1265,8 @@ html.y #ops svg circle {
.opbox input {
position: relative;
margin: .5em;
+}
+#op_cfg input[type=text] {
top: -.3em;
}
.opview input[type=text] {
diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js
index 8771847a..d3019695 100644
--- a/copyparty/web/browser.js
+++ b/copyparty/web/browser.js
@@ -125,7 +125,8 @@ var Ls = {
"cut_az": "upload files in alphabetical order, rather than smallest-file-first$N$Nalphabetical order can make it easier to eyeball if something went wrong on the server, but it makes uploading slightly slower on fiber / LAN",
- "cut_nag": "audible alert when upload completes",
+ "cut_nag": "OS notification when upload completes$N(only if the browser or tab is not active)",
+ "cut_sfx": "audible alert when upload completes$N(only if the browser or tab is not active)",
"cut_mt": "use multithreading to accelerate file hashing$N$Nthis uses web-workers and requires$Nmore RAM (up to 512 MiB extra)$N$N30% faster https, 4.5x faster http,$Nand 5.3x faster on android phones",
@@ -493,7 +494,8 @@ var Ls = {
"cut_az": "last opp filer i alfabetisk rekkefølge, istedenfor minste-fil-først$N$Nalfabetisk kan gjøre det lettere å anslå om alt gikk bra, men er bittelitt tregere på fiber / LAN",
- "cut_nag": "lydvarsel når opplastning er ferdig",
+ "cut_nag": "meldingsvarsel når opplastning er ferdig$N(kun on nettleserfanen ikke er synlig)",
+ "cut_sfx": "lydvarsel når opplastning er ferdig$N(kun on nettleserfanen ikke er synlig)",
"cut_mt": "raskere befaring ved å bruke hele CPU'en$N$Ndenne funksjonen anvender web-workers$Nog krever mer RAM (opptil 512 MiB ekstra)$N$N30% raskere https, 4.5x raskere http,$Nog 5.3x raskere på android-telefoner",
@@ -922,6 +924,7 @@ ebi('op_cfg').innerHTML = (
' 💤\n' +
' az\n' +
' 🔔\n' +
+ ' 🔊\n' +
' \n' +
' \n' +
'\n' +
diff --git a/copyparty/web/up2k.js b/copyparty/web/up2k.js
index d6406d5c..152c4b54 100644
--- a/copyparty/web/up2k.js
+++ b/copyparty/web/up2k.js
@@ -713,6 +713,9 @@ function Donut(uc, st) {
strobes = ['████████████████', '________________', '████████████████'];
tstrober = setInterval(strobe, 300);
+ if (uc.upsfx && actx && actx.state != 'suspended')
+ sfx();
+
// firefox may forget that filedrops are user-gestures so it can skip this:
if (uc.upnag && window.Notification && Notification.permission == 'granted')
new Notification(uc.nagtxt);
@@ -724,6 +727,35 @@ function Donut(uc, st) {
if (!txt)
clearInterval(tstrober);
}
+
+ function sfx() {
+ var osc = actx.createOscillator(),
+ gain = actx.createGain(),
+ gg = gain.gain,
+ ft = [660, 880, 440, 660, 880],
+ ofs = 0;
+
+ osc.connect(gain);
+ gain.connect(actx.destination);
+ var ct = actx.currentTime + 0.03;
+
+ osc.type = 'triangle';
+ while (ft.length)
+ osc.frequency.setTargetAtTime(
+ ft.shift(), ct + (ofs += 0.05), 0.001);
+
+ gg.value = 0.15;
+ gg.setTargetAtTime(0.8, ct, 0.01);
+ gg.setTargetAtTime(0.3, ct + 0.13, 0.01);
+ gg.setTargetAtTime(0, ct + ofs + 0.05, 0.02);
+
+ osc.start();
+ setTimeout(function () {
+ osc.stop();
+ osc.disconnect();
+ gain.disconnect();
+ }, 500);
+ }
}
@@ -827,13 +859,15 @@ function up2k_init(subtle) {
bcfg_bind(uc, 'multitask', 'multitask', true, null, false);
bcfg_bind(uc, 'potato', 'potato', false, set_potato, false);
bcfg_bind(uc, 'ask_up', 'ask_up', true, null, false);
- bcfg_bind(uc, 'flag_en', 'flag_en', false, apply_flag_cfg);
bcfg_bind(uc, 'fsearch', 'fsearch', false, set_fsearch, false);
- bcfg_bind(uc, 'turbo', 'u2turbo', turbolvl > 1, draw_turbo, false);
- bcfg_bind(uc, 'datechk', 'u2tdate', turbolvl < 3, null, false);
- bcfg_bind(uc, 'az', 'u2sort', u2sort.indexOf('n') + 1, set_u2sort, false);
- bcfg_bind(uc, 'hashw', 'hashw', !!window.WebAssembly && (!subtle || !CHROME || MOBILE), set_hashw, false);
- bcfg_bind(uc, 'upnag', 'upnag', false, set_upnag, false);
+
+ bcfg_bind(uc, 'flag_en', 'flag_en', false, apply_flag_cfg);
+ bcfg_bind(uc, 'turbo', 'u2turbo', turbolvl > 1, draw_turbo);
+ bcfg_bind(uc, 'datechk', 'u2tdate', turbolvl < 3, null);
+ bcfg_bind(uc, 'az', 'u2sort', u2sort.indexOf('n') + 1, set_u2sort);
+ bcfg_bind(uc, 'hashw', 'hashw', !!window.WebAssembly && (!subtle || !CHROME || MOBILE), set_hashw);
+ bcfg_bind(uc, 'upnag', 'upnag', false, set_upnag);
+ bcfg_bind(uc, 'upsfx', 'upsfx', false);
var st = {
"files": [],
@@ -2647,7 +2681,7 @@ function up2k_init(subtle) {
nopenag();
}
- if (!window.Notification)
+ if (!window.Notification || !HTTPS)
return nopenag();
if (en && Notification.permission == 'default')