Move notification sound to admin

This commit is contained in:
rajchales-monito
2026-07-24 14:43:38 +02:00
parent 04529d2df3
commit 1d6d478993
4 changed files with 82 additions and 62 deletions
+8 -55
View File
@@ -66,7 +66,7 @@
const panel = root.querySelector(".mf-panel");
const launcher = root.querySelector(".mf-launcher");
const close = root.querySelector(".mf-close");
const { soundButton, infoButton } = createHeaderActions(root, close);
const { infoButton } = createHeaderActions(root, close);
const form = root.querySelector(".mf-form");
const messages = root.querySelector(".mf-messages");
const typing = root.querySelector(".mf-typing");
@@ -77,7 +77,6 @@
unreadAdminCount: 0,
knownAdminMessageId: 0
};
renderSoundState(soundButton);
launcher.addEventListener("click", () => {
panel.classList.toggle("open");
@@ -91,11 +90,6 @@
}
});
close.addEventListener("click", () => panel.classList.remove("open"));
soundButton.addEventListener("click", () => {
session.soundMuted = !session.soundMuted;
saveSession();
renderSoundState(soundButton);
});
infoButton.addEventListener("click", () => {
root.querySelector(".mf-gdpr").hidden = !root.querySelector(".mf-gdpr").hidden;
});
@@ -234,17 +228,6 @@
function createHeaderActions(root, closeButton) {
const actions = document.createElement("div");
actions.className = "mf-header-actions";
const soundButton = document.createElement("button");
soundButton.className = "mf-sound";
soundButton.type = "button";
soundButton.innerHTML = `
<svg class="mf-sound-on" viewBox="0 0 24 24" aria-hidden="true">
<path d="M4 9v6h4l5 4V5L8 9H4Zm12.2-1.8-1.4 1.4A4.9 4.9 0 0 1 16 12c0 1.3-.5 2.5-1.2 3.4l1.4 1.4A6.9 6.9 0 0 0 18 12c0-1.8-.7-3.5-1.8-4.8Zm2.6-2.6-1.4 1.4A8.8 8.8 0 0 1 20 12a8.8 8.8 0 0 1-2.6 6l1.4 1.4A10.8 10.8 0 0 0 22 12c0-2.9-1.2-5.5-3.2-7.4Z"></path>
</svg>
<svg class="mf-sound-off" viewBox="0 0 24 24" aria-hidden="true">
<path d="M4 9v6h4l5 4V5L8 9H4Zm12.4 3 2.3-2.3-1.4-1.4-2.3 2.3-2.3-2.3-1.4 1.4 2.3 2.3-2.3 2.3 1.4 1.4 2.3-2.3 2.3 2.3 1.4-1.4-2.3-2.3Z"></path>
</svg>
`;
const infoButton = document.createElement("button");
infoButton.className = "mf-info";
infoButton.type = "button";
@@ -255,38 +238,13 @@
closeButton.setAttribute("aria-label", "Zmensit chat");
closeButton.title = "Zmensit chat";
closeButton.before(actions);
actions.append(soundButton, infoButton, closeButton);
actions.append(infoButton, closeButton);
const gdpr = document.createElement("p");
gdpr.className = "mf-gdpr";
gdpr.hidden = true;
gdpr.textContent = "Odeslanim zpravy nam predavate udaje potrebne pro odpoved. Historii chatu uchovavame pro zakaznickou podporu.";
root.querySelector(".mf-form").prepend(gdpr);
return { soundButton, infoButton };
}
function renderSoundState(button) {
button.classList.toggle("muted", Boolean(session.soundMuted));
button.setAttribute("aria-label", session.soundMuted ? "Zapnout zvuk" : "Vypnout zvuk");
button.title = session.soundMuted ? "Zapnout zvuk" : "Vypnout zvuk";
}
function playNotifySound() {
if (session.soundMuted) return;
const AudioCtor = window.AudioContext || window.webkitAudioContext;
if (!AudioCtor) return;
const audio = new AudioCtor();
const gain = audio.createGain();
gain.gain.value = 0.04;
gain.connect(audio.destination);
[0, 0.12].forEach((offset, index) => {
const osc = audio.createOscillator();
osc.type = "sine";
osc.frequency.value = index ? 980 : 760;
osc.connect(gain);
osc.start(audio.currentTime + offset);
osc.stop(audio.currentTime + offset + 0.09);
});
setTimeout(() => audio.close().catch(() => {}), 420);
return { infoButton };
}
async function loadExistingConversation(messages, panel) {
@@ -333,7 +291,6 @@
if (options.notify !== false && hasNewAdminMessage) {
messageEffectState.unreadAdminCount += 1;
applyAdminReplyEffects(launcher, settings, messageEffectState.unreadAdminCount);
playNotifySound();
}
}
@@ -566,11 +523,8 @@
header strong { font-size: 16px; }
header small { opacity: .92; font-size: 13px; line-height: 1.35; }
.mf-header-actions { position: absolute; top: 9px; right: 9px; display: flex; gap: 6px; }
.mf-close, .mf-sound, .mf-info { width: 30px; height: 30px; display: grid; place-items: center; border: 0; border-radius: 6px; background: rgb(255 255 255 / 16%); color: ${c.brandText}; cursor: pointer; padding: 0; }
.mf-close svg, .mf-sound svg, .mf-info svg { width: 19px; height: 19px; fill: currentColor; }
.mf-sound .mf-sound-off { display: none; }
.mf-sound.muted .mf-sound-on { display: none; }
.mf-sound.muted .mf-sound-off { display: block; }
.mf-close, .mf-info { width: 30px; height: 30px; display: grid; place-items: center; border: 0; border-radius: 6px; background: rgb(255 255 255 / 16%); color: ${c.brandText}; cursor: pointer; padding: 0; }
.mf-close svg, .mf-info svg { width: 19px; height: 19px; fill: currentColor; }
.mf-messages { padding: 14px; overflow: auto; display: flex; flex-direction: column; gap: 10px; }
.mf-message { max-width: 86%; padding: 9px 11px; border-radius: 8px; background: #f1f5f2; color: ${c.text}; }
.mf-message.admin { align-self: flex-start; background: #eef7f4; }
@@ -637,9 +591,9 @@
function loadSession() {
try {
const existing = JSON.parse(localStorage.getItem(storageKey) || "{}");
return { visitorToken: existing.visitorToken || randomId(), conversationId: existing.conversationId || null, history: existing.history || [], soundMuted: Boolean(existing.soundMuted) };
return { visitorToken: existing.visitorToken || randomId(), conversationId: existing.conversationId || null, history: existing.history || [] };
} catch {
return { visitorToken: randomId(), conversationId: null, history: [], soundMuted: false };
return { visitorToken: randomId(), conversationId: null, history: [] };
}
}
@@ -647,8 +601,7 @@
localStorage.setItem(storageKey, JSON.stringify({
visitorToken: session.visitorToken,
conversationId: session.conversationId,
history: session.history || [],
soundMuted: Boolean(session.soundMuted)
history: session.history || []
}));
}