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 %}