chore: Extract strings into resources for upcoming ability to localise through Weblate

This commit is contained in:
Nishant Mishra
2025-09-28 10:22:46 +05:30
parent 039a540ad9
commit ef502892cc
17 changed files with 197 additions and 101 deletions

View File

@@ -74,19 +74,19 @@ class MainActivity : ComponentActivity() {
Screen.Timer,
R.drawable.timer_outlined,
R.drawable.timer_filled,
"Timer"
R.string.timer
),
NavItem(
Screen.Stats,
R.drawable.monitoring,
R.drawable.monitoring_filled,
"Stats"
R.string.stats
),
NavItem(
Screen.Settings,
R.drawable.settings,
R.drawable.settings_filled,
"Settings"
R.string.settings
)
)
}

View File

@@ -14,7 +14,7 @@ class TomatoApplication : Application() {
val notificationChannel = NotificationChannel(
"timer",
"Timer progress",
getString(R.string.timer_progress),
NotificationManager.IMPORTANCE_HIGH
)

View File

@@ -57,7 +57,7 @@ class DefaultAppContainer(context: Context) : AppContainer {
PendingIntent.FLAG_IMMUTABLE
)
)
.addTimerActions(context, R.drawable.play, "Start")
.addTimerActions(context, R.drawable.play, context.getString(R.string.start))
.setShowWhen(true)
.setSilent(true)
.setOngoing(true)

View File

