feat(countdown): verbeter countdown logica voor gebedstijden

De countdown script is bijgewerkt om de logica voor gebedstijden te verbeteren. De huidige en volgende gebeden worden nu correct geanalyseerd, inclusief ondersteuning voor het identificeren of het volgende gebed op de volgende dag valt. Gebedstitels bevatten nu "morgen" indien nodig. CSS en HTML aanpassingen zorgen voor een verbeterde layout van de instellingenpagina met een drie-kolommen structuur en betere zichtbaarheid in lichte modus. Deze wijzigingen zorgen voor een nauwkeurigere weergave van gebedstijden en een gebruiksvriendelijke interface.
This commit is contained in:
filoor 2025-05-28 03:38:58 +02:00
parent 41504ef7a8
commit a83ca22a79
6 changed files with 99 additions and 51 deletions

View File

@ -3,7 +3,7 @@
"activeCommit": 0, "activeCommit": 0,
"commits": [ "commits": [
{ {
"activePatchIndex": 2, "activePatchIndex": 3,
"patches": [ "patches": [
{ {
"date": 1748182675995, "date": 1748182675995,
@ -16,6 +16,10 @@
{ {
"date": 1748204399019, "date": 1748204399019,
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -1,10 +1,30 @@\n function updateCurrentTime() {\n const now = new Date();\n const timeStr = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n document.getElementById(\"current-time\").textContent = timeStr;\n+ \n+ // Update datum informatie elke minuut\n+ updateDateInfo();\n }\n \n+function updateDateInfo() {\n+ fetch('/api/date-info')\n+ .then(response => response.json())\n+ .then(data => {\n+ const gregorianElement = document.querySelector('.gregorian-datum');\n+ const hijriArabicElement = document.querySelector('.hijri-datum-arabic');\n+ const hijriDutchElement = document.querySelector('.hijri-datum-dutch');\n+ \n+ if (gregorianElement) gregorianElement.textContent = data.gregorian_full;\n+ if (hijriArabicElement) hijriArabicElement.textContent = data.hijri_arabic;\n+ if (hijriDutchElement) hijriDutchElement.textContent = data.hijri_dutch;\n+ })\n+ .catch(error => {\n+ console.log('Fout bij bijwerken datum:', error);\n+ });\n+}\n+\n // Gebedstijden ophalen uit een globale variabele (wordt in de template gezet)\n let prayerTimes = window.prayerTimes || [];\n let prayerNames = window.prayerNames || [];\n let currentPrayerIndex = 0;\n" "content": "Index: \n===================================================================\n--- \n+++ \n@@ -1,10 +1,30 @@\n function updateCurrentTime() {\n const now = new Date();\n const timeStr = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n document.getElementById(\"current-time\").textContent = timeStr;\n+ \n+ // Update datum informatie elke minuut\n+ updateDateInfo();\n }\n \n+function updateDateInfo() {\n+ fetch('/api/date-info')\n+ .then(response => response.json())\n+ .then(data => {\n+ const gregorianElement = document.querySelector('.gregorian-datum');\n+ const hijriArabicElement = document.querySelector('.hijri-datum-arabic');\n+ const hijriDutchElement = document.querySelector('.hijri-datum-dutch');\n+ \n+ if (gregorianElement) gregorianElement.textContent = data.gregorian_full;\n+ if (hijriArabicElement) hijriArabicElement.textContent = data.hijri_arabic;\n+ if (hijriDutchElement) hijriDutchElement.textContent = data.hijri_dutch;\n+ })\n+ .catch(error => {\n+ console.log('Fout bij bijwerken datum:', error);\n+ });\n+}\n+\n // Gebedstijden ophalen uit een globale variabele (wordt in de template gezet)\n let prayerTimes = window.prayerTimes || [];\n let prayerNames = window.prayerNames || [];\n let currentPrayerIndex = 0;\n"
},
{
"date": 1748396047266,
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -27,37 +27,52 @@\n // Gebedstijden ophalen uit een globale variabele (wordt in de template gezet)\n let prayerTimes = window.prayerTimes || [];\n let prayerNames = window.prayerNames || [];\n let currentPrayerIndex = 0;\n+let isNextDayPrayer = false;\n \n function startCountdowns(times, names) {\n prayerTimes = times;\n prayerNames = names;\n- currentPrayerIndex = getNextPrayerIndex();\n- startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex]);\n+ const nextPrayer = getNextPrayer();\n+ currentPrayerIndex = nextPrayer.index;\n+ isNextDayPrayer = nextPrayer.isNextDay;\n+ startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex], isNextDayPrayer);\n }\n \n-function getNextPrayerIndex() {\n+function getNextPrayer() {\n const now = new Date();\n+ const currentTime = now.getHours() * 60 + now.getMinutes(); // Huidige tijd in minuten\n+ \n+ // Zoek naar volgende gebed vandaag\n for (let i = 0; i < prayerTimes.length; i++) {\n const [h, m] = prayerTimes[i].split(\":\");\n- const t = new Date();\n- t.setHours(parseInt(h));\n- t.setMinutes(parseInt(m));\n- t.setSeconds(0);\n- if (t > now) return i;\n+ const prayerTimeMinutes = parseInt(h) * 60 + parseInt(m);\n+ \n+ if (prayerTimeMinutes > currentTime) {\n+ return { index: i, isNextDay: false };\n+ }\n }\n- return 0; // fallback: eerste gebed\n+ \n+ // Alle gebeden van vandaag zijn voorbij, volgende is eerste gebed van morgen\n+ return { index: 0, isNextDay: true };\n }\n \n-function startCountdown(targetTimeStr, prayerName) {\n+function startCountdown(targetTimeStr, prayerName, isNextDay = false) {\n const parts = targetTimeStr.split(\":\");\n let target = new Date();\n target.setHours(parseInt(parts[0]));\n target.setMinutes(parseInt(parts[1]));\n target.setSeconds(0);\n+ \n+ // Als het volgende gebed morgen is, voeg een dag toe\n+ if (isNextDay) {\n+ target.setDate(target.getDate() + 1);\n+ }\n \n- document.querySelector('.huidig-gebed .naam').textContent = prayerName;\n+ // Update de naam met \"morgen\" indicator als nodig\n+ const displayName = isNextDay ? `${prayerName} (morgen)` : prayerName;\n+ document.querySelector('.huidig-gebed .naam').textContent = displayName;\n \n function update() {\n const now = new Date();\n let diff = Math.floor((target - now) / 1000);\n@@ -65,16 +80,40 @@\n if (diff <= 0) {\n // Speel adhaan af via browser\n const audio = document.getElementById('adhanAudio');\n if (audio) audio.play();\n+ \n // Ga naar volgende gebed\n- currentPrayerIndex = (currentPrayerIndex + 1) % prayerTimes.length;\n- const nextTime = prayerTimes[currentPrayerIndex];\n- const nextName = prayerNames[currentPrayerIndex];\n- startCountdown(nextTime, nextName);\n+ if (isNextDayPrayer) {\n+ // We waren aan het wachten op het eerste gebed van de nieuwe dag\n+ // Nu gaan we naar het tweede gebed van vandaag (nieuwe dag)\n+ currentPrayerIndex = 1;\n+ isNextDayPrayer = false;\n+ \n+ if (currentPrayerIndex < prayerTimes.length) {\n+ startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex], false);\n+ } else {\n+ // Dit zou niet moeten gebeuren, maar veiligheidshalve\n+ currentPrayerIndex = 0;\n+ isNextDayPrayer = true;\n+ startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex], true);\n+ }\n+ } else {\n+ // Normaal doorgang naar volgende gebed\n+ currentPrayerIndex++;\n+ \n+ if (currentPrayerIndex >= prayerTimes.length) {\n+ // Alle gebeden van vandaag zijn klaar, ga naar eerste gebed van morgen\n+ currentPrayerIndex = 0;\n+ isNextDayPrayer = true;\n+ }\n+ \n+ startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex], isNextDayPrayer);\n+ }\n return;\n }\n \n+ // Toon countdown\n const h = String(Math.floor(diff / 3600)).padStart(2, '0');\n const m = String(Math.floor((diff % 3600) / 60)).padStart(2, '0');\n const s = String(diff % 60).padStart(2, '0');\n \n"
} }
], ],
"date": 1748182675995, "date": 1748182675995,

View File

@ -5,3 +5,8 @@ Mon May 26 18:17:57 CEST 2025: Tijdzone probleem opgelost - Container gebruikt n
2025-05-27 14:07:15 - Gebedstijd offsets toegevoegd - kan nu minuten toevoegen/afhalen van VUMG tijden 2025-05-27 14:07:15 - Gebedstijd offsets toegevoegd - kan nu minuten toevoegen/afhalen van VUMG tijden
2025-05-27 14:16:04 - Offset bug gerepareerd - seconden weggehaald van VUMG API tijden zodat parsing correct werkt 2025-05-27 14:16:04 - Offset bug gerepareerd - seconden weggehaald van VUMG API tijden zodat parsing correct werkt
2025-05-27 14:24:39 - Quran pagina gerepareerd - gebedstijden variabele toegevoegd aan template 2025-05-27 14:24:39 - Quran pagina gerepareerd - gebedstijden variabele toegevoegd aan template
2025-05-27 23:39:20 - Sonos speakers getest: Kantoor (192.168.0.94) en Slaapkamer (192.168.0.85) reageren correct op UPnP calls
2025-05-27 23:41:37 - Sonos API volledig werkend: 4 zones gevonden (Woonkamer, Slaapkamer, Kantoor, Keuken), alle speakers hebben adhaan tracks geladen
2025-05-28 03:34:23 - Countdown logica gerepareerd: na laatste gebed van de dag toont nu correct 'Fajr (morgen)' met juiste countdown tot volgende dag
2025-05-28 03:36:17 - Settings pagina layout verbeterd: volledige breedte gebruikt, drie-kolommen layout voor gebedstijd aanpassingen
2025-05-28 03:37:57 - Light theme kleuren gerepareerd: teksten nu zichtbaar in light mode, accent kleuren aangepast voor betere contrast

View File

@ -28,35 +28,50 @@ function updateDateInfo() {
let prayerTimes = window.prayerTimes || []; let prayerTimes = window.prayerTimes || [];
let prayerNames = window.prayerNames || []; let prayerNames = window.prayerNames || [];
let currentPrayerIndex = 0; let currentPrayerIndex = 0;
let isNextDayPrayer = false;
function startCountdowns(times, names) { function startCountdowns(times, names) {
prayerTimes = times; prayerTimes = times;
prayerNames = names; prayerNames = names;
currentPrayerIndex = getNextPrayerIndex(); const nextPrayer = getNextPrayer();
startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex]); currentPrayerIndex = nextPrayer.index;
isNextDayPrayer = nextPrayer.isNextDay;
startCountdown(prayerTimes[currentPrayerIndex], prayerNames[currentPrayerIndex], isNextDayPrayer);
} }
function getNextPrayerIndex() { function getNextPrayer() {
const now = new Date(); 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++) { for (let i = 0; i < prayerTimes.length; i++) {
const [h, m] = prayerTimes[i].split(":"); const [h, m] = prayerTimes[i].split(":");
const t = new Date(); const prayerTimeMinutes = parseInt(h) * 60 + parseInt(m);
t.setHours(parseInt(h));
t.setMinutes(parseInt(m)); if (prayerTimeMinutes > currentTime) {
t.setSeconds(0); return { index: i, isNextDay: false };
if (t > now) return i; }
} }
return 0; // fallback: eerste gebed
// Alle gebeden van vandaag zijn voorbij, volgende is eerste gebed van morgen
return { index: 0, isNextDay: true };
} }
function startCountdown(targetTimeStr, prayerName) { function startCountdown(targetTimeStr, prayerName, isNextDay = false) {
const parts = targetTimeStr.split(":"); const parts = targetTimeStr.split(":");
let target = new Date(); let target = new Date();
target.setHours(parseInt(parts[0])); target.setHours(parseInt(parts[0]));
target.setMinutes(parseInt(parts[1])); target.setMinutes(parseInt(parts[1]));
target.setSeconds(0); target.setSeconds(0);
document.querySelector('.huidig-gebed .naam').textContent = prayerName; // Als het volgende gebed morgen is, voeg een dag toe
if (isNextDay) {
target.setDate(target.getDate() + 1);
}
// Update de naam met "morgen" indicator als nodig
const displayName = isNextDay ? `${prayerName} (morgen)` : prayerName;
document.querySelector('.huidig-gebed .naam').textContent = displayName;
function update() { function update() {
const now = new Date(); const now = new Date();
@ -66,14 +81,38 @@ function startCountdown(targetTimeStr, prayerName) {
// Speel adhaan af via browser // Speel adhaan af via browser
const audio = document.getElementById('adhanAudio'); const audio = document.getElementById('adhanAudio');
if (audio) audio.play(); if (audio) audio.play();
// Ga naar volgende gebed // Ga naar volgende gebed
currentPrayerIndex = (currentPrayerIndex + 1) % prayerTimes.length; if (isNextDayPrayer) {
const nextTime = prayerTimes[currentPrayerIndex]; // We waren aan het wachten op het eerste gebed van de nieuwe dag
const nextName = prayerNames[currentPrayerIndex]; // Nu gaan we naar het tweede gebed van vandaag (nieuwe dag)
startCountdown(nextTime, nextName); 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; return;
} }
// Toon countdown
const h = String(Math.floor(diff / 3600)).padStart(2, '0'); const h = String(Math.floor(diff / 3600)).padStart(2, '0');
const m = String(Math.floor((diff % 3600) / 60)).padStart(2, '0'); const m = String(Math.floor((diff % 3600) / 60)).padStart(2, '0');
const s = String(diff % 60).padStart(2, '0'); const s = String(diff % 60).padStart(2, '0');

View File

@ -3,8 +3,9 @@
--bg-dark: #162447; --bg-dark: #162447;
--text-light: #222; --text-light: #222;
--text-dark: #fff; --text-dark: #fff;
--accent: #fff; /* goud */ --accent-light: #2563eb;
--accent-blue: #222; /* zwart voor knoppen */ --accent-dark: #fff;
--accent-blue: #222;
--panel-radius: 0rem; --panel-radius: 0rem;
--panel-shadow: 0 8px 32px 0 rgba(0,0,0,0.25); --panel-shadow: 0 8px 32px 0 rgba(0,0,0,0.25);
--tijdkleur-light: #222; --tijdkleur-light: #222;
@ -15,10 +16,11 @@
html.light { html.light {
--bg: #f7fafc; --bg: #f7fafc;
--text: #222;
--weather-temp: #222; --weather-temp: #222;
--panel-bg: #fff; --panel-bg: #fff;
--panel-text: #222; --panel-text: #222;
--accent: #fff; --accent: #2563eb;
--accent-blue: #f0f0f0; --accent-blue: #f0f0f0;
--panel-border: #e0e6ed; --panel-border: #e0e6ed;
--list-bg: #f7fafc; --list-bg: #f7fafc;
@ -28,7 +30,7 @@ html.light {
--icoon-kleur: var(--icoon-light); --icoon-kleur: var(--icoon-light);
--card-bg: #ffffff; --card-bg: #ffffff;
--border-color: #e0e6ed; --border-color: #e0e6ed;
--primary-color: #fff; --primary-color: #2563eb;
--text-color: #222; --text-color: #222;
--text-secondary: #666; --text-secondary: #666;
} }
@ -88,7 +90,7 @@ body.settings-page {
.overlay { .overlay {
background: rgba(0, 0, 0, 0.3); background: rgba(0, 0, 0, 0.3);
color: var(--text); color: #fff;
height: 100%; height: 100%;
padding: 2rem; padding: 2rem;
display: flex; display: flex;
@ -108,7 +110,7 @@ body.settings-page {
font-weight: bold; font-weight: bold;
letter-spacing: 0.1em; letter-spacing: 0.1em;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
color: var(--accent); color: #fff;
text-shadow: 2px 2px 8px #000; text-shadow: 2px 2px 8px #000;
} }
@ -166,7 +168,8 @@ body.settings-page {
font-size: 4rem; font-size: 4rem;
font-weight: 700; font-weight: 700;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
color: var(--accent); color: #fff;
text-shadow: 2px 2px 8px #000;
} }
#countdown { #countdown {
@ -208,7 +211,7 @@ blockquote {
border: none; border: none;
margin: 2rem 0 0.5rem 0; margin: 2rem 0 0.5rem 0;
padding: 0; padding: 0;
color: var(--text); color: var(--panel-text);
text-align: center; text-align: center;
font-family: 'Cairo', Arial, sans-serif; font-family: 'Cairo', Arial, sans-serif;
line-height: 1.3; line-height: 1.3;
@ -216,7 +219,7 @@ blockquote {
blockquote footer { blockquote footer {
font-size: 1.3rem; font-size: 1.3rem;
color: var(--accent); color: var(--primary-color);
margin-top: 1rem; margin-top: 1rem;
text-align: right; text-align: right;
font-family: 'Lato', Arial, sans-serif; font-family: 'Lato', Arial, sans-serif;
@ -242,9 +245,9 @@ blockquote footer {
.gebedstijden li.active { .gebedstijden li.active {
font-weight: bold; font-weight: bold;
color: var(--accent); color: var(--primary-color);
background: var(--active-bg); background: var(--active-bg);
border-left: 4px solid var(--accent); border-left: 4px solid var(--primary-color);
} }
.icoontjes { .icoontjes {
@ -647,15 +650,15 @@ blockquote footer {
/* Instellingen pagina styling */ /* Instellingen pagina styling */
.settings-container { .settings-container {
max-width: 800px; width: 100%;
margin: 0 auto; margin: 0;
padding: 1.5rem; padding: 2rem;
background: var(--panel-bg); background: var(--panel-bg);
border-radius: var(--panel-radius); border-radius: 0;
border: 1px solid var(--panel-border); border: none;
box-shadow: var(--panel-shadow); box-shadow: none;
min-height: auto; min-height: 100vh;
max-height: 100vh; max-height: none;
overflow-y: auto; overflow-y: auto;
} }
@ -710,11 +713,15 @@ blockquote footer {
.form-row { .form-row {
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem; gap: 2rem;
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
} }
.form-row.three-columns {
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
.form-row .form-group { .form-row .form-group {
margin-bottom: 0; margin-bottom: 0;
} }
@ -905,10 +912,9 @@ blockquote footer {
/* Responsive design voor instellingen */ /* Responsive design voor instellingen */
@media (max-width: 768px) { @media (max-width: 768px) {
.settings-container { .settings-container {
margin: 0.5rem; padding: 1.5rem;
padding: 1rem; min-height: 100vh;
min-height: auto; max-height: none;
max-height: 100vh;
overflow-y: auto; overflow-y: auto;
} }

View File

@ -131,7 +131,7 @@
</p> </p>
</div> </div>
<div class="form-row"> <div class="form-row three-columns">
<div class="form-group"> <div class="form-group">
<label for="fajr_offset"> <label for="fajr_offset">
<span class="material-icons">wb_twilight</span> <span class="material-icons">wb_twilight</span>
@ -147,9 +147,7 @@
</label> </label>
<input type="number" name="zuhr_offset" value="{{ settings.zuhr_offset or 0 }}" min="-120" max="120" step="5" /> <input type="number" name="zuhr_offset" value="{{ settings.zuhr_offset or 0 }}" min="-120" max="120" step="5" />
</div> </div>
</div>
<div class="form-row">
<div class="form-group"> <div class="form-group">
<label for="asr_offset"> <label for="asr_offset">
<span class="material-icons">brightness_low</span> <span class="material-icons">brightness_low</span>
@ -157,7 +155,9 @@
</label> </label>
<input type="number" name="asr_offset" value="{{ settings.asr_offset or 0 }}" min="-120" max="120" step="5" /> <input type="number" name="asr_offset" value="{{ settings.asr_offset or 0 }}" min="-120" max="120" step="5" />
</div> </div>
</div>
<div class="form-row">
<div class="form-group"> <div class="form-group">
<label for="maghrib_offset"> <label for="maghrib_offset">
<span class="material-icons">brightness_3</span> <span class="material-icons">brightness_3</span>
@ -165,9 +165,7 @@
</label> </label>
<input type="number" name="maghrib_offset" value="{{ settings.maghrib_offset or 0 }}" min="-120" max="120" step="5" /> <input type="number" name="maghrib_offset" value="{{ settings.maghrib_offset or 0 }}" min="-120" max="120" step="5" />
</div> </div>
</div>
<div class="form-row">
<div class="form-group"> <div class="form-group">
<label for="isha_offset"> <label for="isha_offset">
<span class="material-icons">brightness_2</span> <span class="material-icons">brightness_2</span>
@ -175,10 +173,6 @@
</label> </label>
<input type="number" name="isha_offset" value="{{ settings.isha_offset or 0 }}" min="-120" max="120" step="5" /> <input type="number" name="isha_offset" value="{{ settings.isha_offset or 0 }}" min="-120" max="120" step="5" />
</div> </div>
<div class="form-group">
<!-- Lege ruimte voor symmetrie -->
</div>
</div> </div>
<div class="button-group"> <div class="button-group">