From 80ea0a5eedc948fe50d3f23ddce041d8144f0f23 Mon Sep 17 00:00:00 2001 From: Nek-12 Date: Thu, 19 Sep 2024 08:08:42 +0200 Subject: [PATCH] feat: improve design of the sample app --- .../composeResources/values/strings.xml | 1 + .../features/decompose/DecomposeScreen.kt | 16 ++++++++++++++-- .../features/diconfig/DIConfigScreen.kt | 4 ++-- .../sample/features/home/HomeScreen.kt | 9 +++++++-- .../flowmvi/sample/features/lce/LCEScreen.kt | 4 ++-- .../sample/features/logging/LoggingScreen.kt | 3 +-- .../features/savedstate/SavedStateScreen.kt | 4 ++-- .../sample/features/simple/SimpleScreen.kt | 4 ++-- .../features/undoredo/UndoRedoScreen.kt | 3 +-- .../flowmvi/sample/ui/widgets/CodeView.kt | 19 ++++++++++++------- .../flowmvi/sample/ui/widgets/RMenuItem.kt | 4 ++-- .../flowmvi/sample/ui/widgets/RTextInput.kt | 2 ++ .../respawn/flowmvi/sample/util/Compose.kt | 5 ----- 13 files changed, 48 insertions(+), 30 deletions(-) diff --git a/sample/src/commonMain/composeResources/values/strings.xml b/sample/src/commonMain/composeResources/values/strings.xml index 0f25f4ff..63727103 100644 --- a/sample/src/commonMain/composeResources/values/strings.xml +++ b/sample/src/commonMain/composeResources/values/strings.xml @@ -10,4 +10,5 @@ Android XML Support Undo/Redo Decompose | Essenty Integration + Run the app on another platform to experience this feature diff --git a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/decompose/DecomposeScreen.kt b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/decompose/DecomposeScreen.kt index 53759caa..d4ae3c7f 100644 --- a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/decompose/DecomposeScreen.kt +++ b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/decompose/DecomposeScreen.kt @@ -17,12 +17,14 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Card import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha import androidx.compose.ui.unit.dp import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.childContext @@ -42,13 +44,14 @@ import pro.respawn.flowmvi.sample.features.decompose.pages.PagesComponentState.D import pro.respawn.flowmvi.sample.features.decompose.pages.PagesIntent.SelectedPage import pro.respawn.flowmvi.sample.navigation.util.Navigator import pro.respawn.flowmvi.sample.navigation.util.backNavigator +import pro.respawn.flowmvi.sample.ui.theme.Opacity import pro.respawn.flowmvi.sample.ui.widgets.CodeText import pro.respawn.flowmvi.sample.ui.widgets.RErrorView import pro.respawn.flowmvi.sample.ui.widgets.RFilledButton import pro.respawn.flowmvi.sample.ui.widgets.RScaffold import pro.respawn.flowmvi.sample.ui.widgets.TypeCrossfade -import pro.respawn.flowmvi.sample.util.adaptiveWidth import pro.respawn.flowmvi.sample.util.formatAsMultiline +import pro.respawn.kmmutils.compose.windowsize.isWideScreen private const val Description = """ This feature showcases FlowMVI <> Essenty integration. @@ -148,7 +151,7 @@ private fun DecomposeScreenContent( is DisplayingPages -> Column( modifier = Modifier .fillMaxHeight() - .adaptiveWidth() + .fillMaxWidth() .verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally ) { @@ -156,6 +159,7 @@ private fun DecomposeScreenContent( text = Description.formatAsMultiline(), modifier = Modifier.padding(horizontal = 12.dp) ) + ChildPages( pages = pagesComponent.pages, onPageSelected = { pagesComponent.intent(SelectedPage(it)) }, @@ -163,6 +167,14 @@ private fun DecomposeScreenContent( scrollAnimation = PagesScrollAnimation.Default, pageContent = { _, page -> PageContent(page) }, ) + if (isWideScreen) { + Text( + text = "On desktop, scroll while holding Shift or using a horizontal scroll wheel", + style = MaterialTheme.typography.labelLarge, + modifier = Modifier.padding(horizontal = 12.dp).alpha(Opacity.secondary) + ) + Spacer(Modifier.height(12.dp)) + } CodeText(Code, modifier = Modifier.padding(horizontal = 12.dp)) Spacer(Modifier.navigationBarsPadding()) } diff --git a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/diconfig/DIConfigScreen.kt b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/diconfig/DIConfigScreen.kt index f99259a4..4bc85f86 100644 --- a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/diconfig/DIConfigScreen.kt +++ b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/diconfig/DIConfigScreen.kt @@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding @@ -27,7 +28,6 @@ import pro.respawn.flowmvi.sample.navigation.util.Navigator import pro.respawn.flowmvi.sample.navigation.util.backNavigator import pro.respawn.flowmvi.sample.ui.widgets.CodeText import pro.respawn.flowmvi.sample.ui.widgets.RScaffold -import pro.respawn.flowmvi.sample.util.adaptiveWidth import pro.respawn.flowmvi.sample.util.formatAsMultiline private const val Description = """ @@ -94,7 +94,7 @@ fun DiConfigScreen( private fun DiConfigScreenContent(state: PersistedCounterState) = Column( modifier = Modifier .fillMaxHeight() - .adaptiveWidth() + .fillMaxWidth() .padding(horizontal = 12.dp) .verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally, diff --git a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/home/HomeScreen.kt b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/home/HomeScreen.kt index b6d910af..666d1cad 100644 --- a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/home/HomeScreen.kt +++ b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/home/HomeScreen.kt @@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding @@ -57,6 +58,7 @@ import pro.respawn.flowmvi.sample.lce_feature_title import pro.respawn.flowmvi.sample.logging_feature_title import pro.respawn.flowmvi.sample.navigation.AppNavigator import pro.respawn.flowmvi.sample.navigation.util.backNavigator +import pro.respawn.flowmvi.sample.platform_feature_unavailable_label import pro.respawn.flowmvi.sample.savedstate_feature_title import pro.respawn.flowmvi.sample.simple_feature_title import pro.respawn.flowmvi.sample.ui.theme.rainbow @@ -65,9 +67,9 @@ import pro.respawn.flowmvi.sample.ui.widgets.RMenuItem import pro.respawn.flowmvi.sample.ui.widgets.RScaffold import pro.respawn.flowmvi.sample.ui.widgets.TypeCrossfade import pro.respawn.flowmvi.sample.undoredo_feature_title -import pro.respawn.flowmvi.sample.util.adaptiveWidth import pro.respawn.flowmvi.sample.util.platform import pro.respawn.flowmvi.sample.xml_feature_title +import pro.respawn.kmmutils.compose.resources.string @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -104,7 +106,7 @@ private fun IntentReceiver.HomeScreenContent( is DisplayingHome -> Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxHeight() - .adaptiveWidth() + .fillMaxWidth() .verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.Top, ) { @@ -126,6 +128,7 @@ private fun IntentReceiver.HomeScreenContent( title = stringResource(item.title), color = rainbow[i % rainbow.size], icon = item.icon, + subtitle = item.subtitle?.string(), onClick = { intent(ClickedFeature(item)) } ) } @@ -159,3 +162,5 @@ private val HomeFeature.icon } private val HomeFeature.enabled get() = platform == null || BuildFlags.platform == platform + +private val HomeFeature.subtitle get() = Res.string.platform_feature_unavailable_label.takeIf { !enabled } diff --git a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/lce/LCEScreen.kt b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/lce/LCEScreen.kt index 10f6410b..10a00ca3 100644 --- a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/lce/LCEScreen.kt +++ b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/lce/LCEScreen.kt @@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn @@ -34,7 +35,6 @@ import pro.respawn.flowmvi.sample.ui.widgets.RFilledButton import pro.respawn.flowmvi.sample.ui.widgets.RMenuItem import pro.respawn.flowmvi.sample.ui.widgets.RScaffold import pro.respawn.flowmvi.sample.ui.widgets.TypeCrossfade -import pro.respawn.flowmvi.sample.util.adaptiveWidth import pro.respawn.flowmvi.sample.util.formatAsMultiline import pro.respawn.flowmvi.sample.util.verticalListPaddings @@ -112,7 +112,7 @@ private fun IntentReceiver.LCEScreenContent( contentPadding = WindowInsets.verticalListPaddings(), modifier = Modifier .padding(horizontal = 12.dp) - .adaptiveWidth() + .fillMaxWidth() ) { item { Column(modifier = Modifier) { diff --git a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/logging/LoggingScreen.kt b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/logging/LoggingScreen.kt index 15ce23e3..b3941ba2 100644 --- a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/logging/LoggingScreen.kt +++ b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/logging/LoggingScreen.kt @@ -38,7 +38,6 @@ import pro.respawn.flowmvi.sample.ui.widgets.RErrorView import pro.respawn.flowmvi.sample.ui.widgets.RFilledButton import pro.respawn.flowmvi.sample.ui.widgets.RScaffold import pro.respawn.flowmvi.sample.ui.widgets.TypeCrossfade -import pro.respawn.flowmvi.sample.util.adaptiveWidth import pro.respawn.flowmvi.sample.util.formatAsMultiline import pro.respawn.flowmvi.sample.util.verticalListPaddings @@ -111,7 +110,7 @@ private fun IntentReceiver.LoggingScreenContent( is LoggingState.Loading -> CircularProgressIndicator() is LoggingState.Error -> RErrorView(e) is DisplayingLogs -> LazyColumn( - modifier = Modifier.fillMaxHeight().adaptiveWidth(), + modifier = Modifier.fillMaxHeight().fillMaxWidth(), contentPadding = WindowInsets.verticalListPaddings(), state = listState, horizontalAlignment = Alignment.CenterHorizontally, diff --git a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/savedstate/SavedStateScreen.kt b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/savedstate/SavedStateScreen.kt index ec39174e..3700a59a 100644 --- a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/savedstate/SavedStateScreen.kt +++ b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/savedstate/SavedStateScreen.kt @@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding @@ -33,7 +34,6 @@ import pro.respawn.flowmvi.sample.ui.widgets.CodeText import pro.respawn.flowmvi.sample.ui.widgets.RScaffold import pro.respawn.flowmvi.sample.ui.widgets.RTextInput import pro.respawn.flowmvi.sample.ui.widgets.TypeCrossfade -import pro.respawn.flowmvi.sample.util.adaptiveWidth import pro.respawn.flowmvi.sample.util.formatAsMultiline private const val Description = """ @@ -96,7 +96,7 @@ private fun IntentReceiver.SavedStateScreenContent( .fillMaxHeight() .padding(horizontal = 12.dp) .verticalScroll(rememberScrollState()) - .adaptiveWidth(), + .fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, ) { diff --git a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/simple/SimpleScreen.kt b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/simple/SimpleScreen.kt index 64338b2c..7033ef43 100644 --- a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/simple/SimpleScreen.kt +++ b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/simple/SimpleScreen.kt @@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding @@ -28,7 +29,6 @@ import pro.respawn.flowmvi.sample.simple_feature_title import pro.respawn.flowmvi.sample.ui.widgets.CodeText import pro.respawn.flowmvi.sample.ui.widgets.ROutlinedButton import pro.respawn.flowmvi.sample.ui.widgets.RScaffold -import pro.respawn.flowmvi.sample.util.adaptiveWidth import pro.respawn.flowmvi.sample.util.formatAsMultiline //language=kotlin @@ -84,7 +84,7 @@ private fun IntentReceiver.SimpleScreenContent( ) = Column( modifier = Modifier .fillMaxHeight() - .adaptiveWidth() + .fillMaxWidth() .padding(horizontal = 12.dp) .verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.Center, diff --git a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/undoredo/UndoRedoScreen.kt b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/undoredo/UndoRedoScreen.kt index afaa5379..ace612ae 100644 --- a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/undoredo/UndoRedoScreen.kt +++ b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/features/undoredo/UndoRedoScreen.kt @@ -38,7 +38,6 @@ import pro.respawn.flowmvi.sample.ui.widgets.RIcon import pro.respawn.flowmvi.sample.ui.widgets.RScaffold import pro.respawn.flowmvi.sample.ui.widgets.RTextInput import pro.respawn.flowmvi.sample.undoredo_feature_title -import pro.respawn.flowmvi.sample.util.adaptiveWidth import pro.respawn.flowmvi.sample.util.formatAsMultiline private const val Description = """ @@ -115,7 +114,7 @@ private fun IntentReceiver.UndoRedoScreenContent( state: UndoRedoState, ) = Column( modifier = Modifier.fillMaxHeight() - .adaptiveWidth() + .fillMaxWidth() .padding(horizontal = 12.dp) .verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally, diff --git a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/ui/widgets/CodeView.kt b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/ui/widgets/CodeView.kt index 53f73b5c..317399c2 100644 --- a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/ui/widgets/CodeView.kt +++ b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/ui/widgets/CodeView.kt @@ -36,20 +36,25 @@ val Highlights.annotatedString get() = buildAnnotatedString { append(getCode()) - getHighlights().forEach { - when (it) { - is BoldHighlight -> addStyle( - SpanStyle(fontWeight = FontWeight.Bold), + getHighlights() + .filterIsInstance() + .forEach { + addStyle( + SpanStyle(color = Color(it.rgb).copy(alpha = 1f)), start = it.location.start, end = it.location.end, ) - is ColorHighlight -> addStyle( - SpanStyle(color = Color(it.rgb).copy(alpha = 1f)), + } + + getHighlights() + .filterIsInstance() + .forEach { + addStyle( + SpanStyle(fontWeight = FontWeight.Bold), start = it.location.start, end = it.location.end, ) } - } } @Composable diff --git a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/ui/widgets/RMenuItem.kt b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/ui/widgets/RMenuItem.kt index 2149bf5f..9038d9e1 100644 --- a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/ui/widgets/RMenuItem.kt +++ b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/ui/widgets/RMenuItem.kt @@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text @@ -23,7 +24,6 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import pro.respawn.flowmvi.sample.ui.theme.Opacity import pro.respawn.flowmvi.sample.ui.theme.rememberRandomColor -import pro.respawn.flowmvi.sample.util.adaptiveWidth import pro.respawn.flowmvi.sample.util.noIndicationClickable import pro.respawn.kmmutils.common.takeIfValid import kotlin.contracts.contract @@ -50,7 +50,7 @@ fun RMenuItem( modifier = modifier .padding(horizontal = 4.dp, vertical = 4.dp) .animateContentSize() - .adaptiveWidth() + .widthIn(max = 600.dp) .then(if (onClick != null) Modifier.noIndicationClickable(onClick = onClick) else Modifier), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically, diff --git a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/ui/widgets/RTextInput.kt b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/ui/widgets/RTextInput.kt index 7019f1f5..38248ff9 100644 --- a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/ui/widgets/RTextInput.kt +++ b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/ui/widgets/RTextInput.kt @@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons @@ -83,6 +84,7 @@ fun RTextInput( var isFocused by remember { mutableStateOf(false) } Column( modifier = modifier + .widthIn(max = 600.dp) .bringIntoViewOnFocus() .focusRequester(focusRequester) .onFocusChanged { isFocused = it.isFocused } diff --git a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/util/Compose.kt b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/util/Compose.kt index 2956baa9..97966ffb 100644 --- a/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/util/Compose.kt +++ b/sample/src/commonMain/kotlin/pro/respawn/flowmvi/sample/util/Compose.kt @@ -7,10 +7,8 @@ import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsetsSides import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.defaultMinSize -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.only -import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.relocation.BringIntoViewRequester import androidx.compose.foundation.relocation.bringIntoViewRequester import androidx.compose.foundation.text.KeyboardActionScope @@ -45,7 +43,6 @@ import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.LayoutDirection -import androidx.compose.ui.unit.dp import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import pro.respawn.flowmvi.sample.ui.theme.Size @@ -84,8 +81,6 @@ fun rememberSnackbarHostState() = remember { SnackbarHostState() } fun Modifier.minTouchTarget() = defaultMinSize(Size.touchTarget, Size.touchTarget) -fun Modifier.adaptiveWidth(maxWidth: Dp = 600.dp) = widthIn(max = maxWidth).fillMaxWidth() - @Suppress("ComposableParametersOrdering") @Composable fun Modifier.noIndicationClickable(