Skip to content

Commit

Permalink
Push Cobalt prototype changes for 19.06.2023
Browse files Browse the repository at this point in the history
  • Loading branch information
iTaysonLab committed Jun 19, 2023
1 parent 931fac4 commit 406d40d
Show file tree
Hide file tree
Showing 33 changed files with 1,061 additions and 107 deletions.
1 change: 1 addition & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ android {
dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3")
implementation("androidx.compose.ui:ui-text-google-fonts:1.4.3")
implementation("me.onebone:toolbar-compose:2.3.5")

implementation(project(":core:decomposekit"))
implementation(project(":core:ksteam"))
Expand All @@ -70,6 +71,7 @@ dependencies {
implementation(project(":feature:news"))
implementation(project(":feature:home"))
implementation(project(":feature:webview"))
implementation(project(":feature:profile"))

implementation(libs.androidKtxCore)
implementation(libs.androidKtxActivity)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,28 @@ package bruhcollective.itaysonlab.jetisteam.navigation

import bruhcollective.itaysonlab.cobalt.news.DefaultNewsRootComponent
import bruhcollective.itaysonlab.cobalt.news.NewsRootComponent
import bruhcollective.itaysonlab.cobalt.profile.MyProfileComponent
import bruhcollective.itaysonlab.cobalt.profile.ProfileComponent
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.router.stack.ChildStack
import com.arkivanov.decompose.router.stack.StackNavigation
import com.arkivanov.decompose.router.stack.bringToFront
import com.arkivanov.decompose.router.stack.childStack
import com.arkivanov.decompose.value.MutableValue
import com.arkivanov.decompose.value.Value
import com.arkivanov.essenty.parcelable.Parcelable
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import kotlinx.parcelize.Parcelize

class CobaltContainerComponent(
componentContext: ComponentContext
): ComponentContext by componentContext {
private val navigation = StackNavigation<Config>()
private val _currentNavigationItem = MutableValue(NavigationItem.Home)

val currentNavigationItem: Value<NavigationItem> = _currentNavigationItem
val navigationItems: Value<ImmutableList<NavigationItem>> = MutableValue(NavigationItem.values().toList().toImmutableList())

val childStack: Value<ChildStack<*, Child>> = childStack(
source = navigation,
Expand All @@ -25,19 +35,44 @@ class CobaltContainerComponent(
private fun createChild(config: Config, componentContext: ComponentContext): Child {
return when (config) {
Config.Home -> Child.Home(newsComponent(componentContext))
Config.MyProfile -> Child.MyProfile(myProfileComponent(componentContext))
}
}

private fun newsComponent(componentContext: ComponentContext): NewsRootComponent {
return DefaultNewsRootComponent(componentContext)
}

private fun myProfileComponent(componentContext: ComponentContext): ProfileComponent {
return MyProfileComponent(componentContext)
}

fun switch(to: NavigationItem) {
_currentNavigationItem.value = to

when (to) {
NavigationItem.Home -> navigation.bringToFront(Config.Home)
NavigationItem.MyProfile -> navigation.bringToFront(Config.MyProfile)
}
}

fun getNavigationItemIndex(item: NavigationItem): Int {
return navigationItems.value.indexOf(item)
}

@Parcelize
private sealed class Config : Parcelable {
object Home : Config()
object MyProfile : Config()
}

sealed class Child {
class Home(val component: NewsRootComponent) : Child()
class MyProfile(val component: ProfileComponent) : Child()
}

enum class NavigationItem {
Home,
MyProfile
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,39 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.layout
import androidx.compose.ui.unit.dp
import bruhcollective.itaysonlab.jetisteam.news.NewsScreen
import bruhcollective.itaysonlab.jetisteam.profile.ProfileScreen
import bruhcollective.itaysonlab.jetisteam.ui.components.CobaltNavigationBar
import bruhcollective.itaysonlab.jetisteam.ui.components.IslandAnimations
import bruhcollective.itaysonlab.jetisteam.ui.rememberPrevious
import com.arkivanov.decompose.extensions.compose.jetpack.stack.Children
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.StackAnimator
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.fade
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.plus
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.slide
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.stackAnimation
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.stackAnimator
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState

@Composable
fun CobaltContainerScreen(
isConnectionRowShown: Boolean,
component: CobaltContainerComponent
) {
val currentNavItem by component.currentNavigationItem.subscribeAsState()
val previousNavItem = rememberPrevious(current = currentNavItem)

Scaffold(
bottomBar = {
CobaltNavigationBar()
val navbarItems by component.navigationItems.subscribeAsState()

CobaltNavigationBar(
items = navbarItems,
selectedItem = currentNavItem,
onSelected = component::switch
)
}
) { innerPadding ->
val stackTopPadding by animateDpAsState(
Expand All @@ -30,10 +50,34 @@ fun CobaltContainerScreen(
}, label = "Cobalt container status bar neutralizer"
)

Children(stack = component.childStack, modifier = Modifier.padding(top = stackTopPadding, bottom = 0.dp)) {
Children(stack = component.childStack, animation = stackAnimation { _, _, _ ->
val direction = if (previousNavItem != null && component.getNavigationItemIndex(currentNavItem) > component.getNavigationItemIndex(previousNavItem)) {
IslandAnimations.Direction.RIGHT
} else {
IslandAnimations.Direction.LEFT
}

slideWithDirection(direction) + fade(IslandAnimations.islandSpec())
}) {
when (val child = it.instance) {
is CobaltContainerComponent.Child.Home -> NewsScreen(child.component)
is CobaltContainerComponent.Child.Home -> NewsScreen(stackTopPadding, child.component)
is CobaltContainerComponent.Child.MyProfile -> ProfileScreen(stackTopPadding, child.component)
}
}
}
}
}

private fun slideWithDirection(
direction: IslandAnimations.Direction,
): StackAnimator = stackAnimator(IslandAnimations.islandSpec()) { factor, _, content ->
content(Modifier.offsetXFactor(factor * if (direction == IslandAnimations.Direction.RIGHT) 1f else -1f))
}

private fun Modifier.offsetXFactor(factor: Float): Modifier =
layout { measurable, constraints ->
val placeable = measurable.measure(constraints)

layout(placeable.width, placeable.height) {
placeable.placeRelative(x = (placeable.width.toFloat() * factor).toInt(), y = 0)
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package bruhcollective.itaysonlab.jetisteam.news

import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import bruhcollective.itaysonlab.cobalt.news.NewsRootComponent
import bruhcollective.itaysonlab.jetisteam.news.discover.DiscoverScreen
import com.arkivanov.decompose.extensions.compose.jetpack.stack.Children

@Composable
fun NewsScreen(
topPadding: Dp,
component: NewsRootComponent
) {
Children(stack = component.childStack) {
Children(stack = component.childStack, modifier = Modifier.padding(top = topPadding)) {
when (val child = it.instance) {
is NewsRootComponent.Child.Discover -> DiscoverScreen(component = child.component)
}
Expand Down
Loading

0 comments on commit 406d40d

Please sign in to comment.