mirror of
https://github.com/wismna/DoNext.git
synced 2025-10-03 23:50:13 -04:00
Fix date issues
Change primary theme color
This commit is contained in:
12
.idea/caches/deviceStreaming.xml
generated
12
.idea/caches/deviceStreaming.xml
generated
@@ -366,18 +366,6 @@
|
|||||||
<option name="screenX" value="384" />
|
<option name="screenX" value="384" />
|
||||||
<option name="screenY" value="384" />
|
<option name="screenY" value="384" />
|
||||||
</PersistentDeviceSelectionData>
|
</PersistentDeviceSelectionData>
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="35" />
|
|
||||||
<option name="brand" value="motorola" />
|
|
||||||
<option name="codename" value="eqe" />
|
|
||||||
<option name="id" value="eqe" />
|
|
||||||
<option name="labId" value="google" />
|
|
||||||
<option name="manufacturer" value="Motorola" />
|
|
||||||
<option name="name" value="edge 50 pro" />
|
|
||||||
<option name="screenDensity" value="450" />
|
|
||||||
<option name="screenX" value="1220" />
|
|
||||||
<option name="screenY" value="2712" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
<PersistentDeviceSelectionData>
|
||||||
<option name="api" value="33" />
|
<option name="api" value="33" />
|
||||||
<option name="brand" value="google" />
|
<option name="brand" value="google" />
|
||||||
|
@@ -125,8 +125,8 @@ abstract class AppDatabase : RoomDatabase() {
|
|||||||
// insert default lists
|
// insert default lists
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
val dao = DB_INSTANCE?.taskListDao()
|
val dao = DB_INSTANCE?.taskListDao()
|
||||||
dao?.insertTaskList(TaskListEntity(name = "Work", order = 2))
|
|
||||||
dao?.insertTaskList(TaskListEntity(name = "Personal", order = 1))
|
dao?.insertTaskList(TaskListEntity(name = "Personal", order = 1))
|
||||||
|
dao?.insertTaskList(TaskListEntity(name = "Work", order = 2))
|
||||||
dao?.insertTaskList(TaskListEntity(name = "Shopping", order = 3))
|
dao?.insertTaskList(TaskListEntity(name = "Shopping", order = 3))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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()
|
@@ -218,7 +218,7 @@ fun AddListBottomSheet(
|
|||||||
//var description by remember { mutableStateOf("") }
|
//var description by remember { mutableStateOf("") }
|
||||||
|
|
||||||
Column(modifier = Modifier.padding(16.dp)) {
|
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))
|
Spacer(Modifier.height(8.dp))
|
||||||
/*TextField(
|
/*TextField(
|
||||||
@@ -234,8 +234,7 @@ fun AddListBottomSheet(
|
|||||||
label = { Text("Title") },
|
label = { Text("Title") },
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.focusRequester(titleFocusRequester),
|
.focusRequester(titleFocusRequester)
|
||||||
isError = name.isEmpty(),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(Modifier.height(8.dp))
|
Spacer(Modifier.height(8.dp))
|
||||||
@@ -253,11 +252,14 @@ fun AddListBottomSheet(
|
|||||||
Row(horizontalArrangement = Arrangement.End, modifier = Modifier.fillMaxWidth()) {
|
Row(horizontalArrangement = Arrangement.End, modifier = Modifier.fillMaxWidth()) {
|
||||||
//TextButton(onClick = onDismiss) { Text("Cancel") }
|
//TextButton(onClick = onDismiss) { Text("Cancel") }
|
||||||
//Spacer(Modifier.width(8.dp))
|
//Spacer(Modifier.width(8.dp))
|
||||||
Button(onClick = {
|
Button(
|
||||||
viewModel.createTaskList(name/*, type, description*/, 1)
|
onClick = {
|
||||||
|
viewModel.createTaskList(name/*, type, description*/, viewModel.taskCount + 1)
|
||||||
onDismiss()
|
onDismiss()
|
||||||
}) {
|
},
|
||||||
Text("Add")
|
enabled = name.isNotBlank()
|
||||||
|
) {
|
||||||
|
Text("Create")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.unit.dp
|
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.domain.model.Priority
|
||||||
import com.wismna.geoffroy.donext.presentation.viewmodel.TaskViewModel
|
import com.wismna.geoffroy.donext.presentation.viewmodel.TaskViewModel
|
||||||
import java.time.Instant
|
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.ZoneId
|
import java.time.ZoneId
|
||||||
import java.time.ZoneOffset
|
import java.time.ZoneOffset
|
||||||
@@ -76,8 +76,7 @@ fun TaskBottomSheet(
|
|||||||
label = { Text("Title") },
|
label = { Text("Title") },
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.focusRequester(titleFocusRequester),
|
.focusRequester(titleFocusRequester)
|
||||||
isError = viewModel.title.isEmpty(),
|
|
||||||
)
|
)
|
||||||
Spacer(Modifier.height(12.dp))
|
Spacer(Modifier.height(12.dp))
|
||||||
|
|
||||||
@@ -107,12 +106,9 @@ fun TaskBottomSheet(
|
|||||||
|
|
||||||
// --- Due Date ---
|
// --- Due Date ---
|
||||||
var showDatePicker by remember { mutableStateOf(false) }
|
var showDatePicker by remember { mutableStateOf(false) }
|
||||||
val formattedDate = viewModel.dueDate?.let {
|
val formattedDate = viewModel.dueDate?.toLocalDate()?.format(
|
||||||
Instant.ofEpochMilli(it)
|
DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM))
|
||||||
.atZone(ZoneId.systemDefault())
|
?: ""
|
||||||
.toLocalDate()
|
|
||||||
.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM))
|
|
||||||
} ?: ""
|
|
||||||
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = formattedDate,
|
value = formattedDate,
|
||||||
@@ -143,11 +139,11 @@ fun TaskBottomSheet(
|
|||||||
initialSelectedDateMillis = viewModel.dueDate,
|
initialSelectedDateMillis = viewModel.dueDate,
|
||||||
selectableDates = object: SelectableDates {
|
selectableDates = object: SelectableDates {
|
||||||
override fun isSelectableDate(utcTimeMillis: Long): Boolean {
|
override fun isSelectableDate(utcTimeMillis: Long): Boolean {
|
||||||
val todayStartMillis = LocalDate.now(ZoneOffset.UTC)
|
val todayStartUtcMillis = LocalDate.now(ZoneId.systemDefault())
|
||||||
.atStartOfDay(ZoneOffset.UTC)
|
.atStartOfDay(ZoneOffset.UTC)
|
||||||
.toInstant()
|
.toInstant()
|
||||||
.toEpochMilli()
|
.toEpochMilli()
|
||||||
return utcTimeMillis >= todayStartMillis
|
return utcTimeMillis >= todayStartUtcMillis
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -155,7 +151,8 @@ fun TaskBottomSheet(
|
|||||||
DatePickerDialog(
|
DatePickerDialog(
|
||||||
onDismissRequest = { showDatePicker = false },
|
onDismissRequest = { showDatePicker = false },
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
TextButton(onClick = {
|
TextButton(
|
||||||
|
onClick = {
|
||||||
datePickerState.selectedDateMillis?.let { viewModel.onDueDateChanged(it) }
|
datePickerState.selectedDateMillis?.let { viewModel.onDueDateChanged(it) }
|
||||||
showDatePicker = false
|
showDatePicker = false
|
||||||
}) { Text("OK") }
|
}) { Text("OK") }
|
||||||
|
@@ -3,7 +3,7 @@ package com.wismna.geoffroy.donext.presentation.ui.theme
|
|||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
||||||
// Primary shades
|
// Primary shades
|
||||||
val Purple80 = Color(0xFFD0BCFF) // Light theme primary
|
val Purple80 = Color(0xFF6A59C7) // Light theme primary
|
||||||
val Purple40 = Color(0xFF6650A4) // Dark theme primary
|
val Purple40 = Color(0xFF6650A4) // Dark theme primary
|
||||||
|
|
||||||
val PurpleGrey80 = Color(0xFFCCC2DC)
|
val PurpleGrey80 = Color(0xFFCCC2DC)
|
||||||
|
@@ -48,7 +48,7 @@ fun DoNextTheme(
|
|||||||
|
|
||||||
else -> lightColorScheme(
|
else -> lightColorScheme(
|
||||||
primary = Purple80,
|
primary = Purple80,
|
||||||
onPrimary = DarkSurfaceContainer,
|
onPrimary = LightSurfaceContainer,
|
||||||
primaryContainer = Purple80Container,
|
primaryContainer = Purple80Container,
|
||||||
onPrimaryContainer = DarkSurfaceContainer,
|
onPrimaryContainer = DarkSurfaceContainer,
|
||||||
secondary = PurpleGrey80,
|
secondary = PurpleGrey80,
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package com.wismna.geoffroy.donext.presentation.viewmodel
|
package com.wismna.geoffroy.donext.presentation.viewmodel
|
||||||
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
@@ -26,11 +27,14 @@ class ManageListsViewModel @Inject constructor(
|
|||||||
|
|
||||||
var taskLists by mutableStateOf<List<TaskList>>(emptyList())
|
var taskLists by mutableStateOf<List<TaskList>>(emptyList())
|
||||||
private set
|
private set
|
||||||
|
var taskCount by mutableIntStateOf(0)
|
||||||
|
private set
|
||||||
|
|
||||||
init {
|
init {
|
||||||
getTaskListsUseCase()
|
getTaskListsUseCase()
|
||||||
.onEach { lists ->
|
.onEach { lists ->
|
||||||
taskLists = lists
|
taskLists = lists
|
||||||
|
taskCount = lists.size
|
||||||
}
|
}
|
||||||
.launchIn(viewModelScope)
|
.launchIn(viewModelScope)
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
package com.wismna.geoffroy.donext.presentation.viewmodel
|
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.Priority
|
||||||
import com.wismna.geoffroy.donext.domain.model.Task
|
import com.wismna.geoffroy.donext.domain.model.Task
|
||||||
import java.time.Instant
|
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.ZoneId
|
import java.time.ZoneId
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
@@ -21,16 +21,14 @@ class TaskItemViewModel(task: Task) {
|
|||||||
val today: LocalDate = LocalDate.now(ZoneId.systemDefault())
|
val today: LocalDate = LocalDate.now(ZoneId.systemDefault())
|
||||||
|
|
||||||
val isOverdue: Boolean = task.dueDate?.let { millis ->
|
val isOverdue: Boolean = task.dueDate?.let { millis ->
|
||||||
val dueDate = Instant.ofEpochMilli(millis)
|
val dueDate = millis.toLocalDate()
|
||||||
.atZone(ZoneId.systemDefault())
|
|
||||||
.toLocalDate()
|
|
||||||
dueDate.isBefore(today)
|
dueDate.isBefore(today)
|
||||||
} ?: false
|
} ?: false
|
||||||
|
|
||||||
val dueDateText: String? = task.dueDate?.let { formatDueDate(it) }
|
val dueDateText: String? = task.dueDate?.let { formatDueDate(it) }
|
||||||
|
|
||||||
private fun formatDueDate(dueMillis: Long): String {
|
private fun formatDueDate(dueMillis: Long): String {
|
||||||
val dueDate = Instant.ofEpochMilli(dueMillis).atZone(ZoneId.systemDefault()).toLocalDate()
|
val dueDate = dueMillis.toLocalDate()
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
dueDate.isEqual(today) -> "Today"
|
dueDate.isEqual(today) -> "Today"
|
||||||
|
@@ -12,6 +12,9 @@ import com.wismna.geoffroy.donext.domain.usecase.ToggleTaskDeletedUseCase
|
|||||||
import com.wismna.geoffroy.donext.domain.usecase.UpdateTaskUseCase
|
import com.wismna.geoffroy.donext.domain.usecase.UpdateTaskUseCase
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import java.time.Instant
|
||||||
|
import java.time.ZoneId
|
||||||
|
import java.time.ZoneOffset
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
@@ -59,7 +62,15 @@ class TaskViewModel @Inject constructor(
|
|||||||
fun onTitleChanged(value: String) { title = value }
|
fun onTitleChanged(value: String) { title = value }
|
||||||
fun onDescriptionChanged(value: String) { description = value }
|
fun onDescriptionChanged(value: String) { description = value }
|
||||||
fun onPriorityChanged(value: Priority) { priority = 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
|
if (title.isBlank()) return
|
||||||
|
Reference in New Issue
Block a user