@@ -34,7 +34,7 @@ fun NotificationCompat.Builder.addTimerActions(
)
.addAction(
R.drawable.restart,
"Exit",
context.getString(R.string.exit),
PendingIntent.getService(
context,
0,
@@ -46,7 +46,7 @@ fun NotificationCompat.Builder.addTimerActions(
)
.addAction(
R.drawable.skip_next,
"Skip",
context.getString(R.string.skip),
PendingIntent.getService(
context,
0,
@@ -62,7 +62,7 @@ fun NotificationCompat.Builder.addStopAlarmAction(
): NotificationCompat.Builder = this
.addAction(
R.drawable.alarm,
"Stop alarm",
context.getString(R.string.stop_alarm),
PendingIntent.getService(
context,
0,

View File

@@ -119,7 +119,7 @@ class TimerService : Service() {
if (timerState.value.timerRunning) {
notificationBuilder.clearActions().addTimerActions(
this, R.drawable.play, "Start"
this, R.drawable.play, getString(R.string.start)
)
showTimerNotification(time.toInt(), paused = true)
_timerState.update { currentState ->
@@ -128,7 +128,7 @@ class TimerService : Service() {
pauseTime = SystemClock.elapsedRealtime()
} else {
notificationBuilder.clearActions().addTimerActions(
this, R.drawable.pause, "Stop"
this, R.drawable.pause, getString(R.string.stop)
)
_timerState.update { it.copy(timerRunning = true) }
if (pauseTime != 0L) pauseDuration += SystemClock.elapsedRealtime() - pauseTime
@@ -186,15 +186,15 @@ class TimerService : Service() {
}
val currentTimer = when (timerState.value.timerMode) {
TimerMode.FOCUS -> "Focus"
TimerMode.SHORT_BREAK -> "Short break"
else -> "Long break"
TimerMode.FOCUS -> getString(R.string.focus)
TimerMode.SHORT_BREAK -> getString(R.string.short_break)
else -> getString(R.string.long_break)
}
val nextTimer = when (timerState.value.nextTimerMode) {
TimerMode.FOCUS -> "Focus"
TimerMode.SHORT_BREAK -> "Short break"
else -> "Long break"
TimerMode.FOCUS -> getString(R.string.focus)
TimerMode.SHORT_BREAK -> getString(R.string.short_break)
else -> getString(R.string.long_break)
}
val remainingTimeString = if ((remainingTime.toFloat() / 60000f) < 1.0f) "< 1"
@@ -205,10 +205,18 @@ class TimerService : Service() {
notificationBuilder
.setContentTitle(
if (!complete) {
"$currentTimer $middleDot $remainingTimeString min remaining" + if (paused) " $middleDot Paused" else ""
} else "$currentTimer $middleDot Completed"
"$currentTimer $middleDot ${
getString(R.string.min_remaining_notification, remainingTimeString)
}" + if (paused) " $middleDot ${getString(R.string.paused)}" else ""
} else "$currentTimer $middleDot ${getString(R.string.completed)}"
)
.setContentText(
getString(
R.string.up_next_notification,
nextTimer,
timerState.value.nextTimeStr
)
)
.setContentText("Up next: $nextTimer (${timerState.value.nextTimeStr})")
.setStyle(
notificationStyle
.setProgress( // Set the current progress by filling the previous intervals and part of the current interval
@@ -364,7 +372,10 @@ class TimerService : Service() {
_timerState.update { currentState ->
currentState.copy(alarmRinging = false)
}
notificationBuilder.clearActions().addTimerActions(this, R.drawable.play, "Start next")
notificationBuilder.clearActions().addTimerActions(
this, R.drawable.play,
getString(R.string.start_next)
)
showTimerNotification(
when (timerState.value.timerMode) {
TimerMode.FOCUS -> timerRepository.focusTime.toInt()

View File

@@ -35,6 +35,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation3.runtime.entryProvider
@@ -110,7 +111,7 @@ fun AppScreen(
iconPosition =
if (wide) NavigationItemIconPosition.Start
else NavigationItemIconPosition.Top,
label = { Text(it.label) }
label = { Text(stringResource(it.label)) }
)
}
}

View File

@@ -1,23 +1,24 @@
package org.nsh07.pomodoro.ui
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.navigation3.runtime.NavKey
import kotlinx.serialization.Serializable
sealed class Screen: NavKey {
sealed class Screen : NavKey {
@Serializable
object Timer : Screen()
@Serializable
object Settings : Screen()
@Serializable
object Stats : Screen()
}
data class NavItem(
val route: Screen,
@param:DrawableRes
val unselectedIcon: Int,
@param:DrawableRes
val selectedIcon: Int,
val label: String
@param:DrawableRes val unselectedIcon: Int,
@param:DrawableRes val selectedIcon: Int,
@param:StringRes val label: Int
)

View File

@@ -32,6 +32,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEach
@@ -100,7 +101,7 @@ fun ColorSchemePickerDialog(
) {
Column(modifier = Modifier.padding(24.dp)) {
Text(
text = "Choose color scheme",
text = stringResource(R.string.choose_color_scheme),
style = MaterialTheme.typography.headlineSmall
)
@@ -136,7 +137,7 @@ fun ColorSchemePickerDialog(
onClick = { setShowDialog(false) },
modifier = Modifier.align(Alignment.End)
) {
Text("Ok")
Text(stringResource(R.string.ok))
}
}
}

View File

@@ -19,6 +19,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import org.nsh07.pomodoro.R
import org.nsh07.pomodoro.ui.ClickableListItem
import org.nsh07.pomodoro.ui.theme.CustomColors.listItemColors
@@ -49,11 +50,11 @@ fun ColorSchemePickerListItem(
tint = colorScheme.primary
)
},
headlineContent = { Text("Color scheme") },
headlineContent = { Text(stringResource(R.string.color_scheme)) },
supportingContent = {
Text(
if (color == Color.White) "Dynamic"
else "Color"
if (color == Color.White) stringResource(R.string.dynamic)
else stringResource(R.string.color)
)
},
colors = listItemColors,

View File

@@ -68,6 +68,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
@@ -174,6 +175,7 @@ private fun SettingsScreen(
onColorSchemeChange: (Color) -> Unit,
modifier: Modifier = Modifier
) {
val context = LocalContext.current
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
val switchColors = SwitchDefaults.colors(
checkedIconColor = colorScheme.primary,
@@ -183,21 +185,20 @@ private fun SettingsScreen(
mapOf(
"auto" to Pair(
R.drawable.brightness_auto,
"System default"
context.getString(R.string.system_default)
),
"light" to Pair(R.drawable.light_mode, "Light"),
"dark" to Pair(R.drawable.dark_mode, "Dark")
"light" to Pair(R.drawable.light_mode, context.getString(R.string.light)),
"dark" to Pair(R.drawable.dark_mode, context.getString(R.string.dark))
)
}
val reverseThemeMap: Map<String, String> = remember {
mapOf(
"System default" to "auto",
"Light" to "light",
"Dark" to "dark"
context.getString(R.string.system_default) to "auto",
context.getString(R.string.light) to "light",
context.getString(R.string.dark) to "dark"
)
}
val context = LocalContext.current
var alarmName by remember { mutableStateOf("") }
LaunchedEffect(alarmSound) {
@@ -233,7 +234,7 @@ private fun SettingsScreen(
val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER).apply {
putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_ALARM)
putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "Alarm sound")
putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, stringResource(R.string.alarm_sound))
putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, alarmSound.toUri())
}
@@ -242,22 +243,22 @@ private fun SettingsScreen(
SettingsSwitchItem(
checked = preferencesState.blackTheme,
icon = R.drawable.contrast,
label = "Black theme",
description = "Use a pure black dark theme",
label = context.getString(R.string.black_theme),
description = context.getString(R.string.black_theme_desc),
onClick = onBlackThemeChange
),
SettingsSwitchItem(
checked = alarmEnabled,
icon = R.drawable.alarm_on,
label = "Alarm",
description = "Ring alarm when a timer completes",
label = context.getString(R.string.alarm),
description = context.getString(R.string.alarm_desc),
onClick = onAlarmEnabledChange
),
SettingsSwitchItem(
checked = vibrateEnabled,
icon = R.drawable.mobile_vibrate,
label = "Vibrate",
description = "Vibrate when a timer completes",
label = context.getString(R.string.vibrate),
description = context.getString(R.string.vibrate_desc),
onClick = onVibrateEnabledChange
)
)
@@ -267,7 +268,7 @@ private fun SettingsScreen(
TopAppBar(
title = {
Text(
"Settings",
stringResource(R.string.settings),
style = LocalTextStyle.current.copy(
fontFamily = robotoFlexTopBar,
fontSize = 32.sp,
@@ -303,7 +304,7 @@ private fun SettingsScreen(
verticalArrangement = Arrangement.spacedBy(2.dp)
) {
Text(
"Focus",
stringResource(R.string.focus),
style = typography.titleSmallEmphasized
)
MinuteInputField(
@@ -323,7 +324,7 @@ private fun SettingsScreen(
verticalArrangement = Arrangement.spacedBy(2.dp)
) {
Text(
"Short break",
stringResource(R.string.short_break),
style = typography.titleSmallEmphasized
)
MinuteInputField(
@@ -338,7 +339,7 @@ private fun SettingsScreen(
verticalArrangement = Arrangement.spacedBy(2.dp)
) {
Text(
"Long break",
stringResource(R.string.long_break),
style = typography.titleSmallEmphasized
)
MinuteInputField(
@@ -366,11 +367,16 @@ private fun SettingsScreen(
)
},
headlineContent = {
Text("Session length")
Text(stringResource(R.string.session_length))
},
supportingContent = {
Column {
Text("Focus intervals in one session: ${sessionsSliderState.value.toInt()}")
Text(
stringResource(
R.string.session_length_desc,
sessionsSliderState.value.toInt()
)
)
Slider(
state = sessionsSliderState,
modifier = Modifier.padding(vertical = 4.dp)
@@ -446,7 +452,7 @@ private fun SettingsScreen(
leadingContent = {
Icon(painterResource(R.drawable.alarm), null)
},
headlineContent = { Text("Alarm sound") },
headlineContent = { Text(stringResource(R.string.alarm_sound)) },
supportingContent = { Text(alarmName) },
colors = listItemColors,
modifier = Modifier
@@ -514,9 +520,7 @@ private fun SettingsScreen(
}
AnimatedVisibility(expanded) {
Text(
"A \"session\" is a sequence of pomodoro intervals that contain focus" +
" intervals, short break intervals, and a long break interval. The " +
"last break of a session is always a long break.",
stringResource(R.string.pomodoro_info),
style = typography.bodyMedium,
color = colorScheme.onSurfaceVariant,
modifier = Modifier.padding(8.dp)
@@ -558,7 +562,7 @@ fun SettingsScreenPreview() {
data class SettingsSwitchItem(
val checked: Boolean,
@DrawableRes val icon: Int,
@param:DrawableRes val icon: Int,
val label: String,
val description: String,
val onClick: (Boolean) -> Unit

View File

@@ -37,6 +37,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import org.nsh07.pomodoro.R
@@ -71,7 +72,7 @@ fun ThemeDialog(
) {
Column(modifier = Modifier.padding(24.dp)) {
Text(
text = "Choose theme",
text = stringResource(R.string.choose_theme),
style = MaterialTheme.typography.headlineSmall
)
Spacer(modifier = Modifier.height(16.dp))
@@ -122,7 +123,7 @@ fun ThemeDialog(
onClick = { setShowThemeDialog(false) },
modifier = Modifier.align(Alignment.End)
) {
Text("Ok")
Text(stringResource(R.string.ok))
}
}
}

View File

@@ -17,6 +17,8 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import org.nsh07.pomodoro.R
import org.nsh07.pomodoro.ui.ClickableListItem
import org.nsh07.pomodoro.ui.theme.CustomColors.listItemColors
@@ -49,7 +51,7 @@ fun ThemePickerListItem(
contentDescription = null
)
},
headlineContent = { Text("Theme") },
headlineContent = { Text(stringResource(R.string.theme)) },
supportingContent = {
Text(themeMap[theme]!!.second)
},

View File

@@ -16,9 +16,11 @@ import androidx.compose.material3.MaterialTheme.typography
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 com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer
import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter
import org.nsh07.pomodoro.R
import org.nsh07.pomodoro.utils.millisecondsToHoursMinutes
@Composable
@@ -26,12 +28,15 @@ fun ColumnScope.ProductivityGraph(
expanded: Boolean,
modelProducer: CartesianChartModelProducer,
modifier: Modifier = Modifier,
label: String = "Productivity analysis"
label: String = stringResource(R.string.productivity_analysis)
) {
AnimatedVisibility(expanded) {
Column(modifier = modifier) {
Text(label, style = typography.titleMedium)
Text("Focus durations at different times of the day", style = typography.bodySmall)
Text(
stringResource(R.string.productivity_analysis_desc),
style = typography.bodySmall
)
Spacer(Modifier.height(8.dp))
TimeColumnChart(
modelProducer,

View File

@@ -45,6 +45,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -114,7 +115,7 @@ fun StatsScreen(
TopAppBar(
title = {
Text(
"Stats",
stringResource(R.string.stats),
style = LocalTextStyle.current.copy(
fontFamily = robotoFlexTopBar,
fontSize = 32.sp,
@@ -138,7 +139,7 @@ fun StatsScreen(
item { Spacer(Modifier) }
item {
Text(
"Today",
stringResource(R.string.today),
style = typography.headlineSmall,
modifier = Modifier
.fillMaxWidth()
@@ -157,7 +158,7 @@ fun StatsScreen(
) {
Column(Modifier.padding(16.dp)) {
Text(
"Focus",
stringResource(R.string.focus),
style = typography.titleMedium,
color = colorScheme.onPrimaryContainer
)
@@ -182,7 +183,7 @@ fun StatsScreen(
) {
Column(Modifier.padding(16.dp)) {
Text(
"Break",
stringResource(R.string.break_),
style = typography.titleMedium,
color = colorScheme.onTertiaryContainer
)
@@ -201,7 +202,7 @@ fun StatsScreen(
item { Spacer(Modifier) }
item {
Text(
"Last week",
stringResource(R.string.last_week),
style = typography.headlineSmall,
modifier = Modifier
.fillMaxWidth()
@@ -222,7 +223,7 @@ fun StatsScreen(
fontFamily = openRundeClock
)
Text(
"focus per day (avg)",
stringResource(R.string.focus_per_day_avg),
style = typography.titleSmall,
modifier = Modifier.padding(bottom = 6.3.dp)
)
@@ -258,14 +259,14 @@ fun StatsScreen(
) {
Icon(
painterResource(R.drawable.arrow_down),
"More info",
stringResource(R.string.more_info),
modifier = Modifier.rotate(iconRotation)
)
}
ProductivityGraph(
lastWeekStatExpanded,
lastWeekSummaryAnalysisModelProducer,
label = "Weekly productivity analysis",
label = stringResource(R.string.weekly_productivity_analysis),
modifier = Modifier.padding(horizontal = 32.dp)
)
}
@@ -273,7 +274,7 @@ fun StatsScreen(
item { Spacer(Modifier) }
item {
Text(
"Last month",
stringResource(R.string.last_month),
style = typography.headlineSmall,
modifier = Modifier
.fillMaxWidth()
@@ -294,7 +295,7 @@ fun StatsScreen(
fontFamily = openRundeClock
)
Text(
"focus per day (avg)",
text = stringResource(R.string.focus_per_day_avg),
style = typography.titleSmall,
modifier = Modifier.padding(bottom = 6.3.dp)
)
@@ -331,14 +332,14 @@ fun StatsScreen(
) {
Icon(
painterResource(R.drawable.arrow_down),
"More info",
stringResource(R.string.more_info),
modifier = Modifier.rotate(iconRotation)
)
}
ProductivityGraph(
lastMonthStatExpanded,
lastMonthSummaryAnalysisModelProducer,
label = "Monthly productivity analysis",
label = stringResource(R.string.monthly_productivity_analysis),
modifier = Modifier.padding(horizontal = 32.dp)
)
}

View File

@@ -16,17 +16,18 @@ import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material3.AlertDialogDefaults
import androidx.compose.material3.BasicAlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MaterialTheme.typography
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
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.unit.dp
import org.nsh07.pomodoro.R
@@ -51,25 +52,25 @@ fun AlarmDialog(
Column(modifier = Modifier.padding(24.dp)) {
Icon(
painter = painterResource(R.drawable.alarm),
contentDescription = "Alarm",
contentDescription = stringResource(R.string.alarm),
modifier = Modifier.align(Alignment.CenterHorizontally)
)
Spacer(Modifier.height(16.dp))
Text(
text = "Stop Alarm?",
text = stringResource(R.string.stop_alarm_question),
style = typography.headlineSmall,
modifier = Modifier.align(Alignment.CenterHorizontally)
)
Spacer(Modifier.height(16.dp))
Text(
text = "Current timer session is complete. Tap anywhere to stop the alarm."
text = stringResource(R.string.stop_alarm_dialog_text)
)
Spacer(modifier = Modifier.height(24.dp))
Button(
TextButton(
onClick = stopAlarm,
modifier = Modifier.align(Alignment.End),
) {
Text("Dismiss")
Text(stringResource(R.string.stop_alarm))
}
}
}

View File

@@ -67,6 +67,7 @@ import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalHapticFeedback
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
@@ -134,7 +135,7 @@ fun TimerScreen(
when (it) {
TimerMode.BRAND ->
Text(
"Tomato",
stringResource(R.string.app_name),
style = TextStyle(
fontFamily = robotoFlexTopBar,
fontSize = 32.sp,
@@ -147,7 +148,7 @@ fun TimerScreen(
TimerMode.FOCUS ->
Text(
"Focus",
stringResource(R.string.focus),
style = TextStyle(
fontFamily = robotoFlexTopBar,
fontSize = 32.sp,
@@ -159,7 +160,7 @@ fun TimerScreen(
)
TimerMode.SHORT_BREAK -> Text(
"Short break",
stringResource(R.string.short_break),
style = TextStyle(
fontFamily = robotoFlexTopBar,
fontSize = 32.sp,
@@ -171,7 +172,7 @@ fun TimerScreen(
)
TimerMode.LONG_BREAK -> Text(
"Long Break",
stringResource(R.string.long_break),
style = TextStyle(
fontFamily = robotoFlexTopBar,
fontSize = 32.sp,
@@ -261,7 +262,11 @@ fun TimerScreen(
shrinkVertically(motionScheme.defaultSpatialSpec())
) {
Text(
"${timerState.currentFocusCount} of ${timerState.totalFocusCount}",
stringResource(
R.string.timer_session_count,
timerState.currentFocusCount,
timerState.totalFocusCount
),
fontFamily = openRundeClock,
style = typography.titleLarge,
color = colorScheme.outline
@@ -289,7 +294,7 @@ fun TimerScreen(
) {
Icon(
painterResource(R.drawable.more_vert_large),
contentDescription = "More",
contentDescription = stringResource(R.string.more),
modifier = Modifier.size(32.dp)
)
}
@@ -323,13 +328,13 @@ fun TimerScreen(
if (timerState.timerRunning) {
Icon(
painterResource(R.drawable.pause_large),
contentDescription = "Pause",
contentDescription = stringResource(R.string.pause),
modifier = Modifier.size(32.dp)
)
} else {
Icon(
painterResource(R.drawable.play_large),
contentDescription = "Play",
contentDescription = stringResource(R.string.play),
modifier = Modifier.size(32.dp)
)
}
@@ -341,16 +346,22 @@ fun TimerScreen(
if (timerState.timerRunning) {
Icon(
painterResource(R.drawable.pause),
contentDescription = "Pause"
contentDescription = stringResource(R.string.pause)
)
} else {
Icon(
painterResource(R.drawable.play),
contentDescription = "Play"
contentDescription = stringResource(R.string.play)
)
}
},
text = { Text(if (timerState.timerRunning) "Pause" else "Play") },
text = {
Text(
if (timerState.timerRunning) stringResource(R.string.pause) else stringResource(
R.string.play
)
)
},
onClick = {
onAction(TimerAction.ToggleTimer)
state.dismiss()
@@ -377,7 +388,7 @@ fun TimerScreen(
) {
Icon(
painterResource(R.drawable.restart_large),
contentDescription = "Restart",
contentDescription = stringResource(R.string.restart),
modifier = Modifier.size(32.dp)
)
}
@@ -387,10 +398,10 @@ fun TimerScreen(
leadingIcon = {
Icon(
painterResource(R.drawable.restart),
"Restart"
stringResource(R.string.restart)
)
},
text = { Text("Restart") },
text = { Text(stringResource(R.string.restart)) },
onClick = {
onAction(TimerAction.ResetTimer)
state.dismiss()
@@ -417,7 +428,7 @@ fun TimerScreen(
) {
Icon(
painterResource(R.drawable.skip_next_large),
contentDescription = "Skip to next",
contentDescription = stringResource(R.string.skip_to_next),
modifier = Modifier.size(32.dp)
)
}
@@ -427,10 +438,10 @@ fun TimerScreen(
leadingIcon = {
Icon(
painterResource(R.drawable.skip_next),
"Skip to next"
stringResource(R.string.skip_to_next)
)
},
text = { Text("Skip to next") },
text = { Text(stringResource(R.string.skip_to_next)) },
onClick = {
onAction(TimerAction.SkipTimer(fromButton = true))
state.dismiss()
@@ -444,7 +455,7 @@ fun TimerScreen(
Spacer(Modifier.height(32.dp))
Column(horizontalAlignment = CenterHorizontally) {
Text("Up next", style = typography.titleSmall)
Text(stringResource(R.string.up_next), style = typography.titleSmall)
Text(
timerState.nextTimeStr,
style = TextStyle(
@@ -457,9 +468,9 @@ fun TimerScreen(
)
Text(
when (timerState.nextTimerMode) {
TimerMode.FOCUS -> "Focus"
TimerMode.SHORT_BREAK -> "Short break"
else -> "Long Break"
TimerMode.FOCUS -> stringResource(R.string.focus)
TimerMode.SHORT_BREAK -> stringResource(R.string.short_break)
else -> stringResource(R.string.long_break)
},
style = typography.titleMediumEmphasized
)

View File

@@ -1,3 +1,59 @@
<resources>
<string name="app_name">Tomato</string>
<string name="start">Start</string>
<string name="stop">Stop</string>
<string name="focus">Focus</string>
<string name="short_break">Short break</string>
<string name="long_break">Long break</string>
<string name="exit">Exit</string>
<string name="skip">Skip</string>
<string name="stop_alarm">Stop alarm</string>
<string name="min_remaining_notification">%1$s min remaining</string>
<string name="paused">Paused</string>
<string name="completed">Completed</string>
<string name="up_next_notification">Up next: %1$s (%2$s)</string>
<string name="start_next">Start next</string>
<string name="choose_color_scheme">Choose color scheme</string>
<string name="ok">OK</string>
<string name="color_scheme">Color scheme</string>
<string name="dynamic">Dynamic</string>
<string name="color">Color</string>
<string name="system_default">System default</string>
<string name="alarm">Alarm</string>
<string name="light">Light</string>
<string name="dark">Dark</string>
<string name="choose_theme">Choose theme</string>
<string name="productivity_analysis">Productivity analysis</string>
<string name="productivity_analysis_desc">Focus durations at different times of the day</string>
<string name="alarm_sound">Alarm sound</string>
<string name="black_theme">Black theme</string>
<string name="black_theme_desc">Use a pure black dark theme</string>
<string name="alarm_desc">Ring alarm when a timer completes</string>
<string name="vibrate">Vibrate</string>
<string name="vibrate_desc">Vibrate when a timer completes</string>
<string name="theme">Theme</string>
<string name="settings">Settings</string>
<string name="session_length">Session length</string>
<string name="session_length_desc">Focus intervals in one session: %1$d</string>
<string name="pomodoro_info">A \"session\" is a sequence of pomodoro intervals that contain focus intervals, short break intervals, and a long break interval. The last break of a session is always a long break.</string>
<string name="stats">Stats</string>
<string name="today">Today</string>
<string name="break_">Break</string>
<string name="last_week">Last week</string>
<string name="focus_per_day_avg">focus per day (avg)</string>
<string name="more_info">More info</string>
<string name="weekly_productivity_analysis">Weekly productivity analysis</string>
<string name="last_month">Last month</string>
<string name="monthly_productivity_analysis">Monthly productivity analysis</string>
<string name="stop_alarm_question">Stop Alarm?</string>
<string name="stop_alarm_dialog_text">Current timer session is complete. Tap anywhere to stop the alarm.</string>
<string name="timer_session_count">%1$d of %2$d</string>
<string name="more">More</string>
<string name="pause">Pause</string>
<string name="play">Play</string>
<string name="restart">Restart</string>
<string name="skip_to_next">Skip to next</string>
<string name="up_next">Up next</string>
<string name="timer">Timer</string>
<string name="timer_progress">Timer progress</string>
</resources>