12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- package eu.kanade.presentation.util
- import androidx.compose.animation.AnimatedContent
- import androidx.compose.animation.AnimatedContentTransitionScope
- import androidx.compose.animation.ContentTransform
- import androidx.compose.runtime.Composable
- import androidx.compose.runtime.ProvidableCompositionLocal
- import androidx.compose.runtime.staticCompositionLocalOf
- import androidx.compose.ui.Modifier
- import cafe.adriel.voyager.core.model.ScreenModel
- import cafe.adriel.voyager.core.model.ScreenModelStore
- import cafe.adriel.voyager.core.screen.Screen
- import cafe.adriel.voyager.core.screen.ScreenKey
- import cafe.adriel.voyager.core.screen.uniqueScreenKey
- import cafe.adriel.voyager.core.stack.StackEvent
- import cafe.adriel.voyager.navigator.Navigator
- import cafe.adriel.voyager.transitions.ScreenTransitionContent
- import kotlinx.coroutines.CoroutineName
- import kotlinx.coroutines.CoroutineScope
- import kotlinx.coroutines.Dispatchers
- import kotlinx.coroutines.SupervisorJob
- import kotlinx.coroutines.cancel
- import kotlinx.coroutines.plus
- import soup.compose.material.motion.animation.materialSharedAxisX
- import soup.compose.material.motion.animation.rememberSlideDistance
- /**
- * For invoking back press to the parent activity
- */
- val LocalBackPress: ProvidableCompositionLocal<(() -> Unit)?> = staticCompositionLocalOf { null }
- interface Tab : cafe.adriel.voyager.navigator.tab.Tab {
- suspend fun onReselect(navigator: Navigator) {}
- }
- abstract class Screen : Screen {
- override val key: ScreenKey = uniqueScreenKey
- }
- /**
- * A variant of ScreenModel.coroutineScope except with the IO dispatcher instead of the
- * main dispatcher.
- */
- val ScreenModel.ioCoroutineScope: CoroutineScope
- get() = ScreenModelStore.getOrPutDependency(
- screenModel = this,
- name = "ScreenModelIoCoroutineScope",
- factory = { key -> CoroutineScope(Dispatchers.IO + SupervisorJob()) + CoroutineName(key) },
- onDispose = { scope -> scope.cancel() },
- )
- interface AssistContentScreen {
- fun onProvideAssistUrl(): String?
- }
- @Composable
- fun DefaultNavigatorScreenTransition(navigator: Navigator) {
- val slideDistance = rememberSlideDistance()
- ScreenTransition(
- navigator = navigator,
- transition = {
- materialSharedAxisX(
- forward = navigator.lastEvent != StackEvent.Pop,
- slideDistance = slideDistance,
- )
- },
- )
- }
- @Composable
- fun ScreenTransition(
- navigator: Navigator,
- transition: AnimatedContentTransitionScope<Screen>.() -> ContentTransform,
- modifier: Modifier = Modifier,
- content: ScreenTransitionContent = { it.Content() },
- ) {
- AnimatedContent(
- targetState = navigator.lastItem,
- transitionSpec = transition,
- modifier = modifier,
- label = "ScreenTransition",
- ) { screen ->
- navigator.saveableState("transition", screen) {
- content(screen)
- }
- }
- }
|