Update packages

Add french translation
Migrate VM strings resources
This commit is contained in:
Geoffroy Bonneville
2025-10-30 12:32:36 -04:00
parent f297427d13
commit a000eff8cc
14 changed files with 115 additions and 26 deletions

View File

@@ -342,6 +342,18 @@
<option name="screenX" value="2220" /> <option name="screenX" value="2220" />
<option name="screenY" value="1080" /> <option name="screenY" value="1080" />
</PersistentDeviceSelectionData> </PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="35" />
<option name="brand" value="samsung" />
<option name="codename" value="dm1q" />
<option name="id" value="dm1q" />
<option name="labId" value="google" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="S23" />
<option name="screenDensity" value="480" />
<option name="screenX" value="1080" />
<option name="screenY" value="2340" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData> <PersistentDeviceSelectionData>
<option name="api" value="34" /> <option name="api" value="34" />
<option name="brand" value="samsung" /> <option name="brand" value="samsung" />
@@ -765,6 +777,18 @@
<option name="screenX" value="1080" /> <option name="screenX" value="1080" />
<option name="screenY" value="2400" /> <option name="screenY" value="2400" />
</PersistentDeviceSelectionData> </PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="35" />
<option name="brand" value="samsung" />
<option name="codename" value="psq" />
<option name="id" value="psq" />
<option name="labId" value="google" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy S25 Edge" />
<option name="screenDensity" value="450" />
<option name="screenX" value="1440" />
<option name="screenY" value="3120" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData> <PersistentDeviceSelectionData>
<option name="api" value="34" /> <option name="api" value="34" />
<option name="brand" value="samsung" /> <option name="brand" value="samsung" />

View File

@@ -2,6 +2,7 @@
<dictionary name="project"> <dictionary name="project">
<words> <words>
<w>donext</w> <w>donext</w>
<w>snackbar</w>
</words> </words>
</dictionary> </dictionary>
</component> </component>

View File

