mirror of https://github.com/tasks/tasks
StartDateRow now works in Compose
parent
9808ca1745
commit
a779500095
@ -0,0 +1,138 @@
|
||||
package org.tasks.compose.pickers
|
||||
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.rememberDatePickerState
|
||||
import androidx.compose.material3.rememberModalBottomSheetState
|
||||
import androidx.compose.material3.rememberTimePickerState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import org.tasks.data.entity.Task
|
||||
import org.tasks.date.DateTimeUtils.newDateTime
|
||||
import org.tasks.dialogs.BaseDateTimePicker
|
||||
import org.tasks.dialogs.StartDatePicker.Companion.DUE_DATE
|
||||
import org.tasks.dialogs.StartDatePicker.Companion.DUE_TIME
|
||||
import org.tasks.extensions.Context.is24HourFormat
|
||||
import org.tasks.preferences.Preferences
|
||||
import org.tasks.time.DateTime
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun StartDateTimePicker (
|
||||
selectedDay: Long,
|
||||
selectedTime: Int,
|
||||
updateValues: (Long, Int) -> Unit,
|
||||
accept: () -> Unit,
|
||||
dismiss: () -> Unit,
|
||||
autoclose: Boolean,
|
||||
showDueDate: Boolean,
|
||||
onDismissHandler: BaseDateTimePicker.OnDismissHandler? = null
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val preferences = remember { Preferences(context) }
|
||||
val state = rememberDatePickerState(
|
||||
initialDisplayMode = remember { preferences.calendarDisplayMode },
|
||||
)
|
||||
|
||||
val today = remember { newDateTime().startOfDay() }
|
||||
|
||||
fun returnDate(day: Long = selectedDay, time: Int = selectedTime) {
|
||||
if (day != selectedDay || time != selectedTime) {
|
||||
updateValues(day, time)
|
||||
}
|
||||
if (autoclose) accept()
|
||||
}
|
||||
|
||||
fun returnSelectedTime(millisOfDay: Int) {
|
||||
val day = when {
|
||||
selectedDay == DUE_TIME -> DUE_DATE
|
||||
selectedDay != 0L -> selectedDay
|
||||
today.withMillisOfDay(millisOfDay).isAfterNow -> today.millis
|
||||
else -> today.plusDays(1).millis
|
||||
}
|
||||
returnDate(day = day, time = millisOfDay)
|
||||
}
|
||||
|
||||
DatePickerBottomSheet(
|
||||
sheetState = rememberModalBottomSheetState(
|
||||
skipPartiallyExpanded = true
|
||||
),
|
||||
state = state,
|
||||
showButtons = !autoclose,
|
||||
setDisplayMode = { preferences.calendarDisplayMode = it },
|
||||
cancel = { dismiss(); onDismissHandler?.onDismiss() },
|
||||
accept = accept,
|
||||
dateShortcuts = {
|
||||
StartDateShortcuts(
|
||||
selected = selectedDay,
|
||||
selectedDay = { returnDate(it) },
|
||||
selectedDayTime = { day, time -> returnDate(day, time) },
|
||||
showDueDate = showDueDate,
|
||||
clearDate = { returnDate(day = 0, time = 0) },
|
||||
)
|
||||
},
|
||||
timeShortcuts = {
|
||||
var showTimePicker by rememberSaveable { mutableStateOf(false) }
|
||||
if (showTimePicker) {
|
||||
val time = if (selectedTime < 0 || !Task.hasDueTime(
|
||||
today.withMillisOfDay(selectedTime).millis
|
||||
)
|
||||
) {
|
||||
today.noon().millisOfDay
|
||||
} else {
|
||||
selectedTime
|
||||
}
|
||||
TimePickerDialog(
|
||||
state = rememberTimePickerState(
|
||||
initialHour = time / (60 * 60_000),
|
||||
initialMinute = (time / (60_000)) % 60,
|
||||
is24Hour = LocalContext.current.is24HourFormat
|
||||
),
|
||||
initialDisplayMode = remember { preferences.timeDisplayMode },
|
||||
setDisplayMode = { preferences.timeDisplayMode = it },
|
||||
selected = { returnSelectedTime(it + 1000) },
|
||||
dismiss = { showTimePicker = false }
|
||||
)
|
||||
}
|
||||
TimeShortcuts(
|
||||
day = selectedDay,
|
||||
selected = selectedTime,
|
||||
morning = remember { preferences.dateShortcutMorning + 1000 },
|
||||
afternoon = remember { preferences.dateShortcutAfternoon + 1000 },
|
||||
evening = remember { preferences.dateShortcutEvening + 1000 },
|
||||
night = remember { preferences.dateShortcutNight + 1000 },
|
||||
selectedMillisOfDay = { returnSelectedTime(it) },
|
||||
pickTime = { showTimePicker = true },
|
||||
clearTime = {
|
||||
returnDate(
|
||||
day = when (selectedDay) {
|
||||
DUE_TIME -> DUE_DATE
|
||||
else -> selectedDay
|
||||
},
|
||||
time = 0
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
LaunchedEffect(selectedDay) {
|
||||
if (selectedDay > 0) {
|
||||
state.selectedDateMillis = selectedDay + (DateTime(selectedDay).offset)
|
||||
} else {
|
||||
state.selectedDateMillis = null
|
||||
}
|
||||
}
|
||||
LaunchedEffect(state.selectedDateMillis) {
|
||||
if (state.selectedDateMillis == selectedDay + (DateTime(selectedDay).offset)) {
|
||||
return@LaunchedEffect
|
||||
}
|
||||
state.selectedDateMillis?.let {
|
||||
returnDate(day = it - DateTime(it).offset)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue