From 180b6af2f9d94dff116371a76a4f552a45f2ce3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolf-Martell=20Montw=C3=A9?= Date: Tue, 19 Sep 2023 11:24:07 +0200 Subject: [PATCH] Add ContentLoadingErrorView to design system --- .../catalog/ui/common/list/SectionInfoItem.kt | 31 +++++++ .../catalog/ui/molecule/items/StateItems.kt | 61 +++++++++++++ .../molecule/ContentLoadingErrorView.kt | 88 +++++++++++++++++++ 3 files changed, 180 insertions(+) create mode 100644 app-ui-catalog/src/main/java/app/k9mail/ui/catalog/ui/common/list/SectionInfoItem.kt create mode 100644 core/ui/compose/designsystem/src/main/kotlin/app/k9mail/core/ui/compose/designsystem/molecule/ContentLoadingErrorView.kt diff --git a/app-ui-catalog/src/main/java/app/k9mail/ui/catalog/ui/common/list/SectionInfoItem.kt b/app-ui-catalog/src/main/java/app/k9mail/ui/catalog/ui/common/list/SectionInfoItem.kt new file mode 100644 index 000000000..dd063ef23 --- /dev/null +++ b/app-ui-catalog/src/main/java/app/k9mail/ui/catalog/ui/common/list/SectionInfoItem.kt @@ -0,0 +1,31 @@ +package app.k9mail.ui.catalog.ui.common.list + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.grid.GridItemSpan +import androidx.compose.foundation.lazy.grid.LazyGridScope +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import app.k9mail.core.ui.compose.designsystem.atom.text.TextCaption +import app.k9mail.core.ui.compose.theme.MainTheme + +fun LazyGridScope.sectionInfoItem( + text: String, +) { + item(span = { GridItemSpan(maxLineSpan) }) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding( + start = MainTheme.spacings.double, + end = MainTheme.spacings.double, + ), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + TextCaption( + text = text, + ) + } + } +} diff --git a/app-ui-catalog/src/main/java/app/k9mail/ui/catalog/ui/molecule/items/StateItems.kt b/app-ui-catalog/src/main/java/app/k9mail/ui/catalog/ui/molecule/items/StateItems.kt index 3bd37e2fa..ad3d56081 100644 --- a/app-ui-catalog/src/main/java/app/k9mail/ui/catalog/ui/molecule/items/StateItems.kt +++ b/app-ui-catalog/src/main/java/app/k9mail/ui/catalog/ui/molecule/items/StateItems.kt @@ -1,10 +1,23 @@ package app.k9mail.ui.catalog.ui.molecule.items +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height import androidx.compose.foundation.lazy.grid.LazyGridScope +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import app.k9mail.core.ui.compose.designsystem.atom.text.TextSubtitle1 +import app.k9mail.core.ui.compose.designsystem.molecule.ContentLoadingErrorState +import app.k9mail.core.ui.compose.designsystem.molecule.ContentLoadingErrorView import app.k9mail.core.ui.compose.designsystem.molecule.ErrorView import app.k9mail.core.ui.compose.designsystem.molecule.LoadingView import app.k9mail.ui.catalog.ui.common.list.ItemOutlined import app.k9mail.ui.catalog.ui.common.list.sectionHeaderItem +import app.k9mail.ui.catalog.ui.common.list.sectionInfoItem import app.k9mail.ui.catalog.ui.common.list.sectionSubtitleItem fun LazyGridScope.stateItems() { @@ -33,4 +46,52 @@ fun LazyGridScope.stateItems() { ) } } + + sectionHeaderItem(text = "ContentLoadingErrorView") + sectionInfoItem(text = "Click below to change state") + item { + Column { + ItemOutlined { + StatefulContentLoadingErrorState() + } + } + } +} + +@Composable +private fun StatefulContentLoadingErrorState() { + val state = remember { + mutableStateOf(ContentLoadingErrorState.Loading) + } + + ContentLoadingErrorView( + state = state.value, + modifier = Modifier + .clickable { + when (state.value) { + ContentLoadingErrorState.Loading -> { + state.value = ContentLoadingErrorState.Content + } + + ContentLoadingErrorState.Content -> { + state.value = ContentLoadingErrorState.Error + } + + ContentLoadingErrorState.Error -> { + state.value = ContentLoadingErrorState.Loading + } + } + } + .height(200.dp) + .fillMaxSize(), + error = { + TextSubtitle1(text = "Error") + }, + loading = { + TextSubtitle1(text = "Loading...") + }, + content = { + TextSubtitle1(text = "Content") + }, + ) } diff --git a/core/ui/compose/designsystem/src/main/kotlin/app/k9mail/core/ui/compose/designsystem/molecule/ContentLoadingErrorView.kt b/core/ui/compose/designsystem/src/main/kotlin/app/k9mail/core/ui/compose/designsystem/molecule/ContentLoadingErrorView.kt new file mode 100644 index 000000000..f1d7f82a9 --- /dev/null +++ b/core/ui/compose/designsystem/src/main/kotlin/app/k9mail/core/ui/compose/designsystem/molecule/ContentLoadingErrorView.kt @@ -0,0 +1,88 @@ +package app.k9mail.core.ui.compose.designsystem.molecule + +import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.ExperimentalAnimationApi +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import app.k9mail.core.ui.compose.designsystem.atom.text.TextSubtitle1 +import app.k9mail.core.ui.compose.theme.PreviewWithThemes + +@OptIn(ExperimentalAnimationApi::class) +@Composable +fun ContentLoadingErrorView( + state: ContentLoadingErrorState, + loading: @Composable () -> Unit, + error: @Composable () -> Unit, + modifier: Modifier = Modifier, + contentAlignment: Alignment = Alignment.Center, + content: @Composable () -> Unit, +) { + Box( + modifier = modifier, + contentAlignment = contentAlignment, + ) { + AnimatedContent( + targetState = state, + label = "CleView", + ) { targetState -> + when (targetState) { + ContentLoadingErrorState.Loading -> loading() + ContentLoadingErrorState.Content -> content() + ContentLoadingErrorState.Error -> error() + } + } + } +} + +sealed interface ContentLoadingErrorState { + object Loading : ContentLoadingErrorState + object Content : ContentLoadingErrorState + object Error : ContentLoadingErrorState +} + +@Composable +@Preview(showBackground = true) +internal fun ContentLoadingErrorViewPreview() { + PreviewWithThemes { + val state = remember { + mutableStateOf(ContentLoadingErrorState.Loading) + } + + ContentLoadingErrorView( + state = state.value, + modifier = Modifier + .clickable { + when (state.value) { + ContentLoadingErrorState.Loading -> { + state.value = ContentLoadingErrorState.Content + } + + ContentLoadingErrorState.Content -> { + state.value = ContentLoadingErrorState.Error + } + + ContentLoadingErrorState.Error -> { + state.value = ContentLoadingErrorState.Loading + } + } + } + .fillMaxSize(), + error = { + TextSubtitle1(text = "Error") + }, + loading = { + TextSubtitle1(text = "Loading...") + }, + content = { + TextSubtitle1(text = "Content") + }, + ) + } +}