TrackDateSelectorScreen: Use M3 date picker (#9138)

This commit is contained in:
Ivan Iskandar
2023-02-25 03:22:23 +07:00
committed by GitHub
parent 83a4e34095
commit ec3ce74af8
3 changed files with 185 additions and 140 deletions

View File

@@ -77,7 +77,9 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.time.Instant
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.ZoneOffset
data class TrackInfoDialogHomeScreen(
private val mangaId: Long,
@@ -432,7 +434,6 @@ private data class TrackDateSelectorScreen(
start = start,
)
}
val state by sm.state.collectAsState()
val canRemove = if (start) {
track.started_reading_date > 0
@@ -445,22 +446,35 @@ private data class TrackDateSelectorScreen(
} else {
stringResource(R.string.track_finished_reading_date)
},
minDate = if (!start && track.started_reading_date > 0) {
// Disallow end date to be set earlier than start date
Instant.ofEpochMilli(track.started_reading_date).atZone(ZoneId.systemDefault()).toLocalDate()
} else {
null
initialSelectedDateMillis = sm.initialSelection,
dateValidator = { utcMillis ->
val dateToCheck = Instant.ofEpochMilli(utcMillis)
.atZone(ZoneOffset.systemDefault())
.toLocalDate()
if (dateToCheck > LocalDate.now()) {
// Disallow future dates
return@TrackDateSelector false
}
if (start && track.finished_reading_date > 0) {
// Disallow start date to be set later than finish date
val dateFinished = Instant.ofEpochMilli(track.finished_reading_date)
.atZone(ZoneId.systemDefault())
.toLocalDate()
dateToCheck <= dateFinished
} else if (!start && track.started_reading_date > 0) {
// Disallow end date to be set earlier than start date
val dateStarted = Instant.ofEpochMilli(track.started_reading_date)
.atZone(ZoneId.systemDefault())
.toLocalDate()
dateToCheck >= dateStarted
} else {
// Nothing set before
true
}
},
maxDate = if (start && track.finished_reading_date > 0) {
// Disallow start date to be set later than finish date
Instant.ofEpochMilli(track.finished_reading_date).atZone(ZoneId.systemDefault()).toLocalDate()
} else {
// Disallow future dates
LocalDate.now()
},
selection = state.selection,
onSelectionChange = sm::setSelection,
onConfirm = { sm.setDate(); navigator.pop() },
onConfirm = { sm.setDate(it); navigator.pop() },
onRemove = { sm.confirmRemoveDate(navigator) }.takeIf { canRemove },
onDismissRequest = navigator::pop,
)
@@ -470,32 +484,26 @@ private data class TrackDateSelectorScreen(
private val track: Track,
private val service: TrackService,
private val start: Boolean,
) : StateScreenModel<Model.State>(
State(
(if (start) track.started_reading_date else track.finished_reading_date)
.takeIf { it != 0L }
?.let {
Instant.ofEpochMilli(it)
.atZone(ZoneId.systemDefault())
.toLocalDate()
}
?: LocalDate.now(),
),
) {
) : ScreenModel {
fun setSelection(selection: LocalDate) {
mutableState.update { it.copy(selection = selection) }
}
// In UTC
val initialSelection: Long
get() {
val millis = (if (start) track.started_reading_date else track.finished_reading_date)
.takeIf { it != 0L }
?: Instant.now().toEpochMilli()
return convertEpochMillisZone(millis, ZoneOffset.systemDefault(), ZoneOffset.UTC)
}
fun setDate() {
// In UTC
fun setDate(millis: Long) {
// Convert to local time
val localMillis = convertEpochMillisZone(millis, ZoneOffset.UTC, ZoneOffset.systemDefault())
coroutineScope.launchNonCancellable {
val millis = state.value.selection.atStartOfDay(ZoneId.systemDefault())
.toInstant()
.toEpochMilli()
if (start) {
service.setRemoteStartDate(track, millis)
service.setRemoteStartDate(track, localMillis)
} else {
service.setRemoteFinishDate(track, millis)
service.setRemoteFinishDate(track, localMillis)
}
}
}
@@ -503,10 +511,19 @@ private data class TrackDateSelectorScreen(
fun confirmRemoveDate(navigator: Navigator) {
navigator.push(TrackDateRemoverScreen(track, service.id, start))
}
}
data class State(
val selection: LocalDate,
)
companion object {
private fun convertEpochMillisZone(
localMillis: Long,
from: ZoneId,
to: ZoneId,
): Long {
return LocalDateTime.ofInstant(Instant.ofEpochMilli(localMillis), from)
.atZone(to)
.toInstant()
.toEpochMilli()
}
}
}