package eu.kanade.presentation.components import androidx.activity.compose.BackHandler import androidx.compose.animation.core.tween import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.togetherWith import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import cafe.adriel.voyager.core.annotation.InternalVoyagerApi import cafe.adriel.voyager.core.lifecycle.DisposableEffectIgnoringConfiguration import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.navigator.Navigator import eu.kanade.presentation.util.ScreenTransition import eu.kanade.presentation.util.isTabletUi import tachiyomi.presentation.core.components.AdaptiveSheet as AdaptiveSheetImpl @OptIn(InternalVoyagerApi::class) @Composable fun NavigatorAdaptiveSheet( screen: Screen, tonalElevation: Dp = 1.dp, enableSwipeDismiss: (Navigator) -> Boolean = { true }, onDismissRequest: () -> Unit, ) { Navigator( screen = screen, content = { sheetNavigator -> AdaptiveSheet( tonalElevation = tonalElevation, enableSwipeDismiss = enableSwipeDismiss(sheetNavigator), onDismissRequest = onDismissRequest, ) { ScreenTransition( navigator = sheetNavigator, transition = { fadeIn(animationSpec = tween(220, delayMillis = 90)) togetherWith fadeOut(animationSpec = tween(90)) }, ) BackHandler( enabled = sheetNavigator.size > 1, onBack = sheetNavigator::pop, ) } // Make sure screens are disposed no matter what if (sheetNavigator.parent?.disposeBehavior?.disposeNestedNavigators == false) { DisposableEffectIgnoringConfiguration { onDispose { sheetNavigator.items .asReversed() .forEach(sheetNavigator::dispose) } } } }, ) } /** * Sheet with adaptive position aligned to bottom on small screen, otherwise aligned to center * and will not be able to dismissed with swipe gesture. * * Max width of the content is set to 460 dp. */ @Composable fun AdaptiveSheet( onDismissRequest: () -> Unit, modifier: Modifier = Modifier, tonalElevation: Dp = 1.dp, enableSwipeDismiss: Boolean = true, content: @Composable () -> Unit, ) { val isTabletUi = isTabletUi() Dialog( onDismissRequest = onDismissRequest, properties = dialogProperties, ) { AdaptiveSheetImpl( modifier = modifier, isTabletUi = isTabletUi, tonalElevation = tonalElevation, enableSwipeDismiss = enableSwipeDismiss, onDismissRequest = onDismissRequest, ) { content() } } } private val dialogProperties = DialogProperties( usePlatformDefaultWidth = false, decorFitsSystemWindows = false, )