From 4c0aef85cbfaf66823b977b0541ad40559710bcb Mon Sep 17 00:00:00 2001 From: chindaronit Date: Sat, 18 Jul 2026 13:32:20 +0530 Subject: [PATCH] fix: bug in instance clearance for todo, when reminder time changes. src: consistency maintenance for todo to save just like notes --- README.md | 10 ++- .../main/java/com/flux/data/dao/TodoDao.kt | 5 +- .../java/com/flux/data/dao/TodoInstanceDao.kt | 5 +- .../com/flux/ui/screens/todo/NewTodoList.kt | 71 ++++++++++++------- 4 files changed, 53 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index bbfcb77..68023b8 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ English, Hindi, French, Portugal (Brazil), Russian, German, Spanish, Dutch, Chin ## 🛠️ Architecture - **MVI**: Model View ViewModel -- + ## 📦 Installation To build and run this application, you need to install the latest version of Android Studio. Then, @@ -98,12 +98,10 @@ In Android Studio, select `Run > Run 'app'` to start the application. Any form of contribution is welcome! If you find a bug or have a new feature request, please create an issue. If you want to contribute code directly to this project, you can create a pull request. + +## Credits +
- -## Credits. - -[![Stargazers over time](https://starchart.cc/chindaronit/Flux.svg?variant=adaptive)](https://starchart.cc/chindaronit/Flux) - diff --git a/app/src/main/java/com/flux/data/dao/TodoDao.kt b/app/src/main/java/com/flux/data/dao/TodoDao.kt index 5893e0b..0dfa179 100644 --- a/app/src/main/java/com/flux/data/dao/TodoDao.kt +++ b/app/src/main/java/com/flux/data/dao/TodoDao.kt @@ -2,9 +2,8 @@ package com.flux.data.dao import androidx.room.Dao import androidx.room.Delete -import androidx.room.Insert -import androidx.room.OnConflictStrategy import androidx.room.Query +import androidx.room.Upsert import com.flux.data.model.TodoModel import kotlinx.coroutines.flow.Flow @@ -13,7 +12,7 @@ interface TodoDao { @Query("SELECT EXISTS(SELECT 1 FROM TodoModel WHERE id = :id)") suspend fun exists(id: String): Boolean - @Insert(onConflict = OnConflictStrategy.REPLACE) + @Upsert suspend fun upsertList(list: TodoModel) @Delete diff --git a/app/src/main/java/com/flux/data/dao/TodoInstanceDao.kt b/app/src/main/java/com/flux/data/dao/TodoInstanceDao.kt index eadb073..14c19d1 100644 --- a/app/src/main/java/com/flux/data/dao/TodoInstanceDao.kt +++ b/app/src/main/java/com/flux/data/dao/TodoInstanceDao.kt @@ -1,9 +1,8 @@ package com.flux.data.dao import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy import androidx.room.Query +import androidx.room.Upsert import com.flux.data.model.TodoInstance import kotlinx.coroutines.flow.Flow @@ -24,7 +23,7 @@ interface TodoInstanceDao { @Query("SELECT * FROM TodoInstance WHERE instanceDate = :date and todoId = :todoId") fun observeInstanceForDate(todoId: String, date: Long): Flow> - @Insert(onConflict = OnConflictStrategy.REPLACE) + @Upsert suspend fun upsertTodoInstance(instance: TodoInstance) @Query("DELETE FROM TodoInstance WHERE todoId = :listId") diff --git a/app/src/main/java/com/flux/ui/screens/todo/NewTodoList.kt b/app/src/main/java/com/flux/ui/screens/todo/NewTodoList.kt index f2451dc..d7e3fb0 100644 --- a/app/src/main/java/com/flux/ui/screens/todo/NewTodoList.kt +++ b/app/src/main/java/com/flux/ui/screens/todo/NewTodoList.kt @@ -1,5 +1,7 @@ package com.flux.ui.screens.todo +import android.widget.Toast +import androidx.activity.compose.BackHandler import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row @@ -15,7 +17,6 @@ import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Alarm -import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.Lock import androidx.compose.material.icons.filled.LockOpen import androidx.compose.material.icons.filled.Menu @@ -28,6 +29,7 @@ import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold +import androidx.compose.material3.SnackbarDuration import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarResult @@ -81,7 +83,6 @@ fun NewTodoList( val deleteQueue = remember { Channel>(Channel.UNLIMITED) } - // True = normal editing mode (locked ordering) // False = reorder mode (unlocked ordering, drag handles visible) var isReordering by remember { mutableStateOf(false) } @@ -113,7 +114,8 @@ fun NewTodoList( val result = snackbarHostState.showSnackbar( message = itemRemovedLabel, - actionLabel = undoLabel + actionLabel = undoLabel, + duration = SnackbarDuration.Short ) if (result == SnackbarResult.ActionPerformed) { @@ -123,6 +125,40 @@ fun NewTodoList( } } + fun saveTodoIfPossible(): Boolean { + val hasContent = title.isNotBlank() || itemList.isNotEmpty() + + if (!hasContent) { return true } + + if (title.isBlank()) { + Toast.makeText(context, "Title is Required", Toast.LENGTH_SHORT).show() + return false + } + + onTodoEvents( + TodoEvents.UpsertList( + context, + list.recurrence is RecurrenceRule.Weekly && recurrence is RecurrenceRule.NONE, + list.copy( + title = title, + items = itemList.toList(), + workspaceId = workspaceId, + recurrence = recurrence, + startDateTime = reminderTime + ) + ) + ) + + return true + } + + BackHandler { + if (saveTodoIfPossible()) { + isReordering = false + navController.popBackStack() + } + } + Scaffold( modifier = Modifier.imePadding(), snackbarHost = { SnackbarHost(hostState = snackbarHostState) }, @@ -154,7 +190,12 @@ fun NewTodoList( ) }, navigationIcon = { - IconButton({ navController.popBackStack() }) { + IconButton({ + if (saveTodoIfPossible()) { + isReordering = false + navController.popBackStack() + } + }) { Icon(Icons.AutoMirrored.Default.ArrowBack, null) } }, @@ -168,28 +209,6 @@ fun NewTodoList( IconButton(onClick = { isReordering = !isReordering }) { Icon(if(!isReordering) Icons.Default.Lock else Icons.Default.LockOpen, null) } - - // ✓ in edit mode: persist everything to ViewModel - IconButton( - enabled = title.isNotBlank(), - onClick = { - onTodoEvents( - TodoEvents.UpsertList( - context, - list.recurrence is RecurrenceRule.Weekly && recurrence is RecurrenceRule.NONE, - list.copy( - title = title, - items = itemList.toList(), - workspaceId = workspaceId, - recurrence = recurrence, - startDateTime = reminderTime - ) - ) - ) - isReordering = false - navController.popBackStack() - } - ) { Icon(Icons.Default.Check, null) } } ) }