Add repeatable admin notification sounds
This commit is contained in:
@@ -12,8 +12,10 @@ const state = {
|
||||
soundMuted: localStorage.getItem("mf_admin_sound_muted") === "1",
|
||||
soundVolume: Number(localStorage.getItem("mf_admin_sound_volume") || 70),
|
||||
soundStyle: localStorage.getItem("mf_admin_sound_style") || "bright",
|
||||
soundRepeat: localStorage.getItem("mf_admin_sound_repeat") === "1",
|
||||
replyFiles: [],
|
||||
attentionTimer: null,
|
||||
soundRepeatTimer: null,
|
||||
attentionOn: false,
|
||||
originalTitle: document.title,
|
||||
originalFavicon: document.querySelector("link[rel='icon']")?.href || "/favicon.svg"
|
||||
@@ -68,6 +70,12 @@ $("#adminSoundStyle").addEventListener("change", (event) => {
|
||||
localStorage.setItem("mf_admin_sound_style", state.soundStyle);
|
||||
renderAdminSoundControls();
|
||||
});
|
||||
$("#adminSoundRepeat").addEventListener("change", (event) => {
|
||||
state.soundRepeat = event.target.checked;
|
||||
localStorage.setItem("mf_admin_sound_repeat", state.soundRepeat ? "1" : "0");
|
||||
if (!state.soundRepeat) stopRepeatingSound();
|
||||
renderAdminSoundControls();
|
||||
});
|
||||
$("#adminSoundTest").addEventListener("click", () => {
|
||||
playNotifySound({ ignoreMuted: true });
|
||||
});
|
||||
@@ -804,6 +812,7 @@ async function saveSite(patch) {
|
||||
function notify() {
|
||||
startAttention();
|
||||
playNotifySound();
|
||||
startRepeatingSound();
|
||||
}
|
||||
|
||||
function renderAdminSoundControls() {
|
||||
@@ -812,6 +821,7 @@ function renderAdminSoundControls() {
|
||||
const settingsToggle = $("#adminSoundToggleSettings");
|
||||
const settingsVolume = $("#adminSoundVolumeSettings");
|
||||
const settingsStyle = $("#adminSoundStyle");
|
||||
const settingsRepeat = $("#adminSoundRepeat");
|
||||
const safeVolume = clamp(state.soundVolume, 0, 100);
|
||||
if (toggle) {
|
||||
toggle.classList.toggle("muted", state.soundMuted || safeVolume <= 0);
|
||||
@@ -825,6 +835,7 @@ function renderAdminSoundControls() {
|
||||
if (settingsToggle) settingsToggle.checked = !state.soundMuted;
|
||||
if (settingsVolume) settingsVolume.value = String(safeVolume);
|
||||
if (settingsStyle) settingsStyle.value = state.soundStyle;
|
||||
if (settingsRepeat) settingsRepeat.checked = state.soundRepeat;
|
||||
}
|
||||
|
||||
function setAdminSoundMuted(isMuted) {
|
||||
@@ -832,6 +843,7 @@ function setAdminSoundMuted(isMuted) {
|
||||
if (!state.soundMuted && state.soundVolume <= 0) state.soundVolume = 70;
|
||||
localStorage.setItem("mf_admin_sound_muted", state.soundMuted ? "1" : "0");
|
||||
localStorage.setItem("mf_admin_sound_volume", String(state.soundVolume));
|
||||
if (state.soundMuted) stopRepeatingSound();
|
||||
renderAdminSoundControls();
|
||||
}
|
||||
|
||||
@@ -840,6 +852,7 @@ function setAdminSoundVolume(value) {
|
||||
state.soundMuted = state.soundVolume <= 0;
|
||||
localStorage.setItem("mf_admin_sound_volume", String(state.soundVolume));
|
||||
localStorage.setItem("mf_admin_sound_muted", state.soundMuted ? "1" : "0");
|
||||
if (state.soundMuted) stopRepeatingSound();
|
||||
renderAdminSoundControls();
|
||||
}
|
||||
|
||||
@@ -863,8 +876,28 @@ function playNotifySound(options = {}) {
|
||||
setTimeout(() => audio.close().catch(() => {}), 720);
|
||||
}
|
||||
|
||||
function startRepeatingSound() {
|
||||
if (!state.soundRepeat || state.soundRepeatTimer || state.soundMuted || clamp(state.soundVolume, 0, 100) <= 0) return;
|
||||
state.soundRepeatTimer = setInterval(() => {
|
||||
playNotifySound();
|
||||
}, 5500);
|
||||
}
|
||||
|
||||
function stopRepeatingSound() {
|
||||
if (state.soundRepeatTimer) clearInterval(state.soundRepeatTimer);
|
||||
state.soundRepeatTimer = null;
|
||||
}
|
||||
|
||||
function soundPattern(style) {
|
||||
const patterns = {
|
||||
tap: [
|
||||
{ offset: 0, duration: 0.08, frequency: 720, type: "sine" }
|
||||
],
|
||||
double: [
|
||||
{ offset: 0, duration: 0.09, frequency: 760, type: "sine" },
|
||||
{ offset: 0.12, duration: 0.09, frequency: 760, type: "sine" },
|
||||
{ offset: 0.28, duration: 0.1, frequency: 980, type: "triangle" }
|
||||
],
|
||||
soft: [
|
||||
{ offset: 0, duration: 0.13, frequency: 520, type: "sine" },
|
||||
{ offset: 0.16, duration: 0.12, frequency: 680, type: "sine" }
|
||||
@@ -905,6 +938,7 @@ function startAttention() {
|
||||
function stopAttention() {
|
||||
if (state.attentionTimer) clearInterval(state.attentionTimer);
|
||||
state.attentionTimer = null;
|
||||
stopRepeatingSound();
|
||||
state.attentionOn = false;
|
||||
document.title = state.originalTitle;
|
||||
const favicon = document.querySelector("link[rel='icon']");
|
||||
|
||||
Reference in New Issue
Block a user