From c212ec498763dc8aeb1f88203e47ba89670fd6e9 Mon Sep 17 00:00:00 2001 From: filoor Date: Wed, 28 May 2025 18:59:15 +0200 Subject: [PATCH] feat(debug): debug mode tijdsynchronisatie toegevoegd De commit introduceert een debug tijdsynchronisatie tussen de cron script, de hoofdpagina en de Flask API. Deze functies maken het mogelijk om de huidige tijd te simuleren met een instelbare offset voor testdoeleinden. Het volume en de gebedstijden passen zich nu aan op basis van deze debug tijd indien actief. Debugger gebruikers kunnen via de nieuwe '/api/debug-time' endpoint de tijd aanpassen. De wijzigingen verbeteren de testbaarheid van de applicatie en zorgen ervoor dat gebedsafroepen en volumebepaling correct functioneren onder simulatieomstandigheden. --- adhan-webapp/adhan_cron.py | 31 +++- adhan-webapp/app.py | 93 +++++++++- adhan-webapp/done | 1 + adhan-webapp/static/countdown.js | 281 +++++++++++++++++++++--------- adhan-webapp/static/style.css | 208 ++++++++++++++++++++++ adhan-webapp/templates/debug.html | 116 ++++++++---- adhan-webapp/templates/index.html | 193 ++++++++++++++++++++ done | 3 + 8 files changed, 806 insertions(+), 120 deletions(-) diff --git a/adhan-webapp/adhan_cron.py b/adhan-webapp/adhan_cron.py index e041eae..7222233 100644 --- a/adhan-webapp/adhan_cron.py +++ b/adhan-webapp/adhan_cron.py @@ -4,9 +4,10 @@ import time SETTINGS_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'settings.json') VUMG_API = 'https://www.vumg.nl/?rest_route=/dpt/v1/prayertime&filter=today' -SONOS_API_IP = '192.168.0.114' # Pas aan indien nodig +SONOS_API_IP = '192.168.0.114' # IP van Raspberry Pi waar Sonos API draait LOG_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'adhan_cron.log') LAST_PLAYED_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'last_played.json') +FLASK_API_URL = 'http://localhost:80' # Flask app URL def logregel(message): timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') @@ -15,13 +16,32 @@ def logregel(message): with open(LOG_PATH, 'a') as log: log.write(log_message + '\n') +def get_current_time(): + """Haal de huidige tijd op, gebruik debug tijd als actief""" + try: + # Probeer debug tijd API + response = requests.get(f'{FLASK_API_URL}/api/debug-time', timeout=3) + if response.status_code == 200: + data = response.json() + if data.get('success') and data.get('debug_active'): + debug_time = data.get('current_time_display', '') + logregel(f"๐Ÿ”ง CRON gebruikt debug tijd: {debug_time}") + return debug_time + except Exception as e: + logregel(f"Debug tijd API niet beschikbaar: {e}") + + # Fallback naar normale tijd + normal_time = datetime.now().strftime('%H:%M') + return normal_time + def get_current_volume(settings): """Bepaal het juiste volume op basis van de huidige tijd""" # Fallback naar oude volume als nieuwe instellingen niet bestaan if 'volume_day' not in settings or 'volume_night' not in settings: return settings.get('volume', 30) - current_time = datetime.now().strftime('%H:%M') + # Gebruik debug tijd als beschikbaar + current_time = get_current_time() night_start = settings.get('night_start', '20:00') day_start = settings.get('day_start', '07:00') @@ -38,11 +58,11 @@ def get_current_volume(settings): if is_night: volume = settings.get('volume_night', settings.get('volume', 30) // 2) - logregel(f"๐ŸŒ™ Avond volume gebruikt: {volume}") + logregel(f"๐ŸŒ™ Avond volume gebruikt: {volume} (tijd: {current_time})") return volume else: volume = settings.get('volume_day', settings.get('volume', 30)) - logregel(f"โ˜€๏ธ Dag volume gebruikt: {volume}") + logregel(f"โ˜€๏ธ Dag volume gebruikt: {volume} (tijd: {current_time})") return volume def apply_prayer_offsets(gebedstijden, settings): @@ -145,7 +165,8 @@ def play_sonos_clip(zone, audio_clip, volume, prayer_name): logregel(f"โŒ FOUT Sonos {zone} {prayer_name}: {e}") return False -now = datetime.now().strftime('%H:%M') +# Gebruik debug tijd als beschikbaar +now = get_current_time() logregel(f"CRON gestart, huidige tijd: {now}") # Laad settings diff --git a/adhan-webapp/app.py b/adhan-webapp/app.py index 65c8886..5c2b273 100644 --- a/adhan-webapp/app.py +++ b/adhan-webapp/app.py @@ -22,7 +22,11 @@ SETTINGS_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'settin HADITHS_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static', 'hadiths.json') VUMG_API = 'https://www.vumg.nl/?rest_route=/dpt/v1/prayertime&filter=today' CLIPS_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static', 'clips') -SONOS_API_IP = '192.168.0.114' # IP van host waar Sonos API draait +SONOS_API_IP = '192.168.0.114' # IP van Raspberry Pi waar Sonos API draait + +# Globale variabelen +debug_time_offset = 0 # Offset in seconden voor debug mode +debug_mode_active = False def fetch_weather_data(): """Haalt weersinformatie op voor de geconfigureerde locatie""" @@ -77,13 +81,20 @@ def load_settings(): def get_current_volume(settings): """Bepaal het juiste volume op basis van de huidige tijd""" - from datetime import datetime + from datetime import datetime, timedelta # Fallback naar oude volume als nieuwe instellingen niet bestaan if 'volume_day' not in settings or 'volume_night' not in settings: return settings.get('volume', 30) - current_time = datetime.now().strftime('%H:%M') + # Gebruik debug tijd als actief + global debug_mode_active, debug_time_offset + if debug_mode_active: + current_time = (datetime.now() + timedelta(seconds=debug_time_offset)).strftime('%H:%M') + print(f"๐Ÿ”ง Volume bepaling gebruikt debug tijd: {current_time}") + else: + current_time = datetime.now().strftime('%H:%M') + night_start = settings.get('night_start', '20:00') day_start = settings.get('day_start', '07:00') @@ -99,9 +110,13 @@ def get_current_volume(settings): is_night = current_minutes >= night_minutes and current_minutes < day_minutes if is_night: - return settings.get('volume_night', settings.get('volume', 30) // 2) + volume = settings.get('volume_night', settings.get('volume', 30) // 2) + print(f"๐ŸŒ™ Avond volume gebruikt: {volume} (tijd: {current_time})") + return volume else: - return settings.get('volume_day', settings.get('volume', 30)) + volume = settings.get('volume_day', settings.get('volume', 30)) + print(f"โ˜€๏ธ Dag volume gebruikt: {volume} (tijd: {current_time})") + return volume def apply_prayer_offsets(gebedstijden, settings): """Pas offsets toe op gebedstijden""" @@ -644,5 +659,73 @@ def trigger_adzkaar(): except Exception as e: return jsonify({'success': False, 'error': str(e)}), 500 +@app.route('/api/debug-time', methods=['GET', 'POST']) +def debug_time(): + """API endpoint voor debug tijd beheer""" + global debug_time_offset, debug_mode_active + + if flask_request.method == 'POST': + # Check of debug mode is ingeschakeld voor POST requests + settings = load_settings() + if not settings.get('debug_mode', False): + return jsonify({'success': False, 'error': 'Debug mode is niet ingeschakeld'}), 403 + + try: + data = flask_request.get_json() + action = data.get('action') + + if action == 'set_offset': + debug_time_offset = data.get('offset', 0) + debug_mode_active = True + return jsonify({ + 'success': True, + 'message': f'Debug tijd offset ingesteld op {debug_time_offset} seconden', + 'offset': debug_time_offset, + 'debug_active': debug_mode_active + }) + + elif action == 'reset': + debug_time_offset = 0 + debug_mode_active = False + return jsonify({ + 'success': True, + 'message': 'Debug tijd gereset naar echte tijd', + 'offset': debug_time_offset, + 'debug_active': debug_mode_active + }) + + elif action == 'adjust': + adjustment = data.get('seconds', 0) + debug_time_offset += adjustment + debug_mode_active = True + return jsonify({ + 'success': True, + 'message': f'Debug tijd aangepast met {adjustment} seconden', + 'offset': debug_time_offset, + 'debug_active': debug_mode_active + }) + + else: + return jsonify({'success': False, 'error': 'Onbekende actie'}), 400 + + except Exception as e: + return jsonify({'success': False, 'error': str(e)}), 500 + + else: # GET request - altijd beschikbaar voor cron script + from datetime import datetime, timedelta + + current_time = datetime.now() + if debug_mode_active: + current_time += timedelta(seconds=debug_time_offset) + + return jsonify({ + 'success': True, + 'current_time': current_time.strftime('%H:%M:%S'), + 'current_time_display': current_time.strftime('%H:%M'), + 'offset': debug_time_offset, + 'debug_active': debug_mode_active, + 'real_time': datetime.now().strftime('%H:%M:%S') + }) + if __name__ == '__main__': app.run(host='0.0.0.0', port=80) \ No newline at end of file diff --git a/adhan-webapp/done b/adhan-webapp/done index 63b4dfa..f009148 100644 --- a/adhan-webapp/done +++ b/adhan-webapp/done @@ -12,3 +12,4 @@ Mon May 26 18:17:57 CEST 2025: Tijdzone probleem opgelost - Container gebruikt n 2025-05-28 03:37:57 - Light theme kleuren gerepareerd: teksten nu zichtbaar in light mode, accent kleuren aangepast voor betere contrast 2025-05-28 03:49:24 - Adzkaar fullscreen functionaliteit geรฏmplementeerd: nieuwe /adzkaar route, instellingen, debug knoppen, automatische trigger na gebedstijden, Nederlandse/Arabische dhikr content 2025-05-28 03:55:38 - Adzkaar scherm verbeterd naar kaart-voor-kaart weergave met navigatie knoppen en toetsenbord besturing +Wed May 28 14:09:12 CEST 2025: Sonos debug tijd synchronisatie geรฏmplementeerd - get_current_volume functie en cron script gebruiken nu debug tijd API, volume bepaling werkt correct in debug mode diff --git a/adhan-webapp/static/countdown.js b/adhan-webapp/static/countdown.js index 919efdc..c110c7f 100644 --- a/adhan-webapp/static/countdown.js +++ b/adhan-webapp/static/countdown.js @@ -1,10 +1,31 @@ function updateCurrentTime() { - const now = new Date(); - const timeStr = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); - document.getElementById("current-time").textContent = timeStr; - - // Update datum informatie elke minuut - updateDateInfo(); + // Check eerst of debug mode actief is + fetch('/api/debug-time') + .then(response => response.json()) + .then(data => { + if (data.success && data.debug_active) { + // Gebruik debug tijd + document.getElementById("current-time").textContent = data.current_time_display; + console.log(`๐Ÿ”ง Debug tijd actief: ${data.current_time_display} (offset: ${data.offset}s)`); + } else { + // Gebruik normale tijd + const now = new Date(); + const timeStr = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); + document.getElementById("current-time").textContent = timeStr; + } + + // Update datum informatie elke minuut + updateDateInfo(); + }) + .catch(error => { + // Fallback naar normale tijd bij fout + const now = new Date(); + const timeStr = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); + document.getElementById("current-time").textContent = timeStr; + + // Update datum informatie elke minuut + updateDateInfo(); + }); } function updateDateInfo() { @@ -33,28 +54,69 @@ let isNextDayPrayer = false; function startCountdowns(times, names) { prayerTimes = times; prayerNames = names; - const nextPrayer = getNextPrayer(); - currentPrayerIndex = nextPrayer.index; - isNextDayPrayer = nextPrayer.isNextDay; - startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex], isNextDayPrayer); + + getNextPrayer().then(nextPrayer => { + currentPrayerIndex = nextPrayer.index; + isNextDayPrayer = nextPrayer.isNextDay; + startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex], isNextDayPrayer); + }).catch(error => { + console.log('Fout bij bepalen volgende gebed:', error); + // Fallback + currentPrayerIndex = 0; + isNextDayPrayer = false; + startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex], isNextDayPrayer); + }); } function getNextPrayer() { - const now = new Date(); - const currentTime = now.getHours() * 60 + now.getMinutes(); // Huidige tijd in minuten - - // Zoek naar volgende gebed vandaag - for (let i = 0; i < prayerTimes.length; i++) { - const [h, m] = prayerTimes[i].split(":"); - const prayerTimeMinutes = parseInt(h) * 60 + parseInt(m); - - if (prayerTimeMinutes > currentTime) { - return { index: i, isNextDay: false }; - } - } - - // Alle gebeden van vandaag zijn voorbij, volgende is eerste gebed van morgen - return { index: 0, isNextDay: true }; + // Gebruik debug tijd als actief + return fetch('/api/debug-time') + .then(response => response.json()) + .then(data => { + let currentTime; + + if (data.success && data.debug_active) { + // Gebruik debug tijd + const debugTime = data.current_time_display; + const [h, m] = debugTime.split(":"); + currentTime = parseInt(h) * 60 + parseInt(m); + console.log(`๐Ÿ”ง Debug tijd gebruikt voor countdown: ${debugTime}`); + } else { + // Gebruik normale tijd + const now = new Date(); + currentTime = now.getHours() * 60 + now.getMinutes(); + } + + // Zoek naar volgende gebed vandaag + for (let i = 0; i < prayerTimes.length; i++) { + const [h, m] = prayerTimes[i].split(":"); + const prayerTimeMinutes = parseInt(h) * 60 + parseInt(m); + + if (prayerTimeMinutes > currentTime) { + return { index: i, isNextDay: false }; + } + } + + // Alle gebeden van vandaag zijn voorbij, volgende is eerste gebed van morgen + return { index: 0, isNextDay: true }; + }) + .catch(error => { + console.log('Fout bij ophalen debug tijd, gebruik normale tijd:', error); + // Fallback naar normale tijd + const now = new Date(); + const currentTime = now.getHours() * 60 + now.getMinutes(); + + for (let i = 0; i < prayerTimes.length; i++) { + const [h, m] = prayerTimes[i].split(":"); + const prayerTimeMinutes = parseInt(h) * 60 + parseInt(m); + + if (prayerTimeMinutes > currentTime) { + return { index: i, isNextDay: false }; + } + } + + return { index: 0, isNextDay: true }; + }); } function startCountdown(targetTimeStr, prayerName, isNextDay = false) { @@ -74,55 +136,119 @@ function startCountdown(targetTimeStr, prayerName, isNextDay = false) { document.querySelector('.huidig-gebed-bottom .naam').textContent = displayName; function update() { - const now = new Date(); - let diff = Math.floor((target - now) / 1000); - - if (diff <= 0) { - // Speel adhaan af via browser - const audio = document.getElementById('adhanAudio'); - if (audio) audio.play(); - - // Trigger Adzkaar scherm na 3 seconden (geef adhaan tijd om te starten) - setTimeout(() => { - triggerAdzkaarScreen(displayName); - }, 3000); - - // Ga naar volgende gebed - if (isNextDayPrayer) { - // We waren aan het wachten op het eerste gebed van de nieuwe dag - // Nu gaan we naar het tweede gebed van vandaag (nieuwe dag) - currentPrayerIndex = 1; - isNextDayPrayer = false; + // Gebruik debug tijd als actief + fetch('/api/debug-time') + .then(response => response.json()) + .then(data => { + let now; - if (currentPrayerIndex < prayerTimes.length) { - startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex], false); + if (data.success && data.debug_active) { + // Gebruik debug tijd + const debugTime = data.current_time; + const [h, m, s] = debugTime.split(":"); + now = new Date(); + now.setHours(parseInt(h), parseInt(m), parseInt(s), 0); } else { - // Dit zou niet moeten gebeuren, maar veiligheidshalve - currentPrayerIndex = 0; - isNextDayPrayer = true; - startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex], true); - } - } else { - // Normaal doorgang naar volgende gebed - currentPrayerIndex++; - - if (currentPrayerIndex >= prayerTimes.length) { - // Alle gebeden van vandaag zijn klaar, ga naar eerste gebed van morgen - currentPrayerIndex = 0; - isNextDayPrayer = true; + // Gebruik normale tijd + now = new Date(); } - startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex], isNextDayPrayer); - } - return; - } + let diff = Math.floor((target - now) / 1000); - // Toon countdown - const h = String(Math.floor(diff / 3600)).padStart(2, '0'); - const m = String(Math.floor((diff % 3600) / 60)).padStart(2, '0'); - const s = String(diff % 60).padStart(2, '0'); + if (diff <= 0) { + // Speel adhaan af via browser + const audio = document.getElementById('adhanAudio'); + if (audio) audio.play(); + + // Trigger Adzkaar scherm na 3 seconden (geef adhaan tijd om te starten) + setTimeout(() => { + triggerAdzkaarScreen(displayName); + }, 3000); + + // Ga naar volgende gebed + if (isNextDayPrayer) { + // We waren aan het wachten op het eerste gebed van de nieuwe dag + // Nu gaan we naar het tweede gebed van vandaag (nieuwe dag) + currentPrayerIndex = 1; + isNextDayPrayer = false; + + if (currentPrayerIndex < prayerTimes.length) { + startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex], false); + } else { + // Dit zou niet moeten gebeuren, maar veiligheidshalve + currentPrayerIndex = 0; + isNextDayPrayer = true; + startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex], true); + } + } else { + // Normaal doorgang naar volgende gebed + currentPrayerIndex++; + + if (currentPrayerIndex >= prayerTimes.length) { + // Alle gebeden van vandaag zijn klaar, ga naar eerste gebed van morgen + currentPrayerIndex = 0; + isNextDayPrayer = true; + } + + startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex], isNextDayPrayer); + } + return; + } - document.getElementById("countdown").textContent = `${h}:${m}:${s}`; + // Toon countdown + const h = String(Math.floor(diff / 3600)).padStart(2, '0'); + const m = String(Math.floor((diff % 3600) / 60)).padStart(2, '0'); + const s = String(diff % 60).padStart(2, '0'); + + document.getElementById("countdown").textContent = `${h}:${m}:${s}`; + }) + .catch(error => { + // Fallback naar normale tijd + const now = new Date(); + let diff = Math.floor((target - now) / 1000); + + if (diff <= 0) { + // Speel adhaan af via browser + const audio = document.getElementById('adhanAudio'); + if (audio) audio.play(); + + // Trigger Adzkaar scherm na 3 seconden (geef adhaan tijd om te starten) + setTimeout(() => { + triggerAdzkaarScreen(displayName); + }, 3000); + + // Ga naar volgende gebed + if (isNextDayPrayer) { + currentPrayerIndex = 1; + isNextDayPrayer = false; + + if (currentPrayerIndex < prayerTimes.length) { + startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex], false); + } else { + currentPrayerIndex = 0; + isNextDayPrayer = true; + startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex], true); + } + } else { + currentPrayerIndex++; + + if (currentPrayerIndex >= prayerTimes.length) { + currentPrayerIndex = 0; + isNextDayPrayer = true; + } + + startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex], isNextDayPrayer); + } + return; + } + + // Toon countdown + const h = String(Math.floor(diff / 3600)).padStart(2, '0'); + const m = String(Math.floor((diff % 3600) / 60)).padStart(2, '0'); + const s = String(diff % 60).padStart(2, '0'); + + document.getElementById("countdown").textContent = `${h}:${m}:${s}`; + }); } update(); @@ -159,18 +285,13 @@ function triggerAdzkaarScreen(prayerName) { if (data.success) { console.log(`๐Ÿ“ฟ Adzkaar scherm wordt getoond na ${prayerName}`); - // Open Adzkaar scherm in fullscreen - // In kiosk mode proberen we een nieuw venster te openen - const adzkaarWindow = window.open( - data.url, - 'adzkaar', - 'fullscreen=yes,scrollbars=no,resizable=no,toolbar=no,menubar=no,status=no' - ); - - // Als window.open niet werkt (bijv. popup blocker), navigeer naar de pagina - if (!adzkaarWindow) { - console.log('๐Ÿ“ฟ Popup geblokkeerd, navigeren naar Adzkaar pagina...'); - window.location.href = data.url; + // Toon Adzkaar modal in plaats van nieuwe pagina + if (window.showAdzkaarModal) { + // Gebruik de duur uit de API response of standaard 5 minuten + const durationMinutes = data.duration_minutes || 5; + window.showAdzkaarModal(durationMinutes); + } else { + console.log('๐Ÿ“ฟ Adzkaar modal functie niet beschikbaar'); } } else { console.log(`๐Ÿ“ฟ Adzkaar niet getoond: ${data.error}`); diff --git a/adhan-webapp/static/style.css b/adhan-webapp/static/style.css index fa3ce61..44913e3 100644 --- a/adhan-webapp/static/style.css +++ b/adhan-webapp/static/style.css @@ -1400,3 +1400,211 @@ html.dark .hadith-center { max-width: 300px; } } + +/* Adzkaar Modal Styles */ +.adzkaar-modal { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background: rgba(0, 0, 0, 0.95); + z-index: 10000; + display: flex; + justify-content: center; + align-items: center; +} + +.adzkaar-container { + position: relative; + width: 100vw; + height: 100vh; + background: var(--primary-gradient); + color: var(--white); + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 2rem; + box-sizing: border-box; + overflow-y: auto; +} + +.adzkaar-header { + text-align: center; + margin-bottom: 3rem; +} + +.adzkaar-title { + font-family: 'Cairo', sans-serif; + font-size: 3.5rem; + font-weight: 700; + margin-bottom: 1rem; + text-shadow: var(--text-shadow); +} + +.adzkaar-subtitle { + font-family: 'Lato', sans-serif; + font-size: 1.5rem; + opacity: 0.9; + font-weight: 300; +} + +.adzkaar-content { + max-width: 900px; + width: 100%; + text-align: center; +} + +.dhikr-container { + position: relative; + min-height: 400px; + display: flex; + justify-content: center; + align-items: center; +} + +.dhikr-item { + display: none; + background: var(--white-10); + border-radius: 15px; + padding: 2rem; + backdrop-filter: blur(10px); + border: 1px solid var(--white-20); + transition: all 0.3s ease; + max-width: 800px; + width: 100%; + text-align: center; +} + +.dhikr-item.active { + display: block; + background: var(--white-15); + border: 1px solid var(--white-30); + transform: scale(1.02); +} + +.dhikr-arabic { + font-family: 'Cairo', sans-serif; + font-size: 2.2rem; + font-weight: 600; + margin-bottom: 1rem; + direction: rtl; + line-height: 1.6; + color: var(--white); +} + +.dhikr-transliteration { + font-family: 'Lato', sans-serif; + font-size: 1.3rem; + font-style: italic; + margin-bottom: 1rem; + opacity: 0.8; + color: var(--text-muted-dark); +} + +.dhikr-translation { + font-family: 'Lato', sans-serif; + font-size: 1.2rem; + color: var(--text-muted-dark); + line-height: 1.5; +} + +.dhikr-count { + display: inline-block; + background: var(--white-20); + padding: 0.5rem 1rem; + border-radius: 20px; + font-size: 0.9rem; + margin-top: 1rem; + font-weight: 600; +} + +.countdown-timer { + position: fixed; + top: 2rem; + right: 2rem; + background: var(--black-50); + padding: 1rem 1.5rem; + border-radius: 10px; + font-family: 'Cairo', sans-serif; + font-size: 1.2rem; + font-weight: 600; +} + +.close-button { + position: fixed; + top: 2rem; + left: 2rem; + background: var(--white-20); + border: none; + color: var(--white); + padding: 0.8rem; + border-radius: 50%; + cursor: pointer; + font-size: 1.5rem; + transition: background 0.3s ease; +} + +.close-button:hover { + background: var(--white-30); +} + +.dhikr-navigation { + display: flex; + justify-content: center; + align-items: center; + margin-bottom: 2rem; +} + +.nav-btn { + background: var(--white-20); + border: none; + color: var(--white); + font-size: 2rem; + cursor: pointer; + margin: 0 2rem; + padding: 1rem; + border-radius: 50%; + transition: all 0.3s ease; +} + +.nav-btn:hover:not(:disabled) { + background: var(--white-30); + transform: scale(1.1); +} + +.nav-btn:disabled { + opacity: 0.3; + cursor: not-allowed; +} + +.dhikr-counter { + font-size: 1.3rem; + font-weight: 600; + background: var(--black-30); + padding: 0.5rem 1rem; + border-radius: 20px; +} + +@media (max-width: 768px) { + .adzkaar-title { + font-size: 2.5rem; + } + + .dhikr-arabic { + font-size: 1.8rem; + } + + .dhikr-transliteration { + font-size: 1.1rem; + } + + .dhikr-translation { + font-size: 1rem; + } + + .dhikr-item { + padding: 1.5rem; + } +} diff --git a/adhan-webapp/templates/debug.html b/adhan-webapp/templates/debug.html index 356f530..9eae957 100644 --- a/adhan-webapp/templates/debug.html +++ b/adhan-webapp/templates/debug.html @@ -302,17 +302,29 @@ } function updateDebugDisplay() { - const debugTime = getDebugTime(); - const timeStr = debugTime.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); - document.getElementById('currentDebugTime').textContent = timeStr; - - // Update status - const statusElement = document.getElementById('debugStatus'); - statusElement.textContent = isDebugMode ? 'Debug Mode Actief' : 'Normaal'; - statusElement.style.color = isDebugMode ? '#ff6b6b' : '#00ff00'; - - // Check voor gebedstijd - checkPrayerTime(timeStr); + fetch('/api/debug-time') + .then(response => response.json()) + .then(data => { + if (data.success) { + document.getElementById('currentDebugTime').textContent = data.current_time_display; + + // Update status + const statusElement = document.getElementById('debugStatus'); + statusElement.textContent = data.debug_active ? 'Debug Mode Actief' : 'Normaal'; + statusElement.style.color = data.debug_active ? '#ff6b6b' : '#00ff00'; + + // Check voor gebedstijd + checkPrayerTime(data.current_time_display); + } + }) + .catch(error => { + console.log('Fout bij ophalen debug tijd:', error); + // Fallback naar normale tijd + const now = new Date(); + const timeStr = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); + document.getElementById('currentDebugTime').textContent = timeStr; + document.getElementById('debugStatus').textContent = 'Normaal'; + }); } function checkPrayerTime(currentTime) { @@ -384,20 +396,41 @@ const targetTime = new Date(); targetTime.setHours(parseInt(hours), parseInt(minutes), 0, 0); - debugTimeOffset = Math.floor((targetTime - now) / 1000); - isDebugMode = true; + const offsetSeconds = Math.floor((targetTime - now) / 1000); - log(`โฐ Tijd handmatig ingesteld op ${timeInput.value}`); - updateDebugDisplay(); + fetch('/api/debug-time', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ action: 'set_offset', offset: offsetSeconds }) + }) + .then(response => response.json()) + .then(data => { + if (data.success) { + log(`โฐ ${data.message}`); + updateDebugDisplay(); + } else { + log(`โŒ Fout: ${data.error}`); + } + }) + .catch(error => log(`โŒ Netwerk fout: ${error.message}`)); } function adjustTime(seconds) { - debugTimeOffset += seconds; - isDebugMode = true; - - const sign = seconds > 0 ? '+' : ''; - log(`โฐ Tijd aangepast: ${sign}${seconds} seconden`); - updateDebugDisplay(); + fetch('/api/debug-time', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ action: 'adjust', seconds: seconds }) + }) + .then(response => response.json()) + .then(data => { + if (data.success) { + log(`โฐ ${data.message}`); + updateDebugDisplay(); + } else { + log(`โŒ Fout: ${data.error}`); + } + }) + .catch(error => log(`โŒ Netwerk fout: ${error.message}`)); } function setTimeToPrayer(prayerTime, offsetMinutes) { @@ -407,12 +440,24 @@ targetTime.setHours(parseInt(hours), parseInt(minutes), 0, 0); targetTime.setTime(targetTime.getTime() + (offsetMinutes * 60 * 1000)); - debugTimeOffset = Math.floor((targetTime - now) / 1000); - isDebugMode = true; + const offsetSeconds = Math.floor((targetTime - now) / 1000); - const offsetText = offsetMinutes === 0 ? 'exact' : `${offsetMinutes} min ervoor`; - log(`๐Ÿ•Œ Tijd ingesteld op ${prayerTime} (${offsetText})`); - updateDebugDisplay(); + fetch('/api/debug-time', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ action: 'set_offset', offset: offsetSeconds }) + }) + .then(response => response.json()) + .then(data => { + if (data.success) { + const offsetText = offsetMinutes === 0 ? 'exact' : `${offsetMinutes} min ervoor`; + log(`๐Ÿ•Œ Tijd ingesteld op ${prayerTime} (${offsetText})`); + updateDebugDisplay(); + } else { + log(`โŒ Fout: ${data.error}`); + } + }) + .catch(error => log(`โŒ Netwerk fout: ${error.message}`)); } function setTimeToNextPrayer(offsetMinutes) { @@ -433,10 +478,21 @@ } function resetTime() { - debugTimeOffset = 0; - isDebugMode = false; - log(`๐Ÿ”„ Tijd gereset naar echte tijd`); - updateDebugDisplay(); + fetch('/api/debug-time', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ action: 'reset' }) + }) + .then(response => response.json()) + .then(data => { + if (data.success) { + log(`๐Ÿ”„ ${data.message}`); + updateDebugDisplay(); + } else { + log(`โŒ Fout: ${data.error}`); + } + }) + .catch(error => log(`โŒ Netwerk fout: ${error.message}`)); } function checkSonosStatus() { diff --git a/adhan-webapp/templates/index.html b/adhan-webapp/templates/index.html index 2b502f5..ee46084 100644 --- a/adhan-webapp/templates/index.html +++ b/adhan-webapp/templates/index.html @@ -85,6 +85,84 @@ + + + diff --git a/done b/done index ec7c1c1..e7f4cae 100644 --- a/done +++ b/done @@ -62,3 +62,6 @@ Wed May 28 08:02:50 CEST 2025: Countdown gerepareerd - JavaScript aangepast om h Wed May 28 08:35:42 CEST 2025: Hadith auto-update gerepareerd - JavaScript selector aangepast van .hadith-section naar .hadith-center voor nieuwe layout Wed May 28 08:37:45 CEST 2025: Hadith interval instelbaar gemaakt - nieuwe setting hadith_interval_seconds toegevoegd aan settings.json, settings.html en app.py, JavaScript gebruikt nu variabele interval Wed May 28 08:39:34 CEST 2025: Settings pagina georganiseerd in tabbladen - 4 tabs: Audio & Volume, Gebedstijden, Functies, Systeem. Inclusief CSS styling en JavaScript functionaliteit met localStorage voor actieve tab +Wed May 28 13:43:52 CEST 2025: Bevestigd dat Adzkaar scherm wordt geopend in nieuwe pagina bij gebedstijd +Wed May 28 13:46:26 CEST 2025: Adzkaar aangepast van nieuwe pagina naar fullscreen modal in hoofdpagina +Wed May 28 14:02:31 CEST 2025: Debug tijd synchronisatie toegevoegd tussen debug pagina en hoofdpagina