MainActivity: Avoid navigator-related crash when handling onNewIntent (#9104)

(cherry picked from commit d3dadf71e8d7d029fdb87b44217e001f95f21c1a)
(cherry picked from commit a163223d83e21f0dbcb74dc2887c4108f0f85449)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
This commit is contained in:
Ivan Iskandar 2023-02-18 22:08:37 +07:00 committed by Jobobby04
parent 1e3f0ad9d3
commit 3455971fe8

View File

@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.main
import android.animation.ValueAnimator import android.animation.ValueAnimator
import android.app.SearchManager import android.app.SearchManager
import android.app.assist.AssistContent import android.app.assist.AssistContent
import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Color import android.graphics.Color
import android.os.Build import android.os.Build
@ -10,6 +11,7 @@ import android.os.Bundle
import android.os.Looper import android.os.Looper
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@ -38,6 +40,7 @@ import androidx.core.animation.doOnEnd
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.core.splashscreen.SplashScreen import androidx.core.splashscreen.SplashScreen
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.util.Consumer
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import androidx.interpolator.view.animation.FastOutSlowInInterpolator import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import androidx.interpolator.view.animation.LinearOutSlowInInterpolator import androidx.interpolator.view.animation.LinearOutSlowInInterpolator
@ -89,7 +92,10 @@ import exh.source.BlacklistedSources
import exh.source.EH_SOURCE_ID import exh.source.EH_SOURCE_ID
import exh.source.EXH_SOURCE_ID import exh.source.EXH_SOURCE_ID
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
@ -128,8 +134,7 @@ class MainActivity : BaseActivity() {
*/ */
private var settingsSheet: LibrarySettingsSheet? = null private var settingsSheet: LibrarySettingsSheet? = null
private var isHandlingShortcut: Boolean = false private var navigator: Navigator? = null
private lateinit var navigator: Navigator
// SY --> // SY -->
// Idle-until-urgent // Idle-until-urgent
@ -245,7 +250,7 @@ class MainActivity : BaseActivity() {
if (savedInstanceState == null) { if (savedInstanceState == null) {
// Set start screen // Set start screen
handleIntentAction(intent) handleIntentAction(intent, navigator)
// Reset Incognito Mode on relaunch // Reset Incognito Mode on relaunch
preferences.incognitoMode().set(false) preferences.incognitoMode().set(false)
@ -305,7 +310,9 @@ class MainActivity : BaseActivity() {
.launchIn(this) .launchIn(this)
} }
CheckForUpdate() HandleOnNewIntent(context = context, navigator = navigator)
CheckForUpdates()
} }
// SY --> // SY -->
@ -348,7 +355,7 @@ class MainActivity : BaseActivity() {
override fun onProvideAssistContent(outContent: AssistContent) { override fun onProvideAssistContent(outContent: AssistContent) {
super.onProvideAssistContent(outContent) super.onProvideAssistContent(outContent)
when (val screen = navigator.lastItem) { when (val screen = navigator?.lastItem) {
is AssistContentScreen -> { is AssistContentScreen -> {
screen.onProvideAssistUrl()?.let { outContent.webUri = it.toUri() } screen.onProvideAssistUrl()?.let { outContent.webUri = it.toUri() }
} }
@ -380,7 +387,19 @@ class MainActivity : BaseActivity() {
} }
@Composable @Composable
private fun CheckForUpdate() { fun HandleOnNewIntent(context: Context, navigator: Navigator) {
LaunchedEffect(Unit) {
callbackFlow<Intent> {
val componentActivity = context as ComponentActivity
val consumer = Consumer<Intent> { trySend(it) }
componentActivity.addOnNewIntentListener(consumer)
awaitClose { componentActivity.removeOnNewIntentListener(consumer) }
}.collectLatest { handleIntentAction(it, navigator) }
}
}
@Composable
private fun CheckForUpdates() {
val context = LocalContext.current val context = LocalContext.current
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
@ -447,37 +466,26 @@ class MainActivity : BaseActivity() {
} }
} }
override fun onNewIntent(intent: Intent) { private fun handleIntentAction(intent: Intent, navigator: Navigator): Boolean {
lifecycleScope.launch {
val handle = handleIntentAction(intent)
if (!handle) {
super.onNewIntent(intent)
}
}
}
private suspend fun handleIntentAction(intent: Intent): Boolean {
val notificationId = intent.getIntExtra("notificationId", -1) val notificationId = intent.getIntExtra("notificationId", -1)
if (notificationId > -1) { if (notificationId > -1) {
NotificationReceiver.dismissNotification(applicationContext, notificationId, intent.getIntExtra("groupId", 0)) NotificationReceiver.dismissNotification(applicationContext, notificationId, intent.getIntExtra("groupId", 0))
} }
isHandlingShortcut = true val tabToOpen = when (intent.action) {
Constants.SHORTCUT_LIBRARY -> HomeScreen.Tab.Library()
when (intent.action) {
Constants.SHORTCUT_LIBRARY -> HomeScreen.openTab(HomeScreen.Tab.Library())
Constants.SHORTCUT_MANGA -> { Constants.SHORTCUT_MANGA -> {
val idToOpen = intent.extras?.getLong(Constants.MANGA_EXTRA) ?: return false val idToOpen = intent.extras?.getLong(Constants.MANGA_EXTRA) ?: return false
navigator.popUntilRoot() navigator.popUntilRoot()
HomeScreen.openTab(HomeScreen.Tab.Library(idToOpen)) HomeScreen.Tab.Library(idToOpen)
} }
Constants.SHORTCUT_UPDATES -> HomeScreen.openTab(HomeScreen.Tab.Updates) Constants.SHORTCUT_UPDATES -> HomeScreen.Tab.Updates
Constants.SHORTCUT_HISTORY -> HomeScreen.openTab(HomeScreen.Tab.History) Constants.SHORTCUT_HISTORY -> HomeScreen.Tab.History
Constants.SHORTCUT_SOURCES -> HomeScreen.openTab(HomeScreen.Tab.Browse(false)) Constants.SHORTCUT_SOURCES -> HomeScreen.Tab.Browse(false)
Constants.SHORTCUT_EXTENSIONS -> HomeScreen.openTab(HomeScreen.Tab.Browse(true)) Constants.SHORTCUT_EXTENSIONS -> HomeScreen.Tab.Browse(true)
Constants.SHORTCUT_DOWNLOADS -> { Constants.SHORTCUT_DOWNLOADS -> {
navigator.popUntilRoot() navigator.popUntilRoot()
HomeScreen.openTab(HomeScreen.Tab.More(toDownloads = true)) HomeScreen.Tab.More(toDownloads = true)
} }
Intent.ACTION_SEARCH, Intent.ACTION_SEND, "com.google.android.gms.actions.SEARCH_ACTION" -> { Intent.ACTION_SEARCH, Intent.ACTION_SEND, "com.google.android.gms.actions.SEARCH_ACTION" -> {
// If the intent match the "standard" Android search intent // If the intent match the "standard" Android search intent
@ -489,6 +497,7 @@ class MainActivity : BaseActivity() {
navigator.popUntilRoot() navigator.popUntilRoot()
navigator.push(GlobalSearchScreen(query)) navigator.push(GlobalSearchScreen(query))
} }
null
} }
INTENT_SEARCH -> { INTENT_SEARCH -> {
val query = intent.getStringExtra(INTENT_SEARCH_QUERY) val query = intent.getStringExtra(INTENT_SEARCH_QUERY)
@ -497,15 +506,16 @@ class MainActivity : BaseActivity() {
navigator.popUntilRoot() navigator.popUntilRoot()
navigator.push(GlobalSearchScreen(query, filter)) navigator.push(GlobalSearchScreen(query, filter))
} }
null
} }
else -> { else -> return false
isHandlingShortcut = false
return false
} }
if (tabToOpen != null) {
lifecycleScope.launch { HomeScreen.openTab(tabToOpen) }
} }
ready = true ready = true
isHandlingShortcut = false
return true return true
} }
@ -516,7 +526,7 @@ class MainActivity : BaseActivity() {
} }
override fun onBackPressed() { override fun onBackPressed() {
if (navigator.size == 1 && if (navigator?.size == 1 &&
!onBackPressedDispatcher.hasEnabledCallbacks() && !onBackPressedDispatcher.hasEnabledCallbacks() &&
libraryPreferences.autoClearChapterCache().get() libraryPreferences.autoClearChapterCache().get()
) { ) {