commit 178b003ba0e0edabeb73548c4cacd98e9c7715bf
parent 367f9f8f612b67244f83979d1af998a5d1b4cf2c
Author: MTRNord <MTRNord@users.noreply.github.com>
Date: Mon, 28 Jul 2025 10:30:00 +0200
Add translation support
Diffstat:
7 files changed, 119 insertions(+), 38 deletions(-)
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/MainActivity.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/MainActivity.kt
@@ -39,6 +39,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
@@ -116,7 +117,7 @@ class MainActivity : ComponentActivity() {
didSetTab.value = true
}
AppScaffold(
- title = "NordicCalendar",
+ title = stringResource(R.string.app_name),
calendars = calendars,
selectedCalendars = selectedCalendars,
selectedDestination = "calendar",
@@ -126,7 +127,10 @@ class MainActivity : ComponentActivity() {
onCalendarClick = { navController.navigate(Destinations.Calendar.route + "&tab=$selectedTab") },
floatingActionButton = {
FloatingActionButton(onClick = { /* Event hinzufügen (später) */ }) {
- Icon(Icons.Default.Add, contentDescription = "Event hinzufügen")
+ Icon(
+ Icons.Default.Add,
+ contentDescription = stringResource(R.string.event_add)
+ )
}
}
) { innerPadding ->
@@ -153,7 +157,7 @@ class MainActivity : ComponentActivity() {
composable(Destinations.EventDetails.route) { backStackEntry ->
val eventId = backStackEntry.arguments?.getString("eventId")
AppScaffold(
- title = "Event Details",
+ title = stringResource(R.string.event_details_title),
calendars = emptyList(),
selectedCalendars = emptyList(),
selectedDestination = "eventDetails",
@@ -174,7 +178,7 @@ class MainActivity : ComponentActivity() {
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
- Text("Details für Event ID: $eventId")
+ Text(stringResource(R.string.event_details, eventId ?: ""))
Spacer(modifier = Modifier.height(24.dp))
// Weitere Event-Details hier
}
@@ -185,7 +189,7 @@ class MainActivity : ComponentActivity() {
val calendars by calendarViewModel.calendars.collectAsState()
val selectedCalendars by calendarViewModel.selectedCalendars.collectAsState()
AppScaffold(
- title = "Einstellungen",
+ title = stringResource(R.string.settings),
calendars = calendars,
selectedCalendars = selectedCalendars,
selectedDestination = "settings",
@@ -198,7 +202,10 @@ class MainActivity : ComponentActivity() {
modifier = innerPadding
.fillMaxSize()
) {
- Text("Einstellungen", modifier = Modifier.padding(16.dp))
+ Text(
+ stringResource(R.string.settings),
+ modifier = Modifier.padding(16.dp)
+ )
// Weitere Einstellungen hier
}
}
@@ -208,7 +215,7 @@ class MainActivity : ComponentActivity() {
val calendars by calendarViewModel.calendars.collectAsState()
val selectedCalendars by calendarViewModel.selectedCalendars.collectAsState()
AppScaffold(
- title = "Über NordicCalendar",
+ title = stringResource(R.string.about) + " Nordic Calendar",
calendars = calendars,
selectedCalendars = selectedCalendars,
selectedDestination = "about",
@@ -221,7 +228,10 @@ class MainActivity : ComponentActivity() {
modifier = innerPadding
.fillMaxSize()
) {
- Text("Über NordicCalendar", modifier = Modifier.padding(16.dp))
+ Text(
+ stringResource(R.string.about) + " Nordic Calendar",
+ modifier = Modifier.padding(16.dp)
+ )
// Weitere Infos hier
}
}
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/components/AppScaffold.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/components/AppScaffold.kt
@@ -16,13 +16,15 @@ import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
import kotlinx.coroutines.launch
+import space.midnightthoughts.nordiccalendar.R
import space.midnightthoughts.nordiccalendar.util.Calendar
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppScaffold(
- title: String,
+ title: String? = null,
calendars: List<Calendar>,
selectedCalendars: List<Calendar>,
selectedDestination: String,
@@ -62,18 +64,21 @@ fun AppScaffold(
Scaffold(
topBar = {
TopAppBar(
- title = { Text(title) },
+ title = { title ?: Text(stringResource(R.string.app_name)) },
navigationIcon = {
if (onBackClick != null) {
IconButton(onClick = onBackClick) {
Icon(
Icons.AutoMirrored.Filled.ArrowBack,
- contentDescription = "Zurück"
+ contentDescription = stringResource(R.string.back)
)
}
} else {
IconButton(onClick = { scope.launch { drawerState.open() } }) {
- Icon(Icons.Default.Menu, contentDescription = "Menü")
+ Icon(
+ Icons.Default.Menu,
+ contentDescription = stringResource(R.string.menu)
+ )
}
}
}
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/components/SidebarDrawer.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/components/SidebarDrawer.kt
@@ -17,7 +17,9 @@ import androidx.compose.material3.NavigationDrawerItemDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
+import space.midnightthoughts.nordiccalendar.R
import space.midnightthoughts.nordiccalendar.util.Calendar
@Composable
@@ -37,21 +39,21 @@ fun SidebarDrawer(
.padding(top = 32.dp, start = 8.dp, end = 8.dp, bottom = 8.dp)
) {
NavigationDrawerItem(
- label = { Text("Kalender") },
+ label = { Text(stringResource(R.string.calendar)) },
selected = selectedDestination == "calendar",
onClick = onCalendarClick,
modifier = Modifier.fillMaxWidth(),
colors = NavigationDrawerItemDefaults.colors()
)
NavigationDrawerItem(
- label = { Text("Einstellungen") },
+ label = { Text(stringResource(R.string.settings)) },
selected = selectedDestination == "settings",
onClick = onSettingsClick,
modifier = Modifier.fillMaxWidth(),
colors = NavigationDrawerItemDefaults.colors()
)
NavigationDrawerItem(
- label = { Text("Über") },
+ label = { Text(stringResource(R.string.about)) },
selected = selectedDestination == "about",
onClick = onAboutClick,
modifier = Modifier.fillMaxWidth(),
@@ -60,7 +62,10 @@ fun SidebarDrawer(
Spacer(Modifier.height(16.dp))
HorizontalDivider(Modifier, DividerDefaults.Thickness, DividerDefaults.color)
Spacer(Modifier.height(8.dp))
- Text("Kalenderauswahl", style = MaterialTheme.typography.titleMedium)
+ Text(
+ stringResource(R.string.calendar_selection),
+ style = MaterialTheme.typography.titleMedium
+ )
Spacer(Modifier.height(8.dp))
calendars.forEach { calendar ->
Row(verticalAlignment = androidx.compose.ui.Alignment.CenterVertically) {
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/onboarding/Onboarding.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/onboarding/Onboarding.kt
@@ -16,6 +16,7 @@ import androidx.compose.runtime.MutableState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
@@ -23,11 +24,12 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberMultiplePermissionsState
+import space.midnightthoughts.nordiccalendar.R
data class OnBoardModel(
val imageRes: Int? = null,
- val title: String,
- val description: String,
+ val titleRes: Int,
+ val descriptionRes: Int,
val permissionRequest: List<String> = emptyList(),
val showPermissionRequest: Boolean = false
)
@@ -35,14 +37,13 @@ data class OnBoardModel(
val onBoardingData = listOf(
// Explain the purpose of the app
OnBoardModel(
- title = "Welcome to Nordic Calendar",
- description = "A simple open source calendar app for Android that helps you keep track of Nordic holidays and events."
+ titleRes = R.string.onboarding_intro_title,
+ descriptionRes = R.string.onboarding_intro_text
),
// Ask for permissions
OnBoardModel(
- title = "Permissions Required",
- description = "To provide you with the best experience, we need access to your calendar permissions. " +
- "This allows us to add Nordic holidays and events directly to your calendar.",
+ titleRes = R.string.onboarding_permissions_title,
+ descriptionRes = R.string.onboarding_permissions_text,
permissionRequest = listOf(
android.Manifest.permission.READ_CALENDAR,
android.Manifest.permission.WRITE_CALENDAR
@@ -80,7 +81,7 @@ fun OnBoardItem(page: OnBoardModel, hasPermissions: MutableState<Boolean>) {
)
}
Text(
- text = page.title, style = TextStyle(
+ text = stringResource(page.titleRes), style = TextStyle(
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onBackground,
@@ -88,7 +89,7 @@ fun OnBoardItem(page: OnBoardModel, hasPermissions: MutableState<Boolean>) {
)
)
Text(
- text = page.description,
+ text = stringResource(page.descriptionRes),
modifier = Modifier.padding(horizontal = 16.dp, vertical = 10.dp),
style = TextStyle(
fontSize = 14.sp,
@@ -101,7 +102,7 @@ fun OnBoardItem(page: OnBoardModel, hasPermissions: MutableState<Boolean>) {
// Show permission request if needed
if (!permissionsState.allPermissionsGranted && page.showPermissionRequest) {
Text(
- text = "Please grant the required permissions to continue.",
+ text = stringResource(R.string.onboarding_permissions_request),
style = TextStyle(
fontSize = 14.sp,
fontWeight = FontWeight.Normal,
@@ -114,7 +115,7 @@ fun OnBoardItem(page: OnBoardModel, hasPermissions: MutableState<Boolean>) {
permissionsState.launchMultiplePermissionRequest()
}) {
Text(
- text = "Request Permissions",
+ text = stringResource(R.string.onboarding_permissions_button),
style = TextStyle(
fontSize = 14.sp,
fontWeight = FontWeight.Normal,
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/screens/CalendarScreen.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/screens/CalendarScreen.kt
@@ -47,6 +47,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntOffset
@@ -54,6 +55,7 @@ import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
+import space.midnightthoughts.nordiccalendar.R
import space.midnightthoughts.nordiccalendar.util.Event
import space.midnightthoughts.nordiccalendar.viewmodels.CalendarViewModel
import java.text.SimpleDateFormat
@@ -128,7 +130,7 @@ fun CalendarScreen(
)
Spacer(Modifier.height(8.dp))
if (events.isEmpty()) {
- Text("Keine Events gefunden.", modifier = Modifier.padding(16.dp))
+ Text(stringResource(R.string.no_events_found), modifier = Modifier.padding(16.dp))
} else if (selectedTab == 2) {
val hourHeightDp = 64.dp
val timeColumnWidth = 64.dp
@@ -248,7 +250,7 @@ fun CalendarScreen(
verticalAlignment = Alignment.CenterVertically
) {
Text(
- "Jetzt",
+ stringResource(R.string.now),
color = lineColor,
style = MaterialTheme.typography.labelSmall,
modifier = Modifier.padding(start = 16.dp, end = 24.dp)
@@ -285,7 +287,11 @@ fun CalendarScreen(
@Composable
fun CalendarTabBar(selectedTab: Int, onTabSelected: (Int) -> Unit) {
- val tabTitles = listOf("Monat", "Woche", "Tag")
+ val tabTitles = listOf(
+ stringResource(R.string.tab_month),
+ stringResource(R.string.tab_week),
+ stringResource(R.string.tab_day)
+ )
TabRow(selectedTabIndex = selectedTab) {
tabTitles.forEachIndexed { index, title ->
Tab(
@@ -337,9 +343,7 @@ fun DateRangeHeader(
2 -> {
val cal = Calendar.getInstance()
- val today = cal.timeInMillis
val startDay = Calendar.getInstance().apply { timeInMillis = startMillis }
- val endDay = Calendar.getInstance().apply { timeInMillis = endMillis }
cal.get(Calendar.YEAR) == startDay.get(Calendar.YEAR) &&
cal.get(Calendar.DAY_OF_YEAR) == startDay.get(Calendar.DAY_OF_YEAR)
}
@@ -356,7 +360,7 @@ fun DateRangeHeader(
IconButton(onClick = onPrev) {
Icon(
Icons.AutoMirrored.Filled.ArrowBack,
- contentDescription = "Vorheriger Zeitraum"
+ contentDescription = stringResource(R.string.previous_period)
)
}
Row(verticalAlignment = Alignment.CenterVertically) {
@@ -364,14 +368,14 @@ fun DateRangeHeader(
if (!isToday) {
Spacer(Modifier.width(8.dp))
TextButton(onClick = onToday) {
- Text("Heute")
+ Text(stringResource(R.string.today))
}
}
}
IconButton(onClick = onNext) {
Icon(
Icons.AutoMirrored.Filled.ArrowForward,
- contentDescription = "Nächster Zeitraum"
+ contentDescription = stringResource(R.string.next_period)
)
}
}
diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">NordicCalendar</string>
+ <string name="calendar">Calendar</string>
+ <string name="settings">Settings</string>
+ <string name="about">About</string>
+ <string name="calendar_selection">Calendar selection</string>
+ <string name="no_events_found">No events found.</string>
+ <string name="event_add">Add event</string>
+ <string name="event_details">Details for event ID: %1$s</string>
+ <string name="event_details_title">Event Details</string>
+ <string name="today">Today</string>
+ <string name="previous_period">Previous period</string>
+ <string name="next_period">Next period</string>
+ <string name="menu">Menu</string>
+ <string name="back">Back</string>
+ <string name="onboarding_finish">Finish</string>
+ <string name="onboarding_next">Next</string>
+ <string name="onboarding_intro_title">Welcome to NordicCalendar</string>
+ <string name="onboarding_intro_text">Your calendar for the north.</string>
+ <string name="onboarding_permissions_title">Permissions required</string>
+ <string name="onboarding_permissions_text">To use all features, the app needs access to your calendar.</string>
+ <string name="onboarding_permissions_request">Please allow access to the calendar.</string>
+ <string name="onboarding_permissions_button">Request permission</string>
+ <string name="tab_month">Month</string>
+ <string name="tab_week">Week</string>
+ <string name="tab_day">Day</string>
+ <string name="now">Now</string>
+</resources>
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
@@ -1,3 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
<resources>
- <string name="app_name">Nordic Calendar</string>
-</resources>
-\ No newline at end of file
+ <string name="app_name">NordicCalendar</string>
+ <string name="calendar">Kalender</string>
+ <string name="settings">Einstellungen</string>
+ <string name="about">Über</string>
+ <string name="calendar_selection">Kalenderauswahl</string>
+ <string name="no_events_found">Keine Events gefunden.</string>
+ <string name="event_add">Event hinzufügen</string>
+ <string name="event_details">Details für Event ID: %1$s</string>
+ <string name="event_details_title">Event Details</string>
+ <string name="today">Heute</string>
+ <string name="previous_period">Vorheriger Zeitraum</string>
+ <string name="next_period">Nächster Zeitraum</string>
+ <string name="menu">Menü</string>
+ <string name="back">Zurück</string>
+ <string name="onboarding_finish">Fertig</string>
+ <string name="onboarding_next">Weiter</string>
+ <string name="onboarding_intro_title">Willkommen bei NordicCalendar</string>
+ <string name="onboarding_intro_text">Dein Kalender für den Norden.</string>
+ <string name="onboarding_permissions_title">Berechtigungen benötigt</string>
+ <string name="onboarding_permissions_text">Um alle Funktionen zu nutzen, benötigt die App Zugriff auf deinen Kalender.</string>
+ <string name="onboarding_permissions_request">Bitte erlaube den Zugriff auf den Kalender.</string>
+ <string name="onboarding_permissions_button">Berechtigung anfragen</string>
+ <string name="tab_month">Monat</string>
+ <string name="tab_week">Woche</string>
+ <string name="tab_day">Tag</string>
+ <string name="now">Jetzt</string>
+</resources>
+