feat(Calendar): update localization and enhance regression checklist
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 47s

- Updated the regression checklist to reflect the completion of Phase 14.
- Incremented versionCode to 4 and versionName to 1.2.0 in build.gradle.kts for the new release.
- Added new localization keys for calendar features in multiple languages, improving user accessibility and clarity.
- Enhanced the generate-mobile-i18n script to support new calendar translations, ensuring comprehensive coverage across locales.
This commit is contained in:
Torsten Schulz (local)
2026-05-15 07:55:32 +02:00
parent bf3e1af084
commit 2f15827658
6 changed files with 830 additions and 9 deletions

View File

@@ -133,6 +133,376 @@ const MOBILE_STRINGS = {
},
};
/** Kalender-Tab (CalendarScreen.kt): eigene Übersetzungen pro Locale, damit nicht nur Deutsch aus dem Basis-Flat greift. */
const MOBILE_CALENDAR_I18N = {
de: {
'mobile.calendarSourceDiary': 'Tagebuch',
'mobile.calendarSourceTrainingTimes': 'Trainingszeiten',
'mobile.calendarSourceCancellations': 'Trainingsausfälle',
'mobile.calendarSourceTournaments': 'Turniere',
'mobile.calendarSourceMatches': 'Punktspiele',
'mobile.calendarSourceOfficial': 'Turnierteilnahmen',
'mobile.calendarSourceHolidays': 'Ferien/Feiertage',
'mobile.calendarLegendTraining': 'Training',
'mobile.calendarLegendTournament': 'Turnier',
'mobile.calendarLegendOfficial': 'Teilnahme',
'mobile.calendarLegendMatch': 'Punktspiel',
'mobile.calendarLegendHoliday': 'Feiertag',
'mobile.calendarLegendSchool': 'Ferien',
'mobile.calendarLegendCancellation': 'Ausfall',
'mobile.calendarTitle': 'Kalender',
'mobile.calendarSubtitle': 'Training, Turniere, Spiele und Feiertage im Monat.',
'mobile.calendarToday': 'Heute',
'mobile.calendarAllSourcesFailed': 'Kalenderdaten konnten nicht geladen werden.',
'mobile.calendarSourceFailed': 'nicht geladen',
'mobile.calendarLegend': 'Anzeige',
'mobile.calendarCancellationTitle': 'Training fällt aus',
'mobile.calendarCancellationHint': 'Blendet regelmäßige Trainingszeiten an den Tagen aus.',
'mobile.calendarCancellationStart': 'Datum (YYYY-MM-DD)',
'mobile.calendarCancellationEnd': 'Bis optional',
'mobile.calendarCancellationReason': 'Grund',
'mobile.calendarCancellationSave': 'Eintragen',
'mobile.calendarCancellationInMonth': 'Ausfälle diesen Monat',
'mobile.calendarGridTitle': 'Monat',
'mobile.calendarAgendaTitle': 'Termine im Monat',
'mobile.calendarAgendaEmpty': 'Keine Termine in diesem Monat.',
},
en: {
'mobile.calendarSourceDiary': 'Diary',
'mobile.calendarSourceTrainingTimes': 'Training times',
'mobile.calendarSourceCancellations': 'Training cancellations',
'mobile.calendarSourceTournaments': 'Tournaments',
'mobile.calendarSourceMatches': 'League matches',
'mobile.calendarSourceOfficial': 'Official participations',
'mobile.calendarSourceHolidays': 'Holidays / school breaks',
'mobile.calendarLegendTraining': 'Training',
'mobile.calendarLegendTournament': 'Tournament',
'mobile.calendarLegendOfficial': 'Participation',
'mobile.calendarLegendMatch': 'League match',
'mobile.calendarLegendHoliday': 'Public holiday',
'mobile.calendarLegendSchool': 'School break',
'mobile.calendarLegendCancellation': 'Cancellation',
'mobile.calendarTitle': 'Calendar',
'mobile.calendarSubtitle': 'Training, tournaments, matches and holidays for the month.',
'mobile.calendarToday': 'Today',
'mobile.calendarAllSourcesFailed': 'Calendar data could not be loaded.',
'mobile.calendarSourceFailed': 'not loaded',
'mobile.calendarLegend': 'Display',
'mobile.calendarCancellationTitle': 'Training cancelled',
'mobile.calendarCancellationHint': 'Hides recurring training times on those days.',
'mobile.calendarCancellationStart': 'Date (YYYY-MM-DD)',
'mobile.calendarCancellationEnd': 'Until (optional)',
'mobile.calendarCancellationReason': 'Reason',
'mobile.calendarCancellationSave': 'Save',
'mobile.calendarCancellationInMonth': 'Cancellations this month',
'mobile.calendarGridTitle': 'Month',
'mobile.calendarAgendaTitle': 'Events this month',
'mobile.calendarAgendaEmpty': 'No events in this month.',
},
es: {
'mobile.calendarSourceDiary': 'Diario',
'mobile.calendarSourceTrainingTimes': 'Horarios de entrenamiento',
'mobile.calendarSourceCancellations': 'Cancelaciones',
'mobile.calendarSourceTournaments': 'Torneos',
'mobile.calendarSourceMatches': 'Partidos de liga',
'mobile.calendarSourceOfficial': 'Participaciones oficiales',
'mobile.calendarSourceHolidays': 'Vacaciones / festivos',
'mobile.calendarLegendTraining': 'Entrenamiento',
'mobile.calendarLegendTournament': 'Torneo',
'mobile.calendarLegendOfficial': 'Participación',
'mobile.calendarLegendMatch': 'Partido de liga',
'mobile.calendarLegendHoliday': 'Festivo',
'mobile.calendarLegendSchool': 'Vacaciones escolares',
'mobile.calendarLegendCancellation': 'Cancelación',
'mobile.calendarTitle': 'Calendario',
'mobile.calendarSubtitle': 'Entrenamientos, torneos, partidos y festivos del mes.',
'mobile.calendarToday': 'Hoy',
'mobile.calendarAllSourcesFailed': 'No se pudieron cargar los datos del calendario.',
'mobile.calendarSourceFailed': 'no cargado',
'mobile.calendarLegend': 'Vista',
'mobile.calendarCancellationTitle': 'Entrenamiento cancelado',
'mobile.calendarCancellationHint': 'Oculta los horarios recurrentes en esos días.',
'mobile.calendarCancellationStart': 'Fecha (AAAA-MM-DD)',
'mobile.calendarCancellationEnd': 'Hasta (opcional)',
'mobile.calendarCancellationReason': 'Motivo',
'mobile.calendarCancellationSave': 'Guardar',
'mobile.calendarCancellationInMonth': 'Cancelaciones este mes',
'mobile.calendarGridTitle': 'Mes',
'mobile.calendarAgendaTitle': 'Citas del mes',
'mobile.calendarAgendaEmpty': 'No hay citas en este mes.',
},
fr: {
'mobile.calendarSourceDiary': 'Journal',
'mobile.calendarSourceTrainingTimes': 'Créneaux dentraînement',
'mobile.calendarSourceCancellations': 'Annulations',
'mobile.calendarSourceTournaments': 'Tournois',
'mobile.calendarSourceMatches': 'Matchs de championnat',
'mobile.calendarSourceOfficial': 'Participations officielles',
'mobile.calendarSourceHolidays': 'Vacances / jours fériés',
'mobile.calendarLegendTraining': 'Entraînement',
'mobile.calendarLegendTournament': 'Tournoi',
'mobile.calendarLegendOfficial': 'Participation',
'mobile.calendarLegendMatch': 'Match',
'mobile.calendarLegendHoliday': 'Jour férié',
'mobile.calendarLegendSchool': 'Vacances scolaires',
'mobile.calendarLegendCancellation': 'Annulation',
'mobile.calendarTitle': 'Calendrier',
'mobile.calendarSubtitle': 'Entraînements, tournois, matchs et vacances du mois.',
'mobile.calendarToday': 'Aujourdhui',
'mobile.calendarAllSourcesFailed': 'Impossible de charger le calendrier.',
'mobile.calendarSourceFailed': 'non chargé',
'mobile.calendarLegend': 'Affichage',
'mobile.calendarCancellationTitle': 'Entraînement annulé',
'mobile.calendarCancellationHint': 'Masque les créneaux récurrents ces jours-là.',
'mobile.calendarCancellationStart': 'Date (AAAA-MM-JJ)',
'mobile.calendarCancellationEnd': 'Jusquau (optionnel)',
'mobile.calendarCancellationReason': 'Motif',
'mobile.calendarCancellationSave': 'Enregistrer',
'mobile.calendarCancellationInMonth': 'Annulations ce mois-ci',
'mobile.calendarGridTitle': 'Mois',
'mobile.calendarAgendaTitle': 'Rendez-vous du mois',
'mobile.calendarAgendaEmpty': 'Aucun rendez-vous ce mois-ci.',
},
it: {
'mobile.calendarSourceDiary': 'Diario',
'mobile.calendarSourceTrainingTimes': 'Orari allenamento',
'mobile.calendarSourceCancellations': 'Cancellazioni',
'mobile.calendarSourceTournaments': 'Tornei',
'mobile.calendarSourceMatches': 'Partite campionato',
'mobile.calendarSourceOfficial': 'Partecipazioni ufficiali',
'mobile.calendarSourceHolidays': 'Vacanze / festività',
'mobile.calendarLegendTraining': 'Allenamento',
'mobile.calendarLegendTournament': 'Torneo',
'mobile.calendarLegendOfficial': 'Partecipazione',
'mobile.calendarLegendMatch': 'Partita',
'mobile.calendarLegendHoliday': 'Festività',
'mobile.calendarLegendSchool': 'Vacanze scolastiche',
'mobile.calendarLegendCancellation': 'Cancellazione',
'mobile.calendarTitle': 'Calendario',
'mobile.calendarSubtitle': 'Allenamenti, tornei, partite e festività del mese.',
'mobile.calendarToday': 'Oggi',
'mobile.calendarAllSourcesFailed': 'Impossibile caricare il calendario.',
'mobile.calendarSourceFailed': 'non caricato',
'mobile.calendarLegend': 'Vista',
'mobile.calendarCancellationTitle': 'Allenamento annullato',
'mobile.calendarCancellationHint': 'Nasconde gli orari ricorrenti in quei giorni.',
'mobile.calendarCancellationStart': 'Data (AAAA-MM-GG)',
'mobile.calendarCancellationEnd': 'Fino al (opzionale)',
'mobile.calendarCancellationReason': 'Motivo',
'mobile.calendarCancellationSave': 'Salva',
'mobile.calendarCancellationInMonth': 'Cancellazioni questo mese',
'mobile.calendarGridTitle': 'Mese',
'mobile.calendarAgendaTitle': 'Appuntamenti del mese',
'mobile.calendarAgendaEmpty': 'Nessun appuntamento in questo mese.',
},
pl: {
'mobile.calendarSourceDiary': 'Dziennik',
'mobile.calendarSourceTrainingTimes': 'Terminy treningów',
'mobile.calendarSourceCancellations': 'Odwołania',
'mobile.calendarSourceTournaments': 'Turnieje',
'mobile.calendarSourceMatches': 'Mecze ligowe',
'mobile.calendarSourceOfficial': 'Oficjalne starty',
'mobile.calendarSourceHolidays': 'Święta / ferie',
'mobile.calendarLegendTraining': 'Trening',
'mobile.calendarLegendTournament': 'Turniej',
'mobile.calendarLegendOfficial': 'Start',
'mobile.calendarLegendMatch': 'Mecz',
'mobile.calendarLegendHoliday': 'Święto',
'mobile.calendarLegendSchool': 'Ferie',
'mobile.calendarLegendCancellation': 'Odwołanie',
'mobile.calendarTitle': 'Kalendarz',
'mobile.calendarSubtitle': 'Treningi, turnieje, mecze i święta w miesiącu.',
'mobile.calendarToday': 'Dziś',
'mobile.calendarAllSourcesFailed': 'Nie udało się wczytać kalendarza.',
'mobile.calendarSourceFailed': 'nie wczytano',
'mobile.calendarLegend': 'Widok',
'mobile.calendarCancellationTitle': 'Trening odwołany',
'mobile.calendarCancellationHint': 'Ukrywa cykliczne terminy treningów w te dni.',
'mobile.calendarCancellationStart': 'Data (RRRR-MM-DD)',
'mobile.calendarCancellationEnd': 'Do (opcjonalnie)',
'mobile.calendarCancellationReason': 'Powód',
'mobile.calendarCancellationSave': 'Zapisz',
'mobile.calendarCancellationInMonth': 'Odwołania w tym miesiącu',
'mobile.calendarGridTitle': 'Miesiąc',
'mobile.calendarAgendaTitle': 'Terminy w miesiącu',
'mobile.calendarAgendaEmpty': 'Brak terminów w tym miesiącu.',
},
ja: {
'mobile.calendarSourceDiary': '日記',
'mobile.calendarSourceTrainingTimes': '練習時間',
'mobile.calendarSourceCancellations': '練習中止',
'mobile.calendarSourceTournaments': '大会',
'mobile.calendarSourceMatches': 'リーグ戦',
'mobile.calendarSourceOfficial': '公式参加',
'mobile.calendarSourceHolidays': '休日・学校休暇',
'mobile.calendarLegendTraining': '練習',
'mobile.calendarLegendTournament': '大会',
'mobile.calendarLegendOfficial': '参加',
'mobile.calendarLegendMatch': 'リーグ戦',
'mobile.calendarLegendHoliday': '祝日',
'mobile.calendarLegendSchool': '学校の休み',
'mobile.calendarLegendCancellation': '中止',
'mobile.calendarTitle': 'カレンダー',
'mobile.calendarSubtitle': '今月の練習・大会・試合・休日。',
'mobile.calendarToday': '今日',
'mobile.calendarAllSourcesFailed': 'カレンダーを読み込めませんでした。',
'mobile.calendarSourceFailed': '未読込',
'mobile.calendarLegend': '表示',
'mobile.calendarCancellationTitle': '練習中止',
'mobile.calendarCancellationHint': 'その日の定例練習時間を非表示にします。',
'mobile.calendarCancellationStart': '日付 (YYYY-MM-DD)',
'mobile.calendarCancellationEnd': '終了日(任意)',
'mobile.calendarCancellationReason': '理由',
'mobile.calendarCancellationSave': '保存',
'mobile.calendarCancellationInMonth': '今月の中止',
'mobile.calendarGridTitle': '月',
'mobile.calendarAgendaTitle': '今月の予定',
'mobile.calendarAgendaEmpty': '今月の予定はありません。',
},
zh: {
'mobile.calendarSourceDiary': '日记',
'mobile.calendarSourceTrainingTimes': '训练时间',
'mobile.calendarSourceCancellations': '训练取消',
'mobile.calendarSourceTournaments': '比赛',
'mobile.calendarSourceMatches': '联赛',
'mobile.calendarSourceOfficial': '官方参赛',
'mobile.calendarSourceHolidays': '假期/节日',
'mobile.calendarLegendTraining': '训练',
'mobile.calendarLegendTournament': '锦标赛',
'mobile.calendarLegendOfficial': '参赛',
'mobile.calendarLegendMatch': '联赛',
'mobile.calendarLegendHoliday': '节日',
'mobile.calendarLegendSchool': '学校假期',
'mobile.calendarLegendCancellation': '取消',
'mobile.calendarTitle': '日历',
'mobile.calendarSubtitle': '本月训练、比赛与假期一览。',
'mobile.calendarToday': '今天',
'mobile.calendarAllSourcesFailed': '无法加载日历数据。',
'mobile.calendarSourceFailed': '未加载',
'mobile.calendarLegend': '显示',
'mobile.calendarCancellationTitle': '训练取消',
'mobile.calendarCancellationHint': '在这些日期隐藏定期训练时间。',
'mobile.calendarCancellationStart': '日期 (YYYY-MM-DD)',
'mobile.calendarCancellationEnd': '结束(可选)',
'mobile.calendarCancellationReason': '原因',
'mobile.calendarCancellationSave': '保存',
'mobile.calendarCancellationInMonth': '本月取消',
'mobile.calendarGridTitle': '月份',
'mobile.calendarAgendaTitle': '本月日程',
'mobile.calendarAgendaEmpty': '本月没有日程。',
},
th: {
'mobile.calendarSourceDiary': 'ไดอารี่',
'mobile.calendarSourceTrainingTimes': 'เวลาฝึก',
'mobile.calendarSourceCancellations': 'ยกเลิกการฝึก',
'mobile.calendarSourceTournaments': 'การแข่งขัน',
'mobile.calendarSourceMatches': 'แมตช์ลีก',
'mobile.calendarSourceOfficial': 'การเข้าร่วมอย่างเป็นทางการ',
'mobile.calendarSourceHolidays': 'วันหยุด/ปิดเทอม',
'mobile.calendarLegendTraining': 'ฝึก',
'mobile.calendarLegendTournament': 'ทัวร์นาเมนต์',
'mobile.calendarLegendOfficial': 'เข้าร่วม',
'mobile.calendarLegendMatch': 'แมตช์',
'mobile.calendarLegendHoliday': 'วันหยุด',
'mobile.calendarLegendSchool': 'ปิดเทอม',
'mobile.calendarLegendCancellation': 'ยกเลิก',
'mobile.calendarTitle': 'ปฏิทิน',
'mobile.calendarSubtitle': 'การฝึก ทัวร์นาเมนต์ แมตช์ และวันหยุดในเดือนนี้',
'mobile.calendarToday': 'วันนี้',
'mobile.calendarAllSourcesFailed': 'โหลดข้อมูลปฏิทินไม่สำเร็จ',
'mobile.calendarSourceFailed': 'ไม่ได้โหลด',
'mobile.calendarLegend': 'แสดง',
'mobile.calendarCancellationTitle': 'ยกเลิกการฝึก',
'mobile.calendarCancellationHint': 'ซ่อนเวลาฝึกประจำในวันเหล่านั้น',
'mobile.calendarCancellationStart': 'วันที่ (YYYY-MM-DD)',
'mobile.calendarCancellationEnd': 'ถึง (ไม่บังคับ)',
'mobile.calendarCancellationReason': 'เหตุผล',
'mobile.calendarCancellationSave': 'บันทึก',
'mobile.calendarCancellationInMonth': 'การยกเลิกในเดือนนี้',
'mobile.calendarGridTitle': 'เดือน',
'mobile.calendarAgendaTitle': 'นัดในเดือนนี้',
'mobile.calendarAgendaEmpty': 'ไม่มีนัดในเดือนนี้',
},
tl: {
'mobile.calendarSourceDiary': 'Diaryo',
'mobile.calendarSourceTrainingTimes': 'Mga oras ng training',
'mobile.calendarSourceCancellations': 'Mga pagkansela',
'mobile.calendarSourceTournaments': 'Mga torneo',
'mobile.calendarSourceMatches': 'Mga laban sa liga',
'mobile.calendarSourceOfficial': 'Opisyal na pakikilahok',
'mobile.calendarSourceHolidays': 'Holiday / bakasyon',
'mobile.calendarLegendTraining': 'Training',
'mobile.calendarLegendTournament': 'Torneo',
'mobile.calendarLegendOfficial': 'Pakikilahok',
'mobile.calendarLegendMatch': 'Laban',
'mobile.calendarLegendHoliday': 'Holiday',
'mobile.calendarLegendSchool': 'Bakasyon sa paaralan',
'mobile.calendarLegendCancellation': 'Kansela',
'mobile.calendarTitle': 'Kalendaryo',
'mobile.calendarSubtitle': 'Training, torneo, liga at holiday sa buwan.',
'mobile.calendarToday': 'Ngayon',
'mobile.calendarAllSourcesFailed': 'Hindi ma-load ang kalendaryo.',
'mobile.calendarSourceFailed': 'hindi na-load',
'mobile.calendarLegend': 'Ipakita',
'mobile.calendarCancellationTitle': 'Kanseladong training',
'mobile.calendarCancellationHint': 'Itinatago ang paulit-ulit na oras ng training sa mga araw na iyon.',
'mobile.calendarCancellationStart': 'Petsa (YYYY-MM-DD)',
'mobile.calendarCancellationEnd': 'Hanggang (opsyonal)',
'mobile.calendarCancellationReason': 'Dahilan',
'mobile.calendarCancellationSave': 'I-save',
'mobile.calendarCancellationInMonth': 'Mga kansela ngayong buwan',
'mobile.calendarGridTitle': 'Buwan',
'mobile.calendarAgendaTitle': 'Mga appointment sa buwan',
'mobile.calendarAgendaEmpty': 'Walang appointment sa buwang ito.',
},
fil: {
'mobile.calendarSourceDiary': 'Tala-arawan',
'mobile.calendarSourceTrainingTimes': 'Mga oras ng pagsasanay',
'mobile.calendarSourceCancellations': 'Mga pagkansela',
'mobile.calendarSourceTournaments': 'Mga torneo',
'mobile.calendarSourceMatches': 'Mga laban sa liga',
'mobile.calendarSourceOfficial': 'Opisyal na pakikilahok',
'mobile.calendarSourceHolidays': 'Holiday / bakasyon',
'mobile.calendarLegendTraining': 'Pagsasanay',
'mobile.calendarLegendTournament': 'Torneo',
'mobile.calendarLegendOfficial': 'Pakikilahok',
'mobile.calendarLegendMatch': 'Laban',
'mobile.calendarLegendHoliday': 'Holiday',
'mobile.calendarLegendSchool': 'Bakasyon sa paaralan',
'mobile.calendarLegendCancellation': 'Kansela',
'mobile.calendarTitle': 'Kalendaryo',
'mobile.calendarSubtitle': 'Pagsasanay, torneo, liga at holiday sa buwan.',
'mobile.calendarToday': 'Ngayon',
'mobile.calendarAllSourcesFailed': 'Hindi ma-load ang kalendaryo.',
'mobile.calendarSourceFailed': 'hindi na-load',
'mobile.calendarLegend': 'Ipakita',
'mobile.calendarCancellationTitle': 'Kinanselang pagsasanay',
'mobile.calendarCancellationHint': 'Itinatago ang paulit-ulit na oras sa mga araw na iyon.',
'mobile.calendarCancellationStart': 'Petsa (YYYY-MM-DD)',
'mobile.calendarCancellationEnd': 'Hanggang (opsyonal)',
'mobile.calendarCancellationReason': 'Dahilan',
'mobile.calendarCancellationSave': 'I-save',
'mobile.calendarCancellationInMonth': 'Mga kansela ngayong buwan',
'mobile.calendarGridTitle': 'Buwan',
'mobile.calendarAgendaTitle': 'Mga appointment sa buwan',
'mobile.calendarAgendaEmpty': 'Walang appointment sa buwang ito.',
},
};
function calendarStringsForLocale(code) {
if (code === 'de' || code === 'de-CH' || code === 'de-extended') return MOBILE_CALENDAR_I18N.de;
if (code.startsWith('en-')) return MOBILE_CALENDAR_I18N.en;
if (code === 'es') return MOBILE_CALENDAR_I18N.es;
if (code === 'fr') return MOBILE_CALENDAR_I18N.fr;
if (code === 'it') return MOBILE_CALENDAR_I18N.it;
if (code === 'pl') return MOBILE_CALENDAR_I18N.pl;
if (code === 'ja') return MOBILE_CALENDAR_I18N.ja;
if (code === 'zh') return MOBILE_CALENDAR_I18N.zh;
if (code === 'th') return MOBILE_CALENDAR_I18N.th;
if (code === 'tl' || code === 'fil') return MOBILE_CALENDAR_I18N[code === 'fil' ? 'fil' : 'tl'];
return MOBILE_CALENDAR_I18N.en;
}
function flatten(obj, prefix = '', out = {}) {
for (const [key, value] of Object.entries(obj || {})) {
const nextKey = prefix ? `${prefix}.${key}` : key;
@@ -192,6 +562,7 @@ function main() {
...baseFlat,
...flatten(localeJson),
...specificMobileStrings,
...calendarStringsForLocale(code),
};
lines.push(` private val ${kotlinIdentifier(code)}: Map<String, String> by lazy { mapOf(`);
for (const [key, value] of Object.entries(flat).sort(([a], [b]) => a.localeCompare(b))) {