Fix back press exit confirmation

master
Koitharu 10 months ago
parent e549d141a4
commit 40584cb6f5
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -2,6 +2,7 @@ package org.koitharu.kotatsu.core.util.ext
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.res.Resources import android.content.res.Resources
import android.database.sqlite.SQLiteFullException
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import coil3.network.HttpException import coil3.network.HttpException
import com.davemorrissey.labs.subscaleview.decoder.ImageDecodeException import com.davemorrissey.labs.subscaleview.decoder.ImageDecodeException
@ -91,6 +92,7 @@ private fun Throwable.getDisplayMessageOrNull(resources: Resources): String? = w
} }
} }
is SQLiteFullException -> resources.getString(R.string.error_no_space_left)
is UnsupportedFileException -> resources.getString(R.string.text_file_not_supported) is UnsupportedFileException -> resources.getString(R.string.text_file_not_supported)
is BadBackupFormatException -> resources.getString(R.string.unsupported_backup_message) is BadBackupFormatException -> resources.getString(R.string.unsupported_backup_message)
is FileNotFoundException -> parseMessage(resources) ?: message is FileNotFoundException -> parseMessage(resources) ?: message

@ -3,13 +3,15 @@ package org.koitharu.kotatsu.main.ui
import android.view.View import android.view.View
import androidx.activity.OnBackPressedCallback import androidx.activity.OnBackPressedCallback
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.google.android.material.search.SearchView
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
@ -19,12 +21,24 @@ import org.koitharu.kotatsu.main.ui.owners.BottomNavOwner
class ExitCallback( class ExitCallback(
private val activity: MainActivity, private val activity: MainActivity,
private val snackbarHost: View, private val snackbarHost: View,
) : OnBackPressedCallback(false) { ) : OnBackPressedCallback(false), SearchView.TransitionListener {
private var job: Job? = null private var job: Job? = null
private val isSearchOpen = MutableStateFlow(activity.viewBinding.searchView.isShowing)
private val isDisabledByTimeout = MutableStateFlow(false)
init { init {
observeSettings() activity.lifecycleScope.launch {
combine(
observeSettings(),
isSearchOpen,
isDisabledByTimeout,
) { enabledInSettings, searchOpen, disabledTemporary ->
enabledInSettings && !searchOpen && !disabledTemporary
}.collect {
isEnabled = it
}
}
} }
override fun handleOnBackPressed() { override fun handleOnBackPressed() {
@ -34,21 +48,25 @@ class ExitCallback(
} }
} }
override fun onStateChanged(
searchView: SearchView,
previousState: SearchView.TransitionState,
newState: SearchView.TransitionState
) {
isSearchOpen.value = newState >= SearchView.TransitionState.SHOWING
}
private suspend fun resetExitConfirmation() { private suspend fun resetExitConfirmation() {
isEnabled = false isDisabledByTimeout.value = true
val snackbar = Snackbar.make(snackbarHost, R.string.confirm_exit, Snackbar.LENGTH_INDEFINITE) val snackbar = Snackbar.make(snackbarHost, R.string.confirm_exit, Snackbar.LENGTH_INDEFINITE)
snackbar.anchorView = (activity as? BottomNavOwner)?.bottomNav snackbar.anchorView = (activity as? BottomNavOwner)?.bottomNav
snackbar.show() snackbar.show()
delay(2000) delay(2000)
snackbar.dismiss() snackbar.dismiss()
isEnabled = true isDisabledByTimeout.value = false
} }
private fun observeSettings() { private fun observeSettings(): Flow<Boolean> = activity.settings
activity.settings .observeAsFlow(AppSettings.KEY_EXIT_CONFIRM) { isExitConfirmationEnabled }
.observeAsFlow(AppSettings.KEY_EXIT_CONFIRM) { isExitConfirmationEnabled } .flowOn(Dispatchers.Default)
.flowOn(Dispatchers.Default)
.onEach { isEnabled = it }
.launchIn(activity.lifecycleScope)
}
} }

@ -127,7 +127,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
addMenuProvider(MainMenuProvider(router, viewModel)) addMenuProvider(MainMenuProvider(router, viewModel))
onBackPressedDispatcher.addCallback(ExitCallback(this, viewBinding.container)) val exitCallback = ExitCallback(this, viewBinding.container)
onBackPressedDispatcher.addCallback(exitCallback)
onBackPressedDispatcher.addCallback(navigationDelegate) onBackPressedDispatcher.addCallback(navigationDelegate)
if (savedInstanceState == null) { if (savedInstanceState == null) {
@ -145,6 +146,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
searchSuggestionViewModel.isIncognitoModeEnabled.observe(this, this::onIncognitoModeChanged) searchSuggestionViewModel.isIncognitoModeEnabled.observe(this, this::onIncognitoModeChanged)
viewBinding.bottomNav?.addOnLayoutChangeListener(this) viewBinding.bottomNav?.addOnLayoutChangeListener(this)
viewBinding.searchView.addTransitionListener(this) viewBinding.searchView.addTransitionListener(this)
viewBinding.searchView.addTransitionListener(exitCallback)
initSearch() initSearch()
} }

Loading…
Cancel
Save