Selaa lähdekoodia

Migrate to some newer date/time APIs

arkon 1 vuosi sitten
vanhempi
commit
ab9a26f6bd
18 muutettua tiedostoa jossa 65 lisäystä ja 68 poistoa
  1. 2 2
      app/src/main/java/eu/kanade/domain/chapter/interactor/SyncChaptersWithSource.kt
  2. 6 6
      app/src/main/java/eu/kanade/domain/manga/interactor/UpdateManga.kt
  3. 2 2
      app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAppearanceScreen.kt
  4. 2 2
      app/src/main/java/eu/kanade/presentation/util/TimeUtils.kt
  5. 2 2
      app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreateJob.kt
  6. 2 2
      app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt
  7. 2 2
      app/src/main/java/eu/kanade/tachiyomi/data/saver/ImageSaver.kt
  8. 17 13
      app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt
  9. 5 3
      app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt
  10. 2 2
      app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateDialog.kt
  11. 2 2
      app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt
  12. 2 1
      app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
  13. 3 6
      app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt
  14. 4 4
      app/src/main/java/eu/kanade/tachiyomi/util/MangaExtensions.kt
  15. 3 7
      app/src/main/java/eu/kanade/tachiyomi/util/lang/DateExtensions.kt
  16. 3 3
      domain/src/main/java/tachiyomi/domain/updates/interactor/GetUpdates.kt
  17. 5 8
      presentation-widget/src/main/java/tachiyomi/presentation/widget/BaseUpdatesGridGlanceWidget.kt
  18. 1 1
      presentation-widget/src/main/java/tachiyomi/presentation/widget/WidgetManager.kt

+ 2 - 2
app/src/main/java/eu/kanade/domain/chapter/interactor/SyncChaptersWithSource.kt

@@ -22,8 +22,8 @@ import tachiyomi.domain.chapter.service.ChapterRecognition
 import tachiyomi.domain.manga.model.Manga
 import tachiyomi.source.local.isLocal
 import java.lang.Long.max
+import java.time.Instant
 import java.time.ZonedDateTime
-import java.util.Date
 import java.util.TreeSet
 
 class SyncChaptersWithSource(
@@ -83,7 +83,7 @@ class SyncChaptersWithSource(
             }
         }
 
-        val rightNow = Date().time
+        val rightNow = Instant.now().toEpochMilli()
 
         // Used to not set upload date of older chapters
         // to a higher value than newer chapters

+ 6 - 6
app/src/main/java/eu/kanade/domain/manga/interactor/UpdateManga.kt

@@ -10,8 +10,8 @@ import tachiyomi.domain.manga.repository.MangaRepository
 import tachiyomi.source.local.isLocal
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
+import java.time.Instant
 import java.time.ZonedDateTime