@@ -51,7 +51,7 @@ android {
dependencies { dependencies {
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.9.4") implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.9.4")
implementation("androidx.activity:activity-compose:1.11.0") implementation("androidx.activity:activity-compose:1.11.0")
implementation(platform("androidx.compose:compose-bom:2025.10.00")) implementation(platform("androidx.compose:compose-bom:2025.10.01"))
implementation("androidx.compose.ui:ui") implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics") implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview") implementation("androidx.compose.ui:ui-tooling-preview")
@@ -62,12 +62,12 @@ dependencies {
implementation("androidx.hilt:hilt-navigation-compose:1.3.0") implementation("androidx.hilt:hilt-navigation-compose:1.3.0")
implementation("androidx.test.ext:junit-ktx:1.3.0") implementation("androidx.test.ext:junit-ktx:1.3.0")
implementation("sh.calvin.reorderable:reorderable:3.0.0") implementation("sh.calvin.reorderable:reorderable:3.0.0")
androidTestImplementation(platform("androidx.compose:compose-bom:2025.10.00")) androidTestImplementation(platform("androidx.compose:compose-bom:2025.10.01"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4") androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling") debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest") debugImplementation("androidx.compose.ui:ui-test-manifest")
val roomVersion = "2.8.2" val roomVersion = "2.8.3"
implementation("androidx.room:room-runtime:$roomVersion") implementation("androidx.room:room-runtime:$roomVersion")
ksp("androidx.room:room-compiler:$roomVersion") ksp("androidx.room:room-compiler:$roomVersion")

View File

@@ -13,16 +13,13 @@ sealed class AppDestination(
object DueTodayList : AppDestination( object DueTodayList : AppDestination(
route = "todayList", route = "todayList",
title = "Due Today", title = "Due Today",
showBackButton = false,
) )
object ManageLists : AppDestination( object ManageLists : AppDestination(
route = "manageLists", route = "manageLists",
title = "Manage Lists", title = "Manage Lists",
showBackButton = false,
) )
object RecycleBin : AppDestination( object RecycleBin : AppDestination(
route = "recycleBin", route = "recycleBin",
title = "Recycle Bin", title = "Recycle Bin",
showBackButton = false,
) )
} }

View File

@@ -57,6 +57,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.Dialog
@@ -199,7 +200,7 @@ fun AppContent(
) { ) {
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val snackbarHostState = remember { SnackbarHostState() } val snackbarHostState = remember { SnackbarHostState() }
val snackbarActionLabel = stringResource(R.string.snackbar_action) val context = LocalContext.current
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
viewModel.uiEventBus.events.collectLatest { event -> viewModel.uiEventBus.events.collectLatest { event ->
@@ -211,8 +212,8 @@ fun AppContent(
is UiEvent.NavigateBack -> navController.popBackStack() is UiEvent.NavigateBack -> navController.popBackStack()
is UiEvent.ShowUndoSnackbar -> { is UiEvent.ShowUndoSnackbar -> {
val result = snackbarHostState.showSnackbar( val result = snackbarHostState.showSnackbar(
message = event.message, message = context.getString(event.message),
actionLabel = snackbarActionLabel, actionLabel = context.getString(R.string.snackbar_action),
duration = SnackbarDuration.Short duration = SnackbarDuration.Short
) )
if (result == SnackbarResult.ActionPerformed) { if (result == SnackbarResult.ActionPerformed) {
@@ -238,7 +239,14 @@ fun AppContent(
snackbarHost = { SnackbarHost(hostState = snackbarHostState) }, snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
topBar = { topBar = {
TopAppBar( TopAppBar(
title = { Text(viewModel.currentDestination.title) }, title = { Text(
when (viewModel.currentDestination) {
is AppDestination.DueTodayList -> stringResource(R.string.navigation_due_today)
is AppDestination.ManageLists -> stringResource(R.string.navigation_edit_lists)
is AppDestination.RecycleBin -> stringResource(R.string.navigation_recycle_bin)
else -> viewModel.currentDestination.title
}
)},
colors = TopAppBarDefaults.topAppBarColors( colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.primaryContainer, containerColor = MaterialTheme.colorScheme.primaryContainer,
titleContentColor = MaterialTheme.colorScheme.onPrimaryContainer, titleContentColor = MaterialTheme.colorScheme.onPrimaryContainer,

View File

@@ -63,7 +63,11 @@ fun TaskScreen(
Column(Modifier.padding(16.dp)) { Column(Modifier.padding(16.dp)) {
Text( Text(
viewModel.screenTitle(), stringResource(
if (viewModel.isDeleted) R.string.task_title_deleted
else
if (viewModel.isEditing()) R.string.task_title_edit
else R.string.task_title_new),
style = MaterialTheme.typography.titleLarge style = MaterialTheme.typography.titleLarge
) )
Spacer(Modifier.height(8.dp)) Spacer(Modifier.height(8.dp))

View File

@@ -9,7 +9,7 @@ sealed class UiEvent {
data class CreateNewTask(val taskListId: Long) : UiEvent() data class CreateNewTask(val taskListId: Long) : UiEvent()
data object CloseTask : UiEvent() data object CloseTask : UiEvent()
data class ShowUndoSnackbar( data class ShowUndoSnackbar(
val message: String, val message: Int,
val undoAction: () -> Unit val undoAction: () -> Unit
) : UiEvent() ) : UiEvent()
} }

View File

@@ -5,6 +5,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.wismna.geoffroy.donext.R
import com.wismna.geoffroy.donext.domain.model.Task import com.wismna.geoffroy.donext.domain.model.Task
import com.wismna.geoffroy.donext.domain.usecase.GetDueTodayTasksUseCase import com.wismna.geoffroy.donext.domain.usecase.GetDueTodayTasksUseCase
import com.wismna.geoffroy.donext.domain.usecase.ToggleTaskDeletedUseCase import com.wismna.geoffroy.donext.domain.usecase.ToggleTaskDeletedUseCase
@@ -48,7 +49,7 @@ class DueTodayViewModel @Inject constructor(
uiEventBus.send( uiEventBus.send(
UiEvent.ShowUndoSnackbar( UiEvent.ShowUndoSnackbar(
message = "Task done", message = R.string.snackbar_message_task_done,
undoAction = { undoAction = {
viewModelScope.launch { viewModelScope.launch {
toggleTaskDoneUseCase(taskId, false) toggleTaskDoneUseCase(taskId, false)
@@ -65,7 +66,7 @@ class DueTodayViewModel @Inject constructor(
uiEventBus.send( uiEventBus.send(
UiEvent.ShowUndoSnackbar( UiEvent.ShowUndoSnackbar(
message = "Task moved to recycle bin", message = R.string.snackbar_message_task_recycle,
undoAction = { undoAction = {
viewModelScope.launch { viewModelScope.launch {
toggleTaskDeletedUseCase(taskId, false) toggleTaskDeletedUseCase(taskId, false)

View File

@@ -6,6 +6,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.wismna.geoffroy.donext.R
import com.wismna.geoffroy.donext.domain.model.TaskList import com.wismna.geoffroy.donext.domain.model.TaskList
import com.wismna.geoffroy.donext.domain.usecase.AddTaskListUseCase import com.wismna.geoffroy.donext.domain.usecase.AddTaskListUseCase
import com.wismna.geoffroy.donext.domain.usecase.DeleteTaskListUseCase import com.wismna.geoffroy.donext.domain.usecase.DeleteTaskListUseCase
@@ -58,7 +59,7 @@ class ManageListsViewModel @Inject constructor(
uiEventBus.send( uiEventBus.send(
UiEvent.ShowUndoSnackbar( UiEvent.ShowUndoSnackbar(
message = "Task list moved to recycle bin", message = R.string.snackbar_message_task_list_recycle,
undoAction = { undoAction = {
viewModelScope.launch { viewModelScope.launch {
deleteTaskListUseCase(taskListId, false) deleteTaskListUseCase(taskListId, false)

View File

@@ -6,6 +6,7 @@ import androidx.compose.runtime.setValue
import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.wismna.geoffroy.donext.R
import com.wismna.geoffroy.donext.domain.model.Task import com.wismna.geoffroy.donext.domain.model.Task
import com.wismna.geoffroy.donext.domain.model.TaskWithListName import com.wismna.geoffroy.donext.domain.model.TaskWithListName
import com.wismna.geoffroy.donext.domain.usecase.EmptyRecycleBinUseCase import com.wismna.geoffroy.donext.domain.usecase.EmptyRecycleBinUseCase
@@ -64,7 +65,7 @@ class RecycleBinViewModel @Inject constructor(
uiEventBus.send( uiEventBus.send(
UiEvent.ShowUndoSnackbar( UiEvent.ShowUndoSnackbar(
message = "Task restored", message = R.string.snackbar_message_task_restore,
undoAction = { undoAction = {
viewModelScope.launch { viewModelScope.launch {
toggleTaskDeletedUseCase(taskId, true) toggleTaskDeletedUseCase(taskId, true)

View File

@@ -6,6 +6,7 @@ import androidx.compose.runtime.setValue
import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.wismna.geoffroy.donext.R
import com.wismna.geoffroy.donext.domain.model.Task import com.wismna.geoffroy.donext.domain.model.Task
import com.wismna.geoffroy.donext.domain.usecase.GetTasksForListUseCase import com.wismna.geoffroy.donext.domain.usecase.GetTasksForListUseCase
import com.wismna.geoffroy.donext.domain.usecase.ToggleTaskDeletedUseCase import com.wismna.geoffroy.donext.domain.usecase.ToggleTaskDeletedUseCase
@@ -55,7 +56,7 @@ class TaskListViewModel @Inject constructor(
uiEventBus.send( uiEventBus.send(
UiEvent.ShowUndoSnackbar( UiEvent.ShowUndoSnackbar(
message = "Task done", message = if (isDone) R.string.snackbar_message_task_done else R.string.snackbar_message_task_undone,
undoAction = { undoAction = {
viewModelScope.launch { viewModelScope.launch {
toggleTaskDoneUseCase(taskId, !isDone) toggleTaskDoneUseCase(taskId, !isDone)
@@ -71,7 +72,7 @@ class TaskListViewModel @Inject constructor(
uiEventBus.send( uiEventBus.send(
UiEvent.ShowUndoSnackbar( UiEvent.ShowUndoSnackbar(
message = "Task moved to recycle bin", message = R.string.snackbar_message_task_recycle,
undoAction = { undoAction = {
viewModelScope.launch { viewModelScope.launch {
toggleTaskDeletedUseCase(taskId, false) toggleTaskDeletedUseCase(taskId, false)

View File

@@ -55,7 +55,6 @@ class TaskViewModel @Inject constructor(
} }
} }
fun screenTitle(): String = if (isDeleted) "Task details" else if (isEditing()) "Edit Task" else "New Task"
fun isEditing(): Boolean = editingTaskId != null fun isEditing(): Boolean = editingTaskId != null
fun onTitleChanged(value: String) { title = value } fun onTitleChanged(value: String) { title = value }
fun onDescriptionChanged(value: String) { description = value } fun onDescriptionChanged(value: String) { description = value }

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="navigation_edit_lists">Edition des listes</string>
<string name="navigation_recycle_bin">Corbeille</string>
<string name="navigation_due_today">À faire aujourd\'hui</string>
<string name="action_create_list">Créer une tâche</string>
<string name="tasklist_no_tasks">Cliquez sur + pour créer un nouvelle tâche.</string>
<string name="recycle_bin_no_tasks">La corbeille est vide</string>
<string name="today_no_tasks">Rien à faire aujourd\'hui !</string>
<string name="task_title_new">Nouvelle tâche</string>
<string name="task_title_edit">Edition de tâche</string>
<string name="task_title_deleted">Détails de la tâche</string>
<string name="task_name">Titre</string>
<string name="task_description">Description</string>
<string name="task_priority">Priorité</string>
<string name="task_priority_low">Basse</string>
<string name="task_priority_normal">Normale</string>
<string name="task_priority_high">Haute</string>
<string name="task_due_date">Echéance</string>
<string name="task_save_new">Créer</string>
<string name="task_save_edit">Sauvegarder</string>
<string name="task_cancel">Annuler</string>
<string name="due_date_yesterday">Hier</string>
<string name="due_date_today">Aujourd\'hui</string>
<string name="due_date_tomorrow">Demain</string>
<string name="task_action_recycle">Mettre à la corbeille</string>
<string name="task_action_delete">Supprimer</string>
<string name="task_action_restore">Restaurer</string>
<string name="task_action_done">Terminée</string>
<string name="task_action_undone">En cours</string>
<string name="dialog_due_date_ok">OK</string>
<string name="dialog_due_date_cancel">Annuler</string>
<string name="dialog_delete_task_title">Supprimer la tâche</string>
<string name="dialog_delete_task_description">Êtes-vous sûr de vouloir supprimer cette tâche ? Cette action ne peut être annulée.</string>
<string name="dialog_delete_task_cancel">Annuler</string>
<string name="dialog_delete_task_delete">Supprimer</string>
<string name="dialog_empty_task_title">Vider la corbeille</string>
<string name="dialog_empty_task_description">Êtes-vous sûr de vider la corbeille ? Cette action ne peut être annulée.</string>
<string name="dialog_empty_task_cancel">Annuler</string>
<string name="dialog_empty_task_delete">Vider</string>
<string name="tasklist_new_title">Nouvelle liste</string>
<string name="tasklist_new_name">Titre</string>
<string name="tasklist_new_create">Créer</string>
<string name="snackbar_message_task_done">Tâche terminée.</string>
<string name="snackbar_message_task_undone">Tâche active.</string>
<string name="snackbar_message_task_recycle">Tâche placée dans la corbeille.</string>
<string name="snackbar_message_task_list_recycle">Liste de tâches déplacée dans la corbeille.</string>
<string name="snackbar_message_task_restore">Tâche restaurée</string>
<string name="snackbar_action">Annuler</string>
</resources>

View File

@@ -1,8 +1,8 @@
<resources> <resources>
<string name="app_name">DoNext</string> <string name="app_name" translatable="false">DoNext</string>
<string name="title_activity_main">MainActivity</string> <string name="title_activity_main" translatable="false">MainActivity</string>
<string name="navigation_title">DoNext v2</string> <string name="navigation_title" translatable="false">DoNext v2</string>
<string name="navigation_edit_lists">Edit lists</string> <string name="navigation_edit_lists">Edit lists</string>
<string name="navigation_recycle_bin">Recycle Bin</string> <string name="navigation_recycle_bin">Recycle Bin</string>
<string name="navigation_due_today">Due Today</string> <string name="navigation_due_today">Due Today</string>
@@ -15,6 +15,7 @@
<string name="task_title_new">New Task</string> <string name="task_title_new">New Task</string>
<string name="task_title_edit">Edit Task</string> <string name="task_title_edit">Edit Task</string>
<string name="task_title_deleted">Task Details</string>
<string name="task_name">Title</string> <string name="task_name">Title</string>
<string name="task_description">Description</string> <string name="task_description">Description</string>
<string name="task_priority">Priority</string> <string name="task_priority">Priority</string>
@@ -53,9 +54,10 @@
<string name="tasklist_new_name">Title</string> <string name="tasklist_new_name">Title</string>
<string name="tasklist_new_create">Create</string> <string name="tasklist_new_create">Create</string>
<string name="snackbar_message_done">Task done</string> <string name="snackbar_message_task_done">Task done</string>
<string name="snackbar_message_undone">Task undone</string> <string name="snackbar_message_task_undone">Task undone</string>
<string name="snackbar_message_recycle">Task moved to recycle bin</string> <string name="snackbar_message_task_recycle">Task moved to recycle bin</string>
<string name="snackbar_message_restore">Task restored</string> <string name="snackbar_message_task_list_recycle">Task list moved to recycle bin</string>
<string name="snackbar_message_task_restore">Task restored</string>
<string name="snackbar_action">Undo</string> <string name="snackbar_action">Undo</string>
</resources> </resources>