update display
This commit is contained in:
parent
8d5d2b0838
commit
197c4b56f7
@ -84,6 +84,21 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
fullscreenButton.hidden = true;
|
fullscreenButton.hidden = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let audioCtx = null;
|
||||||
|
const initAudio = () => {
|
||||||
|
try {
|
||||||
|
const AudioContext = window.AudioContext || window.webkitAudioContext;
|
||||||
|
if (!audioCtx && AudioContext) {
|
||||||
|
audioCtx = new AudioContext();
|
||||||
|
}
|
||||||
|
if (audioCtx && audioCtx.state === 'suspended') {
|
||||||
|
audioCtx.resume();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('AudioContext init failed', e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const audioBtn = document.querySelector('.js-audio-toggle');
|
const audioBtn = document.querySelector('.js-audio-toggle');
|
||||||
if (audioBtn) {
|
if (audioBtn) {
|
||||||
const updateAudioBtnState = () => {
|
const updateAudioBtnState = () => {
|
||||||
@ -109,38 +124,120 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
window.localStorage.setItem('hospitalQueue:audioEnabled', nextState.toString());
|
window.localStorage.setItem('hospitalQueue:audioEnabled', nextState.toString());
|
||||||
updateAudioBtnState();
|
updateAudioBtnState();
|
||||||
|
|
||||||
if (nextState && 'speechSynthesis' in window) {
|
if (nextState) {
|
||||||
const primeUtterance = new SpeechSynthesisUtterance('');
|
initAudio();
|
||||||
window.speechSynthesis.speak(primeUtterance);
|
if ('speechSynthesis' in window) {
|
||||||
|
const primeUtterance = new SpeechSynthesisUtterance('');
|
||||||
|
window.speechSynthesis.speak(primeUtterance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const cards = Array.from(document.querySelectorAll('.announcement-card'));
|
const playChime = () => {
|
||||||
const latest = cards[0];
|
try {
|
||||||
const audioEnabled = window.localStorage.getItem('hospitalQueue:audioEnabled') === 'true';
|
if (!audioCtx) initAudio();
|
||||||
if (latest && 'speechSynthesis' in window && audioEnabled) {
|
if (!audioCtx) return;
|
||||||
const announcementKey = latest.dataset.announcementKey || '';
|
if (audioCtx.state === 'suspended') audioCtx.resume();
|
||||||
const storageKey = `hospitalQueue:lastAnnouncement:${locale}`;
|
|
||||||
const storedKey = window.localStorage.getItem(storageKey) || '';
|
const playTone = (freq, startTime, duration) => {
|
||||||
if (announcementKey && announcementKey !== storedKey) {
|
const osc = audioCtx.createOscillator();
|
||||||
const text = locale === 'ar' ? (latest.dataset.announcementAr || '') : (latest.dataset.announcementEn || '');
|
const gain = audioCtx.createGain();
|
||||||
const utterance = new SpeechSynthesisUtterance(text);
|
osc.connect(gain);
|
||||||
utterance.lang = locale === 'ar' ? 'ar-SA' : 'en-US';
|
gain.connect(audioCtx.destination);
|
||||||
const voices = window.speechSynthesis.getVoices();
|
osc.type = 'sine';
|
||||||
const preferredVoice = voices.find((voice) => voice.lang.toLowerCase().startsWith(locale === 'ar' ? 'ar' : 'en'));
|
osc.frequency.setValueAtTime(freq, audioCtx.currentTime + startTime);
|
||||||
if (preferredVoice) utterance.voice = preferredVoice;
|
gain.gain.setValueAtTime(0, audioCtx.currentTime + startTime);
|
||||||
window.speechSynthesis.cancel();
|
gain.gain.linearRampToValueAtTime(0.5, audioCtx.currentTime + startTime + 0.05);
|
||||||
if (text) {
|
gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + startTime + duration);
|
||||||
window.speechSynthesis.speak(utterance);
|
osc.start(audioCtx.currentTime + startTime);
|
||||||
|
osc.stop(audioCtx.currentTime + startTime + duration);
|
||||||
|
};
|
||||||
|
playTone(523.25, 0, 0.4); // C5
|
||||||
|
playTone(659.25, 0.3, 0.6); // E5
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('AudioContext failed', e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkAnnouncements = () => {
|
||||||
|
const cards = Array.from(document.querySelectorAll('.announcement-card'));
|
||||||
|
const latest = cards[0];
|
||||||
|
const audioEnabled = window.localStorage.getItem('hospitalQueue:audioEnabled') === 'true';
|
||||||
|
|
||||||
|
if (latest) {
|
||||||
|
const announcementKey = latest.dataset.announcementKey || '';
|
||||||
|
const storageKey = `hospitalQueue:lastAnnouncement:${locale}`;
|
||||||
|
const storedKey = window.localStorage.getItem(storageKey) || '';
|
||||||
|
|
||||||
|
if (announcementKey && announcementKey !== storedKey) {
|
||||||
window.localStorage.setItem(storageKey, announcementKey);
|
window.localStorage.setItem(storageKey, announcementKey);
|
||||||
|
|
||||||
|
if (audioEnabled) {
|
||||||
|
const videoPlayer = document.getElementById('adsVideoPlayer');
|
||||||
|
if (videoPlayer) videoPlayer.volume = 0.1;
|
||||||
|
|
||||||
|
playChime();
|
||||||
|
|
||||||
|
if ('speechSynthesis' in window) {
|
||||||
|
setTimeout(() => {
|
||||||
|
const text = locale === 'ar' ? (latest.dataset.announcementAr || '') : (latest.dataset.announcementEn || '');
|
||||||
|
if (text) {
|
||||||
|
window.speechSynthesis.cancel();
|
||||||
|
const utterance = new SpeechSynthesisUtterance(text);
|
||||||
|
utterance.lang = locale === 'ar' ? 'ar-SA' : 'en-US';
|
||||||
|
const voices = window.speechSynthesis.getVoices();
|
||||||
|
const preferredVoice = voices.find((voice) => voice.lang.toLowerCase().startsWith(locale === 'ar' ? 'ar' : 'en'));
|
||||||
|
if (preferredVoice) utterance.voice = preferredVoice;
|
||||||
|
|
||||||
|
utterance.onend = () => { if (videoPlayer) videoPlayer.volume = 1.0; };
|
||||||
|
utterance.onerror = () => { if (videoPlayer) videoPlayer.volume = 1.0; };
|
||||||
|
|
||||||
|
window.speechSynthesis.speak(utterance);
|
||||||
|
} else {
|
||||||
|
if (videoPlayer) videoPlayer.volume = 1.0;
|
||||||
|
}
|
||||||
|
}, 1200); // play voice after chime finishes
|
||||||
|
} else {
|
||||||
|
setTimeout(() => { if (videoPlayer) videoPlayer.volume = 1.0; }, 2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
checkAnnouncements();
|
||||||
|
|
||||||
const autoRefreshSeconds = parseInt(document.querySelector('[data-auto-refresh]')?.dataset.autoRefresh || '0', 10);
|
const autoRefreshSeconds = parseInt(document.querySelector('[data-auto-refresh]')?.dataset.autoRefresh || '0', 10);
|
||||||
if (autoRefreshSeconds > 0) {
|
if (autoRefreshSeconds > 0) {
|
||||||
window.setTimeout(() => window.location.reload(), autoRefreshSeconds * 1000);
|
window.setInterval(async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(window.location.href, {
|
||||||
|
headers: { 'X-Requested-With': 'XMLHttpRequest' }
|
||||||
|
});
|
||||||
|
if (response.ok) {
|
||||||
|
const html = await response.text();
|
||||||
|
const parser = new DOMParser();
|
||||||
|
const doc = parser.parseFromString(html, 'text/html');
|
||||||
|
|
||||||
|
const newSections = doc.querySelector('#queueSections');
|
||||||
|
const currentSections = document.querySelector('#queueSections');
|
||||||
|
if (newSections && currentSections) {
|
||||||
|
currentSections.innerHTML = newSections.innerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
const oldTicker = document.querySelector('.news-ticker-container');
|
||||||
|
const newTicker = doc.querySelector('.news-ticker-container');
|
||||||
|
if (oldTicker && newTicker) {
|
||||||
|
oldTicker.innerHTML = newTicker.innerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkAnnouncements();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Auto-refresh failed', e);
|
||||||
|
}
|
||||||
|
}, autoRefreshSeconds * 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user