From 4522296cf19720abd95d7a53e1a6e29f739724c9 Mon Sep 17 00:00:00 2001
From: Geoffroy Bonneville <24917789+wismna@users.noreply.github.com>
Date: Thu, 25 Sep 2025 20:46:24 -0400
Subject: [PATCH] Fix date issues Change primary theme color
---
.idea/caches/deviceStreaming.xml | 12 -----------
.../geoffroy/donext/data/local/Database.kt | 2 +-
.../geoffroy/donext/domain/extension/Date.kt | 10 +++++++++
.../presentation/screen/ManageListsScreen.kt | 18 +++++++++-------
.../donext/presentation/screen/TaskScreen.kt | 21 ++++++++-----------
.../donext/presentation/ui/theme/Color.kt | 2 +-
.../donext/presentation/ui/theme/Theme.kt | 2 +-
.../viewmodel/ManageListsViewModel.kt | 4 ++++
.../viewmodel/TaskItemViewModel.kt | 8 +++----
.../presentation/viewmodel/TaskViewModel.kt | 15 +++++++++++--
10 files changed, 52 insertions(+), 42 deletions(-)
create mode 100644 donextv2/src/main/java/com/wismna/geoffroy/donext/domain/extension/Date.kt
diff --git a/.idea/caches/deviceStreaming.xml b/.idea/caches/deviceStreaming.xml
index 17b82fc..d7710a0 100644
--- a/.idea/caches/deviceStreaming.xml
+++ b/.idea/caches/deviceStreaming.xml
@@ -366,18 +366,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/donextv2/src/main/java/com/wismna/geoffroy/donext/data/local/Database.kt b/donextv2/src/main/java/com/wismna/geoffroy/donext/data/local/Database.kt
index bb45566..2011acb 100644
--- a/donextv2/src/main/java/com/wismna/geoffroy/donext/data/local/Database.kt
+++ b/donextv2/src/main/java/com/wismna/geoffroy/donext/data/local/Database.kt
@@ -125,8 +125,8 @@ abstract class AppDatabase : RoomDatabase() {
// insert default lists
CoroutineScope(Dispatchers.IO).launch {
val dao = DB_INSTANCE?.taskListDao()
- dao?.insertTaskList(TaskListEntity(name = "Work", order = 2))
dao?.insertTaskList(TaskListEntity(name = "Personal", order = 1))
+ dao?.insertTaskList(TaskListEntity(name = "Work", order = 2))
dao?.insertTaskList(TaskListEntity(name = "Shopping", order = 3))
}
}
diff --git a/donextv2/src/main/java/com/wismna/geoffroy/donext/domain/extension/Date.kt b/donextv2/src/main/java/com/wismna/geoffroy/donext/domain/extension/Date.kt
new file mode 100644
index 0000000..b7abec7
--- /dev/null
+++ b/donextv2/src/main/java/com/wismna/geoffroy/donext/domain/extension/Date.kt
@@ -0,0 +1,10 @@
+package com.wismna.geoffroy.donext.domain.extension
+
+import java.time.Instant
+import java.time.LocalDate
+import java.time.ZoneId
+
+fun Long.toLocalDate(): LocalDate =
+ Instant.ofEpochMilli(this)
+ .atZone(ZoneId.systemDefault())
+ .toLocalDate()
diff --git a/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/screen/ManageListsScreen.kt b/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/screen/ManageListsScreen.kt
index 9685425..78b4909 100644
--- a/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/screen/ManageListsScreen.kt
+++ b/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/screen/ManageListsScreen.kt
@@ -218,7 +218,7 @@ fun AddListBottomSheet(
//var description by remember { mutableStateOf("") }
Column(modifier = Modifier.padding(16.dp)) {
- Text("Create New List", style = MaterialTheme.typography.titleMedium)
+ Text("New List", style = MaterialTheme.typography.titleMedium)
Spacer(Modifier.height(8.dp))
/*TextField(
@@ -234,8 +234,7 @@ fun AddListBottomSheet(
label = { Text("Title") },
modifier = Modifier
.fillMaxWidth()
- .focusRequester(titleFocusRequester),
- isError = name.isEmpty(),
+ .focusRequester(titleFocusRequester)
)
Spacer(Modifier.height(8.dp))
@@ -253,11 +252,14 @@ fun AddListBottomSheet(
Row(horizontalArrangement = Arrangement.End, modifier = Modifier.fillMaxWidth()) {
//TextButton(onClick = onDismiss) { Text("Cancel") }
//Spacer(Modifier.width(8.dp))
- Button(onClick = {
- viewModel.createTaskList(name/*, type, description*/, 1)
- onDismiss()
- }) {
- Text("Add")
+ Button(
+ onClick = {
+ viewModel.createTaskList(name/*, type, description*/, viewModel.taskCount + 1)
+ onDismiss()
+ },
+ enabled = name.isNotBlank()
+ ) {
+ Text("Create")
}
}
}
diff --git a/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/screen/TaskScreen.kt b/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/screen/TaskScreen.kt
index af36967..19d7903 100644
--- a/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/screen/TaskScreen.kt
+++ b/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/screen/TaskScreen.kt
@@ -38,9 +38,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.unit.dp
+import com.wismna.geoffroy.donext.domain.extension.toLocalDate
import com.wismna.geoffroy.donext.domain.model.Priority
import com.wismna.geoffroy.donext.presentation.viewmodel.TaskViewModel
-import java.time.Instant
import java.time.LocalDate
import java.time.ZoneId
import java.time.ZoneOffset
@@ -76,8 +76,7 @@ fun TaskBottomSheet(
label = { Text("Title") },
modifier = Modifier
.fillMaxWidth()
- .focusRequester(titleFocusRequester),
- isError = viewModel.title.isEmpty(),
+ .focusRequester(titleFocusRequester)
)
Spacer(Modifier.height(12.dp))
@@ -107,12 +106,9 @@ fun TaskBottomSheet(
// --- Due Date ---
var showDatePicker by remember { mutableStateOf(false) }
- val formattedDate = viewModel.dueDate?.let {
- Instant.ofEpochMilli(it)
- .atZone(ZoneId.systemDefault())
- .toLocalDate()
- .format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM))
- } ?: ""
+ val formattedDate = viewModel.dueDate?.toLocalDate()?.format(
+ DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM))
+ ?: ""
OutlinedTextField(
value = formattedDate,
@@ -143,11 +139,11 @@ fun TaskBottomSheet(
initialSelectedDateMillis = viewModel.dueDate,
selectableDates = object: SelectableDates {
override fun isSelectableDate(utcTimeMillis: Long): Boolean {
- val todayStartMillis = LocalDate.now(ZoneOffset.UTC)
+ val todayStartUtcMillis = LocalDate.now(ZoneId.systemDefault())
.atStartOfDay(ZoneOffset.UTC)
.toInstant()
.toEpochMilli()
- return utcTimeMillis >= todayStartMillis
+ return utcTimeMillis >= todayStartUtcMillis
}
}
)
@@ -155,7 +151,8 @@ fun TaskBottomSheet(
DatePickerDialog(
onDismissRequest = { showDatePicker = false },
confirmButton = {
- TextButton(onClick = {
+ TextButton(
+ onClick = {
datePickerState.selectedDateMillis?.let { viewModel.onDueDateChanged(it) }
showDatePicker = false
}) { Text("OK") }
diff --git a/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/ui/theme/Color.kt b/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/ui/theme/Color.kt
index 8d64a10..54737c0 100644
--- a/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/ui/theme/Color.kt
+++ b/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/ui/theme/Color.kt
@@ -3,7 +3,7 @@ package com.wismna.geoffroy.donext.presentation.ui.theme
import androidx.compose.ui.graphics.Color
// Primary shades
-val Purple80 = Color(0xFFD0BCFF) // Light theme primary
+val Purple80 = Color(0xFF6A59C7) // Light theme primary
val Purple40 = Color(0xFF6650A4) // Dark theme primary
val PurpleGrey80 = Color(0xFFCCC2DC)
diff --git a/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/ui/theme/Theme.kt b/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/ui/theme/Theme.kt
index 4eefde5..a0724a5 100644
--- a/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/ui/theme/Theme.kt
+++ b/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/ui/theme/Theme.kt
@@ -48,7 +48,7 @@ fun DoNextTheme(
else -> lightColorScheme(
primary = Purple80,
- onPrimary = DarkSurfaceContainer,
+ onPrimary = LightSurfaceContainer,
primaryContainer = Purple80Container,
onPrimaryContainer = DarkSurfaceContainer,
secondary = PurpleGrey80,
diff --git a/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/viewmodel/ManageListsViewModel.kt b/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/viewmodel/ManageListsViewModel.kt
index a53af14..c638699 100644
--- a/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/viewmodel/ManageListsViewModel.kt
+++ b/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/viewmodel/ManageListsViewModel.kt
@@ -1,6 +1,7 @@
package com.wismna.geoffroy.donext.presentation.viewmodel
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
@@ -26,11 +27,14 @@ class ManageListsViewModel @Inject constructor(
var taskLists by mutableStateOf>(emptyList())
private set
+ var taskCount by mutableIntStateOf(0)
+ private set
init {
getTaskListsUseCase()
.onEach { lists ->
taskLists = lists
+ taskCount = lists.size
}
.launchIn(viewModelScope)
}
diff --git a/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/viewmodel/TaskItemViewModel.kt b/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/viewmodel/TaskItemViewModel.kt
index 4480993..491905d 100644
--- a/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/viewmodel/TaskItemViewModel.kt
+++ b/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/viewmodel/TaskItemViewModel.kt
@@ -1,8 +1,8 @@
package com.wismna.geoffroy.donext.presentation.viewmodel
+import com.wismna.geoffroy.donext.domain.extension.toLocalDate
import com.wismna.geoffroy.donext.domain.model.Priority
import com.wismna.geoffroy.donext.domain.model.Task
-import java.time.Instant
import java.time.LocalDate
import java.time.ZoneId
import java.time.format.DateTimeFormatter
@@ -21,16 +21,14 @@ class TaskItemViewModel(task: Task) {
val today: LocalDate = LocalDate.now(ZoneId.systemDefault())
val isOverdue: Boolean = task.dueDate?.let { millis ->
- val dueDate = Instant.ofEpochMilli(millis)
- .atZone(ZoneId.systemDefault())
- .toLocalDate()
+ val dueDate = millis.toLocalDate()
dueDate.isBefore(today)
} ?: false
val dueDateText: String? = task.dueDate?.let { formatDueDate(it) }
private fun formatDueDate(dueMillis: Long): String {
- val dueDate = Instant.ofEpochMilli(dueMillis).atZone(ZoneId.systemDefault()).toLocalDate()
+ val dueDate = dueMillis.toLocalDate()
return when {
dueDate.isEqual(today) -> "Today"
diff --git a/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/viewmodel/TaskViewModel.kt b/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/viewmodel/TaskViewModel.kt
index b9ecf63..d8596b5 100644
--- a/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/viewmodel/TaskViewModel.kt
+++ b/donextv2/src/main/java/com/wismna/geoffroy/donext/presentation/viewmodel/TaskViewModel.kt
@@ -12,6 +12,9 @@ import com.wismna.geoffroy.donext.domain.usecase.ToggleTaskDeletedUseCase
import com.wismna.geoffroy.donext.domain.usecase.UpdateTaskUseCase
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
+import java.time.Instant
+import java.time.ZoneId
+import java.time.ZoneOffset
import javax.inject.Inject
@HiltViewModel
@@ -59,9 +62,17 @@ class TaskViewModel @Inject constructor(
fun onTitleChanged(value: String) { title = value }
fun onDescriptionChanged(value: String) { description = value }
fun onPriorityChanged(value: Priority) { priority = value }
- fun onDueDateChanged(value: Long?) { dueDate = value }
+ fun onDueDateChanged(value: Long?) {
+ dueDate = if (value == null) null else
+ Instant.ofEpochMilli(value)
+ .atZone(ZoneOffset.UTC)
+ .toLocalDate()
+ .atStartOfDay(ZoneId.systemDefault())
+ .toInstant()
+ .toEpochMilli()
+ }
- fun save(onDone: (() -> Unit)? = null) {
+ fun save(onDone: (() -> Unit)? = null) {
if (title.isBlank()) return
viewModelScope.launch {