-import java.util.Date
 
 class UpdateManga(
     private val mangaRepository: MangaRepository,
@@ -46,14 +46,14 @@ class UpdateManga(
                 // Never refresh covers if the url is empty to avoid "losing" existing covers
                 remoteManga.thumbnail_url.isNullOrEmpty() -> null
                 !manualFetch && localManga.thumbnailUrl == remoteManga.thumbnail_url -> null
-                localManga.isLocal() -> Date().time
+                localManga.isLocal() -> Instant.now().toEpochMilli()
                 localManga.hasCustomCover(coverCache) -> {
                     coverCache.deleteFromCache(localManga, false)
                     null
                 }
                 else -> {
                     coverCache.deleteFromCache(localManga, false)
-                    Date().time
+                    Instant.now().toEpochMilli()
                 }
             }
 
@@ -87,16 +87,16 @@ class UpdateManga(
     }
 
     suspend fun awaitUpdateLastUpdate(mangaId: Long): Boolean {
-        return mangaRepository.update(MangaUpdate(id = mangaId, lastUpdate = Date().time))
+        return mangaRepository.update(MangaUpdate(id = mangaId, lastUpdate = Instant.now().toEpochMilli()))
     }
 
     suspend fun awaitUpdateCoverLastModified(mangaId: Long): Boolean {
-        return mangaRepository.update(MangaUpdate(id = mangaId, coverLastModified = Date().time))
+        return mangaRepository.update(MangaUpdate(id = mangaId, coverLastModified = Instant.now().toEpochMilli()))
     }
 
     suspend fun awaitUpdateFavorite(mangaId: Long, favorite: Boolean): Boolean {
         val dateAdded = when (favorite) {
-            true -> Date().time
+            true -> Instant.now().toEpochMilli()
             false -> 0
         }
         return mangaRepository.update(

+ 2 - 2
app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAppearanceScreen.kt

@@ -33,7 +33,7 @@ import tachiyomi.presentation.core.i18n.stringResource
 import tachiyomi.presentation.core.util.collectAsState
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
-import java.util.Date
+import java.time.Instant
 
 object SettingsAppearanceScreen : SearchableSettings {
 
@@ -123,7 +123,7 @@ object SettingsAppearanceScreen : SearchableSettings {
         var currentLanguage by remember {
             mutableStateOf(AppCompatDelegate.getApplicationLocales().get(0)?.toLanguageTag() ?: "")
         }
-        val now = remember { Date().time }
+        val now = remember { Instant.now().toEpochMilli() }
 
         val dateFormat by uiPreferences.dateFormat().collectAsState()
         val formattedNow = remember(dateFormat) {

+ 2 - 2
app/src/main/java/eu/kanade/presentation/util/TimeUtils.kt

@@ -7,7 +7,7 @@ import androidx.compose.runtime.ReadOnlyComposable
 import tachiyomi.core.i18n.stringResource
 import tachiyomi.i18n.MR
 import tachiyomi.presentation.core.i18n.stringResource
-import java.util.Date
+import java.time.Instant
 import kotlin.time.Duration
 import kotlin.time.Duration.Companion.minutes
 
@@ -29,7 +29,7 @@ fun Duration.toDurationString(context: Context, fallback: String): String {
 @Composable
 @ReadOnlyComposable
 fun relativeTimeSpanString(epochMillis: Long): String {
-    val now = Date().time
+    val now = Instant.now().toEpochMilli()
     return when {
         epochMillis <= 0L -> stringResource(MR.strings.relative_time_span_never)
         now - epochMillis < 1.minutes.inWholeMilliseconds -> stringResource(

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreateJob.kt

@@ -25,7 +25,7 @@ import tachiyomi.domain.backup.service.BackupPreferences
 import tachiyomi.domain.storage.service.StorageManager
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
-import java.util.Date
+import java.time.Instant
 import java.util.concurrent.TimeUnit
 import kotlin.time.Duration.Companion.minutes
 import kotlin.time.toJavaDuration
@@ -52,7 +52,7 @@ class BackupCreateJob(private val context: Context, workerParams: WorkerParamete
         return try {
             val location = BackupCreator(context).createBackup(uri, flags, isAutoBackup)
             if (isAutoBackup) {
-                backupPreferences.lastAutoBackupTimestamp().set(Date().time)
+                backupPreferences.lastAutoBackupTimestamp().set(Instant.now().toEpochMilli())
             } else {
                 notifier.showBackupComplete(UniFile.fromUri(context, location.toUri())!!)
             }

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt

@@ -69,8 +69,8 @@ import tachiyomi.i18n.MR
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
 import java.io.File
+import java.time.Instant
 import java.time.ZonedDateTime
-import java.util.Date
 import java.util.concurrent.CopyOnWriteArrayList
 import java.util.concurrent.TimeUnit
 import java.util.concurrent.atomic.AtomicBoolean
@@ -111,7 +111,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
 
         setForegroundSafely()
 
-        libraryPreferences.lastUpdatedTimestamp().set(Date().time)
+        libraryPreferences.lastUpdatedTimestamp().set(Instant.now().toEpochMilli())
 
         val categoryId = inputData.getLong(KEY_CATEGORY, -1L)
         addMangaToQueue(categoryId)

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/data/saver/ImageSaver.kt

@@ -23,7 +23,7 @@ import java.io.ByteArrayInputStream
 import java.io.ByteArrayOutputStream
 import java.io.File
 import java.io.InputStream
-import java.util.Date
+import java.time.Instant
 
 class ImageSaver(
     val context: Context,
@@ -79,7 +79,7 @@ class ImageSaver(
             MediaStore.Images.Media.RELATIVE_PATH to relativePath,
             MediaStore.Images.Media.DISPLAY_NAME to image.name,
             MediaStore.Images.Media.MIME_TYPE to type.mime,
-            MediaStore.Images.Media.DATE_MODIFIED to Date().time * 1000,
+            MediaStore.Images.Media.DATE_MODIFIED to Instant.now().toEpochMilli(),
         )
 
         val picture = findUriOrDefault(relativePath, filename) {

+ 17 - 13
app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt

@@ -26,7 +26,10 @@ import okhttp3.OkHttpClient
 import okhttp3.RequestBody.Companion.toRequestBody
 import tachiyomi.core.util.lang.withIOContext
 import uy.kohesive.injekt.injectLazy
-import java.util.Calendar
+import java.time.Instant
+import java.time.LocalDate
+import java.time.ZoneId
+import java.time.ZonedDateTime
 import kotlin.time.Duration.Companion.minutes
 
 class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
@@ -328,13 +331,15 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
 
     private fun parseDate(struct: JsonObject, dateKey: String): Long {
         return try {
-            val date = Calendar.getInstance()
-            date.set(
-                struct[dateKey]!!.jsonObject["year"]!!.jsonPrimitive.int,
-                struct[dateKey]!!.jsonObject["month"]!!.jsonPrimitive.int - 1,
-                struct[dateKey]!!.jsonObject["day"]!!.jsonPrimitive.int,
-            )
-            date.timeInMillis
+            return LocalDate
+                .of(
+                    struct[dateKey]!!.jsonObject["year"]!!.jsonPrimitive.int,
+                    struct[dateKey]!!.jsonObject["month"]!!.jsonPrimitive.int,
+                    struct[dateKey]!!.jsonObject["day"]!!.jsonPrimitive.int,
+                )
+                .atStartOfDay(ZoneId.systemDefault())
+                .toInstant()
+                .toEpochMilli()
         } catch (_: Exception) {
             0L
         }
@@ -349,12 +354,11 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
             }
         }
 
-        val calendar = Calendar.getInstance()
-        calendar.timeInMillis = dateValue
+        val dateTime = ZonedDateTime.ofInstant(Instant.ofEpochMilli(dateValue), ZoneId.systemDefault())
         return buildJsonObject {
-            put("year", calendar.get(Calendar.YEAR))
-            put("month", calendar.get(Calendar.MONTH) + 1)
-            put("day", calendar.get(Calendar.DAY_OF_MONTH))
+            put("year", dateTime.year)
+            put("month", dateTime.monthValue)
+            put("day", dateTime.dayOfMonth)
         }
     }
 

+ 5 - 3
app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt

@@ -17,7 +17,7 @@ import tachiyomi.core.preference.PreferenceStore
 import tachiyomi.core.util.lang.withIOContext
 import tachiyomi.core.util.system.logcat
 import uy.kohesive.injekt.injectLazy
-import java.util.Date
+import java.time.Instant
 import kotlin.time.Duration.Companion.days
 
 internal class ExtensionGithubApi {
@@ -76,14 +76,16 @@ internal class ExtensionGithubApi {
         fromAvailableExtensionList: Boolean = false,
     ): List<Extension.Installed>? {
         // Limit checks to once a day at most
-        if (!fromAvailableExtensionList && Date().time < lastExtCheck.get() + 1.days.inWholeMilliseconds) {
+        if (!fromAvailableExtensionList &&
+            Instant.now().toEpochMilli() < lastExtCheck.get() + 1.days.inWholeMilliseconds
+        ) {
             return null
         }
 
         val extensions = if (fromAvailableExtensionList) {
             extensionManager.availableExtensionsFlow.value
         } else {
-            findExtensions().also { lastExtCheck.set(Date().time) }
+            findExtensions().also { lastExtCheck.set(Instant.now().toEpochMilli()) }
         }
 
         val installedExtensions = ExtensionLoader.loadExtensions(context)

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateDialog.kt

@@ -53,7 +53,7 @@ import tachiyomi.presentation.core.i18n.stringResource
 import tachiyomi.presentation.core.screens.LoadingScreen
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
-import java.util.Date
+import java.time.Instant
 
 @Composable
 internal fun MigrateDialog(
@@ -298,7 +298,7 @@ internal class MigrateDialogScreenModel(
                 favorite = true,
                 chapterFlags = oldManga.chapterFlags,
                 viewerFlags = oldManga.viewerFlags,
-                dateAdded = if (replace) oldManga.dateAdded else Date().time,
+                dateAdded = if (replace) oldManga.dateAdded else Instant.now().toEpochMilli(),
             ),
         )
     }

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt

@@ -50,7 +50,7 @@ import tachiyomi.domain.source.interactor.GetRemoteManga
 import tachiyomi.domain.source.service.SourceManager
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
-import java.util.Date
+import java.time.Instant
 import eu.kanade.tachiyomi.source.model.Filter as SourceModelFilter
 
 class BrowseSourceScreenModel(
@@ -225,7 +225,7 @@ class BrowseSourceScreenModel(
                 favorite = !manga.favorite,
                 dateAdded = when (manga.favorite) {
                     true -> 0
-                    false -> Date().time
+                    false -> Instant.now().toEpochMilli()
                 },
             )
 

+ 2 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt

@@ -74,6 +74,7 @@ import tachiyomi.domain.source.service.SourceManager
 import tachiyomi.source.local.isLocal
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
+import java.time.Instant
 import java.util.Date
 
 /**
@@ -539,7 +540,7 @@ class ReaderViewModel @JvmOverloads constructor(
     }
 
     fun restartReadTimer() {
-        chapterReadStartTime = Date().time
+        chapterReadStartTime = Instant.now().toEpochMilli()
     }
 
     fun flushReadTimer() {

+ 3 - 6
app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt

@@ -49,7 +49,7 @@ import tachiyomi.domain.updates.interactor.GetUpdates
 import tachiyomi.domain.updates.model.UpdatesWithRelations
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
-import java.util.Calendar
+import java.time.ZonedDateTime
 import java.util.Date
 
 class UpdatesScreenModel(
@@ -79,13 +79,10 @@ class UpdatesScreenModel(
     init {
         screenModelScope.launchIO {
             // Set date limit for recent chapters
-            val calendar = Calendar.getInstance().apply {
-                time = Date()
-                add(Calendar.MONTH, -3)
-            }
+            val limit = ZonedDateTime.now().minusMonths(3).toInstant()
 
             combine(
-                getUpdates.subscribe(calendar).distinctUntilChanged(),
+                getUpdates.subscribe(limit).distinctUntilChanged(),
                 downloadCache.changes,
                 downloadManager.queueState,
             ) { updates, _, _ -> updates }

+ 4 - 4
app/src/main/java/eu/kanade/tachiyomi/util/MangaExtensions.kt

@@ -12,7 +12,7 @@ import tachiyomi.source.local.isLocal
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
 import java.io.InputStream
-import java.util.Date
+import java.time.Instant
 
 /**
  * Call before updating [Manga.thumbnail_url] to ensure old cover can be cleared from cache
@@ -28,7 +28,7 @@ fun Manga.prepUpdateCover(coverCache: CoverCache, remoteManga: SManga, refreshSa
 
     return when {
         isLocal() -> {
-            this.copy(coverLastModified = Date().time)
+            this.copy(coverLastModified = Instant.now().toEpochMilli())
         }
         hasCustomCover(coverCache) -> {
             coverCache.deleteFromCache(this, false)
@@ -36,7 +36,7 @@ fun Manga.prepUpdateCover(coverCache: CoverCache, remoteManga: SManga, refreshSa
         }
         else -> {
             coverCache.deleteFromCache(this, false)
-            this.copy(coverLastModified = Date().time)
+            this.copy(coverLastModified = Instant.now().toEpochMilli())
         }
     }
 }
@@ -44,7 +44,7 @@ fun Manga.prepUpdateCover(coverCache: CoverCache, remoteManga: SManga, refreshSa
 fun Manga.removeCovers(coverCache: CoverCache = Injekt.get()): Manga {
     if (isLocal()) return this
     return if (coverCache.deleteFromCache(this, true) > 0) {
-        return copy(coverLastModified = Date().time)
+        return copy(coverLastModified = Instant.now().toEpochMilli())
     } else {
         this
     }

+ 3 - 7
app/src/main/java/eu/kanade/tachiyomi/util/lang/DateExtensions.kt

@@ -8,6 +8,7 @@ import java.text.DateFormat
 import java.time.Instant
 import java.time.LocalDateTime
 import java.time.ZoneId
+import java.time.temporal.ChronoUnit
 import java.util.Calendar
 import java.util.Date
 
@@ -38,13 +39,8 @@ fun Long.convertEpochMillisZone(
  * @return date as time key
  */
 fun Long.toDateKey(): Date {
-    val cal = Calendar.getInstance()
-    cal.time = Date(this)
-    cal[Calendar.HOUR_OF_DAY] = 0
-    cal[Calendar.MINUTE] = 0
-    cal[Calendar.SECOND] = 0
-    cal[Calendar.MILLISECOND] = 0
-    return cal.time
+    val instant = Instant.ofEpochMilli(this)
+    return Date.from(instant.truncatedTo(ChronoUnit.DAYS))
 }
 
 private const val MILLISECONDS_IN_DAY = 86_400_000L

+ 3 - 3
domain/src/main/java/tachiyomi/domain/updates/interactor/GetUpdates.kt

@@ -3,7 +3,7 @@ package tachiyomi.domain.updates.interactor
 import kotlinx.coroutines.flow.Flow
 import tachiyomi.domain.updates.model.UpdatesWithRelations
 import tachiyomi.domain.updates.repository.UpdatesRepository
-import java.util.Calendar
+import java.time.Instant
 
 class GetUpdates(
     private val repository: UpdatesRepository,
@@ -13,8 +13,8 @@ class GetUpdates(
         return repository.awaitWithRead(read, after, limit = 500)
     }
 
-    fun subscribe(calendar: Calendar): Flow<List<UpdatesWithRelations>> {
-        return repository.subscribeAll(calendar.time.time, limit = 500)
+    fun subscribe(instant: Instant): Flow<List<UpdatesWithRelations>> {
+        return repository.subscribeAll(instant.toEpochMilli(), limit = 500)
     }
 
     fun subscribe(read: Boolean, after: Long): Flow<List<UpdatesWithRelations>> {

+ 5 - 8
presentation-widget/src/main/java/tachiyomi/presentation/widget/BaseUpdatesGridGlanceWidget.kt

@@ -45,8 +45,8 @@ import tachiyomi.presentation.widget.util.appWidgetBackgroundRadius
 import tachiyomi.presentation.widget.util.calculateRowAndColumnCount
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
-import java.util.Calendar
-import java.util.Date
+import java.time.Instant
+import java.time.ZonedDateTime
 
 abstract class BaseUpdatesGridGlanceWidget(
     private val context: Context = Injekt.get<Application>(),
@@ -89,7 +89,7 @@ abstract class BaseUpdatesGridGlanceWidget(
 
             val flow = remember {
                 getUpdates
-                    .subscribe(false, DateLimit.timeInMillis)
+                    .subscribe(false, DateLimit.toEpochMilli())
                     .map { rawData ->
                         rawData.prepareData(rowCount, columnCount)
                     }
@@ -147,10 +147,7 @@ abstract class BaseUpdatesGridGlanceWidget(
     }
 
     companion object {
-        val DateLimit: Calendar
-            get() = Calendar.getInstance().apply {
-                time = Date()
-                add(Calendar.MONTH, -3)
-            }
+        val DateLimit: Instant
+            get() = ZonedDateTime.now().minusMonths(3).toInstant()
     }
 }

+ 1 - 1
presentation-widget/src/main/java/tachiyomi/presentation/widget/WidgetManager.kt

@@ -19,7 +19,7 @@ class WidgetManager(
 
     fun Context.init(scope: LifecycleCoroutineScope) {
         combine(
-            getUpdates.subscribe(read = false, after = BaseUpdatesGridGlanceWidget.DateLimit.timeInMillis),
+            getUpdates.subscribe(read = false, after = BaseUpdatesGridGlanceWidget.DateLimit.toEpochMilli()),
             securityPreferences.useAuthenticator().changes(),
             transform = { a, _ -> a },
         )