From 6f3ae1934521ec43342f21eaaad6ac4f3d42bc48 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Tue, 20 Oct 2020 20:52:43 +0300 Subject: [PATCH] Checking for updates in settings --- .../koitharu/kotatsu/ui/list/MainActivity.kt | 2 +- .../ui/search/MangaSuggestionsProvider.kt | 2 +- .../kotatsu/ui/settings/AppUpdateChecker.kt | 43 +++++++++++-------- .../ui/settings/HistorySettingsFragment.kt | 12 +++--- .../ui/settings/MainSettingsFragment.kt | 31 +++++++++++++ .../koitharu/kotatsu/utils/ext/FragmentExt.kt | 6 ++- app/src/main/res/values-ru/strings.xml | 8 +++- app/src/main/res/values/constants.xml | 1 + app/src/main/res/values/strings.xml | 8 +++- app/src/main/res/xml/pref_main.xml | 16 ++++++- 10 files changed, 99 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/MainActivity.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/MainActivity.kt index 11bcbb098..f067d9b4a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/MainActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/list/MainActivity.kt @@ -76,7 +76,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList return } TrackWorker.setup(applicationContext) - AppUpdateChecker(this).invoke() + AppUpdateChecker(this).launchIfNeeded() } override fun onDestroy() { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/search/MangaSuggestionsProvider.kt b/app/src/main/java/org/koitharu/kotatsu/ui/search/MangaSuggestionsProvider.kt index 0a2cf5cff..5da084743 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/search/MangaSuggestionsProvider.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/search/MangaSuggestionsProvider.kt @@ -96,7 +96,7 @@ class MangaSuggestionsProvider : SearchRecentSuggestionsProvider() { uri, projection, " ?", - arrayOf(q.toString()), + arrayOf(q?.toString().orEmpty()), null ) } diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/AppUpdateChecker.kt b/app/src/main/java/org/koitharu/kotatsu/ui/settings/AppUpdateChecker.kt index 78ff43e12..1988467bf 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/AppUpdateChecker.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/settings/AppUpdateChecker.kt @@ -8,8 +8,8 @@ import android.net.Uri import androidx.activity.ComponentActivity import androidx.lifecycle.lifecycleScope import com.google.android.material.dialog.MaterialAlertDialogBuilder -import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job import kotlinx.coroutines.launch import org.koin.android.ext.android.inject import org.koitharu.kotatsu.BuildConfig @@ -35,29 +35,38 @@ class AppUpdateChecker(private val activity: ComponentActivity) { private val settings by activity.inject() private val repo by activity.inject() - operator fun invoke() { - if (isUpdateSupported(activity) && settings.appUpdateAuto && settings.appUpdate + PERIOD < System.currentTimeMillis()) { + fun launchIfNeeded(): Job? { + return if (settings.appUpdateAuto && settings.appUpdate + PERIOD < System.currentTimeMillis()) { launch() + } else { + null } } - private fun launch() = activity.lifecycleScope.launch(Dispatchers.Main) { - try { - val version = repo.getLatestVersion() - val newVersionId = VersionId.parse(version.name) - val currentVersionId = VersionId.parse(BuildConfig.VERSION_NAME) - if (newVersionId > currentVersionId) { - showUpdateDialog(version) - } - settings.appUpdate = System.currentTimeMillis() - } catch (_: CancellationException) { - } catch (e: Throwable) { - if (BuildConfig.DEBUG) { - e.printStackTrace() - } + fun launch(): Job? { + return if (isUpdateSupported(activity)) { + launchInternal() + } else { + null } } + suspend fun checkNow() = runCatching { + val version = repo.getLatestVersion() + val newVersionId = VersionId.parse(version.name) + val currentVersionId = VersionId.parse(BuildConfig.VERSION_NAME) + val result = newVersionId > currentVersionId + if (result) { + showUpdateDialog(version) + } + settings.appUpdate = System.currentTimeMillis() + result + }.getOrNull() + + private fun launchInternal() = activity.lifecycleScope.launch(Dispatchers.Main) { + checkNow() + } + private fun showUpdateDialog(version: AppVersion) { MaterialAlertDialogBuilder(activity) .setTitle(R.string.app_update_available) diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/HistorySettingsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/ui/settings/HistorySettingsFragment.kt index dc73e5056..c15dad45c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/HistorySettingsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/settings/HistorySettingsFragment.kt @@ -1,7 +1,6 @@ package org.koitharu.kotatsu.ui.settings import android.os.Bundle -import androidx.lifecycle.lifecycleScope import androidx.preference.Preference import com.google.android.material.snackbar.Snackbar import kotlinx.coroutines.Dispatchers @@ -16,6 +15,7 @@ import org.koitharu.kotatsu.ui.search.MangaSuggestionsProvider import org.koitharu.kotatsu.utils.CacheUtils import org.koitharu.kotatsu.utils.FileSizeUtils import org.koitharu.kotatsu.utils.ext.getDisplayMessage +import org.koitharu.kotatsu.utils.ext.viewLifecycleScope class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cache) { @@ -24,7 +24,7 @@ class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cach override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { addPreferencesFromResource(R.xml.pref_history) findPreference(R.string.key_pages_cache_clear)?.let { pref -> - lifecycleScope.launchWhenResumed { + viewLifecycleScope.launchWhenResumed { val size = withContext(Dispatchers.IO) { CacheUtils.computeCacheSize(pref.context, Cache.PAGES.dir) } @@ -32,7 +32,7 @@ class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cach } } findPreference(R.string.key_thumbs_cache_clear)?.let { pref -> - lifecycleScope.launchWhenResumed { + viewLifecycleScope.launchWhenResumed { val size = withContext(Dispatchers.IO) { CacheUtils.computeCacheSize(pref.context, Cache.THUMBS.dir) } @@ -44,7 +44,7 @@ class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cach p.summary = p.context.resources.getQuantityString(R.plurals.items, items, items) } findPreference(R.string.key_updates_feed_clear)?.let { p -> - lifecycleScope.launchWhenResumed { + viewLifecycleScope.launchWhenResumed { val items = trackerRepo.count() p.summary = p.context.resources.getQuantityString(R.plurals.items, items, items) } @@ -73,7 +73,7 @@ class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cach true } getString(R.string.key_updates_feed_clear) -> { - lifecycleScope.launch { + viewLifecycleScope.launch { trackerRepo.clearLogs() preference.summary = preference.context.resources .getQuantityString(R.plurals.items, 0, 0) @@ -91,7 +91,7 @@ class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cach private fun clearCache(preference: Preference, cache: Cache) { val ctx = preference.context.applicationContext - lifecycleScope.launch { + viewLifecycleScope.launch { try { preference.isEnabled = false val size = withContext(Dispatchers.IO) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/MainSettingsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/ui/settings/MainSettingsFragment.kt index 299c08a91..4be922f5e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/MainSettingsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/settings/MainSettingsFragment.kt @@ -12,6 +12,8 @@ import androidx.appcompat.app.AppCompatDelegate import androidx.collection.arrayMapOf import androidx.preference.* import com.google.android.material.snackbar.Snackbar +import kotlinx.coroutines.launch +import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.prefs.ListMode @@ -23,6 +25,7 @@ import org.koitharu.kotatsu.ui.settings.utils.MultiSummaryProvider import org.koitharu.kotatsu.ui.tracker.TrackWorker import org.koitharu.kotatsu.utils.ext.getStorageName import org.koitharu.kotatsu.utils.ext.md5 +import org.koitharu.kotatsu.utils.ext.viewLifecycleScope import java.io.File @@ -54,6 +57,10 @@ class MainSettingsFragment : BasePreferenceFragment(R.string.settings), } findPreference(R.string.key_protect_app)?.isChecked = !settings.appPassword.isNullOrEmpty() + findPreference(R.string.key_app_version)?.run { + title = getString(R.string.app_version, BuildConfig.VERSION_NAME) + isEnabled = AppUpdateChecker.isUpdateSupported(context) + } } override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String?) { @@ -126,6 +133,10 @@ class MainSettingsFragment : BasePreferenceFragment(R.string.settings), } true } + getString(R.string.key_app_version) -> { + checkForUpdates() + true + } else -> super.onPreferenceTreeClick(preference) } } @@ -184,6 +195,26 @@ class MainSettingsFragment : BasePreferenceFragment(R.string.settings), .show() } + private fun checkForUpdates() { + viewLifecycleScope.launch { + findPreference(R.string.key_app_version)?.run { + setSummary(R.string.checking_for_updates) + isSelectable = false + } + val result = AppUpdateChecker(activity ?: return@launch).checkNow() + findPreference(R.string.key_app_version)?.run { + setSummary( + when (result) { + true -> R.string.check_for_updates + false -> R.string.no_update_available + null -> R.string.update_check_failed + } + ) + isSelectable = true + } + } + } + private companion object { val LIST_MODES = arrayMapOf( diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt index 94f99d8df..931d9e199 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt @@ -2,10 +2,14 @@ package org.koitharu.kotatsu.utils.ext import android.os.Bundle import androidx.fragment.app.Fragment +import androidx.lifecycle.coroutineScope inline fun T.withArgs(size: Int, block: Bundle.() -> Unit): T { val b = Bundle(size) b.block() this.arguments = b return this -} \ No newline at end of file +} + +val Fragment.viewLifecycleScope + get() = viewLifecycleOwner.lifecycle.coroutineScope \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 519c804af..96e202ce5 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -96,7 +96,7 @@ Внешнее хранилище Домен По умолчанию - Обновление приложения + Проверять обновление приложения Доступно обновление приложения Показывать уведомление при наличии новой версии Открыть в браузере @@ -153,4 +153,10 @@ Запрашивать пароль при запуске приложения Повторите пароль Пароли не совпадают + О программе + Версия %s + Проверить обновления + Проверка обновления… + Ошибка при проверке обновления + Нет доступных обновлений \ No newline at end of file diff --git a/app/src/main/res/values/constants.xml b/app/src/main/res/values/constants.xml index 049e10328..da5d6debf 100644 --- a/app/src/main/res/values/constants.xml +++ b/app/src/main/res/values/constants.xml @@ -25,6 +25,7 @@ reader_animation app_password protect_app + app_version domain ssl diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index eb16bb209..5ac4f9064 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -97,7 +97,7 @@ External storage Domain Default - Application update + Check for updates automatically Application update is available Show notification if update is available Open in browser @@ -154,4 +154,10 @@ Ask for password on application start Repeat password Passwords do not match + About + Version %s + Check for updates + Checking for updates… + Update check failed + No updates available \ No newline at end of file diff --git a/app/src/main/res/xml/pref_main.xml b/app/src/main/res/xml/pref_main.xml index e1f84f00a..65c71dedc 100644 --- a/app/src/main/res/xml/pref_main.xml +++ b/app/src/main/res/xml/pref_main.xml @@ -71,7 +71,7 @@ app:iconSpaceReserved="false" /> @@ -87,7 +87,7 @@ android:defaultValue="true" android:key="@string/key_tracker_notifications" android:summary="@string/show_notification_new_chapters" - android:title="@string/new_chapters" + android:title="@string/notifications" app:iconSpaceReserved="false" /> + + + + + + \ No newline at end of file