Skip to content

Commit

Permalink
refactor(navpill): remove circular edges, add background and sliding …
Browse files Browse the repository at this point in the history
…animations
  • Loading branch information
quickdesh committed Aug 9, 2024
1 parent 1770667 commit 8e45259
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 36 deletions.
54 changes: 31 additions & 23 deletions app/src/main/java/eu/kanade/tachiyomi/ui/home/HomeScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandVertically
import androidx.compose.animation.shrinkVertically
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.consumeWindowInsets
Expand Down Expand Up @@ -33,8 +32,7 @@ import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
import soup.compose.material.motion.animation.materialFadeThroughIn
import soup.compose.material.motion.animation.materialFadeThroughOut
import soup.compose.material.motion.animation.materialSharedAxisX
import tachiyomi.presentation.core.components.material.Scaffold
import uy.kohesive.injekt.injectLazy

Expand All @@ -44,7 +42,7 @@ object HomeScreen : Screen() {
private val openTabEvent = Channel<Tab>()
private val showBottomNavEvent = Channel<Boolean>()

private const val TabFadeDuration = 500
private const val TabFadeDuration = 300
private const val TabNavigatorKey = "HomeTabs"

private val uiPreferences: UiPreferences by injectLazy()
Expand All @@ -69,11 +67,18 @@ object HomeScreen : Screen() {
key = TabNavigatorKey,
) { tabNavigator ->
// AM (NAVIGATION_PILL) -->
val currTabIndex = tabNavigator.current.options.index.toInt()
var currentTabIndex by remember { mutableIntStateOf(currTabIndex) }
val setCurrentTabIndex: (Int) -> Unit = { currentTabIndex = it }
// Provide usable navigator to content screen
CompositionLocalProvider(LocalNavigator provides navigator) {
val currTabIndex = tabNavigator.current.options.index.toInt()
var currentTabIndex by remember { mutableIntStateOf(currTabIndex) }
var oldIndex by remember { mutableIntStateOf(currTabIndex) }

val isForward = remember(currentTabIndex) {
val forward = oldIndex < currentTabIndex
oldIndex = currentTabIndex
forward
}
val setCurrentTabIndex: (Int) -> Unit = { currentTabIndex = it }
Scaffold(
bottomBar = {
val bottomNavVisible by produceState(initialValue = true) {
Expand Down Expand Up @@ -103,11 +108,11 @@ object HomeScreen : Screen() {
AnimatedContent(
targetState = tabNavigator.current,
transitionSpec = {
materialFadeThroughIn(
initialScale = 1f,
materialSharedAxisX(
forward = !isForward,
slideDistance = 500,
durationMillis = TabFadeDuration,
) togetherWith
materialFadeThroughOut(durationMillis = TabFadeDuration)
)
},
label = "tabContent",
) {
Expand All @@ -116,6 +121,21 @@ object HomeScreen : Screen() {
}
}
}
// AM (NAVIGATION_PILL) -->
LaunchedEffect(tabNavigator.current) {
launch {
currentTabIndex = when (tabNavigator.current) {
is AnimeLibraryTab -> 0
// AM (RECENTS) -->
is RecentsTab -> 1
// <-- AM (RECENTS)
is BrowseTab -> 2
is MoreTab -> 3
else -> 0
}
}
}
// <-- AM (NAVIGATION_PILL)
}
}

Expand All @@ -124,7 +144,6 @@ object HomeScreen : Screen() {
librarySearchEvent.receiveAsFlow().collectLatest {
when (defaultTab) {
AnimeLibraryTab -> AnimeLibraryTab.search(it)
else -> {}
}
}
}
Expand All @@ -141,17 +160,6 @@ object HomeScreen : Screen() {
is Tab.More -> MoreTab
}

// AM (NAVIGATION_PILL) -->
currentTabIndex = when (it) {
is Tab.AnimeLib -> 0
// AM (RECENTS) -->
is Tab.Recents -> 1
// <-- AM (RECENTS)
is Tab.Browse -> 2
is Tab.More -> 3
}
// <-- AM (NAVIGATION_PILL)

if (it is Tab.AnimeLib && it.animeIdToOpen != null) {
navigator.push(AnimeScreen(it.animeIdToOpen))
}
Expand Down
66 changes: 53 additions & 13 deletions app/src/main/java/eu/kanade/tachiyomi/ui/home/NavigationPill.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.home

import androidx.activity.compose.BackHandler
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.AnimationSpec
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
Expand All @@ -18,7 +19,7 @@ import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.requiredWidthIn
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.selection.selectableGroup
import androidx.compose.foundation.shape.ZeroCornerSize
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.material3.Badge
import androidx.compose.material3.BadgedBox
import androidx.compose.material3.Icon
Expand Down Expand Up @@ -128,21 +129,31 @@ fun NavigationPill(
},
)
},
shape = MaterialTheme.shapes.extraLarge.copy(
bottomEnd = ZeroCornerSize,
bottomStart = ZeroCornerSize,
),
tonalElevation = 1.4.dp,
) {
NavigationBarItemBackground(navigationOffsetX, pillItemWidth, pillItemHeight)
val topStartCornerSize = remember { Animatable(0f) }
val topEndCornerSize = remember { Animatable(28f) }
val bottomStartCornerSize = remember { Animatable(0f) }
val bottomEndCornerSize = remember { Animatable(28f) }

NavigationPillItemBackground(
pillItemWidth = pillItemWidth,
pillItemHeight = pillItemHeight,
pillOffsetX = navigationOffsetX,
topStartCornerSize = topStartCornerSize.value.dp,
topEndCornerSize = topEndCornerSize.value.dp,
bottomStartCornerSize = bottomStartCornerSize.value.dp,
bottomEndCornerSize = bottomEndCornerSize.value.dp,
)
Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
Row {
tabs.fastForEach {
NavigationBarItem(it, updateTab, pillItemWidth, pillItemHeight)
NavigationPillItem(it, updateTab, pillItemWidth, pillItemHeight)
}
}

val alpha = remember { Animatable(-1f) }
val cornerAnimationSpec: AnimationSpec<Float> = tween(durationMillis = labelFade * 2)

LaunchedEffect(currentTabIndex) {
scope.launchUI {
Expand All @@ -154,6 +165,27 @@ fun NavigationPill(
alpha.animateTo(-0.5f, animationSpec = tween(durationMillis = labelFade))
}
}

when (currentTabIndex) {
0 -> {
scope.launch { topStartCornerSize.animateTo(0f, animationSpec = cornerAnimationSpec) }
scope.launch { topEndCornerSize.animateTo(28f, animationSpec = cornerAnimationSpec) }
scope.launch { bottomStartCornerSize.animateTo(0f, animationSpec = cornerAnimationSpec) }
scope.launch { bottomEndCornerSize.animateTo(28f, animationSpec = cornerAnimationSpec) }
}
tabs.size - 1 -> {
scope.launch { topStartCornerSize.animateTo(28f, animationSpec = cornerAnimationSpec) }
scope.launch { topEndCornerSize.animateTo(0f, animationSpec = cornerAnimationSpec) }
scope.launch { bottomStartCornerSize.animateTo(28f, animationSpec = cornerAnimationSpec) }
scope.launch { bottomEndCornerSize.animateTo(0f, animationSpec = cornerAnimationSpec) }
}
else -> {
scope.launch { topStartCornerSize.animateTo(28f, animationSpec = cornerAnimationSpec) }
scope.launch { topEndCornerSize.animateTo(28f, animationSpec = cornerAnimationSpec) }
scope.launch { bottomStartCornerSize.animateTo(28f, animationSpec = cornerAnimationSpec) }
scope.launch { bottomEndCornerSize.animateTo(28f, animationSpec = cornerAnimationSpec) }
}
}
}

LaunchedEffect(alpha.value) {
Expand All @@ -178,8 +210,6 @@ fun NavigationPill(
alpha.animateTo(0f, animationSpec = tween(durationMillis = labelFade))
}
}

else -> {}
}
}
}
Expand All @@ -203,16 +233,26 @@ fun NavigationPill(
}

@Composable
private fun NavigationBarItemBackground(
pillOffsetX: Dp,
private fun NavigationPillItemBackground(
pillItemWidth: Dp,
pillItemHeight: Dp,
pillOffsetX: Dp,
topStartCornerSize: Dp,
topEndCornerSize: Dp,
bottomStartCornerSize: Dp,
bottomEndCornerSize: Dp,
) {
Surface(
modifier = Modifier
.offset(x = pillOffsetX)
.requiredWidthIn(max = pillItemWidth),
shape = MaterialTheme.shapes.extraLarge,

shape = MaterialTheme.shapes.extraLarge.copy(
topStart = CornerSize(topStartCornerSize),
topEnd = CornerSize(topEndCornerSize),
bottomStart = CornerSize(bottomStartCornerSize),
bottomEnd = CornerSize(bottomEndCornerSize),
),
) {
Box(
modifier = Modifier
Expand All @@ -223,7 +263,7 @@ private fun NavigationBarItemBackground(
}

@Composable
private fun NavigationBarItem(
private fun NavigationPillItem(
tab: Tab,
updateTab: (Int) -> Unit,
pillItemWidth: Dp,
Expand Down

0 comments on commit 8e45259

Please sign in to comment.