Refactor use of Java.util.date to Java.time.*, to fix localized date issues. (#402)
* Add support for localdate based relative times * Update History Screen to use new localdate based relative times * Update Updates Screen to use new localdate based relative times * Cleaned up date util classes * Updated build time display * Code cleanup * Fixed crash in settings * Updated Preferences item * Worker Info works * Fixed Tracker date display * Code changes to pass detekt (cherry picked from commit 7ff95e21babda98dd1b479912278d6029cd15f0d) # Conflicts: # app/src/main/java/eu/kanade/tachiyomi/ui/history/HistoryScreenModel.kt # app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt # app/src/main/java/eu/kanade/tachiyomi/util/lang/DateExtensions.kt
This commit is contained in:
parent
1fe309f363
commit
6c6f09ac5a
@ -8,8 +8,8 @@ import eu.kanade.tachiyomi.util.system.DeviceUtil
|
|||||||
import eu.kanade.tachiyomi.util.system.isDynamicColorAvailable
|
import eu.kanade.tachiyomi.util.system.isDynamicColorAvailable
|
||||||
import tachiyomi.core.common.preference.PreferenceStore
|
import tachiyomi.core.common.preference.PreferenceStore
|
||||||
import tachiyomi.core.common.preference.getEnum
|
import tachiyomi.core.common.preference.getEnum
|
||||||
import java.text.DateFormat
|
import java.time.format.DateTimeFormatter
|
||||||
import java.text.SimpleDateFormat
|
import java.time.format.FormatStyle
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
class UiPreferences(
|
class UiPreferences(
|
||||||
@ -59,9 +59,9 @@ class UiPreferences(
|
|||||||
// SY <--
|
// SY <--
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun dateFormat(format: String): DateFormat = when (format) {
|
fun dateFormat(format: String): DateTimeFormatter = when (format) {
|
||||||
"" -> DateFormat.getDateInstance(DateFormat.SHORT)
|
"" -> DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
|
||||||
else -> SimpleDateFormat(format, Locale.getDefault())
|
else -> DateTimeFormatter.ofPattern(format, Locale.getDefault())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,8 @@ import tachiyomi.presentation.core.components.Badge
|
|||||||
import tachiyomi.presentation.core.components.BadgeGroup
|
import tachiyomi.presentation.core.components.BadgeGroup
|
||||||
import tachiyomi.presentation.core.components.material.padding
|
import tachiyomi.presentation.core.components.material.padding
|
||||||
import tachiyomi.presentation.core.i18n.stringResource
|
import tachiyomi.presentation.core.i18n.stringResource
|
||||||
import java.util.Date
|
import java.time.Instant
|
||||||
|
import java.time.ZoneId
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BrowseSourceEHentaiList(
|
fun BrowseSourceEHentaiList(
|
||||||
@ -128,9 +129,11 @@ fun BrowseSourceEHentaiListItem(
|
|||||||
}
|
}
|
||||||
val datePosted by produceState("", metadata) {
|
val datePosted by produceState("", metadata) {
|
||||||
value = withIOContext {
|
value = withIOContext {
|
||||||
runCatching { metadata.datePosted?.let { MetadataUtil.EX_DATE_FORMAT.format(Date(it)) } }
|
runCatching {
|
||||||
.getOrNull()
|
metadata.datePosted?.let {
|
||||||
.orEmpty()
|
MetadataUtil.EX_DATE_FORMAT.format(Instant.ofEpochMilli(it).atZone(ZoneId.systemDefault()))
|
||||||
|
}
|
||||||
|
}.getOrNull().orEmpty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val genre by produceState<Pair<GenreColor, StringResource>?>(null, metadata) {
|
val genre by produceState<Pair<GenreColor, StringResource>?>(null, metadata) {
|
||||||
|
@ -4,25 +4,31 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import eu.kanade.domain.ui.UiPreferences
|
import eu.kanade.domain.ui.UiPreferences
|
||||||
import eu.kanade.tachiyomi.util.lang.toRelativeString
|
import eu.kanade.tachiyomi.util.lang.toRelativeSting
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
import tachiyomi.presentation.core.i18n.stringResource
|
import tachiyomi.presentation.core.i18n.stringResource
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.Date
|
import java.time.Instant
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.ZoneId
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun relativeDateText(
|
fun relativeDateText(
|
||||||
dateEpochMillis: Long,
|
dateEpochMillis: Long,
|
||||||
): String {
|
): String {
|
||||||
return relativeDateText(
|
return relativeDateText(
|
||||||
date = Date(dateEpochMillis).takeIf { dateEpochMillis > 0L },
|
localDate = LocalDate.ofInstant(
|
||||||
|
Instant.ofEpochMilli(dateEpochMillis),
|
||||||
|
ZoneId.systemDefault(),
|
||||||
|
)
|
||||||
|
.takeIf { dateEpochMillis > 0L },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun relativeDateText(
|
fun relativeDateText(
|
||||||
date: Date?,
|
localDate: LocalDate?,
|
||||||
): String {
|
): String {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
@ -30,11 +36,10 @@ fun relativeDateText(
|
|||||||
val relativeTime = remember { preferences.relativeTime().get() }
|
val relativeTime = remember { preferences.relativeTime().get() }
|
||||||
val dateFormat = remember { UiPreferences.dateFormat(preferences.dateFormat().get()) }
|
val dateFormat = remember { UiPreferences.dateFormat(preferences.dateFormat().get()) }
|
||||||
|
|
||||||
return date
|
return localDate?.toRelativeSting(
|
||||||
?.toRelativeString(
|
context = context,
|
||||||
context = context,
|
relative = relativeTime,
|
||||||
relative = relativeTime,
|
dateFormat = dateFormat,
|
||||||
dateFormat = dateFormat,
|
)
|
||||||
)
|
|
||||||
?: stringResource(MR.strings.not_applicable)
|
?: stringResource(MR.strings.not_applicable)
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ import tachiyomi.presentation.core.components.material.Scaffold
|
|||||||
import tachiyomi.presentation.core.i18n.stringResource
|
import tachiyomi.presentation.core.i18n.stringResource
|
||||||
import tachiyomi.presentation.core.screens.EmptyScreen
|
import tachiyomi.presentation.core.screens.EmptyScreen
|
||||||
import tachiyomi.presentation.core.screens.LoadingScreen
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||||
import java.util.Date
|
import java.time.LocalDate
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun HistoryScreen(
|
fun HistoryScreen(
|
||||||
@ -134,7 +134,7 @@ private fun HistoryScreenContent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
sealed interface HistoryUiModel {
|
sealed interface HistoryUiModel {
|
||||||
data class Header(val date: Date) : HistoryUiModel
|
data class Header(val date: LocalDate) : HistoryUiModel
|
||||||
data class Item(val item: HistoryWithRelations) : HistoryUiModel
|
data class Item(val item: HistoryWithRelations) : HistoryUiModel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import kotlinx.collections.immutable.toImmutableList
|
|||||||
import tachiyomi.domain.history.model.HistoryWithRelations
|
import tachiyomi.domain.history.model.HistoryWithRelations
|
||||||
import tachiyomi.domain.manga.model.MangaCover
|
import tachiyomi.domain.manga.model.MangaCover
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
import java.time.LocalDate
|
||||||
import java.time.temporal.ChronoUnit
|
import java.time.temporal.ChronoUnit
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
@ -73,10 +74,10 @@ class HistoryScreenModelStateProvider : PreviewParameterProvider<HistoryScreenMo
|
|||||||
private object HistoryUiModelExamples {
|
private object HistoryUiModelExamples {
|
||||||
val headerToday = header()
|
val headerToday = header()
|
||||||
val headerTomorrow =
|
val headerTomorrow =
|
||||||
HistoryUiModel.Header(Date.from(Instant.now().plus(1, ChronoUnit.DAYS)))
|
HistoryUiModel.Header(LocalDate.now().plusDays(1))
|
||||||
|
|
||||||
fun header(instantBuilder: (Instant) -> Instant = { it }) =
|
fun header(instantBuilder: (Instant) -> Instant = { it }) =
|
||||||
HistoryUiModel.Header(Date.from(instantBuilder(Instant.now())))
|
HistoryUiModel.Header(LocalDate.from(instantBuilder(Instant.now())))
|
||||||
|
|
||||||
fun items() = sequence {
|
fun items() = sequence {
|
||||||
var count = 1
|
var count = 1
|
||||||
|
@ -106,7 +106,8 @@ import tachiyomi.presentation.core.util.isScrolledToEnd
|
|||||||
import tachiyomi.presentation.core.util.isScrollingUp
|
import tachiyomi.presentation.core.util.isScrollingUp
|
||||||
import tachiyomi.source.local.isLocal
|
import tachiyomi.source.local.isLocal
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.util.Date
|
import java.time.ZoneId
|
||||||
|
import java.time.ZonedDateTime
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MangaScreen(
|
fun MangaScreen(
|
||||||
@ -986,9 +987,10 @@ private fun LazyListScope.sharedChapterItems(
|
|||||||
?.let {
|
?.let {
|
||||||
// SY -->
|
// SY -->
|
||||||
if (manga.isEhBasedManga()) {
|
if (manga.isEhBasedManga()) {
|
||||||
MetadataUtil.EX_DATE_FORMAT.format(Date(it))
|
MetadataUtil.EX_DATE_FORMAT
|
||||||
|
.format(ZonedDateTime.ofInstant(Instant.ofEpochMilli(it), ZoneId.systemDefault()))
|
||||||
} else {
|
} else {
|
||||||
relativeDateText(Date(item.chapter.dateUpload))
|
relativeDateText(item.chapter.dateUpload)
|
||||||
}
|
}
|
||||||
// SY <--
|
// SY <--
|
||||||
},
|
},
|
||||||
|
@ -28,7 +28,7 @@ import tachiyomi.presentation.core.i18n.stringResource
|
|||||||
import tachiyomi.presentation.core.util.collectAsState
|
import tachiyomi.presentation.core.util.collectAsState
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.time.Instant
|
import java.time.LocalDate
|
||||||
|
|
||||||
object SettingsAppearanceScreen : SearchableSettings {
|
object SettingsAppearanceScreen : SearchableSettings {
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ object SettingsAppearanceScreen : SearchableSettings {
|
|||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
|
|
||||||
val now = remember { Instant.now().toEpochMilli() }
|
val now = remember { LocalDate.now() }
|
||||||
|
|
||||||
val dateFormat by uiPreferences.dateFormat().collectAsState()
|
val dateFormat by uiPreferences.dateFormat().collectAsState()
|
||||||
val formattedNow = remember(dateFormat) {
|
val formattedNow = remember(dateFormat) {
|
||||||
|
@ -56,10 +56,10 @@ import tachiyomi.presentation.core.icons.Reddit
|
|||||||
import tachiyomi.presentation.core.icons.X
|
import tachiyomi.presentation.core.icons.X
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.text.DateFormat
|
import java.time.LocalDateTime
|
||||||
import java.text.SimpleDateFormat
|
import java.time.ZoneId
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import java.util.TimeZone
|
|
||||||
|
|
||||||
object AboutScreen : Screen() {
|
object AboutScreen : Screen() {
|
||||||
|
|
||||||
@ -293,16 +293,9 @@ object AboutScreen : Screen() {
|
|||||||
|
|
||||||
internal fun getFormattedBuildTime(): String {
|
internal fun getFormattedBuildTime(): String {
|
||||||
return try {
|
return try {
|
||||||
val inputDf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'", Locale.US)
|
val df = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm'Z'", Locale.US)
|
||||||
inputDf.timeZone = TimeZone.getTimeZone("UTC")
|
.withZone(ZoneId.of("UTC"))
|
||||||
val buildTime = inputDf.parse(BuildConfig.BUILD_TIME)
|
val buildTime = LocalDateTime.from(df.parse(BuildConfig.BUILD_TIME))
|
||||||
|
|
||||||
val outputDf = DateFormat.getDateTimeInstance(
|
|
||||||
DateFormat.MEDIUM,
|
|
||||||
DateFormat.SHORT,
|
|
||||||
Locale.getDefault(),
|
|
||||||
)
|
|
||||||
outputDf.timeZone = TimeZone.getDefault()
|
|
||||||
|
|
||||||
buildTime!!.toDateTimestampString(UiPreferences.dateFormat(Injekt.get<UiPreferences>().dateFormat().get()))
|
buildTime!!.toDateTimestampString(UiPreferences.dateFormat(Injekt.get<UiPreferences>().dateFormat().get()))
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
@ -42,7 +42,9 @@ import tachiyomi.presentation.core.i18n.stringResource
|
|||||||
import tachiyomi.presentation.core.util.plus
|
import tachiyomi.presentation.core.util.plus
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.Date
|
import java.time.Instant
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.ZoneId
|
||||||
|
|
||||||
class WorkerInfoScreen : Screen() {
|
class WorkerInfoScreen : Screen() {
|
||||||
|
|
||||||
@ -149,11 +151,17 @@ class WorkerInfoScreen : Screen() {
|
|||||||
appendLine("State: ${workInfo.state}")
|
appendLine("State: ${workInfo.state}")
|
||||||
if (workInfo.state == WorkInfo.State.ENQUEUED) {
|
if (workInfo.state == WorkInfo.State.ENQUEUED) {
|
||||||
appendLine(
|
appendLine(
|
||||||
"Next scheduled run: ${Date(workInfo.nextScheduleTimeMillis).toDateTimestampString(
|
"Next scheduled run: ${
|
||||||
UiPreferences.dateFormat(
|
LocalDateTime.ofInstant(
|
||||||
Injekt.get<UiPreferences>().dateFormat().get(),
|
Instant.ofEpochMilli(workInfo.nextScheduleTimeMillis),
|
||||||
),
|
ZoneId.systemDefault(),
|
||||||
)}",
|
)
|
||||||
|
.toDateTimestampString(
|
||||||
|
UiPreferences.dateFormat(
|
||||||
|
Injekt.get<UiPreferences>().dateFormat().get(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}",
|
||||||
)
|
)
|
||||||
appendLine("Attempt #${workInfo.runAttemptCount + 1}")
|
appendLine("Attempt #${workInfo.runAttemptCount + 1}")
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,16 @@ import eu.kanade.presentation.manga.components.MangaChapterListItem
|
|||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
import eu.kanade.tachiyomi.ui.reader.chapter.ReaderChapterItem
|
import eu.kanade.tachiyomi.ui.reader.chapter.ReaderChapterItem
|
||||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
|
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
|
||||||
import eu.kanade.tachiyomi.util.lang.toRelativeString
|
import eu.kanade.tachiyomi.util.lang.toRelativeSting
|
||||||
import exh.metadata.MetadataUtil
|
import exh.metadata.MetadataUtil
|
||||||
import exh.source.isEhBasedManga
|
import exh.source.isEhBasedManga
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import tachiyomi.domain.chapter.model.Chapter
|
import tachiyomi.domain.chapter.model.Chapter
|
||||||
import tachiyomi.domain.library.service.LibraryPreferences
|
import tachiyomi.domain.library.service.LibraryPreferences
|
||||||
import java.util.Date
|
import java.time.Instant
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.ZoneId
|
||||||
|
import java.time.ZonedDateTime
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ChapterListDialog(
|
fun ChapterListDialog(
|
||||||
@ -56,9 +59,13 @@ fun ChapterListDialog(
|
|||||||
?.let {
|
?.let {
|
||||||
// SY -->
|
// SY -->
|
||||||
if (manga?.isEhBasedManga() == true) {
|
if (manga?.isEhBasedManga() == true) {
|
||||||
MetadataUtil.EX_DATE_FORMAT.format(Date(it))
|
MetadataUtil.EX_DATE_FORMAT
|
||||||
|
.format(ZonedDateTime.ofInstant(Instant.ofEpochMilli(it), ZoneId.systemDefault()))
|
||||||
} else {
|
} else {
|
||||||
Date(it).toRelativeString(context, dateRelativeTime, chapterItem.dateFormat)
|
LocalDate.ofInstant(
|
||||||
|
Instant.ofEpochMilli(it),
|
||||||
|
ZoneId.systemDefault(),
|
||||||
|
).toRelativeSting(context, dateRelativeTime, chapterItem.dateFormat)
|
||||||
}
|
}
|
||||||
// SY <--
|
// SY <--
|
||||||
},
|
},
|
||||||
|
@ -52,17 +52,18 @@ import eu.kanade.presentation.theme.TachiyomiPreviewTheme
|
|||||||
import eu.kanade.presentation.track.components.TrackLogoIcon
|
import eu.kanade.presentation.track.components.TrackLogoIcon
|
||||||
import eu.kanade.tachiyomi.data.track.Tracker
|
import eu.kanade.tachiyomi.data.track.Tracker
|
||||||
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
|
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
|
||||||
|
import eu.kanade.tachiyomi.util.lang.toLocalDate
|
||||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
import tachiyomi.presentation.core.i18n.stringResource
|
import tachiyomi.presentation.core.i18n.stringResource
|
||||||
import java.text.DateFormat
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
private const val UnsetStatusTextAlpha = 0.5F
|
private const val UnsetStatusTextAlpha = 0.5F
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TrackInfoDialogHome(
|
fun TrackInfoDialogHome(
|
||||||
trackItems: List<TrackItem>,
|
trackItems: List<TrackItem>,
|
||||||
dateFormat: DateFormat,
|
dateFormat: DateTimeFormatter,
|
||||||
onStatusClick: (TrackItem) -> Unit,
|
onStatusClick: (TrackItem) -> Unit,
|
||||||
onChapterClick: (TrackItem) -> Unit,
|
onChapterClick: (TrackItem) -> Unit,
|
||||||
onScoreClick: (TrackItem) -> Unit,
|
onScoreClick: (TrackItem) -> Unit,
|
||||||
@ -104,11 +105,11 @@ fun TrackInfoDialogHome(
|
|||||||
.takeIf { supportsScoring && item.track.score != 0.0 },
|
.takeIf { supportsScoring && item.track.score != 0.0 },
|
||||||
onScoreClick = { onScoreClick(item) }
|
onScoreClick = { onScoreClick(item) }
|
||||||
.takeIf { supportsScoring },
|
.takeIf { supportsScoring },
|
||||||
startDate = remember(item.track.startDate) { dateFormat.format(item.track.startDate) }
|
startDate = remember(item.track.startDate) { dateFormat.format(item.track.startDate.toLocalDate()) }
|
||||||
.takeIf { supportsReadingDates && item.track.startDate != 0L },
|
.takeIf { supportsReadingDates && item.track.startDate != 0L },
|
||||||
onStartDateClick = { onStartDateEdit(item) } // TODO
|
onStartDateClick = { onStartDateEdit(item) } // TODO
|
||||||
.takeIf { supportsReadingDates },
|
.takeIf { supportsReadingDates },
|
||||||
endDate = dateFormat.format(item.track.finishDate)
|
endDate = dateFormat.format(item.track.finishDate.toLocalDate())
|
||||||
.takeIf { supportsReadingDates && item.track.finishDate != 0L },
|
.takeIf { supportsReadingDates && item.track.finishDate != 0L },
|
||||||
onEndDateClick = { onEndDateEdit(item) }
|
onEndDateClick = { onEndDateEdit(item) }
|
||||||
.takeIf { supportsReadingDates },
|
.takeIf { supportsReadingDates },
|
||||||
|
@ -5,7 +5,8 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
|||||||
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
|
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
|
||||||
import eu.kanade.test.DummyTracker
|
import eu.kanade.test.DummyTracker
|
||||||
import tachiyomi.domain.track.model.Track
|
import tachiyomi.domain.track.model.Track
|
||||||
import java.text.DateFormat
|
import java.time.format.DateTimeFormatter
|
||||||
|
import java.time.format.FormatStyle
|
||||||
|
|
||||||
internal class TrackInfoDialogHomePreviewProvider :
|
internal class TrackInfoDialogHomePreviewProvider :
|
||||||
PreviewParameterProvider<@Composable () -> Unit> {
|
PreviewParameterProvider<@Composable () -> Unit> {
|
||||||
@ -46,7 +47,7 @@ internal class TrackInfoDialogHomePreviewProvider :
|
|||||||
trackItemWithoutTrack,
|
trackItemWithoutTrack,
|
||||||
trackItemWithTrack,
|
trackItemWithTrack,
|
||||||
),
|
),
|
||||||
dateFormat = DateFormat.getDateInstance(),
|
dateFormat = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM),
|
||||||
onStatusClick = {},
|
onStatusClick = {},
|
||||||
onChapterClick = {},
|
onChapterClick = {},
|
||||||
onScoreClick = {},
|
onScoreClick = {},
|
||||||
@ -61,7 +62,7 @@ internal class TrackInfoDialogHomePreviewProvider :
|
|||||||
private val noTrackers = @Composable {
|
private val noTrackers = @Composable {
|
||||||
TrackInfoDialogHome(
|
TrackInfoDialogHome(
|
||||||
trackItems = listOf(),
|
trackItems = listOf(),
|
||||||
dateFormat = DateFormat.getDateInstance(),
|
dateFormat = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM),
|
||||||
onStatusClick = {},
|
onStatusClick = {},
|
||||||
onChapterClick = {},
|
onChapterClick = {},
|
||||||
onScoreClick = {},
|
onScoreClick = {},
|
||||||
|
@ -36,7 +36,7 @@ import tachiyomi.presentation.core.components.material.Scaffold
|
|||||||
import tachiyomi.presentation.core.i18n.stringResource
|
import tachiyomi.presentation.core.i18n.stringResource
|
||||||
import tachiyomi.presentation.core.screens.EmptyScreen
|
import tachiyomi.presentation.core.screens.EmptyScreen
|
||||||
import tachiyomi.presentation.core.screens.LoadingScreen
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||||
import java.util.Date
|
import java.time.LocalDate
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -212,6 +212,6 @@ private fun UpdatesBottomBar(
|
|||||||
}
|
}
|
||||||
|
|
||||||
sealed interface UpdatesUiModel {
|
sealed interface UpdatesUiModel {
|
||||||
data class Header(val date: Date) : UpdatesUiModel
|
data class Header(val date: LocalDate) : UpdatesUiModel
|
||||||
data class Item(val item: UpdatesItem) : UpdatesUiModel
|
data class Item(val item: UpdatesItem) : UpdatesUiModel
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,8 @@ import uy.kohesive.injekt.injectLazy
|
|||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.net.URLEncoder
|
import java.net.URLEncoder
|
||||||
|
import java.time.ZoneOffset
|
||||||
|
import java.time.ZonedDateTime
|
||||||
|
|
||||||
// TODO Consider gallery updating when doing tabbed browsing
|
// TODO Consider gallery updating when doing tabbed browsing
|
||||||
class EHentai(
|
class EHentai(
|
||||||
@ -271,8 +273,9 @@ class EHentai(
|
|||||||
private fun getDateTag(element: Element?): Long? {
|
private fun getDateTag(element: Element?): Long? {
|
||||||
val text = element?.text()?.nullIfBlank()
|
val text = element?.text()?.nullIfBlank()
|
||||||
return if (text != null) {
|
return if (text != null) {
|
||||||
val date = MetadataUtil.EX_DATE_FORMAT.parse(text)
|
println(text)
|
||||||
date?.time
|
val date = ZonedDateTime.parse(text, MetadataUtil.EX_DATE_FORMAT.withZone(ZoneOffset.UTC))
|
||||||
|
date?.toInstant()?.toEpochMilli()
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
@ -376,11 +379,12 @@ class EHentai(
|
|||||||
url = EHentaiSearchMetadata.normalizeUrl(location),
|
url = EHentaiSearchMetadata.normalizeUrl(location),
|
||||||
name = "v1: " + doc.selectFirst("#gn")!!.text(),
|
name = "v1: " + doc.selectFirst("#gn")!!.text(),
|
||||||
chapter_number = 1f,
|
chapter_number = 1f,
|
||||||
date_upload = MetadataUtil.EX_DATE_FORMAT.parse(
|
date_upload = ZonedDateTime.parse(
|
||||||
doc.select("#gdd .gdt1").find { el ->
|
doc.select("#gdd .gdt1").find { el ->
|
||||||
el.text().lowercase() == "posted:"
|
el.text().lowercase() == "posted:"
|
||||||
}!!.nextElementSibling()!!.text(),
|
}!!.nextElementSibling()!!.text(),
|
||||||
)!!.time,
|
MetadataUtil.EX_DATE_FORMAT.withZone(ZoneOffset.UTC)
|
||||||
|
)!!.toInstant().toEpochMilli(),
|
||||||
scanlator = EHentaiSearchMetadata.galleryId(location),
|
scanlator = EHentaiSearchMetadata.galleryId(location),
|
||||||
)
|
)
|
||||||
// Build and append the rest of the galleries
|
// Build and append the rest of the galleries
|
||||||
@ -395,7 +399,10 @@ class EHentai(
|
|||||||
url = EHentaiSearchMetadata.normalizeUrl(link),
|
url = EHentaiSearchMetadata.normalizeUrl(link),
|
||||||
name = "v${index + 2}: $name",
|
name = "v${index + 2}: $name",
|
||||||
chapter_number = index + 2f,
|
chapter_number = index + 2f,
|
||||||
date_upload = MetadataUtil.EX_DATE_FORMAT.parse(posted)!!.time,
|
date_upload = ZonedDateTime.parse(
|
||||||
|
posted,
|
||||||
|
MetadataUtil.EX_DATE_FORMAT.withZone(ZoneOffset.UTC)
|
||||||
|
).toInstant().toEpochMilli(),
|
||||||
scanlator = EHentaiSearchMetadata.galleryId(link),
|
scanlator = EHentaiSearchMetadata.galleryId(link),
|
||||||
)
|
)
|
||||||
}.reversed() + self
|
}.reversed() + self
|
||||||
@ -706,7 +713,10 @@ class EHentai(
|
|||||||
if (left != null && right != null) {
|
if (left != null && right != null) {
|
||||||
ignore {
|
ignore {
|
||||||
when (left.removeSuffix(":").lowercase()) {
|
when (left.removeSuffix(":").lowercase()) {
|
||||||
"posted" -> datePosted = MetadataUtil.EX_DATE_FORMAT.parse(right)!!.time
|
"posted" -> datePosted = ZonedDateTime.parse(
|
||||||
|
right,
|
||||||
|
MetadataUtil.EX_DATE_FORMAT.withZone(ZoneOffset.UTC)
|
||||||
|
).toInstant().toEpochMilli()
|
||||||
// Example gallery with parent: https://e-hentai.org/g/1390451/7f181c2426/
|
// Example gallery with parent: https://e-hentai.org/g/1390451/7f181c2426/
|
||||||
// Example JP gallery: https://exhentai.org/g/1375385/03519d541b/
|
// Example JP gallery: https://exhentai.org/g/1375385/03519d541b/
|
||||||
// Parent is older variation of the gallery
|
// Parent is older variation of the gallery
|
||||||
|
@ -5,7 +5,7 @@ import cafe.adriel.voyager.core.model.StateScreenModel
|
|||||||
import cafe.adriel.voyager.core.model.screenModelScope
|
import cafe.adriel.voyager.core.model.screenModelScope
|
||||||
import eu.kanade.core.util.insertSeparators
|
import eu.kanade.core.util.insertSeparators
|
||||||
import eu.kanade.presentation.history.HistoryUiModel
|
import eu.kanade.presentation.history.HistoryUiModel
|
||||||
import eu.kanade.tachiyomi.util.lang.toDateKey
|
import eu.kanade.tachiyomi.util.lang.toLocalDate
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -30,7 +30,7 @@ import tachiyomi.domain.history.interactor.RemoveHistory
|
|||||||
import tachiyomi.domain.history.model.HistoryWithRelations
|
import tachiyomi.domain.history.model.HistoryWithRelations
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.Date
|
import java.time.LocalDate
|
||||||
|
|
||||||
class HistoryScreenModel(
|
class HistoryScreenModel(
|
||||||
private val getHistory: GetHistory = Injekt.get(),
|
private val getHistory: GetHistory = Injekt.get(),
|
||||||
@ -62,10 +62,12 @@ class HistoryScreenModel(
|
|||||||
private fun List<HistoryWithRelations>.toHistoryUiModels(): List<HistoryUiModel> {
|
private fun List<HistoryWithRelations>.toHistoryUiModels(): List<HistoryUiModel> {
|
||||||
return map { HistoryUiModel.Item(it) }
|
return map { HistoryUiModel.Item(it) }
|
||||||
.insertSeparators { before, after ->
|
.insertSeparators { before, after ->
|
||||||
val beforeDate = before?.item?.readAt?.time?.toDateKey() ?: Date(0)
|
val beforeDate = before?.item?.readAt?.time?.toLocalDate() ?: LocalDate.MIN
|
||||||
val afterDate = after?.item?.readAt?.time?.toDateKey() ?: Date(0)
|
val afterDate = after?.item?.readAt?.time?.toLocalDate() ?: LocalDate.MIN
|
||||||
when {
|
when {
|
||||||
beforeDate.time != afterDate.time && afterDate.time != 0L -> HistoryUiModel.Header(afterDate)
|
beforeDate.isAfter(afterDate)
|
||||||
|
or afterDate.equals(LocalDate.MIN)
|
||||||
|
or beforeDate.equals(LocalDate.MIN) -> HistoryUiModel.Header(afterDate)
|
||||||
// Return null to avoid adding a separator between two items.
|
// Return null to avoid adding a separator between two items.
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,11 @@ package eu.kanade.tachiyomi.ui.reader.chapter
|
|||||||
|
|
||||||
import tachiyomi.domain.chapter.model.Chapter
|
import tachiyomi.domain.chapter.model.Chapter
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import java.text.DateFormat
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
data class ReaderChapterItem(
|
data class ReaderChapterItem(
|
||||||
val chapter: Chapter,
|
val chapter: Chapter,
|
||||||
val manga: Manga,
|
val manga: Manga,
|
||||||
val isCurrent: Boolean,
|
val isCurrent: Boolean,
|
||||||
val dateFormat: DateFormat,
|
val dateFormat: DateTimeFormatter,
|
||||||
)
|
)
|
||||||
|
@ -17,7 +17,7 @@ import eu.kanade.tachiyomi.data.download.DownloadManager
|
|||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
|
||||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
|
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
|
||||||
import eu.kanade.tachiyomi.util.lang.toDateKey
|
import eu.kanade.tachiyomi.util.lang.toLocalDate
|
||||||
import exh.source.EH_SOURCE_ID
|
import exh.source.EH_SOURCE_ID
|
||||||
import exh.source.EXH_SOURCE_ID
|
import exh.source.EXH_SOURCE_ID
|
||||||
import kotlinx.collections.immutable.PersistentList
|
import kotlinx.collections.immutable.PersistentList
|
||||||
@ -48,8 +48,8 @@ import tachiyomi.domain.updates.interactor.GetUpdates
|
|||||||
import tachiyomi.domain.updates.model.UpdatesWithRelations
|
import tachiyomi.domain.updates.model.UpdatesWithRelations
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
import java.time.LocalDate
|
||||||
import java.time.ZonedDateTime
|
import java.time.ZonedDateTime
|
||||||
import java.util.Date
|
|
||||||
|
|
||||||
class UpdatesScreenModel(
|
class UpdatesScreenModel(
|
||||||
private val sourceManager: SourceManager = Injekt.get(),
|
private val sourceManager: SourceManager = Injekt.get(),
|
||||||
@ -386,12 +386,12 @@ class UpdatesScreenModel(
|
|||||||
return items
|
return items
|
||||||
.map { UpdatesUiModel.Item(it) }
|
.map { UpdatesUiModel.Item(it) }
|
||||||
.insertSeparators { before, after ->
|
.insertSeparators { before, after ->
|
||||||
val beforeDate = before?.item?.update?.dateFetch?.toDateKey() ?: Date(0)
|
val beforeDate = before?.item?.update?.dateFetch?.toLocalDate() ?: LocalDate.MIN
|
||||||
val afterDate = after?.item?.update?.dateFetch?.toDateKey() ?: Date(0)
|
val afterDate = after?.item?.update?.dateFetch?.toLocalDate() ?: LocalDate.MIN
|
||||||
when {
|
when {
|
||||||
beforeDate.time != afterDate.time && afterDate.time != 0L -> {
|
beforeDate.isAfter(afterDate)
|
||||||
UpdatesUiModel.Header(afterDate)
|
or afterDate.equals(LocalDate.MIN)
|
||||||
}
|
or beforeDate.equals(LocalDate.MIN) -> UpdatesUiModel.Header(afterDate)
|
||||||
// Return null to avoid adding a separator between two items.
|
// Return null to avoid adding a separator between two items.
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
@ -6,15 +6,17 @@ import tachiyomi.core.common.i18n.stringResource
|
|||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
import java.time.LocalDate
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.time.ZoneId
|
import java.time.ZoneId
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
import java.time.format.FormatStyle
|
||||||
import java.time.temporal.ChronoUnit
|
import java.time.temporal.ChronoUnit
|
||||||
import java.util.Calendar
|
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
fun Date.toDateTimestampString(dateFormatter: DateFormat): String {
|
fun LocalDateTime.toDateTimestampString(dateTimeFormatter: DateTimeFormatter): String {
|
||||||
val date = dateFormatter.format(this)
|
val date = dateTimeFormatter.format(this)
|
||||||
val time = DateFormat.getTimeInstance(DateFormat.SHORT).format(this)
|
val time = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT).format(this)
|
||||||
return "$date $time"
|
return "$date $time"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,51 +34,28 @@ fun Long.convertEpochMillisZone(
|
|||||||
.toEpochMilli()
|
.toEpochMilli()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
fun Long.toLocalDate(): LocalDate {
|
||||||
* Get date as time key
|
return LocalDate.ofInstant(Instant.ofEpochMilli(this), ZoneId.systemDefault())
|
||||||
*
|
|
||||||
* @param date desired date
|
|
||||||
* @return date as time key
|
|
||||||
*/
|
|
||||||
fun Long.toDateKey(): Date {
|
|
||||||
val instant = Instant.ofEpochMilli(this)
|
|
||||||
return Date.from(instant.truncatedTo(ChronoUnit.DAYS))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Date.toRelativeString(
|
fun LocalDate.toRelativeSting(
|
||||||
context: Context,
|
context: Context,
|
||||||
relative: Boolean = true,
|
relative: Boolean = true,
|
||||||
dateFormat: DateFormat = DateFormat.getDateInstance(DateFormat.SHORT),
|
dateFormat: DateTimeFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT),
|
||||||
): String {
|
): String {
|
||||||
if (!relative) {
|
if (!relative) {
|
||||||
return dateFormat.format(this)
|
return dateFormat.format(this)
|
||||||
}
|
}
|
||||||
val now = Date()
|
val now = LocalDate.now()
|
||||||
val difference = now.timeWithOffset.floorNearest(MILLISECONDS_IN_DAY) - this.timeWithOffset.floorNearest(MILLISECONDS_IN_DAY)
|
val difference = ChronoUnit.DAYS.between(this, now)
|
||||||
val days = difference.floorDiv(MILLISECONDS_IN_DAY).toInt()
|
|
||||||
return when {
|
return when {
|
||||||
difference < 0 -> dateFormat.format(this)
|
difference < 0 -> difference.toString()
|
||||||
difference < MILLISECONDS_IN_DAY -> context.stringResource(MR.strings.relative_time_today)
|
difference < 1 -> context.stringResource(MR.strings.relative_time_today)
|
||||||
difference < MILLISECONDS_IN_DAY.times(7) -> context.pluralStringResource(
|
difference < 7 -> context.pluralStringResource(
|
||||||
MR.plurals.relative_time,
|
MR.plurals.relative_time,
|
||||||
days,
|
difference.toInt(),
|
||||||
days,
|
difference.toInt(),
|
||||||
)
|
)
|
||||||
else -> dateFormat.format(this)
|
else -> dateFormat.format(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val MILLISECONDS_IN_DAY = 86_400_000L
|
|
||||||
|
|
||||||
private val Date.timeWithOffset: Long
|
|
||||||
get() {
|
|
||||||
return Calendar.getInstance().run {
|
|
||||||
time = this@timeWithOffset
|
|
||||||
val dstOffset = get(Calendar.DST_OFFSET)
|
|
||||||
this@timeWithOffset.time + timeZone.rawOffset + dstOffset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Long.floorNearest(to: Long): Long {
|
|
||||||
return this.floorDiv(to) * to
|
|
||||||
}
|
|
||||||
|
@ -18,7 +18,9 @@ import tachiyomi.core.common.i18n.pluralStringResource
|
|||||||
import tachiyomi.core.common.i18n.stringResource
|
import tachiyomi.core.common.i18n.stringResource
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
import tachiyomi.i18n.sy.SYMR
|
import tachiyomi.i18n.sy.SYMR
|
||||||
import java.util.Date
|
import java.time.Instant
|
||||||
|
import java.time.ZoneId
|
||||||
|
import java.time.ZonedDateTime
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun NHentaiDescription(state: State.Success, openMetadataViewer: () -> Unit) {
|
fun NHentaiDescription(state: State.Success, openMetadataViewer: () -> Unit) {
|
||||||
@ -50,7 +52,11 @@ fun NHentaiDescription(state: State.Success, openMetadataViewer: () -> Unit) {
|
|||||||
binding.favorites.bindDrawable(context, R.drawable.ic_book_24dp)
|
binding.favorites.bindDrawable(context, R.drawable.ic_book_24dp)
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.whenPosted.text = MetadataUtil.EX_DATE_FORMAT.format(Date((meta.uploadDate ?: 0) * 1000))
|
binding.whenPosted.text = MetadataUtil.EX_DATE_FORMAT
|
||||||
|
.format(
|
||||||
|
ZonedDateTime
|
||||||
|
.ofInstant(Instant.ofEpochSecond(meta.uploadDate ?: 0), ZoneId.systemDefault())
|
||||||
|
)
|
||||||
|
|
||||||
binding.pages.text = context.pluralStringResource(
|
binding.pages.text = context.pluralStringResource(
|
||||||
SYMR.plurals.num_pages,
|
SYMR.plurals.num_pages,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package exh.metadata
|
package exh.metadata
|
||||||
|
|
||||||
import java.text.SimpleDateFormat
|
import java.time.format.DateTimeFormatter
|
||||||
import java.util.Locale
|
|
||||||
import kotlin.math.ln
|
import kotlin.math.ln
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
@ -55,5 +54,5 @@ object MetadataUtil {
|
|||||||
"wip",
|
"wip",
|
||||||
)
|
)
|
||||||
|
|
||||||
val EX_DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US)
|
val EX_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,9 @@ import tachiyomi.i18n.MR
|
|||||||
import tachiyomi.i18n.sy.SYMR
|
import tachiyomi.i18n.sy.SYMR
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.Date
|
import java.time.Instant
|
||||||
|
import java.time.ZoneId
|
||||||
|
import java.time.ZonedDateTime
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
class EHentaiSearchMetadata : RaisedSearchMetadata() {
|
class EHentaiSearchMetadata : RaisedSearchMetadata() {
|
||||||
@ -99,7 +101,13 @@ class EHentaiSearchMetadata : RaisedSearchMetadata() {
|
|||||||
getItem(title) { stringResource(MR.strings.title) },
|
getItem(title) { stringResource(MR.strings.title) },
|
||||||
getItem(altTitle) { stringResource(SYMR.strings.alt_title) },
|
getItem(altTitle) { stringResource(SYMR.strings.alt_title) },
|
||||||
getItem(genre) { stringResource(SYMR.strings.genre) },
|
getItem(genre) { stringResource(SYMR.strings.genre) },
|
||||||
getItem(datePosted, { MetadataUtil.EX_DATE_FORMAT.format(Date(it)) }) {
|
getItem(
|
||||||
|
datePosted,
|
||||||
|
{
|
||||||
|
MetadataUtil.EX_DATE_FORMAT
|
||||||
|
.format(ZonedDateTime.ofInstant(Instant.ofEpochMilli(it), ZoneId.systemDefault()))
|
||||||
|
},
|
||||||
|
) {
|
||||||
stringResource(SYMR.strings.date_posted)
|
stringResource(SYMR.strings.date_posted)
|
||||||
},
|
},
|
||||||
getItem(parent) { stringResource(SYMR.strings.parent) },
|
getItem(parent) { stringResource(SYMR.strings.parent) },
|
||||||
@ -114,9 +122,13 @@ class EHentaiSearchMetadata : RaisedSearchMetadata() {
|
|||||||
getItem(ratingCount) { stringResource(SYMR.strings.total_ratings) },
|
getItem(ratingCount) { stringResource(SYMR.strings.total_ratings) },
|
||||||
getItem(averageRating) { stringResource(SYMR.strings.average_rating) },
|
getItem(averageRating) { stringResource(SYMR.strings.average_rating) },
|
||||||
getItem(aged) { stringResource(SYMR.strings.aged) },
|
getItem(aged) { stringResource(SYMR.strings.aged) },
|
||||||
getItem(lastUpdateCheck, { MetadataUtil.EX_DATE_FORMAT.format(Date(it)) }) {
|
getItem(
|
||||||
stringResource(SYMR.strings.last_update_check)
|
lastUpdateCheck,
|
||||||
},
|
{
|
||||||
|
MetadataUtil.EX_DATE_FORMAT
|
||||||
|
.format(ZonedDateTime.ofInstant(Instant.ofEpochMilli(it), ZoneId.systemDefault()))
|
||||||
|
},
|
||||||
|
) { stringResource(SYMR.strings.last_update_check) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,9 @@ import kotlinx.serialization.Serializable
|
|||||||
import tachiyomi.core.common.i18n.stringResource
|
import tachiyomi.core.common.i18n.stringResource
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
import tachiyomi.i18n.sy.SYMR
|
import tachiyomi.i18n.sy.SYMR
|
||||||
import java.util.Date
|
import java.time.Instant
|
||||||
|
import java.time.ZoneId
|
||||||
|
import java.time.ZonedDateTime
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
class NHentaiSearchMetadata : RaisedSearchMetadata() {
|
class NHentaiSearchMetadata : RaisedSearchMetadata() {
|
||||||
@ -92,7 +94,13 @@ class NHentaiSearchMetadata : RaisedSearchMetadata() {
|
|||||||
return with(context) {
|
return with(context) {
|
||||||
listOfNotNull(
|
listOfNotNull(
|
||||||
getItem(nhId) { stringResource(SYMR.strings.id) },
|
getItem(nhId) { stringResource(SYMR.strings.id) },
|
||||||
getItem(uploadDate, { MetadataUtil.EX_DATE_FORMAT.format(Date(it * 1000)) }) {
|
getItem(
|
||||||
|
uploadDate,
|
||||||
|
{
|
||||||
|
MetadataUtil.EX_DATE_FORMAT
|
||||||
|
.format(ZonedDateTime.ofInstant(Instant.ofEpochSecond(it), ZoneId.systemDefault()))
|
||||||
|
},
|
||||||
|
) {
|
||||||
stringResource(SYMR.strings.date_posted)
|
stringResource(SYMR.strings.date_posted)
|
||||||
},
|
},
|
||||||
getItem(favoritesCount) { stringResource(SYMR.strings.total_favorites) },
|
getItem(favoritesCount) { stringResource(SYMR.strings.total_favorites) },
|
||||||
|
@ -11,7 +11,9 @@ import tachiyomi.core.common.i18n.stringResource
|
|||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
import tachiyomi.i18n.sy.SYMR
|
import tachiyomi.i18n.sy.SYMR
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.time.Instant
|
||||||
|
import java.time.ZoneId
|
||||||
|
import java.time.ZonedDateTime
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@ -73,7 +75,13 @@ class TsuminoSearchMetadata : RaisedSearchMetadata() {
|
|||||||
getItem(tmId) { stringResource(SYMR.strings.id) },
|
getItem(tmId) { stringResource(SYMR.strings.id) },
|
||||||
getItem(title) { stringResource(MR.strings.title) },
|
getItem(title) { stringResource(MR.strings.title) },
|
||||||
getItem(uploader) { stringResource(SYMR.strings.uploader) },
|
getItem(uploader) { stringResource(SYMR.strings.uploader) },
|
||||||
getItem(uploadDate, { MetadataUtil.EX_DATE_FORMAT.format(Date(it)) }) {
|
getItem(
|
||||||
|
uploadDate,
|
||||||
|
{
|
||||||
|
MetadataUtil.EX_DATE_FORMAT
|
||||||
|
.format(ZonedDateTime.ofInstant(Instant.ofEpochMilli(it), ZoneId.systemDefault()))
|
||||||
|
},
|
||||||
|
) {
|
||||||
stringResource(SYMR.strings.date_posted)
|
stringResource(SYMR.strings.date_posted)
|
||||||
},
|
},
|
||||||
getItem(length) { stringResource(SYMR.strings.page_count) },
|
getItem(length) { stringResource(SYMR.strings.page_count) },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user