feat(lang): Automatische Spracherkennung implementieren
Implementiert die serverseitige Spracherkennung basierend auf dem Accept-Language-Header des Browsers. Das Backend liefert nun die index.html-Datei dynamisch mit dem korrekten lang-Attribut aus. Das Frontend-JavaScript wurde aktualisiert, um das lang-Attribut des HTML-Dokuments zu berücksichtigen und eine konsistente Sprachbehandlung zu gewährleisten. Zusätzlich behebt dieser Commit einen Fehler, bei dem die Beispiel-Vorschläge nach dem Hinzufügen eines Artikels nicht ausgeblendet wurden. Außerdem wird die Funktionalität des "Hinzufügen"-Buttons und der Enter-Taste wiederhergestellt.
This commit is contained in:
25
main.py
25
main.py
@@ -12,6 +12,7 @@ from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from translations import get_standard_items, get_all_translations
|
||||
from fastapi import FastAPI, HTTPException, Depends, status, WebSocket, WebSocketDisconnect, Request
|
||||
from fastapi.responses import HTMLResponse
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
@@ -639,4 +640,26 @@ async def websocket_endpoint(websocket: WebSocket, token: str):
|
||||
# Create data directory if it doesn't exist
|
||||
os.makedirs(os.path.dirname(DB_FILE), exist_ok=True)
|
||||
init_db()
|
||||
app.mount("/", StaticFiles(directory="static", html=True), name="static")
|
||||
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||
|
||||
|
||||
@app.get("/{full_path:path}", response_class=HTMLResponse)
|
||||
async def catch_all(request: Request, full_path: str):
|
||||
lang = "de" # default
|
||||
accept_language = request.headers.get("accept-language")
|
||||
if accept_language:
|
||||
langs = accept_language.split(",")[0]
|
||||
if "de" in langs:
|
||||
lang = "de"
|
||||
elif "en" in langs:
|
||||
lang = "en"
|
||||
|
||||
with open("static/index.html") as f:
|
||||
html_content = f.read()
|
||||
|
||||
# Replace lang and favicon path
|
||||
html_content = html_content.replace('lang="de"', f'lang="{lang}"')
|
||||
html_content = html_content.replace(
|
||||
'href="/favicon.png"', 'href="/static/favicon.png"')
|
||||
|
||||
return HTMLResponse(content=html_content)
|
||||
|
||||
@@ -467,7 +467,7 @@
|
||||
}
|
||||
|
||||
async function fetchTranslations() {
|
||||
const lang = navigator.language.startsWith('de') ? 'de' : 'en';
|
||||
const lang = document.documentElement.lang;
|
||||
const response = await fetch(`/api/translations/${lang}?_=${new Date().getTime()}`);
|
||||
translations = await response.json();
|
||||
updateUIWithTranslations();
|
||||
@@ -531,7 +531,7 @@
|
||||
}
|
||||
|
||||
async function fetchStandardItems() {
|
||||
const lang = navigator.language.startsWith('de') ? 'de' : 'en';
|
||||
const lang = document.documentElement.lang;
|
||||
const response = await fetch(`/api/standard-items/${lang}`);
|
||||
standardItems = await response.json();
|
||||
}
|
||||
@@ -707,11 +707,12 @@
|
||||
}
|
||||
itemNameInput.value = newValue;
|
||||
suggestionBox.innerHTML = '';
|
||||
suggestionInfo.style.display = 'none';
|
||||
itemNameInput.focus();
|
||||
}
|
||||
|
||||
async function sendNotification() {
|
||||
const lang = navigator.language.startsWith('de') ? 'de' : 'en';
|
||||
const lang = document.documentElement.lang;
|
||||
notifyBtn.disabled = true;
|
||||
notifyBtn.textContent = translations.sending_notification || 'Sending...';
|
||||
|
||||
@@ -828,12 +829,14 @@
|
||||
await addItemsFromInput(itemNameInput.value, true);
|
||||
itemNameInput.value = '';
|
||||
suggestionBox.innerHTML = '';
|
||||
suggestionInfo.style.display = 'none';
|
||||
});
|
||||
|
||||
addOneButton.addEventListener('click', async () => {
|
||||
await addItemsFromInput(itemNameInput.value, false);
|
||||
itemNameInput.value = '';
|
||||
suggestionBox.innerHTML = '';
|
||||
suggestionInfo.style.display = 'none';
|
||||
});
|
||||
|
||||
itemNameInput.addEventListener('input', handleInputChange);
|
||||
|
||||
Reference in New Issue
Block a user