Drop the haptics

The clock buzzed on every turn change, on a flag and on the confirming
second tap of Reset. Sound and the colour change carry all of it, so the
vibration goes: buzz() and its four call sites, and the iOS README bullet
that explained why the buzz was silent there — a platform difference that
no longer exists now there are no haptics anywhere.

Verified by stubbing navigator.vibrate and driving a turn change, a
timeout and a confirmed reset: zero calls, while the turn still counted
and the flag still fell.

It also means the Android package can declare no permissions at all.
VIBRATE was the only one it would have needed — there is no INTERNET
either, since the whole clock ships inside the APK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-11 19:10:23 +02:00
co-authored by Claude Opus 5
parent 485aa9728d
commit 6069ef270e
3 changed files with 4 additions and 8 deletions
-2
View File
@@ -30,8 +30,6 @@ On iOS a few things behave differently, none of them fatal:
you lose a strip of the screen to the toolbar, and iOS clears the saved you lose a strip of the screen to the toolbar, and iOS clears the saved
settings of a site you haven't visited for a week. The installed app keeps settings of a site you haven't visited for a week. The installed app keeps
its own storage and doesn't get pruned that way. its own storage and doesn't get pruned that way.
- **There's no vibration** — iOS gives web pages no haptics at all, so the
turn-change buzz is silent there. The sounds still play.
- **The ringer switch doesn't mute the clock.** The page claims a playback - **The ringer switch doesn't mute the clock.** The page claims a playback
audio session so you can hear the delay tick with the phone silenced, which audio session so you can hear the delay tick with the phone silenced, which
in exchange pauses any music you had going. If you'd rather keep the music, in exchange pauses any music you had going. If you'd rather keep the music,
+3 -5
View File
@@ -673,7 +673,6 @@
tone(659.25, 0.16, 0.20, 0.24, "triangle", false); tone(659.25, 0.16, 0.20, 0.24, "triangle", false);
tone(440, 0.32, 0.55, 0.26, "triangle", true); tone(440, 0.32, 0.55, 0.26, "triangle", true);
} }
function buzz(ms){ try{ if(navigator.vibrate) navigator.vibrate(ms); }catch(e){} }
/* ============ helpers ============ */ /* ============ helpers ============ */
function elapsed(){ function elapsed(){
@@ -791,7 +790,6 @@
paintPlay(); paintPlay();
render(); render();
sndFlag(); sndFlag();
buzz([90, 70, 90]);
saveGame(); saveGame();
} }
@@ -808,7 +806,7 @@
st.ticked = false; st.ticked = false;
st.phase = RUN; st.phase = RUN;
paintPlay(); // the bar has to show what the clock is doing paintPlay(); // the bar has to show what the clock is doing
sndSwap(); buzz(14); sndSwap();
saveGame(); saveGame();
return; return;
} }
@@ -822,7 +820,7 @@
st.active = 1 - side; st.active = 1 - side;
st.turnAt = now; st.turnAt = now;
st.ticked = false; st.ticked = false;
sndSwap(); buzz(14); sndSwap();
saveGame(); saveGame();
} }
@@ -942,7 +940,7 @@
btnReset.setAttribute("aria-label", "Reset clock"); btnReset.setAttribute("aria-label", "Reset clock");
} }
function armReset(){ function armReset(){
if(armT){ disarm(); resetAll(); buzz(20); return; } // second tap inside the window if(armT){ disarm(); resetAll(); return; } // second tap inside the window
btnReset.classList.remove("armed"); btnReset.classList.remove("armed");
void btnReset.offsetWidth; // restart the drain animation void btnReset.offsetWidth; // restart the drain animation
btnReset.classList.add("armed"); btnReset.classList.add("armed");
+1 -1
View File
@@ -1,5 +1,5 @@
/* Cache-first: once installed the clock never touches the network again. */ /* Cache-first: once installed the clock never touches the network again. */
const CACHE = "bgclock-v14"; const CACHE = "bgclock-v15";
const FILES = [ const FILES = [
"./", "./",
"./index.html", "./index.html",