Simplify time ago calculation.

pull/404/head
Isira Seneviratne 3 years ago
parent f081b0cfd2
commit d3a7c381ad

@ -2,10 +2,9 @@ package org.koitharu.kotatsu.core.ui.model
import android.content.res.Resources import android.content.res.Resources
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.util.ext.daysDiff
import org.koitharu.kotatsu.core.util.ext.format
import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.list.ui.model.ListModel
import java.util.Date import java.time.LocalDate
import java.time.format.DateTimeFormatter
sealed class DateTimeAgo : ListModel { sealed class DateTimeAgo : ListModel {
@ -93,28 +92,16 @@ sealed class DateTimeAgo : ListModel {
override fun toString() = "days_ago_$days" override fun toString() = "days_ago_$days"
} }
class Absolute(private val date: Date) : DateTimeAgo() { data class Absolute(private val date: LocalDate) : DateTimeAgo() {
private val day = date.daysDiff(0)
override fun format(resources: Resources): String { override fun format(resources: Resources): String {
return date.format("d MMMM") return dateFormatter.format(date)
} }
override fun equals(other: Any?): Boolean { override fun toString() = "abs_${date.toEpochDay()}"
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Absolute companion object {
private val dateFormatter = DateTimeFormatter.ofPattern("d MMMM")
return day == other.day
}
override fun hashCode(): Int {
return day
} }
override fun toString() = "abs_$day"
} }
object LongAgo : DateTimeAgo() { object LongAgo : DateTimeAgo() {

@ -1,22 +1,28 @@
package org.koitharu.kotatsu.core.util.ext package org.koitharu.kotatsu.core.util.ext
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.text.format.DateUtils import org.koitharu.kotatsu.core.ui.model.DateTimeAgo
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.temporal.ChronoUnit
import java.util.* import java.util.*
import java.util.concurrent.TimeUnit
@SuppressLint("SimpleDateFormat") @SuppressLint("SimpleDateFormat")
fun Date.format(pattern: String): String = SimpleDateFormat(pattern).format(this) fun Date.format(pattern: String): String = SimpleDateFormat(pattern).format(this)
fun Date.formatRelative(minResolution: Long): CharSequence = DateUtils.getRelativeTimeSpanString( fun calculateTimeAgo(date: Date, showDate: Boolean = true): DateTimeAgo {
time, System.currentTimeMillis(), minResolution, val localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault())
) val now = LocalDateTime.now()
val diffMinutes = localDateTime.until(now, ChronoUnit.MINUTES)
fun Date.daysDiff(other: Long): Int { val diffDays = localDateTime.until(now, ChronoUnit.DAYS).toInt()
val thisDay = time / TimeUnit.DAYS.toMillis(1L) return when {
val otherDay = other / TimeUnit.DAYS.toMillis(1L) diffMinutes < 3 -> DateTimeAgo.JustNow
return (thisDay - otherDay).toInt() diffDays < 1 -> DateTimeAgo.Today
diffDays == 1 -> DateTimeAgo.Yesterday
diffDays < 6 -> DateTimeAgo.DaysAgo(diffDays)
else -> if (showDate) DateTimeAgo.Absolute(localDateTime.toLocalDate()) else DateTimeAgo.LongAgo
}
} }
fun Date.startOfDay(): Long { fun Date.startOfDay(): Long {

@ -21,8 +21,8 @@ import org.koitharu.kotatsu.core.ui.BaseViewModel
import org.koitharu.kotatsu.core.ui.model.DateTimeAgo import org.koitharu.kotatsu.core.ui.model.DateTimeAgo
import org.koitharu.kotatsu.core.ui.util.ReversibleAction import org.koitharu.kotatsu.core.ui.util.ReversibleAction
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow 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.call
import org.koitharu.kotatsu.core.util.ext.daysDiff
import org.koitharu.kotatsu.download.domain.DownloadState import org.koitharu.kotatsu.download.domain.DownloadState
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
import org.koitharu.kotatsu.list.ui.model.EmptyState import org.koitharu.kotatsu.list.ui.model.EmptyState
@ -30,9 +30,7 @@ import org.koitharu.kotatsu.list.ui.model.ListModel
import org.koitharu.kotatsu.list.ui.model.LoadingState import org.koitharu.kotatsu.list.ui.model.LoadingState
import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.util.mapToSet import org.koitharu.kotatsu.parsers.util.mapToSet
import java.util.Date
import java.util.UUID import java.util.UUID
import java.util.concurrent.TimeUnit
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
@ -181,7 +179,7 @@ class DownloadsViewModel @Inject constructor(
val destination = ArrayList<ListModel>((size * 1.4).toInt()) val destination = ArrayList<ListModel>((size * 1.4).toInt())
var prevDate: DateTimeAgo? = null var prevDate: DateTimeAgo? = null
for (item in this) { for (item in this) {
val date = timeAgo(item.timestamp) val date = calculateTimeAgo(item.timestamp)
if (prevDate != date) { if (prevDate != date) {
destination += date destination += date
} }
@ -211,19 +209,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( private fun emptyStateList() = listOf(
EmptyState( EmptyState(
icon = R.drawable.ic_empty_common, icon = R.drawable.ic_empty_common,

@ -15,8 +15,8 @@ import org.koitharu.kotatsu.core.prefs.ListMode
import org.koitharu.kotatsu.core.prefs.observeAsStateFlow import org.koitharu.kotatsu.core.prefs.observeAsStateFlow
import org.koitharu.kotatsu.core.ui.model.DateTimeAgo import org.koitharu.kotatsu.core.ui.model.DateTimeAgo
import org.koitharu.kotatsu.core.ui.util.ReversibleAction 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.call
import org.koitharu.kotatsu.core.util.ext.daysDiff
import org.koitharu.kotatsu.core.util.ext.onFirst import org.koitharu.kotatsu.core.util.ext.onFirst
import org.koitharu.kotatsu.download.ui.worker.DownloadWorker import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
import org.koitharu.kotatsu.history.data.HistoryRepository import org.koitharu.kotatsu.history.data.HistoryRepository
@ -30,8 +30,6 @@ import org.koitharu.kotatsu.list.ui.model.toErrorState
import org.koitharu.kotatsu.list.ui.model.toGridModel import org.koitharu.kotatsu.list.ui.model.toGridModel
import org.koitharu.kotatsu.list.ui.model.toListDetailedModel import org.koitharu.kotatsu.list.ui.model.toListDetailedModel
import org.koitharu.kotatsu.list.ui.model.toListModel import org.koitharu.kotatsu.list.ui.model.toListModel
import java.util.Date
import java.util.concurrent.TimeUnit
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
@ -106,7 +104,7 @@ class HistoryListViewModel @Inject constructor(
var prevDate: DateTimeAgo? = null var prevDate: DateTimeAgo? = null
for ((manga, history) in list) { for ((manga, history) in list) {
if (grouped) { if (grouped) {
val date = timeAgo(history.updatedAt) val date = calculateTimeAgo(history.updatedAt, showDate = false)
if (prevDate != date) { if (prevDate != date) {
result += date result += date
} }
@ -120,17 +118,4 @@ class HistoryListViewModel @Inject constructor(
} }
return result return result
} }
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.LongAgo
}
}
} }

@ -12,16 +12,14 @@ import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.ui.BaseViewModel import org.koitharu.kotatsu.core.ui.BaseViewModel
import org.koitharu.kotatsu.core.ui.model.DateTimeAgo import org.koitharu.kotatsu.core.ui.model.DateTimeAgo
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow 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.call
import org.koitharu.kotatsu.core.util.ext.daysDiff
import org.koitharu.kotatsu.list.ui.model.EmptyState import org.koitharu.kotatsu.list.ui.model.EmptyState
import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.list.ui.model.ListModel
import org.koitharu.kotatsu.list.ui.model.LoadingState import org.koitharu.kotatsu.list.ui.model.LoadingState
import org.koitharu.kotatsu.tracker.domain.TrackingRepository import org.koitharu.kotatsu.tracker.domain.TrackingRepository
import org.koitharu.kotatsu.tracker.domain.model.TrackingLogItem import org.koitharu.kotatsu.tracker.domain.model.TrackingLogItem
import org.koitharu.kotatsu.tracker.ui.feed.model.toFeedItem import org.koitharu.kotatsu.tracker.ui.feed.model.toFeedItem
import java.util.Date
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject import javax.inject.Inject
@ -73,7 +71,7 @@ class FeedViewModel @Inject constructor(
val destination = ArrayList<ListModel>((size * 1.4).toInt()) val destination = ArrayList<ListModel>((size * 1.4).toInt())
var prevDate: DateTimeAgo? = null var prevDate: DateTimeAgo? = null
for (item in this) { for (item in this) {
val date = timeAgo(item.createdAt) val date = calculateTimeAgo(item.createdAt)
if (prevDate != date) { if (prevDate != date) {
destination += date destination += date
} }
@ -82,17 +80,4 @@ class FeedViewModel @Inject constructor(
} }
return destination return destination
} }
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)
}
}
} }

Loading…
Cancel
Save