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.
380 lines
14 KiB
HTML
380 lines
14 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="nl">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Gebedstijden Display</title>
|
|
<link rel="stylesheet" href="/static/style.css">
|
|
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@700&family=Lato:wght@400;700&display=swap" rel="stylesheet">
|
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
|
</head>
|
|
<body>
|
|
<div class="app">
|
|
<!-- Dark/Light toggle -->
|
|
<button id="themeToggle" title="Schakel modus"><span id="themeIcon" class="material-icons">brightness_6</span></button>
|
|
|
|
<div class="left">
|
|
<div class="overlay">
|
|
<div class="tijdstip">
|
|
<div class="tijd-weer-row">
|
|
<div class="tijd-column">
|
|
<div id="current-time">--:--</div>
|
|
</div>
|
|
<div class="weer-column">
|
|
<!-- Weer sectie naast de tijd -->
|
|
<div class="weather-section-left">
|
|
<div class="weather-info">
|
|
<div class="weather-main">
|
|
<span class="weather-temp">{{ weather.temperature }}°C</span>
|
|
<span class="weather-desc">{{ weather.description }}</span>
|
|
</div>
|
|
<div class="weather-details">
|
|
<span class="weather-detail">Voelt als {{ weather.feels_like }}°C</span>
|
|
<span class="weather-detail">Vochtigheid {{ weather.humidity }}%</span>
|
|
<span class="weather-detail">Wind {{ weather.wind_speed }} km/h</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="datum-sectie">
|
|
<div class="gregorian-datum">{{ date_info.gregorian_full }}</div>
|
|
<div class="hijri-datum-arabic">{{ date_info.hijri_arabic }}</div>
|
|
<div class="hijri-datum-dutch">{{ date_info.hijri_dutch }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Huidig gebed sectie onderaan -->
|
|
<div class="huidig-gebed-bottom">
|
|
<div class="naam">{{ next_name }}</div>
|
|
<div id="countdown">--:--:--</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Zijmenu met hadith sectie -->
|
|
<div class="right new-layout">
|
|
<div class="hadith-tijden-row">
|
|
<!-- Hadith sectie met witte achtergrond -->
|
|
<div class="hadith-center">
|
|
<blockquote>
|
|
"{{ hadith.text }}"
|
|
<footer>— {{ hadith.bron }}</footer>
|
|
</blockquote>
|
|
</div>
|
|
|
|
<!-- Compact zijmenu -->
|
|
<div class="vertical-tijden">
|
|
<ul class="tijden-en-icoontjes">
|
|
{% for naam, tijd in gebedstijden.items() %}
|
|
<li class="tijden-rij">
|
|
<span class="naam">{{ naam }}</span>
|
|
<span class="tijd">{{ tijd[:5] }}</span>
|
|
</li>
|
|
{% endfor %}
|
|
<li><a href="/instellingen" title="Instellingen" class="icoon-link"><span class="material-icons">settings</span></a></li>
|
|
<li><a href="#" id="muteBtn" title="Mute" class="icoon-link"><span id="muteIcon" class="material-icons">volume_off</span></a></li>
|
|
{% if settings.debug_mode %}
|
|
<li><a href="/debug" title="Debug Mode" class="icoon-link"><span class="material-icons">bug_report</span></a></li>
|
|
{% endif %}
|
|
<li><a href="/quran" title="Quran Speler" class="icoon-link"><span class="material-icons">menu_book</span></a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<audio id="adhanAudio" src="/static/clips/{{ settings['audio_clip'] }}" preload="auto"></audio>
|
|
|
|
<!-- Adzkaar Modal -->
|
|
<div id="adzkaarModal" class="adzkaar-modal" style="display: none;">
|
|
<div class="adzkaar-container">
|
|
<button class="close-button" onclick="closeAdzkaar()" title="Sluiten">
|
|
<span class="material-icons">close</span>
|
|
</button>
|
|
|
|
<div class="countdown-timer" id="countdownTimer">
|
|
5:00
|
|
</div>
|
|
|
|
<div class="adzkaar-header">
|
|
<h1 class="adzkaar-title">أذكار بعد الصلاة</h1>
|
|
<p class="adzkaar-subtitle">Adzkaar na het Gebed</p>
|
|
</div>
|
|
|
|
<div class="adzkaar-content">
|
|
<div class="dhikr-navigation">
|
|
<button class="nav-btn" id="prevBtn" onclick="previousDhikr()" disabled>
|
|
<span class="material-icons">arrow_back</span>
|
|
</button>
|
|
|
|
<div class="dhikr-counter">
|
|
<span id="currentDhikr">1</span> / <span id="totalDhikr">6</span>
|
|
</div>
|
|
|
|
<button class="nav-btn" id="nextBtn" onclick="nextDhikr()">
|
|
<span class="material-icons">arrow_forward</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="dhikr-container" id="dhikrContainer">
|
|
<div class="dhikr-item active" data-index="0">
|
|
<div class="dhikr-arabic">أَسْتَغْفِرُ اللَّهَ</div>
|
|
<div class="dhikr-transliteration">Astaghfirullah</div>
|
|
<div class="dhikr-translation">Ik vraag Allah om vergeving</div>
|
|
<div class="dhikr-count">3x</div>
|
|
</div>
|
|
|
|
<div class="dhikr-item" data-index="1">
|
|
<div class="dhikr-arabic">اللَّهُمَّ أَنْتَ السَّلاَمُ وَمِنْكَ السَّلاَمُ تَبَارَكْتَ يَا ذَا الْجَلاَلِ وَالإِكْرَامِ</div>
|
|
<div class="dhikr-transliteration">Allahumma anta as-salamu wa minka as-salamu, tabarakta ya dhal-jalali wal-ikram</div>
|
|
<div class="dhikr-translation">O Allah, U bent de Vrede en van U komt de vrede. Gezegend bent U, O Bezitter van Majesteit en Eer</div>
|
|
<div class="dhikr-count">1x</div>
|
|
</div>
|
|
|
|
<div class="dhikr-item" data-index="2">
|
|
<div class="dhikr-arabic">سُبْحَانَ اللَّهِ</div>
|
|
<div class="dhikr-transliteration">Subhan Allah</div>
|
|
<div class="dhikr-translation">Glorie zij Allah</div>
|
|
<div class="dhikr-count">33x</div>
|
|
</div>
|
|
|
|
<div class="dhikr-item" data-index="3">
|
|
<div class="dhikr-arabic">الْحَمْدُ لِلَّهِ</div>
|
|
<div class="dhikr-transliteration">Alhamdulillah</div>
|
|
<div class="dhikr-translation">Alle lof zij Allah</div>
|
|
<div class="dhikr-count">33x</div>
|
|
</div>
|
|
|
|
<div class="dhikr-item" data-index="4">
|
|
<div class="dhikr-arabic">اللَّهُ أَكْبَرُ</div>
|
|
<div class="dhikr-transliteration">Allahu Akbar</div>
|
|
<div class="dhikr-translation">Allah is de Grootste</div>
|
|
<div class="dhikr-count">34x</div>
|
|
</div>
|
|
|
|
<div class="dhikr-item" data-index="5">
|
|
<div class="dhikr-arabic">لاَ إِلَهَ إِلاَّ اللَّهُ وَحْدَهُ لاَ شَرِيكَ لَهُ لَهُ الْمُلْكُ وَلَهُ الْحَمْدُ وَهُوَ عَلَى كُلِّ شَيْءٍ قَدِيرٌ</div>
|
|
<div class="dhikr-transliteration">La ilaha illa Allah wahdahu la sharika lah, lahu al-mulku wa lahu al-hamdu wa huwa 'ala kulli shay'in qadir</div>
|
|
<div class="dhikr-translation">Er is geen god behalve Allah alleen, Hij heeft geen partner. Aan Hem behoort de heerschappij en aan Hem behoort alle lof, en Hij heeft macht over alle dingen</div>
|
|
<div class="dhikr-count">1x</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// Prayer times data from server
|
|
window.prayerTimes = [
|
|
{% for naam, tijd in gebedstijden.items() %}
|
|
"{{ tijd[:5] }}"{% if not loop.last %},{% endif %}
|
|
{% endfor %}
|
|
];
|
|
window.prayerNames = [
|
|
{% for naam, tijd in gebedstijden.items() %}
|
|
"{{ naam }}"{% if not loop.last %},{% endif %}
|
|
{% endfor %}
|
|
];
|
|
const nextPrayerTime = "{{ next_time }}";
|
|
const hadithInterval = {{ settings.hadith_interval_seconds or 30 }} * 1000; // Convert to milliseconds
|
|
</script>
|
|
<script src="/static/countdown.js"></script>
|
|
<script>
|
|
window.onload = function () {
|
|
updateCurrentTime();
|
|
setInterval(updateCurrentTime, 60000);
|
|
setupThemeToggle();
|
|
startCountdowns(window.prayerTimes, window.prayerNames);
|
|
|
|
// Update weerdata elke 10 minuten
|
|
updateWeather();
|
|
setInterval(updateWeather, 600000); // 10 minuten
|
|
|
|
// Update hadith elke X seconden (instelbaar)
|
|
updateHadith();
|
|
setInterval(updateHadith, hadithInterval);
|
|
};
|
|
|
|
// Functie om weerdata bij te werken
|
|
function updateWeather() {
|
|
fetch('/api/weather')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
document.querySelector('.weather-section-left .weather-temp').textContent = data.temperature + '°C';
|
|
document.querySelector('.weather-section-left .weather-desc').textContent = data.description;
|
|
document.querySelector('.weather-section-left .weather-detail:nth-child(1)').textContent = `Voelt als ${data.feels_like}°C`;
|
|
document.querySelector('.weather-section-left .weather-detail:nth-child(2)').textContent = `Vochtigheid ${data.humidity}%`;
|
|
document.querySelector('.weather-section-left .weather-detail:nth-child(3)').textContent = `Wind ${data.wind_speed} km/h`;
|
|
})
|
|
.catch(error => {
|
|
console.log('Fout bij bijwerken weerdata:', error);
|
|
});
|
|
}
|
|
|
|
// Functie om hadith bij te werken
|
|
function updateHadith() {
|
|
fetch('/api/hadith')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
const hadithTextElement = document.querySelector('.hadith-center blockquote');
|
|
|
|
if (hadithTextElement) {
|
|
// Update de tekst en bron
|
|
hadithTextElement.innerHTML = `"${data.text}"<footer>— ${data.bron}</footer>`;
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.log('Fout bij bijwerken hadith:', error);
|
|
});
|
|
}
|
|
|
|
// Theme toggle icon dynamisch aanpassen
|
|
function updateThemeIcon() {
|
|
const html = document.documentElement;
|
|
const icon = document.getElementById('themeIcon');
|
|
if (html.className === 'light') {
|
|
icon.textContent = 'dark_mode';
|
|
} else {
|
|
icon.textContent = 'light_mode';
|
|
}
|
|
}
|
|
updateThemeIcon();
|
|
document.getElementById('themeToggle').addEventListener('click', updateThemeIcon);
|
|
|
|
// Mute functionaliteit
|
|
let muteStatus = false;
|
|
function setMuteIcon() {
|
|
const icon = document.getElementById('muteIcon');
|
|
icon.textContent = muteStatus ? 'volume_off' : 'volume_up';
|
|
}
|
|
function toggleMute(e) {
|
|
e.preventDefault();
|
|
muteStatus = !muteStatus;
|
|
setMuteIcon();
|
|
fetch('/api/mute', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ mute: muteStatus })
|
|
});
|
|
}
|
|
document.getElementById('muteBtn').addEventListener('click', toggleMute);
|
|
setMuteIcon();
|
|
|
|
// Adzkaar Modal Functionaliteit
|
|
let countdownSeconds = 5 * 60; // 5 minuten standaard
|
|
let countdownInterval;
|
|
let currentDhikrIndex = 0;
|
|
const totalDhikrs = 6;
|
|
let autoSwitchInterval;
|
|
|
|
function showAdzkaarModal(durationMinutes = 5) {
|
|
countdownSeconds = durationMinutes * 60;
|
|
currentDhikrIndex = 0;
|
|
|
|
// Toon modal
|
|
document.getElementById('adzkaarModal').style.display = 'flex';
|
|
|
|
// Reset dhikr display
|
|
showDhikr(0);
|
|
|
|
// Start countdown
|
|
countdownInterval = setInterval(updateAdzkaarCountdown, 1000);
|
|
updateAdzkaarCountdown();
|
|
|
|
// Start automatische wissel elke 30 seconden
|
|
autoSwitchInterval = setInterval(autoSwitchDhikr, 30000);
|
|
|
|
// Auto-close na ingestelde tijd
|
|
setTimeout(closeAdzkaar, countdownSeconds * 1000);
|
|
}
|
|
|
|
function updateAdzkaarCountdown() {
|
|
const minutes = Math.floor(countdownSeconds / 60);
|
|
const seconds = countdownSeconds % 60;
|
|
const display = `${minutes}:${seconds.toString().padStart(2, '0')}`;
|
|
document.getElementById('countdownTimer').textContent = display;
|
|
|
|
if (countdownSeconds <= 0) {
|
|
closeAdzkaar();
|
|
return;
|
|
}
|
|
|
|
countdownSeconds--;
|
|
}
|
|
|
|
function closeAdzkaar() {
|
|
clearInterval(countdownInterval);
|
|
clearInterval(autoSwitchInterval);
|
|
document.getElementById('adzkaarModal').style.display = 'none';
|
|
}
|
|
|
|
function showDhikr(index) {
|
|
// Verberg alle dhikr items
|
|
document.querySelectorAll('.dhikr-item').forEach(item => {
|
|
item.classList.remove('active');
|
|
});
|
|
|
|
// Toon de geselecteerde dhikr
|
|
const targetDhikr = document.querySelector(`[data-index="${index}"]`);
|
|
if (targetDhikr) {
|
|
targetDhikr.classList.add('active');
|
|
}
|
|
|
|
// Update counter
|
|
document.getElementById('currentDhikr').textContent = index + 1;
|
|
|
|
// Update navigation buttons
|
|
document.getElementById('prevBtn').disabled = index === 0;
|
|
document.getElementById('nextBtn').disabled = index === totalDhikrs - 1;
|
|
}
|
|
|
|
function nextDhikr() {
|
|
if (currentDhikrIndex < totalDhikrs - 1) {
|
|
currentDhikrIndex++;
|
|
showDhikr(currentDhikrIndex);
|
|
}
|
|
}
|
|
|
|
function previousDhikr() {
|
|
if (currentDhikrIndex > 0) {
|
|
currentDhikrIndex--;
|
|
showDhikr(currentDhikrIndex);
|
|
}
|
|
}
|
|
|
|
function autoSwitchDhikr() {
|
|
if (currentDhikrIndex < totalDhikrs - 1) {
|
|
currentDhikrIndex++;
|
|
showDhikr(currentDhikrIndex);
|
|
} else {
|
|
// Als we bij de laatste dhikr zijn, begin opnieuw
|
|
currentDhikrIndex = 0;
|
|
showDhikr(currentDhikrIndex);
|
|
}
|
|
}
|
|
|
|
// Keyboard navigation voor modal
|
|
document.addEventListener('keydown', function(event) {
|
|
const modal = document.getElementById('adzkaarModal');
|
|
if (modal.style.display === 'flex') {
|
|
if (event.key === 'ArrowRight' || event.key === ' ') {
|
|
event.preventDefault();
|
|
nextDhikr();
|
|
} else if (event.key === 'ArrowLeft') {
|
|
event.preventDefault();
|
|
previousDhikr();
|
|
} else if (event.key === 'Escape') {
|
|
closeAdzkaar();
|
|
}
|
|
}
|
|
});
|
|
|
|
// Maak functies globaal beschikbaar
|
|
window.showAdzkaarModal = showAdzkaarModal;
|
|
window.closeAdzkaar = closeAdzkaar;
|
|
window.nextDhikr = nextDhikr;
|
|
window.previousDhikr = previousDhikr;
|
|
</script>
|
|
</body>
|
|
</html>
|