From 4c98949bb6b66a4a6204c76204ee0480bf182776 Mon Sep 17 00:00:00 2001 From: Thomas Andres Gomez Date: Fri, 7 Apr 2023 17:29:05 +0200 Subject: [PATCH] Add custom loader on the HomeScreen --- .../pixelized/biblib/ui/composable/Loader.kt | 82 +++++++++++++++++++ .../biblib/ui/screen/home/HomeScreen.kt | 49 +++++------ 2 files changed, 108 insertions(+), 23 deletions(-) create mode 100644 app/src/main/java/com/pixelized/biblib/ui/composable/Loader.kt diff --git a/app/src/main/java/com/pixelized/biblib/ui/composable/Loader.kt b/app/src/main/java/com/pixelized/biblib/ui/composable/Loader.kt new file mode 100644 index 0000000..79a41ac --- /dev/null +++ b/app/src/main/java/com/pixelized/biblib/ui/composable/Loader.kt @@ -0,0 +1,82 @@ +package com.pixelized.biblib.ui.composable + +import androidx.compose.animation.Crossfade +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.* +import androidx.compose.material.pullrefresh.PullRefreshState +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp + +@OptIn(ExperimentalMaterialApi::class) +@Composable +fun Loader( + modifier: Modifier = Modifier, + isLoading: State, + refreshState: PullRefreshState +) { + val state = rememberLoaderState(refreshState) + + Box( + modifier = modifier, + contentAlignment = Alignment.Center, + ) { + Divider() + + Crossfade(targetState = isLoading.value) { loading -> + if (loading) { + LinearProgressIndicator( + modifier = Modifier + .fillMaxWidth() + .clip(shape = CircleShape) + ) + } else { + Box( + modifier = Modifier + .height(height = state.height) + .fillMaxWidth(fraction = state.faction) + .background( + shape = CircleShape, + color = state.color, + ) + ) + } + } + } +} + +@OptIn(ExperimentalMaterialApi::class) +@Composable +private fun rememberLoaderState( + refreshState: PullRefreshState, +): LoaderState { + val color = MaterialTheme.colors.primary + + val state by remember { + derivedStateOf { + LoaderState( + color = color.copy( + alpha = (3f * refreshState.progress / 4f + 0.25f).coerceIn(0f, 1f)) + , + height = 1.dp + 2.dp * refreshState.progress, + faction = refreshState.progress * 0.75f, + ) + } + } + return state +} + +@Stable +data class LoaderState( + val color: Color, + val height: Dp, + val faction: Float, +) \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/biblib/ui/screen/home/HomeScreen.kt b/app/src/main/java/com/pixelized/biblib/ui/screen/home/HomeScreen.kt index 6a11cde..1c190e1 100644 --- a/app/src/main/java/com/pixelized/biblib/ui/screen/home/HomeScreen.kt +++ b/app/src/main/java/com/pixelized/biblib/ui/screen/home/HomeScreen.kt @@ -25,10 +25,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.platform.LocalLayoutDirection -import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.ui.platform.* import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview @@ -42,6 +39,7 @@ import com.pixelized.biblib.model.search.FilterType import com.pixelized.biblib.model.search.SortType import com.pixelized.biblib.model.search.SortValue import com.pixelized.biblib.ui.LocalSnackHostState +import com.pixelized.biblib.ui.composable.Loader import com.pixelized.biblib.ui.composable.colorElevation import com.pixelized.biblib.ui.composable.scaffold.* import com.pixelized.biblib.ui.navigation.LocalScreenNavHostController @@ -59,6 +57,7 @@ import com.pixelized.biblib.utils.extention.bibLib import com.pixelized.biblib.utils.extention.imeHeight import com.pixelized.biblib.utils.extention.navigationBarsHeight import com.skydoves.landscapist.glide.GlideImage +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.launch @@ -105,14 +104,7 @@ fun HomeScreen( val largeGridState = rememberLazyGridState() val smallListState = rememberLazyListState() val microListState = rememberLazyListState() - val refreshState = rememberPullRefreshState( - refreshing = false, - onRefresh = { - scope.launch { - bookViewModel.updateLibrary() - } - }, - ) + val refreshState = rememberPullRefreshState(viewModel = bookViewModel) FilterBottomSheet( sheetState = filterState, @@ -358,18 +350,13 @@ private fun HomeScreenContent( ) }, loader = { - Box( + Loader( modifier = Modifier .padding(horizontal = 16.dp) - .height(1.dp) - ) { - Divider() - if (isLoading.value) { - LinearProgressIndicator( - modifier = Modifier.fillMaxWidth() - ) - } - } + .height(3.dp), + refreshState = refreshState, + isLoading = isLoading, + ) }, content = { val navigationBarsHeight = navigationBarsHeight() @@ -607,6 +594,22 @@ private fun BookList( } } +@Composable +@OptIn(ExperimentalMaterialApi::class) +private fun rememberPullRefreshState( + viewModel: BookSearchViewModel, + scope : CoroutineScope = rememberCoroutineScope() +): PullRefreshState { + return rememberPullRefreshState( + refreshing = viewModel.updating.value, + onRefresh = { + scope.launch { + viewModel.updateLibrary() + } + }, + ) +} + @OptIn(ExperimentalComposeUiApi::class) @Composable private fun CollapseKeyboardOnScrollHandler( @@ -651,7 +654,7 @@ private fun HomeScreenPreview() { onSort = { }, onDisplay = { }, isLoading = remember { mutableStateOf(false) }, - refreshState = rememberPullRefreshState(refreshing = false, onRefresh = { }), + refreshState = rememberPullRefreshState(refreshing = false, onRefresh = { }), display = remember { mutableStateOf(HomeDisplay.MICRO) }, gridState = rememberLazyGridState(), items = thumbnailPreviewResources(),