mirror of
https://github.com/wismna/DoNext.git
synced 2025-12-06 00:02:40 -05:00
Added undo snackbar for list deletion
Made all destinations show the menu instead of the back button (for now)
This commit is contained in:
@@ -13,16 +13,16 @@ sealed class AppDestination(
|
|||||||
object DueTodayList : AppDestination(
|
object DueTodayList : AppDestination(
|
||||||
route = "todayList",
|
route = "todayList",
|
||||||
title = "Due Today",
|
title = "Due Today",
|
||||||
showBackButton = true,
|
showBackButton = false,
|
||||||
)
|
)
|
||||||
object ManageLists : AppDestination(
|
object ManageLists : AppDestination(
|
||||||
route = "manageLists",
|
route = "manageLists",
|
||||||
title = "Manage Lists",
|
title = "Manage Lists",
|
||||||
showBackButton = true,
|
showBackButton = false,
|
||||||
)
|
)
|
||||||
object RecycleBin : AppDestination(
|
object RecycleBin : AppDestination(
|
||||||
route = "recycleBin",
|
route = "recycleBin",
|
||||||
title = "Recycle Bin",
|
title = "Recycle Bin",
|
||||||
showBackButton = true,
|
showBackButton = false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import javax.inject.Inject
|
|||||||
class DeleteTaskListUseCase@Inject constructor(
|
class DeleteTaskListUseCase@Inject constructor(
|
||||||
private val repository: TaskRepository
|
private val repository: TaskRepository
|
||||||
) {
|
) {
|
||||||
suspend operator fun invoke(taskListId: Long) {
|
suspend operator fun invoke(taskListId: Long, isDeleted: Boolean) {
|
||||||
repository.deleteTaskList(taskListId, true)
|
repository.deleteTaskList(taskListId, isDeleted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,10 +6,12 @@ import androidx.compose.animation.fadeOut
|
|||||||
import androidx.compose.animation.togetherWith
|
import androidx.compose.animation.togetherWith
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
@@ -62,6 +64,18 @@ fun ManageListsScreen(
|
|||||||
showAddListSheet: () -> Unit
|
showAddListSheet: () -> Unit
|
||||||
) {
|
) {
|
||||||
var lists = viewModel.taskLists.toMutableList()
|
var lists = viewModel.taskLists.toMutableList()
|
||||||
|
|
||||||
|
if (lists.isEmpty()) {
|
||||||
|
// Placeholder when no task lists exist
|
||||||
|
Box(
|
||||||
|
modifier = modifier.fillMaxSize(),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Text("Tap + to create a new task list.")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val lazyListState = rememberLazyListState()
|
val lazyListState = rememberLazyListState()
|
||||||
val reorderState = rememberReorderableLazyListState(
|
val reorderState = rememberReorderableLazyListState(
|
||||||
lazyListState = lazyListState,
|
lazyListState = lazyListState,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.wismna.geoffroy.donext.presentation.screen
|
package com.wismna.geoffroy.donext.presentation.screen
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
@@ -12,8 +12,8 @@ import androidx.compose.material3.HorizontalDivider
|
|||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
import com.wismna.geoffroy.donext.presentation.viewmodel.TaskListViewModel
|
import com.wismna.geoffroy.donext.presentation.viewmodel.TaskListViewModel
|
||||||
@@ -27,12 +27,11 @@ fun TaskListScreen(
|
|||||||
|
|
||||||
if (tasks.isEmpty()) {
|
if (tasks.isEmpty()) {
|
||||||
// Placeholder when recycle bin is empty
|
// Placeholder when recycle bin is empty
|
||||||
Column (
|
Box(
|
||||||
modifier = modifier.fillMaxSize().padding(10.dp),
|
modifier = modifier.fillMaxSize(),
|
||||||
Arrangement.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
Text("Nothing here!", modifier.fillMaxWidth(), textAlign = TextAlign.Center)
|
Text("Tap + to create a new task.")
|
||||||
Text("Add tasks with the Create Task button", modifier.fillMaxWidth(), textAlign = TextAlign.Center)
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class DueTodayViewModel @Inject constructor(
|
|||||||
|
|
||||||
uiEventBus.send(
|
uiEventBus.send(
|
||||||
UiEvent.ShowUndoSnackbar(
|
UiEvent.ShowUndoSnackbar(
|
||||||
message = "Task moved to trash",
|
message = "Task moved to recycle bin",
|
||||||
undoAction = {
|
undoAction = {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
toggleTaskDeletedUseCase(taskId, false)
|
toggleTaskDeletedUseCase(taskId, false)
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import com.wismna.geoffroy.donext.domain.usecase.AddTaskListUseCase
|
|||||||
import com.wismna.geoffroy.donext.domain.usecase.DeleteTaskListUseCase
|
import com.wismna.geoffroy.donext.domain.usecase.DeleteTaskListUseCase
|
||||||
import com.wismna.geoffroy.donext.domain.usecase.GetTaskListsUseCase
|
import com.wismna.geoffroy.donext.domain.usecase.GetTaskListsUseCase
|
||||||
import com.wismna.geoffroy.donext.domain.usecase.UpdateTaskListUseCase
|
import com.wismna.geoffroy.donext.domain.usecase.UpdateTaskListUseCase
|
||||||
|
import com.wismna.geoffroy.donext.presentation.ui.events.UiEvent
|
||||||
|
import com.wismna.geoffroy.donext.presentation.ui.events.UiEventBus
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
@@ -22,7 +24,8 @@ class ManageListsViewModel @Inject constructor(
|
|||||||
getTaskListsUseCase: GetTaskListsUseCase,
|
getTaskListsUseCase: GetTaskListsUseCase,
|
||||||
private val addTaskListUseCase: AddTaskListUseCase,
|
private val addTaskListUseCase: AddTaskListUseCase,
|
||||||
private val updateTaskListUseCase: UpdateTaskListUseCase,
|
private val updateTaskListUseCase: UpdateTaskListUseCase,
|
||||||
private val deleteTaskListUseCase: DeleteTaskListUseCase
|
private val deleteTaskListUseCase: DeleteTaskListUseCase,
|
||||||
|
private val uiEventBus: UiEventBus
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
var taskLists by mutableStateOf<List<TaskList>>(emptyList())
|
var taskLists by mutableStateOf<List<TaskList>>(emptyList())
|
||||||
@@ -51,7 +54,18 @@ class ManageListsViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
fun deleteTaskList(taskListId: Long) {
|
fun deleteTaskList(taskListId: Long) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
deleteTaskListUseCase(taskListId)
|
deleteTaskListUseCase(taskListId, true)
|
||||||
|
|
||||||
|
uiEventBus.send(
|
||||||
|
UiEvent.ShowUndoSnackbar(
|
||||||
|
message = "Task list moved to recycle bin",
|
||||||
|
undoAction = {
|
||||||
|
viewModelScope.launch {
|
||||||
|
deleteTaskListUseCase(taskListId, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class TaskListViewModel @Inject constructor(
|
|||||||
|
|
||||||
uiEventBus.send(
|
uiEventBus.send(
|
||||||
UiEvent.ShowUndoSnackbar(
|
UiEvent.ShowUndoSnackbar(
|
||||||
message = "Task moved to trash",
|
message = "Task moved to recycle bin",
|
||||||
undoAction = {
|
undoAction = {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
toggleTaskDeletedUseCase(taskId, false)
|
toggleTaskDeletedUseCase(taskId, false)
|
||||||
|
|||||||
Reference in New Issue
Block a user