Преглед изворни кода

fix: 修复阅读页后台恢复路由

HapeLee пре 4 месеци
родитељ
комит
3577de5f69

+ 47 - 4
app/src/main/java/io/legado/app/ui/main/MainActivity.kt

@@ -21,6 +21,7 @@ import androidx.compose.animation.togetherWith
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.snapshotFlow
 import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
 import androidx.lifecycle.lifecycleScope
 import androidx.navigation3.runtime.NavKey
@@ -66,6 +67,12 @@ import kotlin.coroutines.suspendCoroutine
 open class MainActivity : BaseComposeActivity(), VariableDialog.Callback {
 
     companion object {
+        private const val KEY_RESTORE_READ_ROUTE = "restoreReadRoute"
+        private const val KEY_RESTORE_READ_BOOK_URL = "restoreReadBookUrl"
+        private const val KEY_RESTORE_READ_ALOUD = "restoreReadAloud"
+        private const val KEY_RESTORE_READ_IN_BOOKSHELF = "restoreReadInBookshelf"
+        private const val KEY_RESTORE_READ_CHAPTER_CHANGED = "restoreReadChapterChanged"
+
         @Volatile
         var hasActiveReadBookRoute: Boolean = false
 
@@ -141,10 +148,14 @@ open class MainActivity : BaseComposeActivity(), VariableDialog.Callback {
     private val viewModel by viewModel<MainViewModel>()
     private val routeEvents = MutableSharedFlow<NavKey>(extraBufferCapacity = 1)
     private var bookInfoVariableSetter: ((String, String?) -> Unit)? = null
+    private var restoredReadBookRoute: MainRouteReadBook? = null
+    private var latestBackStack: List<NavKey> = emptyList()
     internal var activeReadBookInputHandler: ReadBookInputHandler? = null
+    internal var activeReadBookRoute: MainRouteReadBook? = null
 
     override fun onCreate(savedInstanceState: Bundle?) {
         installSplashScreen()
+        restoredReadBookRoute = savedInstanceState?.restoreReadBookRoute()
         super.onCreate(savedInstanceState)
 
         if (checkStartupRoute()) return
@@ -193,12 +204,20 @@ open class MainActivity : BaseComposeActivity(), VariableDialog.Callback {
 
         val startRoutes = remember {
             val resolved = MainNavigator.resolveStartRoute(intent)
-            if (OtherConfig.defaultToRead && resolved == MainRouteHome) {
-                arrayOf(MainRouteHome, MainRouteReadBook())
-            } else {
-                arrayOf(resolved)
+            val hasExplicitStartRoute = intent?.hasExtra(MainIntent.EXTRA_START_ROUTE) == true
+            when {
+                !hasExplicitStartRoute && restoredReadBookRoute != null -> {
+                    arrayOf(MainRouteHome, restoredReadBookRoute!!)
+                }
+                OtherConfig.defaultToRead && resolved == MainRouteHome -> {
+                    arrayOf(MainRouteHome, MainRouteReadBook())
+                }
+                else -> {
+                    arrayOf(resolved)
+                }
             }
         }
+        latestBackStack = startRoutes.toList()
         val backStack = rememberNavBackStack(*startRoutes)
 
         LaunchedEffect(backStack) {
@@ -207,6 +226,11 @@ open class MainActivity : BaseComposeActivity(), VariableDialog.Callback {
             }
         }
 
+        LaunchedEffect(backStack) {
+            snapshotFlow { backStack.toList() }
+                .collect { latestBackStack = it }
+        }
+
         SharedTransitionLayout {
             NavDisplay(
                 backStack = backStack,
@@ -369,6 +393,25 @@ open class MainActivity : BaseComposeActivity(), VariableDialog.Callback {
         if (AppConfig.autoRefreshBook) {
             outState.putBoolean("isAutoRefreshedBook", true)
         }
+        val readRoute = latestBackStack.lastOrNull() as? MainRouteReadBook
+            ?: activeReadBookRoute
+        if (readRoute != null) {
+            outState.putBoolean(KEY_RESTORE_READ_ROUTE, true)
+            outState.putString(KEY_RESTORE_READ_BOOK_URL, readRoute.bookUrl)
+            outState.putBoolean(KEY_RESTORE_READ_ALOUD, readRoute.readAloud)
+            outState.putBoolean(KEY_RESTORE_READ_IN_BOOKSHELF, readRoute.inBookshelf)
+            outState.putBoolean(KEY_RESTORE_READ_CHAPTER_CHANGED, readRoute.chapterChanged)
+        }
+    }
+
+    private fun Bundle.restoreReadBookRoute(): MainRouteReadBook? {
+        if (!getBoolean(KEY_RESTORE_READ_ROUTE, false)) return null
+        return MainRouteReadBook(
+            bookUrl = getString(KEY_RESTORE_READ_BOOK_URL),
+            readAloud = getBoolean(KEY_RESTORE_READ_ALOUD, false),
+            inBookshelf = getBoolean(KEY_RESTORE_READ_IN_BOOKSHELF, true),
+            chapterChanged = getBoolean(KEY_RESTORE_READ_CHAPTER_CHANGED, false),
+        )
     }
 
     override fun dispatchKeyEvent(event: KeyEvent): Boolean {

+ 4 - 0
app/src/main/java/io/legado/app/ui/main/MainNavGraph.kt

@@ -310,6 +310,7 @@ fun MainActivity.mainEntryProvider(
 
         DisposableEffect(controller, lifecycleOwner, route.readAloud) {
             activeReadBookInputHandler = controller
+            activeReadBookRoute = route
             MainActivity.hasActiveReadBookRoute = true
             controller.onClose = { onNavigateBack() }
             controller.onStartContentLoadFinish = {
@@ -335,6 +336,9 @@ fun MainActivity.mainEntryProvider(
                 if (activeReadBookInputHandler === controller) {
                     activeReadBookInputHandler = null
                 }
+                if (activeReadBookRoute == route) {
+                    activeReadBookRoute = null
+                }
                 MainActivity.hasActiveReadBookRoute = false
                 controller.clearTts()
             }