mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	MainActivity: Avoid navigator-related crash when handling onNewIntent (#9104)
This commit is contained in:
		@@ -3,12 +3,14 @@ package eu.kanade.tachiyomi.ui.main
 | 
			
		||||
import android.animation.ValueAnimator
 | 
			
		||||
import android.app.SearchManager
 | 
			
		||||
import android.app.assist.AssistContent
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.graphics.Color
 | 
			
		||||
import android.os.Build
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.view.View
 | 
			
		||||
import android.widget.Toast
 | 
			
		||||
import androidx.activity.ComponentActivity
 | 
			
		||||
import androidx.activity.compose.BackHandler
 | 
			
		||||
import androidx.compose.foundation.isSystemInDarkTheme
 | 
			
		||||
import androidx.compose.foundation.layout.Box
 | 
			
		||||
@@ -41,6 +43,7 @@ import androidx.core.animation.doOnEnd
 | 
			
		||||
import androidx.core.net.toUri
 | 
			
		||||
import androidx.core.splashscreen.SplashScreen
 | 
			
		||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
 | 
			
		||||
import androidx.core.util.Consumer
 | 
			
		||||
import androidx.core.view.WindowCompat
 | 
			
		||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
 | 
			
		||||
import androidx.interpolator.view.animation.LinearOutSlowInInterpolator
 | 
			
		||||
@@ -86,7 +89,10 @@ import eu.kanade.tachiyomi.util.system.openInBrowser
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.toast
 | 
			
		||||
import eu.kanade.tachiyomi.util.view.setComposeContent
 | 
			
		||||
import kotlinx.coroutines.cancel
 | 
			
		||||
import kotlinx.coroutines.channels.awaitClose
 | 
			
		||||
import kotlinx.coroutines.delay
 | 
			
		||||
import kotlinx.coroutines.flow.callbackFlow
 | 
			
		||||
import kotlinx.coroutines.flow.collectLatest
 | 
			
		||||
import kotlinx.coroutines.flow.drop
 | 
			
		||||
import kotlinx.coroutines.flow.filter
 | 
			
		||||
import kotlinx.coroutines.flow.launchIn
 | 
			
		||||
@@ -120,8 +126,7 @@ class MainActivity : BaseActivity() {
 | 
			
		||||
     */
 | 
			
		||||
    private var settingsSheet: LibrarySettingsSheet? = null
 | 
			
		||||
 | 
			
		||||
    private var isHandlingShortcut: Boolean = false
 | 
			
		||||
    private lateinit var navigator: Navigator
 | 
			
		||||
    private var navigator: Navigator? = null
 | 
			
		||||
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        // Prevent splash screen showing up on configuration changes
 | 
			
		||||
@@ -211,7 +216,7 @@ class MainActivity : BaseActivity() {
 | 
			
		||||
 | 
			
		||||
                    if (savedInstanceState == null) {
 | 
			
		||||
                        // Set start screen
 | 
			
		||||
                        handleIntentAction(intent)
 | 
			
		||||
                        handleIntentAction(intent, navigator)
 | 
			
		||||
 | 
			
		||||
                        // Reset Incognito Mode on relaunch
 | 
			
		||||
                        preferences.incognitoMode().set(false)
 | 
			
		||||
@@ -257,6 +262,8 @@ class MainActivity : BaseActivity() {
 | 
			
		||||
                        .launchIn(this)
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                HandleOnNewIntent(context = context, navigator = navigator)
 | 
			
		||||
 | 
			
		||||
                CheckForUpdates()
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -289,7 +296,7 @@ class MainActivity : BaseActivity() {
 | 
			
		||||
 | 
			
		||||
    override fun onProvideAssistContent(outContent: AssistContent) {
 | 
			
		||||
        super.onProvideAssistContent(outContent)
 | 
			
		||||
        when (val screen = navigator.lastItem) {
 | 
			
		||||
        when (val screen = navigator?.lastItem) {
 | 
			
		||||
            is AssistContentScreen -> {
 | 
			
		||||
                screen.onProvideAssistUrl()?.let { outContent.webUri = it.toUri() }
 | 
			
		||||
            }
 | 
			
		||||
@@ -320,6 +327,18 @@ class MainActivity : BaseActivity() {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Composable
 | 
			
		||||
    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
 | 
			
		||||
@@ -398,37 +417,26 @@ class MainActivity : BaseActivity() {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onNewIntent(intent: Intent) {
 | 
			
		||||
        lifecycleScope.launch {
 | 
			
		||||
            val handle = handleIntentAction(intent)
 | 
			
		||||
            if (!handle) {
 | 
			
		||||
                super.onNewIntent(intent)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private suspend fun handleIntentAction(intent: Intent): Boolean {
 | 
			
		||||
    private fun handleIntentAction(intent: Intent, navigator: Navigator): Boolean {
 | 
			
		||||
        val notificationId = intent.getIntExtra("notificationId", -1)
 | 
			
		||||
        if (notificationId > -1) {
 | 
			
		||||
            NotificationReceiver.dismissNotification(applicationContext, notificationId, intent.getIntExtra("groupId", 0))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        isHandlingShortcut = true
 | 
			
		||||
 | 
			
		||||
        when (intent.action) {
 | 
			
		||||
            Constants.SHORTCUT_LIBRARY -> HomeScreen.openTab(HomeScreen.Tab.Library())
 | 
			
		||||
        val tabToOpen = when (intent.action) {
 | 
			
		||||
            Constants.SHORTCUT_LIBRARY -> HomeScreen.Tab.Library()
 | 
			
		||||
            Constants.SHORTCUT_MANGA -> {
 | 
			
		||||
                val idToOpen = intent.extras?.getLong(Constants.MANGA_EXTRA) ?: return false
 | 
			
		||||
                navigator.popUntilRoot()
 | 
			
		||||
                HomeScreen.openTab(HomeScreen.Tab.Library(idToOpen))
 | 
			
		||||
                HomeScreen.Tab.Library(idToOpen)
 | 
			
		||||
            }
 | 
			
		||||
            Constants.SHORTCUT_UPDATES -> HomeScreen.openTab(HomeScreen.Tab.Updates)
 | 
			
		||||
            Constants.SHORTCUT_HISTORY -> HomeScreen.openTab(HomeScreen.Tab.History)
 | 
			
		||||
            Constants.SHORTCUT_SOURCES -> HomeScreen.openTab(HomeScreen.Tab.Browse(false))
 | 
			
		||||
            Constants.SHORTCUT_EXTENSIONS -> HomeScreen.openTab(HomeScreen.Tab.Browse(true))
 | 
			
		||||
            Constants.SHORTCUT_UPDATES -> HomeScreen.Tab.Updates
 | 
			
		||||
            Constants.SHORTCUT_HISTORY -> HomeScreen.Tab.History
 | 
			
		||||
            Constants.SHORTCUT_SOURCES -> HomeScreen.Tab.Browse(false)
 | 
			
		||||
            Constants.SHORTCUT_EXTENSIONS -> HomeScreen.Tab.Browse(true)
 | 
			
		||||
            Constants.SHORTCUT_DOWNLOADS -> {
 | 
			
		||||
                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" -> {
 | 
			
		||||
                // If the intent match the "standard" Android search intent
 | 
			
		||||
@@ -440,6 +448,7 @@ class MainActivity : BaseActivity() {
 | 
			
		||||
                    navigator.popUntilRoot()
 | 
			
		||||
                    navigator.push(GlobalSearchScreen(query))
 | 
			
		||||
                }
 | 
			
		||||
                null
 | 
			
		||||
            }
 | 
			
		||||
            INTENT_SEARCH -> {
 | 
			
		||||
                val query = intent.getStringExtra(INTENT_SEARCH_QUERY)
 | 
			
		||||
@@ -448,15 +457,16 @@ class MainActivity : BaseActivity() {
 | 
			
		||||
                    navigator.popUntilRoot()
 | 
			
		||||
                    navigator.push(GlobalSearchScreen(query, filter))
 | 
			
		||||
                }
 | 
			
		||||
                null
 | 
			
		||||
            }
 | 
			
		||||
            else -> {
 | 
			
		||||
                isHandlingShortcut = false
 | 
			
		||||
                return false
 | 
			
		||||
            }
 | 
			
		||||
            else -> return false
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (tabToOpen != null) {
 | 
			
		||||
            lifecycleScope.launch { HomeScreen.openTab(tabToOpen) }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ready = true
 | 
			
		||||
        isHandlingShortcut = false
 | 
			
		||||
        return true
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -467,7 +477,7 @@ class MainActivity : BaseActivity() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onBackPressed() {
 | 
			
		||||
        if (navigator.size == 1 &&
 | 
			
		||||
        if (navigator?.size == 1 &&
 | 
			
		||||
            !onBackPressedDispatcher.hasEnabledCallbacks() &&
 | 
			
		||||
            libraryPreferences.autoClearChapterCache().get()
 | 
			
		||||
        ) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user