Add custom loader on the HomeScreen

This commit is contained in:
Thomas Andres Gomez 2023-04-07 17:29:05 +02:00
parent 76a5e6dd84
commit 4c98949bb6
2 changed files with 108 additions and 23 deletions

View file

@ -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<Boolean>,
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,
)

View file

@ -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(),