Checking for updates in settings

pull/26/head
Koitharu 6 years ago
parent 2135195f27
commit 6f3ae19345

@ -76,7 +76,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
return return
} }
TrackWorker.setup(applicationContext) TrackWorker.setup(applicationContext)
AppUpdateChecker(this).invoke() AppUpdateChecker(this).launchIfNeeded()
} }
override fun onDestroy() { override fun onDestroy() {

@ -96,7 +96,7 @@ class MangaSuggestionsProvider : SearchRecentSuggestionsProvider() {
uri, uri,
projection, projection,
" ?", " ?",
arrayOf(q.toString()), arrayOf(q?.toString().orEmpty()),
null null
) )
} }

@ -8,8 +8,8 @@ import android.net.Uri
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject import org.koin.android.ext.android.inject
import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.BuildConfig
@ -35,29 +35,38 @@ class AppUpdateChecker(private val activity: ComponentActivity) {
private val settings by activity.inject<AppSettings>() private val settings by activity.inject<AppSettings>()
private val repo by activity.inject<GithubRepository>() private val repo by activity.inject<GithubRepository>()
operator fun invoke() { fun launchIfNeeded(): Job? {
if (isUpdateSupported(activity) && settings.appUpdateAuto && settings.appUpdate + PERIOD < System.currentTimeMillis()) { return if (settings.appUpdateAuto && settings.appUpdate + PERIOD < System.currentTimeMillis()) {
launch() launch()
} else {
null
} }
} }
private fun launch() = activity.lifecycleScope.launch(Dispatchers.Main) { fun launch(): Job? {
try { return if (isUpdateSupported(activity)) {
val version = repo.getLatestVersion() launchInternal()
val newVersionId = VersionId.parse(version.name) } else {
val currentVersionId = VersionId.parse(BuildConfig.VERSION_NAME) null
if (newVersionId > currentVersionId) {
showUpdateDialog(version)
}
settings.appUpdate = System.currentTimeMillis()
} catch (_: CancellationException) {
} catch (e: Throwable) {
if (BuildConfig.DEBUG) {
e.printStackTrace()
}
} }
} }
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) { private fun showUpdateDialog(version: AppVersion) {
MaterialAlertDialogBuilder(activity) MaterialAlertDialogBuilder(activity)
.setTitle(R.string.app_update_available) .setTitle(R.string.app_update_available)

@ -1,7 +1,6 @@
package org.koitharu.kotatsu.ui.settings package org.koitharu.kotatsu.ui.settings
import android.os.Bundle import android.os.Bundle
import androidx.lifecycle.lifecycleScope
import androidx.preference.Preference import androidx.preference.Preference
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.Dispatchers 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.CacheUtils
import org.koitharu.kotatsu.utils.FileSizeUtils import org.koitharu.kotatsu.utils.FileSizeUtils
import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.getDisplayMessage
import org.koitharu.kotatsu.utils.ext.viewLifecycleScope
class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cache) { 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?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.pref_history) addPreferencesFromResource(R.xml.pref_history)
findPreference<Preference>(R.string.key_pages_cache_clear)?.let { pref -> findPreference<Preference>(R.string.key_pages_cache_clear)?.let { pref ->
lifecycleScope.launchWhenResumed { viewLifecycleScope.launchWhenResumed {
val size = withContext(Dispatchers.IO) { val size = withContext(Dispatchers.IO) {
CacheUtils.computeCacheSize(pref.context, Cache.PAGES.dir) CacheUtils.computeCacheSize(pref.context, Cache.PAGES.dir)
} }
@ -32,7 +32,7 @@ class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cach
} }
} }
findPreference<Preference>(R.string.key_thumbs_cache_clear)?.let { pref -> findPreference<Preference>(R.string.key_thumbs_cache_clear)?.let { pref ->
lifecycleScope.launchWhenResumed { viewLifecycleScope.launchWhenResumed {
val size = withContext(Dispatchers.IO) { val size = withContext(Dispatchers.IO) {
CacheUtils.computeCacheSize(pref.context, Cache.THUMBS.dir) 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) p.summary = p.context.resources.getQuantityString(R.plurals.items, items, items)
} }
findPreference<Preference>(R.string.key_updates_feed_clear)?.let { p -> findPreference<Preference>(R.string.key_updates_feed_clear)?.let { p ->
lifecycleScope.launchWhenResumed { viewLifecycleScope.launchWhenResumed {
val items = trackerRepo.count() val items = trackerRepo.count()
p.summary = p.context.resources.getQuantityString(R.plurals.items, items, items) p.summary = p.context.resources.getQuantityString(R.plurals.items, items, items)
} }
@ -73,7 +73,7 @@ class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cach
true true
} }
getString(R.string.key_updates_feed_clear) -> { getString(R.string.key_updates_feed_clear) -> {
lifecycleScope.launch { viewLifecycleScope.launch {
trackerRepo.clearLogs() trackerRepo.clearLogs()
preference.summary = preference.context.resources preference.summary = preference.context.resources
.getQuantityString(R.plurals.items, 0, 0) .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) { private fun clearCache(preference: Preference, cache: Cache) {
val ctx = preference.context.applicationContext val ctx = preference.context.applicationContext
lifecycleScope.launch { viewLifecycleScope.launch {
try { try {
preference.isEnabled = false preference.isEnabled = false
val size = withContext(Dispatchers.IO) { val size = withContext(Dispatchers.IO) {

@ -12,6 +12,8 @@ import androidx.appcompat.app.AppCompatDelegate
import androidx.collection.arrayMapOf import androidx.collection.arrayMapOf
import androidx.preference.* import androidx.preference.*
import com.google.android.material.snackbar.Snackbar 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.R
import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.model.MangaSource
import org.koitharu.kotatsu.core.prefs.ListMode 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.ui.tracker.TrackWorker
import org.koitharu.kotatsu.utils.ext.getStorageName import org.koitharu.kotatsu.utils.ext.getStorageName
import org.koitharu.kotatsu.utils.ext.md5 import org.koitharu.kotatsu.utils.ext.md5
import org.koitharu.kotatsu.utils.ext.viewLifecycleScope
import java.io.File import java.io.File
@ -54,6 +57,10 @@ class MainSettingsFragment : BasePreferenceFragment(R.string.settings),
} }
findPreference<SwitchPreference>(R.string.key_protect_app)?.isChecked = findPreference<SwitchPreference>(R.string.key_protect_app)?.isChecked =
!settings.appPassword.isNullOrEmpty() !settings.appPassword.isNullOrEmpty()
findPreference<Preference>(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?) { override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String?) {
@ -126,6 +133,10 @@ class MainSettingsFragment : BasePreferenceFragment(R.string.settings),
} }
true true
} }
getString(R.string.key_app_version) -> {
checkForUpdates()
true
}
else -> super.onPreferenceTreeClick(preference) else -> super.onPreferenceTreeClick(preference)
} }
} }
@ -184,6 +195,26 @@ class MainSettingsFragment : BasePreferenceFragment(R.string.settings),
.show() .show()
} }
private fun checkForUpdates() {
viewLifecycleScope.launch {
findPreference<Preference>(R.string.key_app_version)?.run {
setSummary(R.string.checking_for_updates)
isSelectable = false
}
val result = AppUpdateChecker(activity ?: return@launch).checkNow()
findPreference<Preference>(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 { private companion object {
val LIST_MODES = arrayMapOf( val LIST_MODES = arrayMapOf(

@ -2,10 +2,14 @@ package org.koitharu.kotatsu.utils.ext
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.coroutineScope
inline fun <T : Fragment> T.withArgs(size: Int, block: Bundle.() -> Unit): T { inline fun <T : Fragment> T.withArgs(size: Int, block: Bundle.() -> Unit): T {
val b = Bundle(size) val b = Bundle(size)
b.block() b.block()
this.arguments = b this.arguments = b
return this return this
} }
val Fragment.viewLifecycleScope
get() = viewLifecycleOwner.lifecycle.coroutineScope

@ -96,7 +96,7 @@
<string name="external_storage">Внешнее хранилище</string> <string name="external_storage">Внешнее хранилище</string>
<string name="domain">Домен</string> <string name="domain">Домен</string>
<string name="_default">По умолчанию</string> <string name="_default">По умолчанию</string>
<string name="application_update">Обновление приложения</string> <string name="application_update">Проверять обновление приложения</string>
<string name="app_update_available">Доступно обновление приложения</string> <string name="app_update_available">Доступно обновление приложения</string>
<string name="show_notification_app_update">Показывать уведомление при наличии новой версии</string> <string name="show_notification_app_update">Показывать уведомление при наличии новой версии</string>
<string name="open_in_browser">Открыть в браузере</string> <string name="open_in_browser">Открыть в браузере</string>
@ -153,4 +153,10 @@
<string name="protect_application_summary">Запрашивать пароль при запуске приложения</string> <string name="protect_application_summary">Запрашивать пароль при запуске приложения</string>
<string name="repeat_password">Повторите пароль</string> <string name="repeat_password">Повторите пароль</string>
<string name="passwords_mismatch">Пароли не совпадают</string> <string name="passwords_mismatch">Пароли не совпадают</string>
<string name="about">О программе</string>
<string name="app_version">Версия %s</string>
<string name="check_for_updates">Проверить обновления</string>
<string name="checking_for_updates">Проверка обновления…</string>
<string name="update_check_failed">Ошибка при проверке обновления</string>
<string name="no_update_available">Нет доступных обновлений</string>
</resources> </resources>

@ -25,6 +25,7 @@
<string name="key_reader_animation">reader_animation</string> <string name="key_reader_animation">reader_animation</string>
<string name="key_app_password">app_password</string> <string name="key_app_password">app_password</string>
<string name="key_protect_app">protect_app</string> <string name="key_protect_app">protect_app</string>
<string name="key_app_version">app_version</string>
<string name="key_parser_domain">domain</string> <string name="key_parser_domain">domain</string>
<string name="key_parser_ssl">ssl</string> <string name="key_parser_ssl">ssl</string>

@ -97,7 +97,7 @@
<string name="external_storage">External storage</string> <string name="external_storage">External storage</string>
<string name="domain">Domain</string> <string name="domain">Domain</string>
<string name="_default">Default</string> <string name="_default">Default</string>
<string name="application_update">Application update</string> <string name="application_update">Check for updates automatically</string>
<string name="app_update_available">Application update is available</string> <string name="app_update_available">Application update is available</string>
<string name="show_notification_app_update">Show notification if update is available</string> <string name="show_notification_app_update">Show notification if update is available</string>
<string name="open_in_browser">Open in browser</string> <string name="open_in_browser">Open in browser</string>
@ -154,4 +154,10 @@
<string name="protect_application_summary">Ask for password on application start</string> <string name="protect_application_summary">Ask for password on application start</string>
<string name="repeat_password">Repeat password</string> <string name="repeat_password">Repeat password</string>
<string name="passwords_mismatch">Passwords do not match</string> <string name="passwords_mismatch">Passwords do not match</string>
<string name="about">About</string>
<string name="app_version">Version %s</string>
<string name="check_for_updates">Check for updates</string>
<string name="checking_for_updates">Checking for updates…</string>
<string name="update_check_failed">Update check failed</string>
<string name="no_update_available">No updates available</string>
</resources> </resources>

@ -71,7 +71,7 @@
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<PreferenceCategory <PreferenceCategory
android:title="@string/notifications" android:title="@string/new_chapters"
app:allowDividerAbove="true" app:allowDividerAbove="true"
app:iconSpaceReserved="false"> app:iconSpaceReserved="false">
@ -87,7 +87,7 @@
android:defaultValue="true" android:defaultValue="true"
android:key="@string/key_tracker_notifications" android:key="@string/key_tracker_notifications"
android:summary="@string/show_notification_new_chapters" android:summary="@string/show_notification_new_chapters"
android:title="@string/new_chapters" android:title="@string/notifications"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<Preference <Preference
@ -96,6 +96,12 @@
android:title="@string/notifications_settings" android:title="@string/notifications_settings"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
</PreferenceCategory>
<PreferenceCategory
android:title="@string/about"
app:iconSpaceReserved="false">
<SwitchPreference <SwitchPreference
android:defaultValue="true" android:defaultValue="true"
android:key="@string/key_app_update_auto" android:key="@string/key_app_update_auto"
@ -105,6 +111,12 @@
app:isPreferenceVisible="false" app:isPreferenceVisible="false"
tools:isPreferenceVisible="true" /> tools:isPreferenceVisible="true" />
<Preference
android:key="@string/key_app_version"
android:persistent="false"
android:summary="@string/check_for_updates"
app:iconSpaceReserved="false" />
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>
Loading…
Cancel
Save