Fix navigation issue when navigating back to a deleted list

Some refactoring
This commit is contained in:
Geoffroy Bonneville
2025-10-09 16:43:27 -04:00
parent 7dddc62377
commit 8e78f9b464
7 changed files with 83 additions and 29 deletions

View File

@@ -15,7 +15,6 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import com.wismna.geoffroy.donext.domain.model.Task
import com.wismna.geoffroy.donext.presentation.viewmodel.DueTodayViewModel
import com.wismna.geoffroy.donext.presentation.viewmodel.TaskItemViewModel
@Composable
fun DueTodayTasksScreen(
@@ -41,7 +40,7 @@ fun DueTodayTasksScreen(
items(tasks, key = { it.id!! }) { task ->
TaskItemScreen(
modifier = Modifier.animateItem(),
viewModel = TaskItemViewModel(task),
task = task,
onTaskClick = { onTaskClick(task) },
onSwipeLeft = {
viewModel.updateTaskDone(task.id!!)

View File

@@ -18,6 +18,7 @@ import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.DrawerState
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LocalContentColor
@@ -31,7 +32,10 @@ import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -60,7 +64,7 @@ fun MainScreen(
val navController = rememberNavController()
val drawerState = rememberDrawerState(DrawerValue.Closed)
val scope = rememberCoroutineScope()
// TODO: find a way to get rid of this
// TODO: find a way to do this better
val taskViewModel: TaskViewModel = hiltViewModel()
if (viewModel.isLoading) {
@@ -154,9 +158,13 @@ fun AppContent(
floatingActionButton = {
when (val dest = viewModel.currentDestination) {
is AppDestination.TaskList -> {
TaskListFab(
taskListId = dest.taskListId,
showBottomSheet = { viewModel.showTaskSheet = it }
ExtendedFloatingActionButton(
onClick = {
taskViewModel.startNewTask(dest.taskListId)
viewModel.showTaskSheet = true
},
icon = { Icon(Icons.Filled.Add, "Create a task.") },
text = { Text("Create a task") },
)
}
else -> null
@@ -192,7 +200,16 @@ fun AppContent(
type = NavType.LongType
})
) { navBackStackEntry ->
// TODO: when task list has been deleted, we should not navigate to it event if in the stack
val taskListId = navBackStackEntry.arguments?.getLong("taskListId") ?: return@composable
val listExists by remember(taskListId, viewModel.destinations) {
derivedStateOf { viewModel.doesListExist(taskListId) }
}
LaunchedEffect(listExists) {
if (!viewModel.doesListExist(taskListId)) {
navController.popBackStack()
}
}
val taskListViewModel: TaskListViewModel = hiltViewModel(navBackStackEntry)
TaskListScreen(
viewModel = taskListViewModel,

View File

@@ -31,7 +31,6 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import com.wismna.geoffroy.donext.domain.model.Task
import com.wismna.geoffroy.donext.presentation.viewmodel.RecycleBinViewModel
import com.wismna.geoffroy.donext.presentation.viewmodel.TaskItemViewModel
@Composable
fun RecycleBinScreen(
@@ -77,7 +76,7 @@ fun RecycleBinScreen(
items(items, key = { it.task.id!! }) { item ->
TaskItemScreen(
modifier = Modifier.animateItem(),
viewModel = TaskItemViewModel(item.task),
task = item.task,
onTaskClick = { onTaskClick(item.task) },
onSwipeLeft = {
viewModel.restore(item.task.id!!)

View File

@@ -38,16 +38,18 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.wismna.geoffroy.donext.domain.model.Priority
import com.wismna.geoffroy.donext.domain.model.Task
import com.wismna.geoffroy.donext.presentation.viewmodel.TaskItemViewModel
@Composable
fun TaskItemScreen(
modifier: Modifier = Modifier,
viewModel: TaskItemViewModel,
task: Task,
onTaskClick: (taskId: Long) -> Unit,
onSwipeLeft: () -> Unit,
onSwipeRight: () -> Unit
) {
val viewModel = TaskItemViewModel(task)
// TODO: change this
val dismissState = rememberSwipeToDismissBoxState(
confirmValueChange = {

View File

@@ -21,7 +21,6 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import com.wismna.geoffroy.donext.domain.model.Task
import com.wismna.geoffroy.donext.presentation.viewmodel.TaskItemViewModel
import com.wismna.geoffroy.donext.presentation.viewmodel.TaskListViewModel
import com.wismna.geoffroy.donext.presentation.viewmodel.TaskViewModel
@@ -50,7 +49,7 @@ fun TaskListScreen(
) { task ->
TaskItemScreen(
modifier = Modifier.animateItem(),
viewModel = TaskItemViewModel(task),
task = task,
onTaskClick = { onTaskClick(task) },
onSwipeLeft = {
viewModel.updateTaskDone(task.id!!, true)
@@ -81,7 +80,7 @@ fun TaskListScreen(
) { task ->
TaskItemScreen(
modifier = Modifier.animateItem(),
viewModel = TaskItemViewModel(task),
task = task,
onTaskClick = { onTaskClick(task) },
onSwipeLeft = {
viewModel.updateTaskDone(task.id!!, false)
@@ -95,20 +94,4 @@ fun TaskListScreen(
}
}
}
@Composable
fun TaskListFab(
taskListId: Long,
viewModel: TaskViewModel = hiltViewModel(),
showBottomSheet: (Boolean) -> Unit = {}
) {
ExtendedFloatingActionButton(
onClick = {
viewModel.startNewTask(taskListId)
showBottomSheet(true)
},
icon = { Icon(Icons.Filled.Add, "Create a task.") },
text = { Text("Create a task") },
)
}

View File

@@ -61,4 +61,10 @@ class MainViewModel @Inject constructor(
}
} ?: startDestination
}
fun doesListExist(taskListId: Long): Boolean {
return destinations.any { dest ->
dest is AppDestination.TaskList && dest.taskListId == taskListId
}
}
}