diff --git a/static/service-worker.js b/static/service-worker.js index f6dc478..2395b1d 100644 --- a/static/service-worker.js +++ b/static/service-worker.js @@ -1,15 +1,25 @@ const CACHE_NAME = 'datumsrechner-cache-v1'; const urlsToCache = [ '/', - '/static/style.css', '/static/favicon.ico', '/static/favicon.png', + '/static/favicon.svg', '/static/logo.svg', + '/static/manifest.json', ]; self.addEventListener('install', event => { event.waitUntil( caches.open(CACHE_NAME) - .then(cache => cache.addAll(urlsToCache)) + .then(cache => { + // Füge nur existierende Dateien zum Cache hinzu + return Promise.allSettled( + urlsToCache.map(url => + cache.add(url).catch(err => { + console.log('Failed to cache:', url, err); + }) + ) + ); + }) ); }); self.addEventListener('fetch', event => { diff --git a/templates/index.html b/templates/index.html index 19c50c8..4b9d74a 100644 --- a/templates/index.html +++ b/templates/index.html @@ -6,7 +6,7 @@ {%- endif -%} {% endmacro %} - + {{ _('Elpatrons Datumsrechner – Open Source Kalender- und Datumsberechnungen') }} @@ -683,7 +683,8 @@ footer br + a { function readAloud(text, button) { // Stoppe vorherige Wiedergabe if (currentSpeech) { - currentSpeech.cancel(); + speechSynthesis.cancel(); + currentSpeech = null; } // Entferne "playing" Klasse von allen Buttons @@ -692,12 +693,92 @@ footer br + a { btn.textContent = '🔊'; }); + // Bestimme die aktuelle Sprache + let currentLang = 'de-DE'; // Standard + + // Methode 1: Prüfe URL-Parameter + const urlParams = new URLSearchParams(window.location.search); + const langParam = urlParams.get('lang'); + + // Methode 2: Prüfe localStorage + const savedLang = localStorage.getItem('preferred_language'); + + // Methode 3: Prüfe das HTML lang-Attribut + const htmlLang = document.documentElement.lang; + + // Debug-Ausgabe + console.log('URL lang param:', langParam); + console.log('Saved lang:', savedLang); + console.log('HTML lang:', htmlLang); + + // Verbesserte Spracherkennung - prüfe alle Quellen + if (langParam === 'en' || savedLang === 'en' || htmlLang === 'en') { + // Prüfe, ob eine britische Stimme verfügbar ist + const voices = speechSynthesis.getVoices(); + const hasBritishVoice = voices.some(voice => voice.lang === 'en-GB'); + const hasAmericanVoice = voices.some(voice => voice.lang === 'en-US'); + + if (hasBritishVoice) { + currentLang = 'en-GB'; + console.log('Setting language to British English:', currentLang); + } else if (hasAmericanVoice) { + currentLang = 'en-US'; + console.log('Setting language to American English:', currentLang); + } else { + // Fallback auf en-US, auch wenn keine Stimme verfügbar ist + currentLang = 'en-US'; + console.log('Setting language to English (no specific voice available):', currentLang); + } + } else { + console.log('Setting language to German:', currentLang); + } + // Erstelle neue Sprachausgabe currentSpeech = new SpeechSynthesisUtterance(text); - currentSpeech.lang = 'de-DE'; + currentSpeech.lang = currentLang; currentSpeech.rate = 0.9; currentSpeech.pitch = 1; + // Versuche eine passende Stimme zu finden + const voices = speechSynthesis.getVoices(); + console.log('Available voices:', voices.map(v => `${v.name} (${v.lang})`)); + + // Suche nach einer Stimme in der gewünschten Sprache + let preferredVoice = voices.find(voice => + voice.lang === currentLang + ); + + // Falls keine exakte Übereinstimmung, suche nach ähnlicher Sprache + if (!preferredVoice) { + preferredVoice = voices.find(voice => + voice.lang.startsWith(currentLang.split('-')[0]) + ); + } + + // Falls immer noch keine Stimme gefunden, suche nach englischen Stimmen für Englisch + if (!preferredVoice && (currentLang === 'en-US' || currentLang === 'en-GB')) { + // Bevorzuge britische Stimmen für en-GB + if (currentLang === 'en-GB') { + preferredVoice = voices.find(voice => + voice.lang === 'en-GB' || voice.name.toLowerCase().includes('british') + ); + } + + // Falls keine britische Stimme, suche nach amerikanischen oder allgemeinen englischen Stimmen + if (!preferredVoice) { + preferredVoice = voices.find(voice => + voice.lang.includes('en') || voice.name.toLowerCase().includes('english') + ); + } + } + + if (preferredVoice) { + currentSpeech.voice = preferredVoice; + console.log('Using voice:', preferredVoice.name, 'for language:', currentLang); + } else { + console.log('No specific voice found for language:', currentLang, '- using default'); + } + // Button-Status aktualisieren button.classList.add('playing'); button.textContent = '⏹️'; @@ -720,6 +801,16 @@ footer br + a { } function readAloudFromElement(button) { + // Prüfe, ob bereits eine Wiedergabe läuft + if (currentSpeech && speechSynthesis.speaking) { + // Stoppe die aktuelle Wiedergabe + speechSynthesis.cancel(); + currentSpeech = null; + button.classList.remove('playing'); + button.textContent = '🔊'; + return; + } + // Finde das Ergebnis-Element (das div mit class="result") const resultElement = button.closest('.result'); if (!resultElement) return; @@ -736,7 +827,7 @@ footer br + a { function stopReading() { if (currentSpeech) { - currentSpeech.cancel(); + speechSynthesis.cancel(); currentSpeech = null; } document.querySelectorAll('.read-aloud-btn').forEach(btn => { @@ -746,6 +837,13 @@ footer br + a { } document.addEventListener('DOMContentLoaded', function() { + // Stelle sicher, dass die Stimmen geladen sind + if (speechSynthesis.onvoiceschanged !== undefined) { + speechSynthesis.onvoiceschanged = function() { + console.log('Voices loaded:', speechSynthesis.getVoices().length); + }; + } + // Prüfe localStorage für gespeicherte Sprachauswahl const savedLanguage = localStorage.getItem('preferred_language'); if (savedLanguage && !window.location.search.includes('lang=')) { @@ -881,7 +979,7 @@ footer br + a { {% if tage is not none %}
- + {% if request.form.get('werktage') %} {{ _('Anzahl der Werktage zwischen') }} {{ format_date(request.form.get('start1', '')) }} {{ _('und') }} {{ format_date(request.form.get('end1', '')) }}:{% if request.form.get('bundesland') %} {{ _('(Feiertage:') }} {{ request.form.get('bundesland') }}){% endif %}: {{ tage }} {% else %} @@ -923,7 +1021,7 @@ footer br + a { {% if wochentag is not none %}
- + {{ _('Wochentag von') }} {{ format_date(request.form.get('datum3', '')) }}: {{ wochentag }}
{% endif %} @@ -949,7 +1047,7 @@ footer br + a { {% if kw_berechnen is not none %}
- + {{ _('Kalenderwoche von') }} {{ format_date(request.form.get('datum6', '')) }}: {{ kw_berechnen }}
{% endif %} @@ -975,7 +1073,7 @@ footer br + a { {% if kw_datum is not none %}
- + {{ _('Start-/Enddatum der KW') }} {{ request.form.get('kw7', '') }} {{ _('im Jahr') }} {{ request.form.get('jahr7', '') }}: {{ kw_datum }}
{% endif %} @@ -1021,7 +1119,7 @@ footer br + a { {% if plusminus_result is not none %}
- + {{ plusminus_result }}
{% endif %}