Fix back press exit confirmation
This commit is contained in:
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.core.util.ext
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.res.Resources
|
||||
import android.database.sqlite.SQLiteFullException
|
||||
import androidx.annotation.DrawableRes
|
||||
import coil3.network.HttpException
|
||||
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 BadBackupFormatException -> resources.getString(R.string.unsupported_backup_message)
|
||||
is FileNotFoundException -> parseMessage(resources) ?: message
|
||||
|
||||
@@ -3,13 +3,15 @@ package org.koitharu.kotatsu.main.ui
|
||||
import android.view.View
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.android.material.search.SearchView
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
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.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
@@ -19,12 +21,24 @@ import org.koitharu.kotatsu.main.ui.owners.BottomNavOwner
|
||||
class ExitCallback(
|
||||
private val activity: MainActivity,
|
||||
private val snackbarHost: View,
|
||||
) : OnBackPressedCallback(false) {
|
||||
) : OnBackPressedCallback(false), SearchView.TransitionListener {
|
||||
|
||||
private var job: Job? = null
|
||||
private val isSearchOpen = MutableStateFlow(activity.viewBinding.searchView.isShowing)
|
||||
private val isDisabledByTimeout = MutableStateFlow(false)
|
||||
|
||||
init {
|
||||
observeSettings()
|
||||
activity.lifecycleScope.launch {
|
||||
combine(
|
||||
observeSettings(),
|
||||
isSearchOpen,
|
||||
isDisabledByTimeout,
|
||||
) { enabledInSettings, searchOpen, disabledTemporary ->
|
||||
enabledInSettings && !searchOpen && !disabledTemporary
|
||||
}.collect {
|
||||
isEnabled = it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
isEnabled = false
|
||||
isDisabledByTimeout.value = true
|
||||
val snackbar = Snackbar.make(snackbarHost, R.string.confirm_exit, Snackbar.LENGTH_INDEFINITE)
|
||||
snackbar.anchorView = (activity as? BottomNavOwner)?.bottomNav
|
||||
snackbar.show()
|
||||
delay(2000)
|
||||
snackbar.dismiss()
|
||||
isEnabled = true
|
||||
isDisabledByTimeout.value = false
|
||||
}
|
||||
|
||||
private fun observeSettings() {
|
||||
activity.settings
|
||||
.observeAsFlow(AppSettings.KEY_EXIT_CONFIRM) { isExitConfirmationEnabled }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.onEach { isEnabled = it }
|
||||
.launchIn(activity.lifecycleScope)
|
||||
}
|
||||
private fun observeSettings(): Flow<Boolean> = activity.settings
|
||||
.observeAsFlow(AppSettings.KEY_EXIT_CONFIRM) { isExitConfirmationEnabled }
|
||||
.flowOn(Dispatchers.Default)
|
||||
}
|
||||
|
||||
@@ -127,7 +127,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
|
||||
|
||||
addMenuProvider(MainMenuProvider(router, viewModel))
|
||||
|
||||
onBackPressedDispatcher.addCallback(ExitCallback(this, viewBinding.container))
|
||||
val exitCallback = ExitCallback(this, viewBinding.container)
|
||||
onBackPressedDispatcher.addCallback(exitCallback)
|
||||
onBackPressedDispatcher.addCallback(navigationDelegate)
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
@@ -145,6 +146,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
|
||||
searchSuggestionViewModel.isIncognitoModeEnabled.observe(this, this::onIncognitoModeChanged)
|
||||
viewBinding.bottomNav?.addOnLayoutChangeListener(this)
|
||||
viewBinding.searchView.addTransitionListener(this)
|
||||
viewBinding.searchView.addTransitionListener(exitCallback)
|
||||
initSearch()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user