mirror of
https://github.com/wismna/DoNext.git
synced 2025-10-03 07:30:13 -04:00
Fix navigation (once and for all ?)
Implement inline edit lists feature Improve task list bottom sheet design
This commit is contained in:
@@ -46,7 +46,7 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.9.3")
|
||||
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.9.4")
|
||||
implementation("androidx.activity:activity-compose:1.11.0")
|
||||
implementation(platform("androidx.compose:compose-bom:2025.09.00"))
|
||||
implementation("androidx.compose.ui:ui")
|
||||
|
@@ -44,6 +44,10 @@ class TaskRepositoryImpl @Inject constructor(
|
||||
taskListDao.insertTaskList(taskList.toEntity())
|
||||
}
|
||||
|
||||
override suspend fun updateTaskList(taskList: TaskList) {
|
||||
taskListDao.updateTaskList(taskList.toEntity())
|
||||
}
|
||||
|
||||
override suspend fun deleteTaskList(taskListId: Long, isDeleted: Boolean) {
|
||||
taskDao.deleteAllTasksFromList(taskListId, isDeleted)
|
||||
taskListDao.deleteTaskList(taskListId, isDeleted)
|
||||
|
@@ -14,6 +14,7 @@ interface TaskRepository {
|
||||
|
||||
fun getTaskLists(): Flow<List<TaskList>>
|
||||
suspend fun insertTaskList(taskList: TaskList)
|
||||
suspend fun updateTaskList(taskList: TaskList)
|
||||
suspend fun deleteTaskList(taskListId: Long, isDeleted: Boolean)
|
||||
fun getTaskListsWithOverdue(nowMillis: Long): Flow<List<TaskListWithOverdue>>
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package com.wismna.geoffroy.donext.domain.usecase
|
||||
|
||||
import com.wismna.geoffroy.donext.domain.model.TaskList
|
||||
import com.wismna.geoffroy.donext.domain.repository.TaskRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
class UpdateTaskListUseCase @Inject constructor(
|
||||
private val repository: TaskRepository
|
||||
) {
|
||||
suspend operator fun invoke(taskListId: Long, title: String, order: Int) {
|
||||
repository.updateTaskList(
|
||||
TaskList(
|
||||
id = taskListId,
|
||||
name = title,
|
||||
order = order,
|
||||
isDeleted = false
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
@@ -15,6 +15,7 @@ import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Menu
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.DrawerState
|
||||
import androidx.compose.material3.DrawerValue
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
@@ -31,15 +32,13 @@ import androidx.compose.material3.rememberDrawerState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
@@ -50,6 +49,7 @@ import com.wismna.geoffroy.donext.domain.model.AppDestination
|
||||
import com.wismna.geoffroy.donext.presentation.viewmodel.MainViewModel
|
||||
import com.wismna.geoffroy.donext.presentation.viewmodel.TaskListViewModel
|
||||
import com.wismna.geoffroy.donext.presentation.viewmodel.TaskViewModel
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
@@ -58,8 +58,6 @@ fun MainScreen(
|
||||
viewModel: MainViewModel = hiltViewModel()
|
||||
) {
|
||||
val navController = rememberNavController()
|
||||
var showTaskSheet by remember { mutableStateOf(false) }
|
||||
var showAddListSheet by remember { mutableStateOf(false) }
|
||||
val drawerState = rememberDrawerState(DrawerValue.Closed)
|
||||
val scope = rememberCoroutineScope()
|
||||
val taskViewModel: TaskViewModel = hiltViewModel()
|
||||
@@ -71,23 +69,20 @@ fun MainScreen(
|
||||
return
|
||||
}
|
||||
|
||||
val startDestination = viewModel.destinations.firstOrNull() ?: AppDestination.ManageLists
|
||||
if (showTaskSheet) {
|
||||
TaskBottomSheet(taskViewModel) { showTaskSheet = false }
|
||||
if (viewModel.showTaskSheet) {
|
||||
TaskBottomSheet(taskViewModel) { viewModel.showTaskSheet = false }
|
||||
}
|
||||
if (showAddListSheet) {
|
||||
AddListBottomSheet { showAddListSheet = false }
|
||||
if (viewModel.showAddListSheet) {
|
||||
AddListBottomSheet { viewModel.showAddListSheet = false }
|
||||
}
|
||||
|
||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||
val currentDestination =
|
||||
viewModel.deriveDestination(navBackStackEntry?.destination?.route)
|
||||
?: startDestination
|
||||
viewModel.setCurrentDestination(navBackStackEntry)
|
||||
|
||||
ModalNavigationDrawer(
|
||||
drawerContent = {
|
||||
MenuScreen (
|
||||
currentDestination = currentDestination,
|
||||
currentDestination = viewModel.currentDestination,
|
||||
onNavigate = { route ->
|
||||
scope.launch { drawerState.close() }
|
||||
navController.navigate(route) {
|
||||
@@ -98,101 +93,113 @@ fun MainScreen(
|
||||
},
|
||||
drawerState = drawerState
|
||||
) {
|
||||
Scaffold(
|
||||
modifier = modifier.background(MaterialTheme.colorScheme.primaryContainer),
|
||||
containerColor = Color.Transparent,
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text(currentDestination!!.title) },
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = MaterialTheme.colorScheme.primaryContainer,
|
||||
titleContentColor = MaterialTheme.colorScheme.onPrimaryContainer,
|
||||
actionIconContentColor = MaterialTheme.colorScheme.onPrimaryContainer
|
||||
),
|
||||
navigationIcon = {
|
||||
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onPrimaryContainer) {
|
||||
if (currentDestination!!.showBackButton) {
|
||||
IconButton(onClick = { navController.popBackStack() }) {
|
||||
Icon(Icons.Default.ArrowBack, contentDescription = "Back")
|
||||
}
|
||||
} else {
|
||||
IconButton(onClick = { scope.launch { drawerState.open() } }) {
|
||||
Icon(
|
||||
Icons.Default.Menu,
|
||||
contentDescription = "Open navigation drawer"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
if (currentDestination is AppDestination.ManageLists) {
|
||||
IconButton(onClick = { showAddListSheet = true }) {
|
||||
Icon(Icons.Default.Add, contentDescription = "Add List")
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
floatingActionButton = {
|
||||
when (val dest = currentDestination) {
|
||||
is AppDestination.TaskList -> {
|
||||
TaskListFab(
|
||||
taskListId = dest.taskListId,
|
||||
showBottomSheet = { showTaskSheet = it }
|
||||
)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
) { contentPadding ->
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.padding(top = contentPadding.calculateTopPadding())
|
||||
.fillMaxSize(),
|
||||
shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp),
|
||||
color = MaterialTheme.colorScheme.surfaceContainer,
|
||||
) {
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = startDestination.route,
|
||||
enterTransition = {
|
||||
slideInHorizontally(initialOffsetX = { fullWidth -> fullWidth }, animationSpec = tween(300))
|
||||
},
|
||||
exitTransition = {
|
||||
slideOutHorizontally(targetOffsetX = { fullWidth -> -fullWidth }, animationSpec = tween(300))
|
||||
},
|
||||
popEnterTransition = {
|
||||
slideInHorizontally(initialOffsetX = { fullWidth -> -fullWidth }, animationSpec = tween(300))
|
||||
},
|
||||
popExitTransition = {
|
||||
slideOutHorizontally(targetOffsetX = { fullWidth -> fullWidth }, animationSpec = tween(300))
|
||||
}
|
||||
) {
|
||||
viewModel.destinations.forEach { destination ->
|
||||
composable(
|
||||
route = "taskList/{taskListId}",
|
||||
arguments = listOf(navArgument("taskListId") {
|
||||
type = NavType.LongType
|
||||
})
|
||||
) { navBackStackEntry ->
|
||||
val viewModel: TaskListViewModel = hiltViewModel(navBackStackEntry)
|
||||
TaskListScreen(
|
||||
viewModel = viewModel,
|
||||
onTaskClick = { task ->
|
||||
taskViewModel.startEditTask(task)
|
||||
showTaskSheet = true
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
AppContent(viewModel = viewModel, taskViewModel = taskViewModel, navController = navController, scope = scope, drawerState = drawerState)
|
||||
}
|
||||
}
|
||||
|
||||
composable(AppDestination.ManageLists.route) {
|
||||
ManageListsScreen(
|
||||
modifier = Modifier,
|
||||
showAddListSheet = {showAddListSheet = true}
|
||||
@Composable
|
||||
fun AppContent(
|
||||
modifier : Modifier = Modifier,
|
||||
viewModel: MainViewModel,
|
||||
taskViewModel: TaskViewModel,
|
||||
navController: NavHostController,
|
||||
scope: CoroutineScope,
|
||||
drawerState: DrawerState
|
||||
) {
|
||||
Scaffold(
|
||||
modifier = modifier.background(MaterialTheme.colorScheme.primaryContainer),
|
||||
containerColor = Color.Transparent,
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text(viewModel.currentDestination.title) },
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = MaterialTheme.colorScheme.primaryContainer,
|
||||
titleContentColor = MaterialTheme.colorScheme.onPrimaryContainer,
|
||||
actionIconContentColor = MaterialTheme.colorScheme.onPrimaryContainer
|
||||
),
|
||||
navigationIcon = {
|
||||
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onPrimaryContainer) {
|
||||
if (viewModel.currentDestination.showBackButton) {
|
||||
IconButton(onClick = { navController.popBackStack() }) {
|
||||
Icon(Icons.Default.ArrowBack, contentDescription = "Back")
|
||||
}
|
||||
} else {
|
||||
IconButton(onClick = { scope.launch { drawerState.open() } }) {
|
||||
Icon(
|
||||
Icons.Default.Menu,
|
||||
contentDescription = "Open navigation drawer"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
if (viewModel.currentDestination is AppDestination.ManageLists) {
|
||||
IconButton(onClick = { viewModel.showAddListSheet = true }) {
|
||||
Icon(Icons.Default.Add, contentDescription = "Add List")
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
floatingActionButton = {
|
||||
when (val dest = viewModel.currentDestination) {
|
||||
is AppDestination.TaskList -> {
|
||||
TaskListFab(
|
||||
taskListId = dest.taskListId,
|
||||
showBottomSheet = { viewModel.showTaskSheet = it }
|
||||
)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
) { contentPadding ->
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.padding(top = contentPadding.calculateTopPadding())
|
||||
.fillMaxSize(),
|
||||
shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp),
|
||||
color = MaterialTheme.colorScheme.surfaceContainer,
|
||||
) {
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = viewModel.startDestination.route,
|
||||
enterTransition = {
|
||||
slideInHorizontally(initialOffsetX = { fullWidth -> fullWidth }, animationSpec = tween(300))
|
||||
},
|
||||
exitTransition = {
|
||||
slideOutHorizontally(targetOffsetX = { fullWidth -> -fullWidth }, animationSpec = tween(300))
|
||||
},
|
||||
popEnterTransition = {
|
||||
slideInHorizontally(initialOffsetX = { fullWidth -> -fullWidth }, animationSpec = tween(300))
|
||||
},
|
||||
popExitTransition = {
|
||||
slideOutHorizontally(targetOffsetX = { fullWidth -> fullWidth }, animationSpec = tween(300))
|
||||
}
|
||||
) {
|
||||
//viewModel.destinations.forEach { destination ->
|
||||
composable(
|
||||
route = "taskList/{taskListId}",
|
||||
arguments = listOf(navArgument("taskListId") {
|
||||
type = NavType.LongType
|
||||
})
|
||||
) { navBackStackEntry ->
|
||||
val taskListViewModel: TaskListViewModel = hiltViewModel(navBackStackEntry)
|
||||
TaskListScreen(
|
||||
viewModel = taskListViewModel,
|
||||
onTaskClick = { task ->
|
||||
taskViewModel.startEditTask(task)
|
||||
viewModel.showTaskSheet = true
|
||||
}
|
||||
)
|
||||
}
|
||||
//}
|
||||
|
||||
composable(AppDestination.ManageLists.route) {
|
||||
ManageListsScreen(
|
||||
modifier = Modifier,
|
||||
showAddListSheet = {viewModel.showAddListSheet = true}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -7,11 +7,11 @@ import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.Edit
|
||||
import androidx.compose.material3.Button
|
||||
@@ -23,9 +23,8 @@ import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@@ -33,12 +32,11 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import com.wismna.geoffroy.donext.domain.model.TaskList
|
||||
import com.wismna.geoffroy.donext.presentation.viewmodel.ManageListsViewModel
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@@ -52,17 +50,46 @@ fun ManageListsScreen(
|
||||
|
||||
LazyColumn(modifier = modifier.fillMaxWidth().padding()) {
|
||||
itemsIndexed(lists, key = { _, list -> list.id!! }) { index, list ->
|
||||
|
||||
var isInEditMode by remember { mutableStateOf(false) }
|
||||
var editedName by remember { mutableStateOf(list.name) }
|
||||
ListItem(
|
||||
modifier = Modifier.animateItem(),
|
||||
headlineContent = { Text(list.name) },
|
||||
headlineContent = {
|
||||
if (isInEditMode) {
|
||||
OutlinedTextField(
|
||||
value = editedName,
|
||||
onValueChange = { editedName = it },
|
||||
singleLine = true
|
||||
)
|
||||
} else {
|
||||
Text(list.name)
|
||||
}
|
||||
},
|
||||
trailingContent = {
|
||||
Row {
|
||||
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onPrimaryContainer) {
|
||||
IconButton(onClick = { /* TODO: edit list */ }) {
|
||||
Icon(Icons.Default.Edit, contentDescription = "Edit")
|
||||
if (isInEditMode) {
|
||||
Row {
|
||||
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onPrimaryContainer) {
|
||||
IconButton(onClick = { isInEditMode = false }) {
|
||||
Icon(Icons.Default.Close, contentDescription = "Cancel")
|
||||
}
|
||||
IconButton(onClick = {
|
||||
viewModel.updateTaskListName(list.copy(name = editedName))
|
||||
isInEditMode = false
|
||||
}) {
|
||||
Icon(Icons.Default.Check, contentDescription = "Save")
|
||||
}
|
||||
}
|
||||
IconButton(onClick = { viewModel.deleteTaskList(list.id!!) }) {
|
||||
Icon(Icons.Default.Delete, contentDescription = "Delete")
|
||||
}
|
||||
} else {
|
||||
Row {
|
||||
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onPrimaryContainer) {
|
||||
IconButton(onClick = { isInEditMode = true }) {
|
||||
Icon(Icons.Default.Edit, contentDescription = "Edit")
|
||||
}
|
||||
IconButton(onClick = { viewModel.deleteTaskList(list.id!!) }) {
|
||||
Icon(Icons.Default.Delete, contentDescription = "Delete")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,34 +100,6 @@ fun ManageListsScreen(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EditableListRow(
|
||||
list: TaskList,
|
||||
onNameChange: (String) -> Unit,
|
||||
//onTypeChange: (ListType) -> Unit,
|
||||
onDone: () -> Unit
|
||||
) {
|
||||
var name by remember { mutableStateOf(list.name) }
|
||||
//var type by remember { mutableStateOf(list.type) }
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.fillMaxWidth().padding(8.dp)
|
||||
) {
|
||||
TextField(
|
||||
value = name,
|
||||
onValueChange = { name = it },
|
||||
modifier = Modifier.weight(1f),
|
||||
singleLine = true
|
||||
)
|
||||
// TODO: implement type
|
||||
//DropdownSelector(selected = type, onSelect = { type = it; onTypeChange(it) })
|
||||
IconButton(onClick = onDone) {
|
||||
Icon(Icons.Default.Check, contentDescription = "Save")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun AddListBottomSheet(
|
||||
@@ -122,11 +121,21 @@ fun AddListBottomSheet(
|
||||
Text("Create New List", style = MaterialTheme.typography.titleMedium)
|
||||
|
||||
Spacer(Modifier.height(8.dp))
|
||||
TextField(
|
||||
/*TextField(
|
||||
value = name,
|
||||
onValueChange = { name = it },
|
||||
label = { Text("List Name") },
|
||||
singleLine = true
|
||||
)*/
|
||||
OutlinedTextField(
|
||||
value = name,
|
||||
singleLine = true,
|
||||
onValueChange = { name = it },
|
||||
label = { Text("Title") },
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.focusRequester(titleFocusRequester),
|
||||
isError = name.isEmpty(),
|
||||
)
|
||||
|
||||
Spacer(Modifier.height(8.dp))
|
||||
@@ -142,8 +151,8 @@ fun AddListBottomSheet(
|
||||
|
||||
Spacer(Modifier.height(16.dp))
|
||||
Row(horizontalArrangement = Arrangement.End, modifier = Modifier.fillMaxWidth()) {
|
||||
TextButton(onClick = onDismiss) { Text("Cancel") }
|
||||
Spacer(Modifier.width(8.dp))
|
||||
//TextButton(onClick = onDismiss) { Text("Cancel") }
|
||||
//Spacer(Modifier.width(8.dp))
|
||||
Button(onClick = {
|
||||
viewModel.createTaskList(name/*, type, description*/, 1)
|
||||
onDismiss()
|
||||
|
@@ -5,6 +5,7 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.navigation.NavBackStackEntry
|
||||
import com.wismna.geoffroy.donext.domain.model.AppDestination
|
||||
import com.wismna.geoffroy.donext.domain.usecase.GetTaskListsUseCase
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
@@ -23,6 +24,15 @@ class MainViewModel @Inject constructor(
|
||||
var destinations by mutableStateOf<List<AppDestination>>(emptyList())
|
||||
private set
|
||||
|
||||
var startDestination by mutableStateOf<AppDestination>(AppDestination.ManageLists)
|
||||
private set
|
||||
|
||||
var currentDestination by mutableStateOf(startDestination)
|
||||
private set
|
||||
|
||||
var showTaskSheet by mutableStateOf(false)
|
||||
var showAddListSheet by mutableStateOf(false)
|
||||
|
||||
init {
|
||||
getTaskLists()
|
||||
.onEach { lists ->
|
||||
@@ -30,17 +40,20 @@ class MainViewModel @Inject constructor(
|
||||
AppDestination.TaskList(taskList.id!!, taskList.name)
|
||||
} + AppDestination.ManageLists
|
||||
isLoading = false
|
||||
if (!destinations.isEmpty()) startDestination = destinations.first()
|
||||
}
|
||||
.launchIn(viewModelScope)
|
||||
}
|
||||
|
||||
fun deriveDestination(route: String?): AppDestination? {
|
||||
if (route == null) return null
|
||||
return destinations.firstOrNull { dest ->
|
||||
fun setCurrentDestination(navBackStackEntry: NavBackStackEntry?) {
|
||||
val route = navBackStackEntry?.destination?.route
|
||||
val taskListId = navBackStackEntry?.arguments?.getLong("taskListId")
|
||||
|
||||
currentDestination = destinations.firstOrNull { dest ->
|
||||
when (dest) {
|
||||
is AppDestination.TaskList -> route.startsWith("tasklist/")
|
||||
is AppDestination.TaskList -> taskListId != null && dest.taskListId == taskListId
|
||||
else -> dest.route == route
|
||||
}
|
||||
}
|
||||
} ?: startDestination
|
||||
}
|
||||
}
|
@@ -9,6 +9,7 @@ import com.wismna.geoffroy.donext.domain.model.TaskList
|
||||
import com.wismna.geoffroy.donext.domain.usecase.AddTaskListUseCase
|
||||
import com.wismna.geoffroy.donext.domain.usecase.DeleteTaskListUseCase
|
||||
import com.wismna.geoffroy.donext.domain.usecase.GetTaskListsUseCase
|
||||
import com.wismna.geoffroy.donext.domain.usecase.UpdateTaskListUseCase
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
@@ -19,6 +20,7 @@ import javax.inject.Inject
|
||||
class ManageListsViewModel @Inject constructor(
|
||||
getTaskListsUseCase: GetTaskListsUseCase,
|
||||
private val addTaskListUseCase: AddTaskListUseCase,
|
||||
private val updateTaskListUseCase: UpdateTaskListUseCase,
|
||||
private val deleteTaskListUseCase: DeleteTaskListUseCase
|
||||
) : ViewModel() {
|
||||
|
||||
@@ -38,6 +40,11 @@ class ManageListsViewModel @Inject constructor(
|
||||
addTaskListUseCase(title, order)
|
||||
}
|
||||
}
|
||||
fun updateTaskListName(taskList: TaskList) {
|
||||
viewModelScope.launch {
|
||||
updateTaskListUseCase(taskList.id!!, taskList.name, taskList.order)
|
||||
}
|
||||
}
|
||||
fun deleteTaskList(taskId: Long) {
|
||||
viewModelScope.launch {
|
||||
deleteTaskListUseCase(taskId)
|
||||
|
Reference in New Issue
Block a user