Switch to java.time

This commit is contained in:
Isira Seneviratne
2023-08-12 09:10:19 +05:30
committed by Koitharu
parent 6159ee36c4
commit 004109a6bc
26 changed files with 114 additions and 184 deletions

View File

@@ -48,11 +48,11 @@ android {
}
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
jvmTarget = JavaVersion.VERSION_17
freeCompilerArgs += [
'-opt-in=kotlin.ExperimentalStdlibApi',
'-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi',

View File

@@ -2,7 +2,7 @@ package org.koitharu.kotatsu.bookmarks.data
import org.koitharu.kotatsu.bookmarks.domain.Bookmark
import org.koitharu.kotatsu.parsers.model.Manga
import java.util.Date
import java.time.Instant
fun BookmarkEntity.toBookmark(manga: Manga) = Bookmark(
manga = manga,
@@ -11,7 +11,7 @@ fun BookmarkEntity.toBookmark(manga: Manga) = Bookmark(
page = page,
scroll = scroll,
imageUrl = imageUrl,
createdAt = Date(createdAt),
createdAt = Instant.ofEpochMilli(createdAt),
percent = percent,
)
@@ -22,7 +22,7 @@ fun Bookmark.toEntity() = BookmarkEntity(
page = page,
scroll = scroll,
imageUrl = imageUrl,
createdAt = createdAt.time,
createdAt = createdAt.toEpochMilli(),
percent = percent,
)

View File

@@ -4,7 +4,7 @@ import org.koitharu.kotatsu.list.ui.model.ListModel
import org.koitharu.kotatsu.local.data.hasImageExtension
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaPage
import java.util.Date
import java.time.Instant
data class Bookmark(
val manga: Manga,
@@ -13,7 +13,7 @@ data class Bookmark(
val page: Int,
val scroll: Int,
val imageUrl: String,
val createdAt: Date,
val createdAt: Instant,
val percent: Float,
) : ListModel {

View File

@@ -5,10 +5,10 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runInterruptible
import okio.Closeable
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.util.ext.format
import org.koitharu.kotatsu.core.zip.ZipOutput
import java.io.File
import java.util.Date
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.Locale
import java.util.zip.Deflater
@@ -39,7 +39,7 @@ suspend fun BackupZipOutput(context: Context): BackupZipOutput = runInterruptibl
val filename = buildString {
append(context.getString(R.string.app_name).replace(' ', '_').lowercase(Locale.ROOT))
append('_')
append(Date().format("ddMMyyyy"))
append(LocalDate.now().format(DateTimeFormatter.ofPattern("ddMMyyyy")))
append(".bk.zip")
}
BackupZipOutput(File(dir, filename))

View File

@@ -1,13 +1,13 @@
package org.koitharu.kotatsu.core.exceptions
import okio.IOException
import java.util.Date
import java.time.Instant
import java.time.temporal.ChronoUnit
class TooManyRequestExceptions(
val url: String,
val retryAt: Date?,
val retryAt: Instant?,
) : IOException() {
val retryAfter: Long
get() = if (retryAt == null) 0 else (retryAt.time - System.currentTimeMillis()).coerceAtLeast(0)
get() = retryAt?.until(Instant.now(), ChronoUnit.MILLIS) ?: 0
}

View File

@@ -20,8 +20,9 @@ import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
import java.io.File
import java.io.FileOutputStream
import java.text.SimpleDateFormat
import java.util.Date
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
import java.util.Locale
import java.util.concurrent.ConcurrentLinkedQueue
@@ -41,11 +42,7 @@ class FileLogger(
}
val isEnabled: Boolean
get() = settings.isLoggingEnabled
private val dateFormat = SimpleDateFormat.getDateTimeInstance(
SimpleDateFormat.SHORT,
SimpleDateFormat.SHORT,
Locale.ROOT,
)
private val dateTimeFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).withLocale(Locale.ROOT)
private val buffer = ConcurrentLinkedQueue<String>()
private val mutex = Mutex()
private var flushJob: Job? = null
@@ -55,7 +52,7 @@ class FileLogger(
return
}
val text = buildString {
append(dateFormat.format(Date()))
append(dateTimeFormatter.format(LocalDateTime.now()))
append(": ")
if (e != null) {
append("E!")

View File

@@ -5,7 +5,7 @@ import kotlinx.parcelize.Parcelize
import org.koitharu.kotatsu.list.domain.ListSortOrder
import org.koitharu.kotatsu.list.ui.ListModelDiffCallback
import org.koitharu.kotatsu.list.ui.model.ListModel
import java.util.Date
import java.time.Instant
@Parcelize
data class FavouriteCategory(
@@ -13,7 +13,7 @@ data class FavouriteCategory(
val title: String,
val sortKey: Int,
val order: ListSortOrder,
val createdAt: Date,
val createdAt: Instant,
val isTrackingEnabled: Boolean,
val isVisibleInLibrary: Boolean,
) : Parcelable, ListModel {

View File

@@ -2,14 +2,14 @@ package org.koitharu.kotatsu.core.model
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import java.util.*
import java.time.Instant
@Parcelize
data class MangaHistory(
val createdAt: Date,
val updatedAt: Date,
val createdAt: Instant,
val updatedAt: Instant,
val chapterId: Long,
val page: Int,
val scroll: Int,
val percent: Float,
) : Parcelable
) : Parcelable

View File

@@ -4,15 +4,11 @@ import okhttp3.Interceptor
import okhttp3.Response
import okhttp3.internal.closeQuietly
import org.koitharu.kotatsu.core.exceptions.TooManyRequestExceptions
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.concurrent.TimeUnit
import java.time.Instant
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
class RateLimitInterceptor : Interceptor {
private val dateFormat = SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss ZZZ", Locale.ENGLISH)
override fun intercept(chain: Interceptor.Chain): Response {
val response = chain.proceed(chain.request())
if (response.code == 429) {
@@ -27,10 +23,8 @@ class RateLimitInterceptor : Interceptor {
return response
}
private fun String.parseRetryDate(): Date? {
toIntOrNull()?.let {
return Date(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(it.toLong()))
}
return dateFormat.parse(this)
private fun String.parseRetryDate(): Instant? {
return toLongOrNull()?.let { Instant.now().plusSeconds(it) }
?: ZonedDateTime.parse(this, DateTimeFormatter.RFC_1123_DATE_TIME).toInstant()
}
}

View File

@@ -2,9 +2,8 @@ package org.koitharu.kotatsu.core.ui.model
import android.content.res.Resources
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.util.ext.daysDiff
import org.koitharu.kotatsu.core.util.ext.format
import java.util.Date
import java.time.LocalDate
import java.time.format.DateTimeFormatter
sealed class DateTimeAgo {
@@ -74,32 +73,20 @@ sealed class DateTimeAgo {
}
}
class Absolute(private val date: Date) : DateTimeAgo() {
private val day = date.daysDiff(0)
data class Absolute(private val date: LocalDate) : DateTimeAgo() {
override fun format(resources: Resources): String {
return if (date.time == 0L) {
return if (date == LocalDate.EPOCH) {
resources.getString(R.string.unknown)
} else {
date.format("d MMMM")
date.format(formatter)
}
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
override fun toString() = "abs_${date.toEpochDay()}"
other as Absolute
return day == other.day
companion object {
private val formatter = DateTimeFormatter.ofPattern("d MMMM")
}
override fun hashCode(): Int {
return day
}
override fun toString() = "abs_$day"
}
object LongAgo : DateTimeAgo() {

View File

@@ -9,10 +9,8 @@ import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentManager.FragmentLifecycleCallbacks
import org.acra.ACRA
import org.koitharu.kotatsu.core.ui.DefaultActivityLifecycleCallbacks
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.time.LocalTime
import java.time.temporal.ChronoUnit
import java.util.WeakHashMap
import javax.inject.Inject
import javax.inject.Singleton
@@ -20,7 +18,6 @@ import javax.inject.Singleton
@Singleton
class AcraScreenLogger @Inject constructor() : FragmentLifecycleCallbacks(), DefaultActivityLifecycleCallbacks {
private val timeFormat = SimpleDateFormat.getTimeInstance(DateFormat.DEFAULT, Locale.ROOT)
private val keys = WeakHashMap<Any, String>()
override fun onFragmentAttached(fm: FragmentManager, f: Fragment, context: Context) {
@@ -47,11 +44,10 @@ class AcraScreenLogger @Inject constructor() : FragmentLifecycleCallbacks(), Def
}
private fun Any.key() = keys.getOrPut(this) {
"${time()}: ${javaClass.simpleName}"
val time = LocalTime.now().truncatedTo(ChronoUnit.SECONDS)
"$time: ${javaClass.simpleName}"
}
private fun time() = timeFormat.format(Date())
@Suppress("DEPRECATION")
private fun Bundle?.contentToString() = this?.keySet()?.joinToString { k ->
val v = get(k)

View File

@@ -1,30 +1,30 @@
package org.koitharu.kotatsu.core.util.ext
import android.annotation.SuppressLint
import android.text.format.DateUtils
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.TimeUnit
import org.koitharu.kotatsu.core.ui.model.DateTimeAgo
import java.time.Instant
import java.time.LocalDate
import java.time.ZoneId
import java.time.temporal.ChronoUnit
@SuppressLint("SimpleDateFormat")
fun Date.format(pattern: String): String = SimpleDateFormat(pattern).format(this)
fun calculateTimeAgo(instant: Instant, showMonths: Boolean = false): DateTimeAgo {
val localDate = LocalDate.ofInstant(instant, ZoneId.systemDefault())
val now = LocalDate.now()
val diffDays = localDate.until(now, ChronoUnit.DAYS)
fun Date.formatRelative(minResolution: Long): CharSequence = DateUtils.getRelativeTimeSpanString(
time, System.currentTimeMillis(), minResolution,
)
fun Date.daysDiff(other: Long): Int {
val thisDay = time / TimeUnit.DAYS.toMillis(1L)
val otherDay = other / TimeUnit.DAYS.toMillis(1L)
return (thisDay - otherDay).toInt()
}
fun Date.startOfDay(): Long {
val calendar = Calendar.getInstance()
calendar.time = this
calendar[Calendar.HOUR_OF_DAY] = 0
calendar[Calendar.MINUTE] = 0
calendar[Calendar.SECOND] = 0
calendar[Calendar.MILLISECOND] = 0
return calendar.timeInMillis
return when {
diffDays == 0L -> {
if (instant.until(Instant.now(), ChronoUnit.MINUTES) < 3) DateTimeAgo.JustNow
else DateTimeAgo.Today
}
diffDays == 1L -> DateTimeAgo.Yesterday
diffDays < 6 -> DateTimeAgo.DaysAgo(diffDays.toInt())
else -> {
val diffMonths = localDate.until(now, ChronoUnit.MONTHS)
if (showMonths && diffMonths <= 6) {
DateTimeAgo.MonthsAgo(diffMonths.toInt())
} else {
DateTimeAgo.Absolute(localDate)
}
}
}
}

View File

@@ -4,7 +4,7 @@ import androidx.work.Data
import org.koitharu.kotatsu.history.data.PROGRESS_NONE
import org.koitharu.kotatsu.local.domain.model.LocalManga
import org.koitharu.kotatsu.parsers.model.Manga
import java.util.Date
import java.time.Instant
data class DownloadState(
val manga: Manga,
@@ -72,7 +72,7 @@ data class DownloadState(
fun getEta(data: Data): Long = data.getLong(DATA_ETA, -1L)
fun getTimestamp(data: Data): Date = Date(data.getLong(DATA_TIMESTAMP, 0L))
fun getTimestamp(data: Data): Instant = Instant.ofEpochMilli(data.getLong(DATA_TIMESTAMP, 0L))
fun getDownloadedChapters(data: Data): Int = data.getInt(DATA_CHAPTERS, 0)
}

View File

@@ -8,7 +8,7 @@ import org.koitharu.kotatsu.download.ui.list.chapters.DownloadChapter
import org.koitharu.kotatsu.list.ui.ListModelDiffCallback
import org.koitharu.kotatsu.list.ui.model.ListModel
import org.koitharu.kotatsu.parsers.model.Manga
import java.util.Date
import java.time.Instant
import java.util.UUID
data class DownloadItemModel(
@@ -21,7 +21,7 @@ data class DownloadItemModel(
val max: Int,
val progress: Int,
val eta: Long,
val timestamp: Date,
val timestamp: Instant,
val chaptersDownloaded: Int,
val isExpanded: Boolean,
val chapters: StateFlow<List<DownloadChapter>?>,

View File

@@ -28,8 +28,8 @@ import org.koitharu.kotatsu.core.ui.BaseViewModel
import org.koitharu.kotatsu.core.ui.model.DateTimeAgo
import org.koitharu.kotatsu.core.ui.util.ReversibleAction
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
import org.koitharu.kotatsu.core.util.ext.calculateTimeAgo
import org.koitharu.kotatsu.core.util.ext.call
import org.koitharu.kotatsu.core.util.ext.daysDiff
import org.koitharu.kotatsu.core.util.ext.isEmpty
import org.koitharu.kotatsu.download.domain.DownloadState
import org.koitharu.kotatsu.download.ui.list.chapters.DownloadChapter
@@ -44,10 +44,8 @@ import org.koitharu.kotatsu.local.domain.model.LocalManga
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.util.mapToSet
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
import java.util.Date
import java.util.LinkedList
import java.util.UUID
import java.util.concurrent.TimeUnit
import javax.inject.Inject
@HiltViewModel
@@ -225,7 +223,7 @@ class DownloadsViewModel @Inject constructor(
WorkInfo.State.ENQUEUED -> queued += item
else -> {
val date = timeAgo(item.timestamp)
val date = calculateTimeAgo(item.timestamp)
if (prevDate != date) {
destination += ListHeader(date)
}
@@ -275,19 +273,6 @@ class DownloadsViewModel @Inject constructor(
)
}
private fun timeAgo(date: Date): DateTimeAgo {
val diff = (System.currentTimeMillis() - date.time).coerceAtLeast(0L)
val diffMinutes = TimeUnit.MILLISECONDS.toMinutes(diff).toInt()
val diffDays = -date.daysDiff(System.currentTimeMillis())
return when {
diffMinutes < 3 -> DateTimeAgo.JustNow
diffDays < 1 -> DateTimeAgo.Today
diffDays == 1 -> DateTimeAgo.Yesterday
diffDays < 6 -> DateTimeAgo.DaysAgo(diffDays)
else -> DateTimeAgo.Absolute(date)
}
}
private fun emptyStateList() = listOf(
EmptyState(
icon = R.drawable.ic_empty_common,

View File

@@ -4,14 +4,14 @@ import org.koitharu.kotatsu.core.db.entity.toManga
import org.koitharu.kotatsu.core.db.entity.toMangaTags
import org.koitharu.kotatsu.core.model.FavouriteCategory
import org.koitharu.kotatsu.list.domain.ListSortOrder
import java.util.Date
import java.time.Instant
fun FavouriteCategoryEntity.toFavouriteCategory(id: Long = categoryId.toLong()) = FavouriteCategory(
id = id,
title = title,
sortKey = sortKey,
order = ListSortOrder(order, ListSortOrder.NEWEST),
createdAt = Date(createdAt),
createdAt = Instant.ofEpochMilli(createdAt),
isTrackingEnabled = track,
isVisibleInLibrary = isVisibleInLibrary,
)

View File

@@ -1,13 +1,13 @@
package org.koitharu.kotatsu.history.data
import org.koitharu.kotatsu.core.model.MangaHistory
import java.util.*
import java.time.Instant
fun HistoryEntity.toMangaHistory() = MangaHistory(
createdAt = Date(createdAt),
updatedAt = Date(updatedAt),
createdAt = Instant.ofEpochMilli(createdAt),
updatedAt = Instant.ofEpochMilli(updatedAt),
chapterId = chapterId,
page = page,
scroll = scroll.toInt(),
percent = percent,
)
)

View File

@@ -8,9 +8,10 @@ import androidx.core.view.MenuProvider
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.ui.dialog.RememberSelectionDialogListener
import org.koitharu.kotatsu.core.util.ext.startOfDay
import java.util.Date
import java.util.concurrent.TimeUnit
import java.time.Instant
import java.time.LocalDate
import java.time.ZoneId
import java.time.temporal.ChronoUnit
import com.google.android.material.R as materialR
class HistoryListMenuProvider(
@@ -50,9 +51,9 @@ class HistoryListMenuProvider(
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.clear) { _, _ ->
val minDate = when (selectionListener.selection) {
0 -> System.currentTimeMillis() - TimeUnit.HOURS.toMillis(2)
1 -> Date().startOfDay()
2 -> 0L
0 -> Instant.now().minus(2, ChronoUnit.HOURS)
1 -> LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant()
2 -> Instant.EPOCH
else -> return@setPositiveButton
}
viewModel.clearHistory(minDate)

View File

@@ -19,10 +19,9 @@ import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.prefs.ListMode
import org.koitharu.kotatsu.core.prefs.observeAsFlow
import org.koitharu.kotatsu.core.prefs.observeAsStateFlow
import org.koitharu.kotatsu.core.ui.model.DateTimeAgo
import org.koitharu.kotatsu.core.ui.util.ReversibleAction
import org.koitharu.kotatsu.core.util.ext.calculateTimeAgo
import org.koitharu.kotatsu.core.util.ext.call
import org.koitharu.kotatsu.core.util.ext.daysDiff
import org.koitharu.kotatsu.core.util.ext.onFirst
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
import org.koitharu.kotatsu.history.data.HistoryRepository
@@ -40,8 +39,7 @@ import org.koitharu.kotatsu.list.ui.model.toGridModel
import org.koitharu.kotatsu.list.ui.model.toListDetailedModel
import org.koitharu.kotatsu.list.ui.model.toListModel
import org.koitharu.kotatsu.local.data.LocalMangaRepository
import java.util.Date
import java.util.concurrent.TimeUnit
import java.time.Instant
import javax.inject.Inject
@HiltViewModel
@@ -100,13 +98,13 @@ class HistoryListViewModel @Inject constructor(
override fun onRetry() = Unit
fun clearHistory(minDate: Long) {
fun clearHistory(minDate: Instant) {
launchJob(Dispatchers.Default) {
val stringRes = if (minDate <= 0) {
val stringRes = if (minDate <= Instant.EPOCH) {
repository.clear()
R.string.history_cleared
} else {
repository.deleteAfter(minDate)
repository.deleteAfter(minDate.toEpochMilli())
R.string.removed_from_history
}
onActionDone.call(ReversibleAction(stringRes, null))
@@ -165,8 +163,8 @@ class HistoryListViewModel @Inject constructor(
}
private fun MangaHistory.header(order: ListSortOrder): ListHeader? = when (order) {
ListSortOrder.UPDATED -> ListHeader(timeAgo(updatedAt))
ListSortOrder.NEWEST -> ListHeader(timeAgo(createdAt))
ListSortOrder.UPDATED -> ListHeader(calculateTimeAgo(updatedAt))
ListSortOrder.NEWEST -> ListHeader(calculateTimeAgo(createdAt))
ListSortOrder.PROGRESS -> ListHeader(
when (percent) {
1f -> R.string.status_completed
@@ -181,18 +179,4 @@ class HistoryListViewModel @Inject constructor(
ListSortOrder.NEW_CHAPTERS,
ListSortOrder.RATING -> null
}
private fun timeAgo(date: Date): DateTimeAgo {
val diff = (System.currentTimeMillis() - date.time).coerceAtLeast(0L)
val diffMinutes = TimeUnit.MILLISECONDS.toMinutes(diff).toInt()
val diffDays = -date.daysDiff(System.currentTimeMillis())
return when {
diffMinutes < 3 -> DateTimeAgo.JustNow
diffDays < 1 -> DateTimeAgo.Today
diffDays == 1 -> DateTimeAgo.Yesterday
diffDays < 6 -> DateTimeAgo.DaysAgo(diffDays)
diffDays < 200 -> DateTimeAgo.MonthsAgo(diffDays / 30)
else -> DateTimeAgo.LongAgo
}
}
}

View File

@@ -24,8 +24,9 @@ import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
import org.koitharu.kotatsu.core.util.ext.resolveDp
import org.koitharu.kotatsu.parsers.util.format
import org.koitharu.kotatsu.reader.ui.pager.ReaderUiState
import java.text.SimpleDateFormat
import java.util.Date
import java.time.LocalTime
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
import com.google.android.material.R as materialR
class ReaderInfoBarView @JvmOverloads constructor(
@@ -36,7 +37,7 @@ class ReaderInfoBarView @JvmOverloads constructor(
private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
private val textBounds = Rect()
private val timeFormat = SimpleDateFormat.getTimeInstance(SimpleDateFormat.SHORT)
private val timeFormat = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)
private val timeReceiver = TimeReceiver()
private var insetLeft: Int = 0
private var insetRight: Int = 0
@@ -52,7 +53,7 @@ class ReaderInfoBarView @JvmOverloads constructor(
200,
)
private var timeText = timeFormat.format(Date())
private var timeText = timeFormat.format(LocalTime.now())
private var text: String = ""
private val innerHeight
@@ -181,7 +182,7 @@ class ReaderInfoBarView @JvmOverloads constructor(
private inner class TimeReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
timeText = timeFormat.format(Date())
timeText = timeFormat.format(LocalTime.now())
invalidate()
}
}

View File

@@ -56,7 +56,7 @@ import org.koitharu.kotatsu.reader.domain.DetectReaderModeUseCase
import org.koitharu.kotatsu.reader.domain.PageLoader
import org.koitharu.kotatsu.reader.ui.config.ReaderSettings
import org.koitharu.kotatsu.reader.ui.pager.ReaderUiState
import java.util.Date
import java.time.Instant
import javax.inject.Inject
private const val BOUNDS_PAGE_OFFSET = 2
@@ -302,7 +302,7 @@ class ReaderViewModel @Inject constructor(
page = state.page,
scroll = state.scroll,
imageUrl = page.preview.ifNullOrEmpty { page.url },
createdAt = Date(),
createdAt = Instant.now(),
percent = computePercent(state.chapterId, state.page),
)
bookmarksRepository.addBookmark(bookmark)

View File

@@ -3,7 +3,7 @@ package org.koitharu.kotatsu.tracker.data
import org.koitharu.kotatsu.core.db.entity.toManga
import org.koitharu.kotatsu.core.db.entity.toMangaTags
import org.koitharu.kotatsu.tracker.domain.model.TrackingLogItem
import java.util.Date
import java.time.Instant
fun TrackLogWithManga.toTrackingLogItem(counters: MutableMap<Long, Int>): TrackingLogItem {
val chaptersList = trackLog.chapters.split('\n').filterNot { x -> x.isEmpty() }
@@ -11,7 +11,7 @@ fun TrackLogWithManga.toTrackingLogItem(counters: MutableMap<Long, Int>): Tracki
id = trackLog.id,
chapters = chaptersList,
manga = manga.toManga(tags.toMangaTags()),
createdAt = Date(trackLog.createdAt),
createdAt = Instant.ofEpochMilli(trackLog.createdAt),
isNew = counters.decrement(trackLog.mangaId, chaptersList.size),
)
}

View File

@@ -25,7 +25,7 @@ import org.koitharu.kotatsu.tracker.data.toTrackingLogItem
import org.koitharu.kotatsu.tracker.domain.model.MangaTracking
import org.koitharu.kotatsu.tracker.domain.model.MangaUpdates
import org.koitharu.kotatsu.tracker.domain.model.TrackingLogItem
import java.util.Date
import java.time.Instant
import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject
import javax.inject.Provider
@@ -89,7 +89,7 @@ class TrackingRepository @Inject constructor(
result += MangaTracking(
manga = manga,
lastChapterId = track?.lastChapterId ?: NO_ID,
lastCheck = track?.lastCheck?.takeUnless { it == 0L }?.let(::Date),
lastCheck = track?.lastCheck?.takeUnless { it == 0L }?.let(Instant::ofEpochMilli),
)
}
return result
@@ -101,7 +101,7 @@ class TrackingRepository @Inject constructor(
return MangaTracking(
manga = manga,
lastChapterId = track?.lastChapterId ?: NO_ID,
lastCheck = track?.lastCheck?.takeUnless { it == 0L }?.let(::Date),
lastCheck = track?.lastCheck?.takeUnless { it == 0L }?.let(Instant::ofEpochMilli),
)
}

View File

@@ -1,12 +1,12 @@
package org.koitharu.kotatsu.tracker.domain.model
import java.util.*
import org.koitharu.kotatsu.parsers.model.Manga
import java.time.Instant
data class MangaTracking(
val manga: Manga,
val lastChapterId: Long,
val lastCheck: Date?,
val lastCheck: Instant?,
) {
fun isEmpty(): Boolean {
return lastChapterId == 0L

View File

@@ -1,12 +1,12 @@
package org.koitharu.kotatsu.tracker.domain.model
import java.util.*
import org.koitharu.kotatsu.parsers.model.Manga
import java.time.Instant
data class TrackingLogItem(
val id: Long,
val manga: Manga,
val chapters: List<String>,
val createdAt: Date,
val createdAt: Instant,
val isNew: Boolean,
)

View File

@@ -15,7 +15,7 @@ import org.koitharu.kotatsu.core.ui.BaseViewModel
import org.koitharu.kotatsu.core.ui.model.DateTimeAgo
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
import org.koitharu.kotatsu.core.util.ext.call
import org.koitharu.kotatsu.core.util.ext.daysDiff
import org.koitharu.kotatsu.core.util.ext.calculateTimeAgo
import org.koitharu.kotatsu.list.domain.ListExtraProvider
import org.koitharu.kotatsu.list.ui.model.EmptyState
import org.koitharu.kotatsu.list.ui.model.ListHeader
@@ -27,8 +27,6 @@ import org.koitharu.kotatsu.tracker.domain.model.TrackingLogItem
import org.koitharu.kotatsu.tracker.ui.feed.model.UpdatedMangaHeader
import org.koitharu.kotatsu.tracker.ui.feed.model.toFeedItem
import org.koitharu.kotatsu.tracker.work.TrackWorker
import java.util.Date
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject
@@ -99,7 +97,7 @@ class FeedViewModel @Inject constructor(
private fun List<TrackingLogItem>.mapListTo(destination: MutableList<ListModel>) {
var prevDate: DateTimeAgo? = null
for (item in this) {
val date = timeAgo(item.createdAt)
val date = calculateTimeAgo(item.createdAt)
if (prevDate != date) {
destination += ListHeader(date)
}
@@ -115,17 +113,4 @@ class FeedViewModel @Inject constructor(
UpdatedMangaHeader(mangaList.toUi(ListMode.GRID, listExtraProvider))
}
}
private fun timeAgo(date: Date): DateTimeAgo {
val diff = (System.currentTimeMillis() - date.time).coerceAtLeast(0L)
val diffMinutes = TimeUnit.MILLISECONDS.toMinutes(diff).toInt()
val diffDays = -date.daysDiff(System.currentTimeMillis())
return when {
diffMinutes < 3 -> DateTimeAgo.JustNow
diffDays < 1 -> DateTimeAgo.Today
diffDays == 1 -> DateTimeAgo.Yesterday
diffDays < 6 -> DateTimeAgo.DaysAgo(diffDays)
else -> DateTimeAgo.Absolute(date)
}
}
}