소스 검색

Add in-app app update check

arkon 3 년 전
부모
커밋
f23f22ab01

+ 1 - 0
app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt

@@ -269,6 +269,7 @@ class PreferencesHelper(val context: Context) {
 
     fun extensionUpdatesCount() = flowPrefs.getInt("ext_updates_count", 0)
 
+    fun lastAppCheck() = flowPrefs.getLong("last_app_check", 0)
     fun lastExtCheck() = flowPrefs.getLong("last_ext_check", 0)
 
     fun searchPinnedSourcesOnly() = prefs.getBoolean(Keys.searchPinnedSourcesOnly, false)

+ 9 - 4
app/src/main/java/eu/kanade/tachiyomi/data/updater/GithubUpdateChecker.kt → app/src/main/java/eu/kanade/tachiyomi/data/updater/AppUpdateChecker.kt

@@ -1,16 +1,19 @@
 package eu.kanade.tachiyomi.data.updater
 
 import eu.kanade.tachiyomi.BuildConfig
+import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 import eu.kanade.tachiyomi.network.GET
 import eu.kanade.tachiyomi.network.NetworkHelper
 import eu.kanade.tachiyomi.network.await
 import eu.kanade.tachiyomi.network.parseAs
 import eu.kanade.tachiyomi.util.lang.withIOContext
 import uy.kohesive.injekt.injectLazy
+import java.util.Date
 
-class GithubUpdateChecker {
+class AppUpdateChecker {
 
     private val networkService: NetworkHelper by injectLazy()
+    private val preferences: PreferencesHelper by injectLazy()
 
     private val repo: String by lazy {
         if (BuildConfig.DEBUG) {
@@ -20,18 +23,20 @@ class GithubUpdateChecker {
         }
     }
 
-    suspend fun checkForUpdate(): GithubUpdateResult {
+    suspend fun checkForUpdate(): AppUpdateResult {
         return withIOContext {
             networkService.client
                 .newCall(GET("https://api.github.com/repos/$repo/releases/latest"))
                 .await()
                 .parseAs<GithubRelease>()
                 .let {
+                    preferences.lastAppCheck().set(Date().time)
+
                     // Check if latest version is different from current version
                     if (isNewVersion(it.version)) {
-                        GithubUpdateResult.NewUpdate(it)
+                        AppUpdateResult.NewUpdate(it)
                     } else {
-                        GithubUpdateResult.NoNewUpdate
+                        AppUpdateResult.NoNewUpdate
                     }
                 }
         }

+ 6 - 0
app/src/main/java/eu/kanade/tachiyomi/data/updater/AppUpdateResult.kt

@@ -0,0 +1,6 @@
+package eu.kanade.tachiyomi.data.updater
+
+sealed class AppUpdateResult {
+    class NewUpdate(val release: GithubRelease) : AppUpdateResult()
+    object NoNewUpdate : AppUpdateResult()
+}

+ 0 - 6
app/src/main/java/eu/kanade/tachiyomi/data/updater/GithubUpdateResult.kt

@@ -1,6 +0,0 @@
-package eu.kanade.tachiyomi.data.updater
-
-sealed class GithubUpdateResult {
-    class NewUpdate(val release: GithubRelease) : GithubUpdateResult()
-    object NoNewUpdate : GithubUpdateResult()
-}

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdaterJob.kt

@@ -16,9 +16,9 @@ class UpdaterJob(private val context: Context, workerParams: WorkerParameters) :
 
     override fun doWork() = runBlocking {
         try {
-            val result = GithubUpdateChecker().checkForUpdate()
+            val result = AppUpdateChecker().checkForUpdate()
 
-            if (result is GithubUpdateResult.NewUpdate) {
+            if (result is AppUpdateResult.NewUpdate) {
                 UpdaterNotifier(context).promptUpdate(result.release.getDownloadLink())
             }
             Result.success()

+ 33 - 8
app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt

@@ -35,6 +35,8 @@ import eu.kanade.tachiyomi.Migrations
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.notification.NotificationReceiver
 import eu.kanade.tachiyomi.data.preference.asImmediateFlow
+import eu.kanade.tachiyomi.data.updater.AppUpdateChecker
+import eu.kanade.tachiyomi.data.updater.AppUpdateResult
 import eu.kanade.tachiyomi.databinding.MainActivityBinding
 import eu.kanade.tachiyomi.extension.api.ExtensionGithubApi
 import eu.kanade.tachiyomi.ui.base.activity.BaseViewBindingActivity
@@ -52,6 +54,7 @@ import eu.kanade.tachiyomi.ui.download.DownloadController
 import eu.kanade.tachiyomi.ui.library.LibraryController
 import eu.kanade.tachiyomi.ui.manga.MangaController
 import eu.kanade.tachiyomi.ui.more.MoreController
+import eu.kanade.tachiyomi.ui.more.NewUpdateDialogController
 import eu.kanade.tachiyomi.ui.recent.history.HistoryController
 import eu.kanade.tachiyomi.ui.recent.updates.UpdatesController
 import eu.kanade.tachiyomi.ui.setting.SettingsMainController
@@ -334,19 +337,32 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
 
     override fun onResume() {
         super.onResume()
-        getExtensionUpdates()
+
+        checkForExtensionUpdates()
+        if (BuildConfig.INCLUDE_UPDATER) {
+            checkForAppUpdates()
+        }
     }
 
-    private fun setExtensionsBadge() {
-        val updates = preferences.extensionUpdatesCount().get()
-        if (updates > 0) {
-            nav.getOrCreateBadge(R.id.nav_browse).number = updates
-        } else {
-            nav.removeBadge(R.id.nav_browse)
+    private fun checkForAppUpdates() {
+        // Limit checks to once a day at most
+        if (Date().time < preferences.lastAppCheck().get() + TimeUnit.DAYS.toMillis(1)) {
+            return
+        }
+
+        lifecycleScope.launchIO {
+            try {
+                val result = AppUpdateChecker().checkForUpdate()
+                if (result is AppUpdateResult.NewUpdate) {
+                    NewUpdateDialogController(result).showDialog(router)
+                }
+            } catch (e: Exception) {
+                Timber.e(e)
+            }
         }
     }
 
-    private fun getExtensionUpdates() {
+    private fun checkForExtensionUpdates() {
         // Limit checks to once a day at most
         if (Date().time < preferences.lastExtCheck().get() + TimeUnit.DAYS.toMillis(1)) {
             return
@@ -362,6 +378,15 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
         }
     }
 
+    private fun setExtensionsBadge() {
+        val updates = preferences.extensionUpdatesCount().get()
+        if (updates > 0) {
+            nav.getOrCreateBadge(R.id.nav_browse).number = updates
+        } else {
+            nav.removeBadge(R.id.nav_browse)
+        }
+    }
+
     private fun handleIntentAction(intent: Intent): Boolean {
         val notificationId = intent.getIntExtra("notificationId", -1)
         if (notificationId > -1) {

+ 7 - 47
app/src/main/java/eu/kanade/tachiyomi/ui/more/AboutController.kt

@@ -1,16 +1,10 @@
 package eu.kanade.tachiyomi.ui.more
 
-import android.app.Dialog
-import android.os.Bundle
-import androidx.core.os.bundleOf
 import androidx.preference.PreferenceScreen
-import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import eu.kanade.tachiyomi.BuildConfig
 import eu.kanade.tachiyomi.R
-import eu.kanade.tachiyomi.data.updater.GithubUpdateChecker
-import eu.kanade.tachiyomi.data.updater.GithubUpdateResult
-import eu.kanade.tachiyomi.data.updater.UpdaterService
-import eu.kanade.tachiyomi.ui.base.controller.DialogController
+import eu.kanade.tachiyomi.data.updater.AppUpdateChecker
+import eu.kanade.tachiyomi.data.updater.AppUpdateResult
 import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController
 import eu.kanade.tachiyomi.ui.base.controller.openInBrowser
 import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
@@ -33,12 +27,10 @@ import java.util.TimeZone
 
 class AboutController : SettingsController(), NoToolbarElevationController {
 
-    private val updateChecker by lazy { GithubUpdateChecker() }
+    private val updateChecker by lazy { AppUpdateChecker() }
 
     private val dateFormat: DateFormat = preferences.dateFormat()
 
-    private val isUpdaterEnabled = BuildConfig.INCLUDE_UPDATER
-
     override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply {
         titleRes = R.string.pref_category_about
 
@@ -60,7 +52,7 @@ class AboutController : SettingsController(), NoToolbarElevationController {
                 }
             }
         }
-        if (isUpdaterEnabled) {
+        if (BuildConfig.INCLUDE_UPDATER) {
             preference {
                 key = "pref_about_check_for_updates"
                 titleRes = R.string.check_for_updates
@@ -103,14 +95,10 @@ class AboutController : SettingsController(), NoToolbarElevationController {
         launchNow {
             try {
                 when (val result = updateChecker.checkForUpdate()) {
-                    is GithubUpdateResult.NewUpdate -> {
-                        val body = result.release.info
-                        val url = result.release.getDownloadLink()
-
-                        // Create confirmation window
-                        NewUpdateDialogController(body, url).showDialog(router)
+                    is AppUpdateResult.NewUpdate -> {
+                        NewUpdateDialogController(result).showDialog(router)
                     }
-                    is GithubUpdateResult.NoNewUpdate -> {
+                    is AppUpdateResult.NoNewUpdate -> {
                         activity?.toast(R.string.update_check_no_new_updates)
                     }
                 }
@@ -121,34 +109,6 @@ class AboutController : SettingsController(), NoToolbarElevationController {
         }
     }
 
-    class NewUpdateDialogController(bundle: Bundle? = null) : DialogController(bundle) {
-
-        constructor(body: String, url: String) : this(
-            bundleOf(BODY_KEY to body, URL_KEY to url)
-        )
-
-        override fun onCreateDialog(savedViewState: Bundle?): Dialog {
-            return MaterialAlertDialogBuilder(activity!!)
-                .setTitle(R.string.update_check_notification_update_available)
-                .setMessage(args.getString(BODY_KEY) ?: "")
-                .setPositiveButton(R.string.update_check_confirm) { _, _ ->
-                    val appContext = applicationContext
-                    if (appContext != null) {
-                        // Start download
-                        val url = args.getString(URL_KEY) ?: ""
-                        UpdaterService.start(appContext, url)
-                    }
-                }
-                .setNegativeButton(R.string.update_check_ignore, null)
-                .create()
-        }
-
-        private companion object {
-            const val BODY_KEY = "NewUpdateDialogController.body"
-            const val URL_KEY = "NewUpdateDialogController.key"
-        }
-    }
-
     private fun getFormattedBuildTime(): String {
         return try {
             val inputDf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'", Locale.US)

+ 38 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/more/NewUpdateDialogController.kt

@@ -0,0 +1,38 @@
+package eu.kanade.tachiyomi.ui.more
+
+import android.app.Dialog
+import android.os.Bundle
+import androidx.core.os.bundleOf
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import eu.kanade.tachiyomi.R
+import eu.kanade.tachiyomi.data.updater.AppUpdateResult
+import eu.kanade.tachiyomi.data.updater.UpdaterService
+import eu.kanade.tachiyomi.ui.base.controller.DialogController
+
+class NewUpdateDialogController(bundle: Bundle? = null) : DialogController(bundle) {
+
+    constructor(update: AppUpdateResult.NewUpdate) : this(
+        bundleOf(BODY_KEY to update.release.info, URL_KEY to update.release.getDownloadLink())
+    )
+
+    override fun onCreateDialog(savedViewState: Bundle?): Dialog {
+        return MaterialAlertDialogBuilder(activity!!)
+            .setTitle(R.string.update_check_notification_update_available)
+            .setMessage(args.getString(BODY_KEY) ?: "")
+            .setPositiveButton(R.string.update_check_confirm) { _, _ ->
+                val appContext = applicationContext
+                if (appContext != null) {
+                    // Start download
+                    val url = args.getString(URL_KEY) ?: ""
+                    UpdaterService.start(appContext, url)
+                }
+            }
+            .setNegativeButton(R.string.update_check_ignore, null)
+            .create()
+    }
+
+    private companion object {
+        const val BODY_KEY = "NewUpdateDialogController.body"
+        const val URL_KEY = "NewUpdateDialogController.key"
+    }
+}