diff --git a/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt b/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt index 87f5ed17f..ea22574c3 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt @@ -155,7 +155,7 @@ object Settings : DataStorePreferences(null) { var searchCategory by intPref("search_pref", EhUtils.ALL_CATEGORY) var requestNewsTimerHour by intPref("request_news_timer_hour", -1) var requestNewsTimerMinute by intPref("request_news_timer_minute", -1) - var updateIntervalDays by intPref("update_interval_days", 0) + var updateIntervalDays by intPref("update_interval_days", 7) var recentToplist by stringPref("recent_toplist", "11") var userAgent by stringPref("user_agent", CHROME_USER_AGENT) var recentDownloadLabel by stringOrNullPref("recent_download_label", null) @@ -163,8 +163,8 @@ object Settings : DataStorePreferences(null) { var displayName by stringOrNullPref("display_name", null) var avatar by stringOrNullPref("avatar", null) var language by stringPref("app_language", "system").observed { updateWhenLocaleChanges() } - var lastDawnDay by longPref("last_dawn_day", 0) - var lastUpdateDay by longPref("last_update_day", 0) + var lastDawnTime by longPref("last_dawn_time", 0) + var lastUpdateTime by longPref("last_update_time", 0) var favDialogTheta by floatPref("fav_select_dialog_delta", 0F) // TODO: Remove this after swipe gestures are correctly handled in compose diff --git a/app/src/main/kotlin/com/hippo/ehviewer/client/EhEngine.kt b/app/src/main/kotlin/com/hippo/ehviewer/client/EhEngine.kt index 409ce5853..a26ad230f 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/client/EhEngine.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/client/EhEngine.kt @@ -48,7 +48,6 @@ import com.hippo.ehviewer.client.parser.TorrentResult import com.hippo.ehviewer.client.parser.VoteCommentResult import com.hippo.ehviewer.client.parser.VoteTagParser import com.hippo.ehviewer.dailycheck.showEventNotification -import com.hippo.ehviewer.dailycheck.today import com.hippo.ehviewer.util.AppConfig import com.hippo.ehviewer.util.StatusCodeException import eu.kanade.tachiyomi.util.system.logcat @@ -66,6 +65,7 @@ import java.nio.ByteBuffer import kotlin.math.ceil import kotlinx.coroutines.CancellationException import kotlinx.coroutines.delay +import kotlinx.datetime.Clock import kotlinx.serialization.SerializationException import kotlinx.serialization.json.add import kotlinx.serialization.json.addJsonArray @@ -216,7 +216,7 @@ object EhEngine { suspend fun getGalleryDetail(url: String) = statement(url, EhUrl.referer).parseString { val eventPane = EventPaneParser.parse(this) if (eventPane != null) { - Settings.lastDawnDay = today + Settings.lastDawnTime = Clock.System.now().epochSeconds showEventNotification(eventPane) } GalleryDetailParser.parse(this) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/dailycheck/DailyCheckWork.kt b/app/src/main/kotlin/com/hippo/ehviewer/dailycheck/DailyCheckWork.kt index 64210a6e1..eb4a95478 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/dailycheck/DailyCheckWork.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/dailycheck/DailyCheckWork.kt @@ -25,15 +25,17 @@ import com.hippo.ehviewer.client.EhCookieStore import com.hippo.ehviewer.client.EhEngine import eu.kanade.tachiyomi.util.lang.withIOContext import java.time.Duration -import java.time.Instant -import java.time.LocalDateTime -import java.time.temporal.ChronoUnit import java.util.concurrent.TimeUnit +import kotlin.time.Duration.Companion.days +import kotlinx.datetime.Clock +import kotlinx.datetime.Instant +import kotlinx.datetime.LocalDateTime +import kotlinx.datetime.LocalTime +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toInstant +import kotlinx.datetime.toLocalDateTime import splitties.init.appCtx -private val signedIn - get() = EhCookieStore.hasSignedIn() - private const val CHANNEL_ID = "DailyCheckNotification" class DailyCheckWork(context: Context, workerParams: WorkerParameters) : @@ -52,22 +54,20 @@ val schedHour val schedMinute get() = Settings.requestNewsTimerMinute.takeUnless { it == -1 } ?: 0 -private val whenToWork - get() = LocalDateTime.now() - .run { withHour(schedHour) } - .run { withMinute(schedMinute) } - -private val initialDelay - get() = Duration.between(LocalDateTime.now(), whenToWork) - .run { if (isNegative) plusDays(1) else this } - private fun getDailyCheckWorkRequest(): PeriodicWorkRequest { + val now = Clock.System.now() + val timeZone = TimeZone.currentSystemDefault() + val whenToWork = LocalDateTime( + now.toLocalDateTime(timeZone).date, + LocalTime(schedHour, schedMinute), + ).toInstant(timeZone) + val initialDelay = (whenToWork - now).run { if (isNegative()) plus(1.days) else this } val constraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .build() return PeriodicWorkRequestBuilder(Duration.ofDays(1)) .setConstraints(constraints) - .setInitialDelay(initialDelay.seconds, TimeUnit.SECONDS) + .setInitialDelay(initialDelay.inWholeSeconds, TimeUnit.SECONDS) .build() } @@ -85,13 +85,12 @@ fun updateDailyCheckWork(context: Context) { } } -val today - get() = Instant.now().truncatedTo(ChronoUnit.DAYS).epochSecond - suspend fun checkDawn() = runCatching { - if (signedIn && Settings.lastDawnDay != today) { + val now = Clock.System.now() + val last = Instant.fromEpochSeconds(Settings.lastDawnTime) + if (EhCookieStore.hasSignedIn() && now > last + 1.days) { EhEngine.getNews(true)?.let { - Settings.lastDawnDay = today + Settings.lastDawnTime = now.epochSeconds showEventNotification(it) } } diff --git a/app/src/main/kotlin/com/hippo/ehviewer/dao/DownloadInfo.kt b/app/src/main/kotlin/com/hippo/ehviewer/dao/DownloadInfo.kt index bb6694769..25a2d52d4 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/dao/DownloadInfo.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/dao/DownloadInfo.kt @@ -10,7 +10,7 @@ import androidx.room.Relation import com.hippo.ehviewer.client.data.AbstractDownloadInfo import com.hippo.ehviewer.client.data.BaseGalleryInfo import com.hippo.ehviewer.client.data.GalleryInfo -import java.time.Instant +import kotlinx.datetime.Clock @Entity( tableName = "DOWNLOADS", @@ -37,7 +37,7 @@ data class DownloadEntity( override var legacy: Int = 0, @ColumnInfo(name = "TIME") - override var time: Long = Instant.now().toEpochMilli(), + override var time: Long = Clock.System.now().toEpochMilliseconds(), @ColumnInfo(name = "LABEL", index = true) override var label: String? = null, diff --git a/app/src/main/kotlin/com/hippo/ehviewer/dao/HistoryInfo.kt b/app/src/main/kotlin/com/hippo/ehviewer/dao/HistoryInfo.kt index 2ccd5d296..8d245aaa8 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/dao/HistoryInfo.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/dao/HistoryInfo.kt @@ -3,7 +3,7 @@ package com.hippo.ehviewer.dao import androidx.room.Entity import androidx.room.ForeignKey import com.hippo.ehviewer.client.data.BaseGalleryInfo -import java.time.Instant +import kotlinx.datetime.Clock @Entity(tableName = "HISTORY", foreignKeys = [ForeignKey(BaseGalleryInfo::class, ["GID"], ["GID"])]) -class HistoryInfo(gid: Long, time: Long = Instant.now().toEpochMilli()) : TimeInfo(gid, time) +class HistoryInfo(gid: Long, time: Long = Clock.System.now().toEpochMilliseconds()) : TimeInfo(gid, time) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/dao/LocalFavoriteInfo.kt b/app/src/main/kotlin/com/hippo/ehviewer/dao/LocalFavoriteInfo.kt index 48fab966b..513231aea 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/dao/LocalFavoriteInfo.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/dao/LocalFavoriteInfo.kt @@ -3,7 +3,7 @@ package com.hippo.ehviewer.dao import androidx.room.Entity import androidx.room.ForeignKey import com.hippo.ehviewer.client.data.BaseGalleryInfo -import java.time.Instant +import kotlinx.datetime.Clock @Entity(tableName = "LOCAL_FAVORITES", foreignKeys = [ForeignKey(BaseGalleryInfo::class, ["GID"], ["GID"])]) -class LocalFavoriteInfo(gid: Long = 0, time: Long = Instant.now().toEpochMilli()) : TimeInfo(gid, time) +class LocalFavoriteInfo(gid: Long = 0, time: Long = Clock.System.now().toEpochMilliseconds()) : TimeInfo(gid, time) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderQueen.kt b/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderQueen.kt index 714f129fc..807975c03 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderQueen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderQueen.kt @@ -41,9 +41,10 @@ import com.hippo.ehviewer.image.Image import com.hippo.ehviewer.util.ExceptionUtils import com.hippo.unifile.UniFile import eu.kanade.tachiyomi.util.lang.launchIO -import java.time.Instant import java.util.concurrent.atomic.AtomicInteger +import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds +import kotlin.time.TimeSource import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -368,8 +369,7 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS referer, ).parseString { val pages = parsePages(this) - val spiderInfo = SpiderInfo(galleryInfo.gid, pages) - spiderInfo.token = galleryInfo.token + val spiderInfo = SpiderInfo(galleryInfo.gid, pages, token = galleryInfo.token) readPreviews(this, 0, spiderInfo) spiderInfo } @@ -519,10 +519,10 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS private val pTokenLock = Mutex() private var showKey: String? = null private val showKeyLock = Mutex() - private val mDownloadDelay = Settings.downloadDelay.toLong() + private val mDownloadDelay = Settings.downloadDelay.milliseconds private val downloadTimeout = Settings.downloadTimeout.seconds private val delayLock = Mutex() - private var delayedTime = 0L + private var delayedTime = TimeSource.Monotonic.markNow() private var isDownloadMode = false fun cancelDecode(index: Int) { @@ -608,9 +608,14 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS } delayLock.withLock { - val curTime = Instant.now().toEpochMilli() - delayedTime = (delayedTime + mDownloadDelay).coerceAtLeast(curTime) - delay(delayedTime - curTime) + val new = delayedTime + mDownloadDelay + val duration = new.elapsedNow() + if (duration.isNegative()) { + delayedTime = new + delay(-duration) + } else { + delayedTime = TimeSource.Monotonic.markNow() + } } var skipHathKey: String? = null diff --git a/app/src/main/kotlin/com/hippo/ehviewer/updater/AppUpdater.kt b/app/src/main/kotlin/com/hippo/ehviewer/updater/AppUpdater.kt index ab57a321f..37dc5ee67 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/updater/AppUpdater.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/updater/AppUpdater.kt @@ -13,11 +13,12 @@ import io.ktor.utils.io.close import io.ktor.utils.io.copyTo import io.ktor.utils.io.jvm.javaio.toInputStream import java.io.File -import java.time.Instant -import java.time.temporal.ChronoUnit import java.util.zip.ZipInputStream import kotlin.io.encoding.Base64 import kotlin.io.encoding.ExperimentalEncodingApi +import kotlin.time.Duration.Companion.days +import kotlinx.datetime.Clock +import kotlinx.datetime.Instant import moe.tarsin.coroutines.runSuspendCatching import org.json.JSONObject import tachiyomi.data.release.GithubArtifacts @@ -30,11 +31,11 @@ private const val LATEST_RELEASE_URL = "$API_URL/releases/latest" object AppUpdater { suspend fun checkForUpdate(forceCheck: Boolean = false): Release? { - val now = Instant.now() - val lastChecked = Instant.ofEpochSecond(Settings.lastUpdateDay) + val now = Clock.System.now() + val last = Instant.fromEpochSeconds(Settings.lastUpdateTime) val interval = Settings.updateIntervalDays - if (forceCheck || interval != 0 && now.isAfter(lastChecked.plus(interval.toLong(), ChronoUnit.DAYS))) { - Settings.lastUpdateDay = now.epochSecond + if (forceCheck || interval != 0 && now > last + interval.days) { + Settings.lastUpdateTime = now.epochSeconds if (Settings.useCIUpdateChannel) { val curSha = BuildConfig.COMMIT_SHA val branch = ghStatement(API_URL).execute { JSONObject(it.bodyAsText()).getString("default_branch") }