feat(localization): expand language support and enhance UI for user settings
All checks were successful
Deploy to production / deploy (push) Successful in 3m0s

- Added support for additional UI locales including Cebuano and Spanish, improving accessibility for a broader user base.
- Updated language selection components in the AppHeader and SettingsWidget to reflect new language options, enhancing user experience.
- Enhanced localization of various UI elements across components, ensuring consistent language representation and improved user engagement.
- Implemented logic to synchronize user language preferences with backend settings, providing a seamless experience when changing languages.
This commit is contained in:
Torsten Schulz (local)
2026-04-02 07:54:44 +02:00
parent ac5d436a36
commit 6d9d69dc10
72 changed files with 1792 additions and 343 deletions

View File

@@ -1,6 +1,11 @@
{
"socialnetwork": {
"usersearch": {
"kicker": "Community-Suche",
"intro": "Mit Namen, Alter und Geschlecht gezielt passende Kontakte in der Community finden.",
"ageSeparator": "bis",
"resultsCount": "{count} Treffer",
"openProfile": "Profil öffnen",
"title": "Benutzersuche",
"username": "Benutzername",
"age_from": "Alter von",
@@ -120,7 +125,8 @@
"hideInput": "Neuer Eintrag verbergen",
"imageUpload": "Bild",
"submit": "Eintrag absenden",
"noEntries": "Keine Einträge gefunden"
"noEntries": "Keine Einträge gefunden",
"entryImageAlt": "Bild zum Gästebucheintrag"
},
"interestedInGender": "Interessiert an",
"hasChildren": "Hat Kinder",
@@ -147,6 +153,8 @@
"weight": "Gewicht"
},
"gallery": {
"kicker": "Bilder und Ordner",
"intro": "Eigene Inhalte organisieren, sichtbar machen und in Ordnern strukturieren.",
"title": "Gallerie",
"folders": "Ordner",
"create_folder": "Ordner anlegen",
@@ -189,15 +197,22 @@
},
"show_image_dialog": {
"title": "Bild"
}
},
"imagePreviewAlt": "Bildvorschau",
"imageLoadingAlt": "Bild wird geladen"
},
"guestbook": {
"kicker": "Gästebuch",
"intro": "Nachrichten, Rückmeldungen und kleine Einblicke aus deinem Netzwerk.",
"title": "Gästebuch",
"prevPage": "Zurück",
"nextPage": "Weiter",
"page": "Seite"
},
"diary": {
"kicker": "Persönliche Einträge",
"intro": "Gedanken, Notizen und kurze Updates in einer ruhigen, persönlichen Ansicht.",
"placeholder": "Schreibe deinen Tagebucheintrag...",
"title": "Tagebuch",
"noEntries": "Du hast noch keine Tagebucheinträge gemacht.",
"newEntry": "Neuer Tagebucheintrag",
@@ -213,6 +228,16 @@
"page": "Seite"
},
"forum": {
"kicker": "Community-Forum",
"intro": "Themen, Diskussionen und neue Beiträge an einem strukturierten Ort.",
"createTitle": "Neues Thema verfassen",
"createIntro": "Erst Titel setzen, dann den Beitrag schreiben und anschließend direkt veröffentlichen.",
"cancelCreation": "Abbrechen",
"creationHint": "Titel und Inhalt müssen beide ausgefüllt sein.",
"communityFallback": "Community",
"topicIntro": "Diskussionen, Antworten und neue Beiträge in einer fokussierten Lesefläche.",
"topicCreated": "Thema erfolgreich erstellt.",
"topicCreateError": "Fehler beim Erstellen des Themas",
"title": "Forum",
"showNewTopic": "Neues Thema erstellen",
"hideNewTopic": "Erstellen unterbrechen",
@@ -277,9 +302,32 @@
"videoUploadHint": "Lade hier Videos für deinen freigeschalteten Erotikbereich hoch und pflege Titel sowie Beschreibung direkt beim Upload.",
"videoDescription": "Beschreibung",
"videoFile": "Videodatei",
"videoFormats": "MP4, WEBM, OGG, MOV",
"myVideos": "Meine Videos",
"sharedVideos": "Freigegebene Videos",
"foreignVideosIntro": "Freigegebene Videos aus dem Erwachsenenbereich.",
"foreignVideosOnlyHint": "Du siehst hier nur Videos, die dir für den Erwachsenenbereich freigegeben wurden.",
"sharedVideosIntro": "Sichtbare Videos aus freigegebenen Erwachsenenbereichen.",
"noSharedVideos": "Für dich sind aktuell keine freigegebenen Videos vorhanden.",
"libraryTitle": "Bibliothek",
"libraryIntro": "Eigene Uploads, Freigaben und Meldungen an einem Ort.",
"libraryEmptyHint": "Lege links dein erstes Video an und verwalte es danach hier in der Bibliothek.",
"latestUpload": "Letzter Upload",
"visibleVideos": "Sichtbare Videos",
"moderationCases": "Moderationsfälle",
"notesTitle": "Hinweise",
"friendsVisibilityHint": "Freunde sehen Inhalte nur dann, wenn sie volljährig und für den Erwachsenenbereich freigeschaltet sind.",
"selectedUsersVisibilityHint": "Gezielt freigegebene Personen müssen ebenfalls volljährig und freigeschaltet sein.",
"selectedUsersPlaceholder": "anna, bert, clara",
"imagePreviewAlt": "Bildvorschau",
"imageLoadingAlt": "Bild wird geladen",
"untitled": "Ohne Titel",
"noUploadYet": "Noch kein Upload",
"closeEditing": "Bearbeitung schließen",
"editVisibility": "Freigaben bearbeiten",
"noVideos": "Du hast noch keine Erotikvideos hochgeladen.",
"reportAction": "Melden",
"reportHint": "Nutze {action} direkt am jeweiligen Eintrag, wenn Inhalte geprüft werden sollen.",
"reportNote": "Kurze Notiz für die Moderation",
"submitReport": "Meldung absenden",
"reportSubmitted": "Die Meldung wurde aufgenommen.",
@@ -323,6 +371,36 @@
"vocab": {
"title": "Vokabeltrainer",
"description": "Lege Sprachen an (oder abonniere sie) und teile sie mit Freunden.",
"heroEyebrow": "Sprachenlernen",
"summaryTotalLabel": "Sprachen gesamt",
"summaryTotalIntro": "Alle aktiven Sprachbereiche, in denen du Inhalte nutzt oder verwaltest.",
"summaryOwnedLabel": "Eigene Bereiche",
"summaryOwnedIntro": "Hier legst du Inhalte, Kapitel und Lernmaterial aktiv selbst an.",
"summarySubscribedLabel": "Abonniert",
"summarySubscribedIntro": "Diese Bereiche sind eher für Lernen und Fortschritt statt Verwaltung gedacht.",
"taskCreateEyebrow": "Schnellstart",
"taskCreateTitle": "Neue Sprache anlegen",
"taskCreateIntro": "Der beste Einstieg, wenn du Inhalte selbst strukturieren und pflegen willst.",
"taskContinueEyebrow": "Weiterlernen",
"taskContinueTitle": "Kurse und Kapitel öffnen",
"taskContinueIntro": "Springe direkt in bestehende Lernpfade und arbeite mit vorhandenen Kursen weiter.",
"ownedSectionTitle": "Eigene Sprachen",
"ownedSectionIntro": "Direkter Einstieg in Bearbeitung, Kapitel und Kursverwaltung.",
"ownedHint": "Verwalten und Inhalte pflegen",
"ownedEmpty": "Noch keine eigenen Sprachbereiche vorhanden.",
"subscribedSectionTitle": "Abonnierte Sprachen",
"subscribedSectionIntro": "Gut für schnellen Wiedereinstieg ins Lernen ohne Verwaltungsaufwand.",
"subscribedHint": "Lernen, üben und Fortschritt ansehen",
"subscribedEmpty": "Keine abonnierten Sprachen vorhanden.",
"languageHeroEyebrow": "Sprache",
"languageHeroIntro": "Kapitel, Suchfunktionen und Freigaben für diese Sprache an einem Ort.",
"newLanguageHeroEyebrow": "Vokabeltrainer",
"newLanguageHeroIntro": "Neue Sprache anlegen, Freigabecode erzeugen und direkt in die Bearbeitung wechseln.",
"newLanguageNameHint": "Ein kurzer, klarer Sprachname reicht für den Start.",
"newLanguageNameValidation": "Der Name sollte mindestens 2 Zeichen haben.",
"subscribeHeroEyebrow": "Vokabeltrainer",
"chapterHeroEyebrow": "Vokabeltrainer",
"chapterHeroIntro": "Kapitelinhalt durchsuchen, Vokabeln pflegen und direkt in die Übung wechseln.",
"newLanguage": "Neue Sprache",
"newLanguageTitle": "Neue Sprache anlegen",
"languageName": "Name der Sprache",
@@ -570,7 +648,91 @@
"languageAssistantPatternHint": "Nutze dabei besonders dieses Muster",
"languageAssistantPresetPracticeStart": "Lass uns zur Lektion \"{lesson}\" einen kurzen alltagsnahen Dialog üben. Stelle mir bitte Fragen und warte auf meine Antworten.",
"languageAssistantPresetCorrectStart": "Ich möchte eigene Sätze zur Lektion \"{lesson}\" schreiben. Bitte korrigiere meine Antworten knapp und verständlich.",
"thisLesson": "dieser Lektion"
"thisLesson": "dieser Lektion",
"courseKicker": "Lernkurs",
"courseListKicker": "Kurse",
"courseListIntro": "Öffentliche und eigene Lernkurse filtern, finden und direkt weiterlernen.",
"courseShareCodePlaceholder": "z. B. abc123def456",
"courseFlowEyebrow": "Tagesfluss",
"courseFlowTitle": "Heute sinnvoll weitermachen",
"courseFlowIntro": "Die Reihenfolge folgt dem Konzept: fällige Wiederholung zuerst, dann aktueller Block, danach Intensivphase und freie Vertiefung.",
"courseFlowReviewStat": "Fällige Wiederholung: {count}",
"courseFlowBlockStat": "Aktiver Block: {block}",
"courseFlowReviewTitle": "Fällige Wiederholung",
"courseFlowReviewDescription": "Bereits abgeschlossene Lektionen, die heute wieder drankommen sollten.",
"courseFlowReviewEmpty": "Heute ist keine ältere Lektion als fällige Wiederholung markiert.",
"courseFlowBlockTitle": "Aktueller Block",
"courseFlowBlockDescription": "Hier liegt der nächste reguläre Fortschritt im Kurs.",
"courseFlowBlockEmpty": "Der aktuelle Block ist bereits abgeschlossen oder es gibt gerade keine offene Blocklektion.",
"courseFlowIntensiveTitle": "Fällige Intensivphase",
"courseFlowIntensiveDescription": "Verdichtete Wiederholung, sobald der Block davor weitgehend sitzt.",
"courseFlowIntensiveEmpty": "Aktuell ist keine neue Intensivphase freigeschaltet.",
"courseFlowPracticeTitle": "Freie Vertiefung",
"courseFlowPracticeDescription": "Abgeschlossene Lektionen für lockeres Nachtrainieren außerhalb des Pflichtpfads.",
"courseFlowPracticeEmpty": "Sobald du erste Lektionen abgeschlossen hast, erscheinen sie hier für freies Nachtrainieren.",
"practiceInTrainer": "Im Trainer üben",
"lessonsCount": "{count} Lektionen",
"lessonBlockLabel": "Block {number}",
"lessonIntensiveBadge": "Intensive Wiederholung",
"addLessonValidation": "Bitte Nummer, Titel und Kapitel vollständig angeben.",
"addLessonSuccess": "Lektion erfolgreich angelegt.",
"addLessonError": "Fehler beim Hinzufügen der Lektion.",
"createCourseError": "Fehler beim Erstellen des Kurses.",
"deleteLessonTitle": "Lektion löschen",
"deleteLessonSuccess": "Lektion erfolgreich gelöscht.",
"deleteLessonError": "Fehler beim Löschen der Lektion.",
"enrollCourseError": "Fehler beim Einschreiben.",
"editLessonPending": "Die Bearbeitung einzelner Lektionen folgt noch.",
"timeToday": "heute",
"timeSinceOneDay": "seit 1 Tag",
"timeSinceDays": "seit {count} Tagen",
"reviewDueNow": "jetzt fällig",
"reviewDueTomorrow": "morgen fällig",
"reviewDueInDays": "in {count} Tagen fällig",
"reviewDueToday": "heute fällig",
"reviewDueSinceOneDay": "seit 1 Tag fällig",
"reviewDueSinceDays": "seit {count} Tagen fällig",
"reviewStageDay1": "Tag 1",
"reviewStageDay3": "Tag 3",
"reviewStageDay7": "Tag 7",
"reviewStageCompleted": "Review abgeschlossen",
"phaseQuickstart": "Schnellstart",
"phaseDailyLife": "Alltag",
"phaseStabilization": "Stabilisierung",
"phaseDefault": "Lernphase",
"didacticModeCoreInput": "Neuer Stoff",
"didacticModeGuidedDialogue": "Geführter Dialog",
"didacticModeContrastTraining": "Kontrasttraining",
"didacticModePatternDrill": "Mustertraining",
"didacticModeRealLifeScenario": "Alltagsszenario",
"didacticModeIntensiveReview": "Wiederholungsphase",
"didacticModeCheckpoint": "Checkpoint",
"didacticModeDefault": "Lerneinheit",
"didacticModeFocusDefault": "Lernfokus",
"lessonMetaFocus": "Fokus",
"lessonMetaPhase": "Phase",
"lessonMetaNewUnits": "Neue Einheiten",
"lessonMetaReview": "Wiederholung",
"intensiveReviewTitle": "Intensive Wiederholungsphase",
"intensiveReviewIntro": "Diese Lektion priorisiert Wiederholung und Vertiefung. Neuer Stoff wird bewusst reduziert, damit vorhandene Muster stabil werden.",
"reviewPriorityTitle": "Wiederholung läuft schrittweise mit",
"reviewPriorityIntro": "Zuerst liegt der Fokus auf den neuen Begriffen dieser Lektion. Mit deinem Fortschritt fließen ältere Vokabeln dann zunehmend mit ein.",
"exerciseLockTitle": "Kapitel-Prüfung noch gesperrt",
"trainerStartWithReview": "Starte mit den neuen Vokabeln dieser Lektion. Mit fortschreitendem Üben mischt der Trainer automatisch passende Wiederholungen ein.",
"startLesson": "Lektion starten",
"trainerProgressNewContent": "Neue Inhalte: {current}/{target}",
"trainerProgressReview": "Wiederholung: {count}",
"trainerProgressMixShare": "Mischanteil: {percent}%",
"unknownExerciseTypeNotice": "Dieser Übungstyp wird in der aktuellen Ansicht noch nicht interaktiv dargestellt.",
"unknownExerciseTypeLabel": "Typ: {type}",
"lessonReviewHeadlineDone": "Diese Lektion ist in der freien Vertiefung angekommen.",
"lessonReviewHeadlineDue": "Diese Review-Welle ist jetzt fällig.",
"lessonReviewHeadlineScheduled": "Diese Lektion ist für die nächste Review-Welle vorgemerkt.",
"lessonReviewHintDone": "Die 1/3/7-Tage-Wiederholung ist abgeschlossen. Du kannst die Lektion jetzt flexibel weitertrainieren.",
"lessonReviewHintNextDue": "Nächste Fälligkeit: {due}.",
"reviewTimeNow": "jetzt",
"reviewTimeTomorrow": "morgen",
"reviewTimeInDays": "in {count} Tagen"
}
}
}