Browse Source

Complete Settings migration to Voyager (#8639)

Now the Controller wrapper can be yeeted anytime
Ivan Iskandar 2 years ago
parent
commit
bcc21e55bd

+ 17 - 0
app/src/main/java/eu/kanade/presentation/util/Constants.kt

@@ -1,5 +1,10 @@
 package eu.kanade.presentation.util
 
+import androidx.compose.animation.ExitTransition
+import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.with
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.ui.unit.dp
@@ -24,3 +29,15 @@ class Padding {
 
 val MaterialTheme.padding: Padding
     get() = Padding()
+
+object Transition {
+
+    /**
+     * Mimics [eu.kanade.tachiyomi.ui.base.controller.OneWayFadeChangeHandler]
+     */
+    val OneWayFade = fadeIn(
+        animationSpec = tween(
+            easing = LinearEasing,
+        ),
+    ) with ExitTransition.None
+}

+ 12 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryScreen.kt

@@ -7,6 +7,8 @@ import androidx.compose.runtime.getValue
 import androidx.compose.ui.platform.LocalContext
 import cafe.adriel.voyager.core.model.rememberScreenModel
 import cafe.adriel.voyager.core.screen.Screen
+import cafe.adriel.voyager.core.screen.uniqueScreenKey
+import cafe.adriel.voyager.navigator.LocalNavigator
 import cafe.adriel.voyager.navigator.currentOrThrow
 import eu.kanade.presentation.category.CategoryScreen
 import eu.kanade.presentation.category.components.CategoryCreateDialog
@@ -19,10 +21,14 @@ import kotlinx.coroutines.flow.collectLatest
 
 class CategoryScreen : Screen {
 
+    // Fix certain crash when wrapped inside a Controller
+    override val key = uniqueScreenKey
+
     @Composable
     override fun Content() {
         val context = LocalContext.current
         val router = LocalRouter.currentOrThrow
+        val navigator = LocalNavigator.currentOrThrow
         val screenModel = rememberScreenModel { CategoryScreenModel() }
 
         val state by screenModel.state.collectAsState()
@@ -41,7 +47,12 @@ class CategoryScreen : Screen {
             onClickDelete = { screenModel.showDialog(CategoryDialog.Delete(it)) },
             onClickMoveUp = screenModel::moveUp,
             onClickMoveDown = screenModel::moveDown,
-            navigateUp = router::popCurrentController,
+            navigateUp = {
+                when {
+                    navigator.canPop -> navigator.pop()
+                    router.backstackSize > 1 -> router.handleBack()
+                }
+            },
         )
 
         when (val dialog = successState.dialog) {

+ 7 - 77
app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsMainController.kt

@@ -1,95 +1,25 @@
 package eu.kanade.tachiyomi.ui.setting
 
 import android.os.Bundle
-import androidx.compose.animation.ExitTransition
-import androidx.compose.animation.core.LinearEasing
-import androidx.compose.animation.core.tween
-import androidx.compose.animation.fadeIn
-import androidx.compose.animation.with
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.runtime.remember
-import androidx.compose.ui.platform.LocalConfiguration
 import androidx.core.os.bundleOf
 import cafe.adriel.voyager.navigator.Navigator
-import cafe.adriel.voyager.transitions.ScreenTransition
-import eu.kanade.presentation.components.TwoPanelBox
-import eu.kanade.presentation.more.settings.screen.AboutScreen
-import eu.kanade.presentation.more.settings.screen.SettingsBackupScreen
-import eu.kanade.presentation.more.settings.screen.SettingsGeneralScreen
-import eu.kanade.presentation.more.settings.screen.SettingsMainScreen
-import eu.kanade.presentation.util.LocalBackPress
-import eu.kanade.presentation.util.LocalRouter
 import eu.kanade.tachiyomi.ui.base.controller.BasicFullComposeController
-import eu.kanade.tachiyomi.util.system.isTabletUi
 
 class SettingsMainController(bundle: Bundle = bundleOf()) : BasicFullComposeController(bundle) {
 
     private val toBackupScreen = args.getBoolean(TO_BACKUP_SCREEN)
     private val toAboutScreen = args.getBoolean(TO_ABOUT_SCREEN)
 
-    /**
-     * Mimics [eu.kanade.tachiyomi.ui.base.controller.OneWayFadeChangeHandler]
-     */
-    private val transition = fadeIn(
-        animationSpec = tween(
-            easing = LinearEasing,
-        ),
-    ) with ExitTransition.None
-
     @Composable
     override fun ComposeContent() {
-        CompositionLocalProvider(LocalRouter provides router) {
-            val configuration = LocalConfiguration.current
-            val isTabletUi = remember { configuration.isTabletUi() } // won't survive config change
-            if (!isTabletUi) {
-                Navigator(
-                    screen = if (toBackupScreen) {
-                        SettingsBackupScreen
-                    } else if (toAboutScreen) {
-                        AboutScreen
-                    } else {
-                        SettingsMainScreen
-                    },
-                    content = {
-                        CompositionLocalProvider(LocalBackPress provides this::back) {
-                            ScreenTransition(
-                                navigator = it,
-                                transition = { transition },
-                            )
-                        }
-                    },
-                )
-            } else {
-                Navigator(
-                    screen = if (toBackupScreen) {
-                        SettingsBackupScreen
-                    } else if (toAboutScreen) {
-                        AboutScreen
-                    } else {
-                        SettingsGeneralScreen
-                    },
-                ) {
-                    TwoPanelBox(
-                        startContent = {
-                            CompositionLocalProvider(LocalBackPress provides this@SettingsMainController::back) {
-                                SettingsMainScreen.Content(twoPane = true)
-                            }
-                        },
-                        endContent = {
-                            ScreenTransition(
-                                navigator = it,
-                                transition = { transition },
-                            )
-                        },
-                    )
-                }
-            }
-        }
-    }
-
-    private fun back() {
-        activity?.onBackPressed()
+        Navigator(
+            screen = when {
+                toBackupScreen -> SettingsScreen.toBackupScreen()
+                toAboutScreen -> SettingsScreen.toAboutScreen()
+                else -> SettingsScreen.toMainScreen()
+            },
+        )
     }
 
     companion object {

+ 87 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsScreen.kt

@@ -0,0 +1,87 @@
+package eu.kanade.tachiyomi.ui.setting
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import cafe.adriel.voyager.core.screen.Screen
+import cafe.adriel.voyager.navigator.LocalNavigator
+import cafe.adriel.voyager.navigator.Navigator
+import cafe.adriel.voyager.navigator.currentOrThrow
+import cafe.adriel.voyager.transitions.ScreenTransition
+import eu.kanade.presentation.components.TwoPanelBox
+import eu.kanade.presentation.more.settings.screen.AboutScreen
+import eu.kanade.presentation.more.settings.screen.SettingsBackupScreen
+import eu.kanade.presentation.more.settings.screen.SettingsGeneralScreen
+import eu.kanade.presentation.more.settings.screen.SettingsMainScreen
+import eu.kanade.presentation.util.LocalBackPress
+import eu.kanade.presentation.util.LocalRouter
+import eu.kanade.presentation.util.Transition
+import eu.kanade.presentation.util.isTabletUi
+
+class SettingsScreen private constructor(
+    val toBackup: Boolean,
+    val toAbout: Boolean,
+) : Screen {
+
+    @Composable
+    override fun Content() {
+        val router = LocalRouter.currentOrThrow
+        val navigator = LocalNavigator.currentOrThrow
+        if (!isTabletUi()) {
+            val back: () -> Unit = {
+                when {
+                    navigator.canPop -> navigator.pop()
+                    router.backstackSize > 1 -> router.handleBack()
+                }
+            }
+            Navigator(
+                screen = if (toBackup) {
+                    SettingsBackupScreen
+                } else if (toAbout) {
+                    AboutScreen
+                } else {
+                    SettingsMainScreen
+                },
+                content = {
+                    CompositionLocalProvider(LocalBackPress provides back) {
+                        ScreenTransition(
+                            navigator = it,
+                            transition = { Transition.OneWayFade },
+                        )
+                    }
+                },
+            )
+        } else {
+            Navigator(
+                screen = if (toBackup) {
+                    SettingsBackupScreen
+                } else if (toAbout) {
+                    AboutScreen
+                } else {
+                    SettingsGeneralScreen
+                },
+            ) {
+                TwoPanelBox(
+                    startContent = {
+                        CompositionLocalProvider(LocalBackPress provides router::popCurrentController) {
+                            SettingsMainScreen.Content(twoPane = true)
+                        }
+                    },
+                    endContent = {
+                        ScreenTransition(
+                            navigator = it,
+                            transition = { Transition.OneWayFade },
+                        )
+                    },
+                )
+            }
+        }
+    }
+
+    companion object {
+        fun toMainScreen() = SettingsScreen(toBackup = false, toAbout = false)
+
+        fun toBackupScreen() = SettingsScreen(toBackup = true, toAbout = false)
+
+        fun toAboutScreen() = SettingsScreen(toBackup = false, toAbout = true)
+    }
+}