Compose DatePicker
This commit is contained in:
1 parent
85bb9b9f97
commit
2ed957b5f2
4 files changed
+88
-33
No files matched your search
@@ -268,6 +268,7 @@ dependencies {
|
||||
implementation(libs.bundles.kotlinx.serialization)
|
||||
|
||||
implementation(libs.kotlinx.coroutines.android)
|
||||
implementation(libs.kotlinx.datetime)
|
||||
implementation(libs.jsoup)
|
||||
|
||||
debugImplementation(libs.chucker)
|
||||
|
||||
@@ -42,6 +42,7 @@ import androidx.compose.material.icons.filled.Translate
|
||||
import androidx.compose.material.icons.outlined.Bookmarks
|
||||
import androidx.compose.material3.DismissDirection
|
||||
import androidx.compose.material3.DismissValue
|
||||
import androidx.compose.material3.DisplayMode
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
@@ -50,6 +51,7 @@ import androidx.compose.material3.LeadingIconTab
|
||||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.PrimaryTabRow
|
||||
import androidx.compose.material3.SelectableDates
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
|
||||
@@ -97,12 +99,6 @@ import androidx.paging.PagingSource
|
||||
import androidx.paging.PagingState
|
||||
import androidx.paging.cachedIn
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import com.google.android.material.datepicker.CalendarConstraints
|
||||
import com.google.android.material.datepicker.CalendarConstraints.DateValidator
|
||||
import com.google.android.material.datepicker.CompositeDateValidator
|
||||
import com.google.android.material.datepicker.DateValidatorPointBackward
|
||||
import com.google.android.material.datepicker.DateValidatorPointForward
|
||||
import com.google.android.material.datepicker.MaterialDatePicker
|
||||
import com.hippo.ehviewer.EhDB
|
||||
import com.hippo.ehviewer.R
|
||||
import com.hippo.ehviewer.Settings
|
||||
@@ -159,15 +155,18 @@ import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||
import java.io.File
|
||||
import java.time.Instant
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
import java.time.ZoneOffset
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.Locale
|
||||
import kotlin.math.roundToInt
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.datetime.DateTimeUnit
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.datetime.LocalDate
|
||||
import kotlinx.datetime.TimeZone
|
||||
import kotlinx.datetime.atStartOfDayIn
|
||||
import kotlinx.datetime.minus
|
||||
import kotlinx.datetime.toLocalDateTime
|
||||
import kotlinx.datetime.todayIn
|
||||
import moe.tarsin.coroutines.runSuspendCatching
|
||||
import sh.calvin.reorderable.ReorderableItem
|
||||
import sh.calvin.reorderable.rememberReorderableLazyColumnState
|
||||
@@ -837,27 +836,28 @@ fun GalleryListScreen(lub: ListUrlBuilder, navigator: DestinationsNavigator) {
|
||||
urlBuilder.setJumpTo(text)
|
||||
data.refresh()
|
||||
} else {
|
||||
val local = LocalDateTime.of(2007, 3, 21, 0, 0)
|
||||
val fromDate =
|
||||
local.atZone(ZoneId.ofOffset("UTC", ZoneOffset.UTC)).toInstant().toEpochMilli()
|
||||
val toDate = MaterialDatePicker.todayInUtcMilliseconds()
|
||||
val listValidators = ArrayList<DateValidator>()
|
||||
listValidators.add(DateValidatorPointForward.from(fromDate))
|
||||
listValidators.add(DateValidatorPointBackward.before(toDate))
|
||||
val constraintsBuilder = CalendarConstraints.Builder()
|
||||
.setStart(fromDate)
|
||||
.setEnd(toDate)
|
||||
.setValidator(CompositeDateValidator.allOf(listValidators))
|
||||
val datePicker = MaterialDatePicker.Builder.datePicker()
|
||||
.setCalendarConstraints(constraintsBuilder.build())
|
||||
.setTitleText(R.string.go_to)
|
||||
.setSelection(toDate)
|
||||
.build()
|
||||
datePicker.show(activity.supportFragmentManager, "date-picker")
|
||||
datePicker.addOnPositiveButtonClickListener { time ->
|
||||
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.US).withZone(ZoneOffset.UTC)
|
||||
val jumpTo = formatter.format(Instant.ofEpochMilli(time))
|
||||
urlBuilder.mJumpTo = jumpTo
|
||||
val initial = LocalDate(2007, 3, 21)
|
||||
val yesterday = Clock.System.todayIn(TimeZone.UTC).minus(1, DateTimeUnit.DAY)
|
||||
val initialMillis = initial.atStartOfDayIn(TimeZone.UTC).toEpochMilliseconds()
|
||||
val yesterdayMillis = yesterday.atStartOfDayIn(TimeZone.UTC).toEpochMilliseconds()
|
||||
val dateRange = initialMillis..yesterdayMillis
|
||||
coroutineScope.launch {
|
||||
// TODO: Enable picker mode
|
||||
// https://issuetracker.google.com/issues/306193893
|
||||
val dateMillis = dialogState.showDatePicker(
|
||||
title = R.string.go_to,
|
||||
yearRange = initial.year..yesterday.year,
|
||||
initialDisplayMode = DisplayMode.Input,
|
||||
selectableDates = object : SelectableDates {
|
||||
override fun isSelectableDate(utcTimeMillis: Long): Boolean {
|
||||
return utcTimeMillis in dateRange
|
||||
}
|
||||
},
|
||||
showModeToggle = false,
|
||||
)
|
||||
urlBuilder.mJumpTo = dateMillis?.let {
|
||||
Instant.fromEpochMilliseconds(it).toLocalDateTime(TimeZone.UTC).date.toString()
|
||||
}
|
||||
data.refresh()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.defaultMinSize
|
||||
@@ -22,6 +23,10 @@ import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.AlertDialogDefaults
|
||||
import androidx.compose.material3.BasicAlertDialog
|
||||
import androidx.compose.material3.Checkbox
|
||||
import androidx.compose.material3.DatePicker
|
||||
import androidx.compose.material3.DatePickerDefaults
|
||||
import androidx.compose.material3.DatePickerDialog
|
||||
import androidx.compose.material3.DisplayMode
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.ListItem
|
||||
@@ -29,12 +34,14 @@ import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.RadioButton
|
||||
import androidx.compose.material3.SelectableDates
|
||||
import androidx.compose.material3.ShapeDefaults
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.material3.TextFieldDefaults
|
||||
import androidx.compose.material3.rememberDatePickerState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
@@ -270,6 +277,50 @@ class DialogState {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun showDatePicker(
|
||||
@StringRes title: Int,
|
||||
initialSelectedDateMillis: Long? = null,
|
||||
initialDisplayedMonthMillis: Long? = initialSelectedDateMillis,
|
||||
yearRange: IntRange = DatePickerDefaults.YearRange,
|
||||
initialDisplayMode: DisplayMode = DisplayMode.Picker,
|
||||
selectableDates: SelectableDates = DatePickerDefaults.AllDates,
|
||||
showModeToggle: Boolean = true,
|
||||
): Long? {
|
||||
return dialog { cont ->
|
||||
val state = rememberDatePickerState(
|
||||
initialSelectedDateMillis,
|
||||
initialDisplayedMonthMillis,
|
||||
yearRange,
|
||||
initialDisplayMode,
|
||||
selectableDates,
|
||||
)
|
||||
DatePickerDialog(
|
||||
onDismissRequest = { cont.cancel() },
|
||||
confirmButton = {
|
||||
TextButton(onClick = { cont.resume(state.selectedDateMillis) }) {
|
||||
Text(text = stringResource(id = android.R.string.ok))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = { cont.cancel() }) {
|
||||
Text(text = stringResource(id = android.R.string.cancel))
|
||||
}
|
||||
},
|
||||
) {
|
||||
DatePicker(
|
||||
state = state,
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(id = title),
|
||||
modifier = Modifier.padding(DatePickerTitlePadding),
|
||||
)
|
||||
},
|
||||
showModeToggle = showModeToggle,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun <R> showNoButton(respectDefaultWidth: Boolean = true, block: @Composable DismissDialogScope<R>.() -> Unit): R {
|
||||
return dialog { cont ->
|
||||
val impl = remember(cont) {
|
||||
@@ -483,5 +534,6 @@ class DialogState {
|
||||
}
|
||||
|
||||
private val IconWithTextCorner = RoundedCornerShape(8.dp)
|
||||
private val DatePickerTitlePadding = PaddingValues(start = 24.dp, end = 12.dp, top = 16.dp)
|
||||
|
||||
val LocalDialogState = compositionLocalOf<DialogState> { error("CompositionLocal LocalDialogState not present!") }
|
||||
@@ -29,6 +29,7 @@ google-accompanist = "0.32.0"
|
||||
google-android-material = "1.12.0-alpha01"
|
||||
kotlin = "2.0.0-Beta1"
|
||||
kotlinx-coroutines = "1.7.3"
|
||||
kotlinx-datetime = "0.4.1"
|
||||
kotlinx-serialization = "1.6.1"
|
||||
ksp = "2.0.0-Beta1-1.0.14"
|
||||
ktlint = "1.0.1"
|
||||
@@ -105,6 +106,7 @@ insetter = "dev.chrisbanes.insetter:insetter:0.6.1"
|
||||
jsoup = "org.jsoup:jsoup:1.17.1"
|
||||
|
||||
kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" }
|
||||
kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" }
|
||||
kotlinx-serialization-cbor = { module = "org.jetbrains.kotlinx:kotlinx-serialization-cbor", version.ref = "kotlinx-serialization" }
|
||||
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" }
|
||||
kotlinx-serialization-json-okio = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json-okio", version.ref = "kotlinx-serialization" }
|
||||
|
||||
Reference in new issue
Block a user