Skip to content

Instantly share code, notes, and snippets.

@DevSrSouza
Created May 17, 2023 13:10
Show Gist options
  • Save DevSrSouza/6a44d1665778148462faafbc2057c267 to your computer and use it in GitHub Desktop.
Save DevSrSouza/6a44d1665778148462faafbc2057c267 to your computer and use it in GitHub Desktop.
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.ProvidableCompositionLocal
import androidx.compose.runtime.remember
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.Modifier
import cafe.adriel.voyager.core.annotation.ExperimentalVoyagerApi
import cafe.adriel.voyager.core.lifecycle.DisposableEffectIgnoringConfiguration
import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.core.stack.previousItem
import cafe.adriel.voyager.navigator.Navigator
import cafe.adriel.voyager.navigator.NavigatorDisposeBehavior
import cafe.adriel.voyager.navigator.compositionUniqueId
import cafe.adriel.voyager.navigator.tab.CurrentTab
import cafe.adriel.voyager.navigator.tab.Tab
public val LocalSideBySideNavigator: ProvidableCompositionLocal<SideBySideNavigator> =
staticCompositionLocalOf { error("SideBySide not initialized") }
@Composable
public fun SideBySideNavigator(
screen: Screen,
key: String = compositionUniqueId(),
content: @Composable (SideBySideNavigator) -> Unit = { CurrentSideBySideScreen() },
) {
Navigator(
screen = screen,
disposeBehavior = NavigatorDisposeBehavior(
disposeSteps = false
),
onBackPressed = null,
key = key,
) { navigator ->
val sideBySideNavigator = remember(navigator) {
SideBySideNavigator(navigator)
}
CompositionLocalProvider(LocalSideBySideNavigator provides sideBySideNavigator) {
content(sideBySideNavigator)
}
}
}
public class SideBySideNavigator internal constructor(
internal val navigator: Navigator
) {
val left: Screen? get() = navigator.previousItem
val right: Screen get() = navigator.lastItem
@Composable
public fun saveableState(
key: String,
screen: Screen,
content: @Composable () -> Unit
) {
navigator.saveableState(key, screen, content)
}
}
@Composable
public fun CurrentSideBySideScreen() {
val sideBySideNavigator = LocalSideBySideNavigator.current
val leftScreen = sideBySideNavigator.left
val rightScreen = sideBySideNavigator.right
Row(
modifier = Modifier.fillMaxWidth(),
) {
if(leftScreen != null) {
Box(modifier = Modifier.weight(1f)) {
sideBySideNavigator.saveableState("sidebyside", leftScreen) {
leftScreen.Content()
}
}
}
Box(modifier = Modifier.weight(1f)) {
sideBySideNavigator.saveableState("sidebyside", rightScreen) {
rightScreen.Content()
}
}
}
}
@DevSrSouza
Copy link
Author

DevSrSouza commented Oct 15, 2023

a funcao push precisa ser reescrita para que possamos validar se: Se o PUSH eh feito da SCREEN anterior para a Screen nova, eh necessario fazer um pop e push da nova screen para funcionar corretamente.

Maior desafio aqui seria funcionar bem com animacoes, para esses efeitos de pop e push, a tela do lado DIREITO deveria ter uma animacao diferete

@DevSrSouza
Copy link
Author

Mas sera que faz sentido isso aqui mesmo? sera que tem algum valor esse tipo de animacao, ponde a tela anterior SEMPRE fica a mostra? Ou sera que esses cenarios so sao interessantes em casos especificos e nesses casos especificos, sera que uma nestead navigation nao seria mais util?
Ou a propria Screen ter esse behaviors?

@DevSrSouza
Copy link
Author

Eu imagino que um comportamento aceitavel desse seria parecido com um discord, barra lateral esquerda e conteudo na direita

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment