Skip to content

Commit b34c024

Browse files
committed
feat(ui): Integrate liquid navigation effect across screens
This commit integrates the `liquid` library to create a "liquefiable" effect between the bottom navigation bar and the content of several feature screens. This adds a fluid, connected animation when interacting with the navigation. - **feat(ui)**: Added the `liquid` library dependency to the `apps`, `search`, and `settings` presentation modules. - **feat(search, settings)**: Applied the `liquefiable` modifier to the `Scaffold` of the Search and Settings screens, linking them to the bottom navigation's liquid state. - **feat(search)**: Also applied the `liquefiable` modifier to the search results list and its items to ensure they participate in the liquid effect.
1 parent 2852d29 commit b34c024

6 files changed

Lines changed: 33 additions & 9 deletions

File tree

feature/apps/presentation/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ kotlin {
1616
implementation(compose.components.resources)
1717

1818
implementation(libs.bundles.landscapist)
19+
implementation(libs.liquid)
1920
}
2021
}
2122

feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/AppsRoot.kt

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import androidx.compose.ui.text.style.TextOverflow
5757
import androidx.compose.ui.unit.dp
5858
import androidx.lifecycle.compose.collectAsStateWithLifecycle
5959
import com.skydoves.landscapist.coil3.CoilImage
60+
import io.github.fletchmckee.liquid.liquefiable
6061
import zed.rainxch.githubstore.core.presentation.res.*
6162
import kotlinx.coroutines.launch
6263
import org.jetbrains.compose.resources.stringResource
@@ -65,6 +66,7 @@ import org.koin.compose.viewmodel.koinViewModel
6566
import zed.rainxch.apps.presentation.model.AppItem
6667
import zed.rainxch.apps.presentation.model.UpdateAllProgress
6768
import zed.rainxch.apps.presentation.model.UpdateState
69+
import zed.rainxch.core.presentation.locals.LocalBottomNavigationLiquid
6870
import zed.rainxch.core.presentation.theme.GithubStoreTheme
6971
import zed.rainxch.core.presentation.utils.ObserveAsEvents
7072

@@ -121,6 +123,7 @@ fun AppsScreen(
121123
onAction: (AppsAction) -> Unit,
122124
snackbarHostState: SnackbarHostState
123125
) {
126+
val liquidState = LocalBottomNavigationLiquid.current
124127
Scaffold(
125128
topBar = {
126129
TopAppBar(
@@ -156,12 +159,14 @@ fun AppsScreen(
156159
},
157160
snackbarHost = {
158161
SnackbarHost(snackbarHostState)
159-
}
162+
},
163+
modifier = Modifier.liquefiable(liquidState)
160164
) { innerPadding ->
161165
Column(
162166
modifier = Modifier
163167
.fillMaxSize()
164168
.padding(innerPadding)
169+
.liquefiable(liquidState)
165170
) {
166171
TextField(
167172
value = state.searchQuery,
@@ -260,7 +265,8 @@ fun AppsScreen(
260265
onOpenClick = { onAction(AppsAction.OnOpenApp(appItem.installedApp)) },
261266
onUpdateClick = { onAction(AppsAction.OnUpdateApp(appItem.installedApp)) },
262267
onCancelClick = { onAction(AppsAction.OnCancelUpdate(appItem.installedApp.packageName)) },
263-
onRepoClick = { onAction(AppsAction.OnNavigateToRepo(appItem.installedApp.repoId)) }
268+
onRepoClick = { onAction(AppsAction.OnNavigateToRepo(appItem.installedApp.repoId)) },
269+
modifier = Modifier.liquefiable(liquidState)
264270
)
265271
}
266272
}
@@ -331,12 +337,13 @@ fun AppItemCard(
331337
onOpenClick: () -> Unit,
332338
onUpdateClick: () -> Unit,
333339
onCancelClick: () -> Unit,
334-
onRepoClick: () -> Unit
340+
onRepoClick: () -> Unit,
341+
modifier: Modifier = Modifier
335342
) {
336343
val app = appItem.installedApp
337344

338345
Card(
339-
modifier = Modifier.fillMaxWidth(),
346+
modifier = modifier.fillMaxWidth(),
340347
onClick = onRepoClick
341348
) {
342349
Column(

feature/search/presentation/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ kotlin {
1212
implementation(projects.core.presentation)
1313
implementation(projects.feature.search.domain)
1414

15+
implementation(libs.liquid)
16+
1517
implementation(compose.components.uiToolingPreview)
1618
implementation(compose.components.resources)
1719
}

feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/SearchRoot.kt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,15 @@ import androidx.compose.ui.text.input.KeyboardType
5757
import androidx.compose.ui.text.style.TextOverflow
5858
import androidx.compose.ui.unit.dp
5959
import androidx.lifecycle.compose.collectAsStateWithLifecycle
60+
import io.github.fletchmckee.liquid.liquefiable
6061
import zed.rainxch.githubstore.core.presentation.res.*
6162
import kotlinx.coroutines.delay
6263
import org.jetbrains.compose.resources.stringResource
6364
import org.jetbrains.compose.ui.tooling.preview.Preview
6465
import org.koin.compose.viewmodel.koinViewModel
6566
import zed.rainxch.core.domain.model.GithubRepoSummary
6667
import zed.rainxch.core.presentation.components.RepositoryCard
68+
import zed.rainxch.core.presentation.locals.LocalBottomNavigationLiquid
6769
import zed.rainxch.core.presentation.theme.GithubStoreTheme
6870
import zed.rainxch.domain.model.ProgrammingLanguage
6971
import zed.rainxch.domain.model.SearchPlatform
@@ -124,6 +126,7 @@ fun SearchScreen(
124126
) {
125127
val focusRequester = remember { FocusRequester() }
126128
val listState = rememberLazyStaggeredGridState()
129+
val liquidState = LocalBottomNavigationLiquid.current
127130

128131
val shouldLoadMore by remember {
129132
derivedStateOf {
@@ -187,14 +190,15 @@ fun SearchScreen(
187190
}
188191

189192
Scaffold(
190-
containerColor = MaterialTheme.colorScheme.background,
191193
topBar = {
192194
SearchTopbar(
193195
onAction = onAction,
194196
state = state,
195197
focusRequester = focusRequester
196198
)
197-
}
199+
},
200+
containerColor = MaterialTheme.colorScheme.background,
201+
modifier = Modifier.liquefiable(liquidState)
198202
) { innerPadding ->
199203
Column(
200204
modifier = Modifier
@@ -334,7 +338,9 @@ fun SearchScreen(
334338
verticalItemSpacing = 12.dp,
335339
horizontalArrangement = Arrangement.spacedBy(12.dp),
336340
contentPadding = PaddingValues(horizontal = 8.dp, vertical = 12.dp),
337-
modifier = Modifier.fillMaxSize()
341+
modifier = Modifier
342+
.fillMaxSize()
343+
.liquefiable(liquidState)
338344
) {
339345
items(
340346
items = state.repositories,
@@ -348,7 +354,9 @@ fun SearchScreen(
348354
onDeveloperClick = { username ->
349355
onAction(SearchAction.OnRepositoryDeveloperClick(username))
350356
},
351-
modifier = Modifier.animateItem()
357+
modifier = Modifier
358+
.animateItem()
359+
.liquefiable(liquidState)
352360
)
353361
}
354362

feature/settings/presentation/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ kotlin {
1414

1515
implementation(compose.components.uiToolingPreview)
1616
implementation(compose.components.resources)
17+
18+
implementation(libs.liquid)
1719
}
1820
}
1921

feature/settings/presentation/src/commonMain/kotlin/zed/rainxch/settings/presentation/SettingsRoot.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,15 @@ import androidx.compose.ui.Modifier
2727
import androidx.compose.ui.text.font.FontWeight
2828
import androidx.compose.ui.unit.dp
2929
import androidx.lifecycle.compose.collectAsStateWithLifecycle
30+
import io.github.fletchmckee.liquid.liquefiable
3031
import zed.rainxch.githubstore.core.presentation.res.*
3132
import kotlinx.coroutines.launch
3233
import org.jetbrains.compose.resources.getString
3334
import org.jetbrains.compose.resources.stringResource
3435
import org.jetbrains.compose.ui.tooling.preview.Preview
3536
import org.koin.compose.viewmodel.koinViewModel
3637
import zed.rainxch.core.domain.model.FontTheme
38+
import zed.rainxch.core.presentation.locals.LocalBottomNavigationLiquid
3739
import zed.rainxch.core.presentation.theme.GithubStoreTheme
3840
import zed.rainxch.core.presentation.utils.ObserveAsEvents
3941
import zed.rainxch.settings.presentation.components.LogoutDialog
@@ -103,14 +105,16 @@ fun SettingsScreen(
103105
onAction: (SettingsAction) -> Unit,
104106
snackbarState: SnackbarHostState
105107
) {
108+
val liquidState = LocalBottomNavigationLiquid.current
106109
Scaffold(
107110
snackbarHost = {
108111
SnackbarHost(hostState = snackbarState)
109112
},
110113
topBar = {
111114
TopAppBar(onAction)
112115
},
113-
containerColor = MaterialTheme.colorScheme.background
116+
containerColor = MaterialTheme.colorScheme.background,
117+
modifier = Modifier.liquefiable(liquidState)
114118
) { innerPadding ->
115119
LazyColumn(
116120
modifier = Modifier

0 commit comments

Comments
 (0)