diff --git a/app/src/main/java/eu/kanade/presentation/util/Constants.kt b/app/src/main/java/eu/kanade/presentation/util/Constants.kt index 651ad0853..c3b0243dc 100644 --- a/app/src/main/java/eu/kanade/presentation/util/Constants.kt +++ b/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 +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryScreen.kt index eb19a475a..02b5e6f3f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryScreen.kt +++ b/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) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsMainController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsMainController.kt index 18fbfbbc7..35961763a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsMainController.kt +++ b/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 { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsScreen.kt new file mode 100644 index 000000000..efb4b5c94 --- /dev/null +++ b/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) + } +}