From 7a45466b53dcd493ef2cae9063ecff0320bd4867 Mon Sep 17 00:00:00 2001 From: Michael Jordan Date: Mon, 8 Jan 2024 15:27:33 +0000 Subject: [PATCH 1/6] Setting up scaling web example --- demos/appyx-interactions/iosApp/Podfile.lock | 2 +- demos/appyx-navigation/iosApp/Podfile.lock | 2 +- .../com/bumble/appyx/navigation/Main.kt | 56 +++++++++++++++---- .../iosApp/Podfile.lock | 2 +- 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/demos/appyx-interactions/iosApp/Podfile.lock b/demos/appyx-interactions/iosApp/Podfile.lock index c14ad6c29..f088988a7 100644 --- a/demos/appyx-interactions/iosApp/Podfile.lock +++ b/demos/appyx-interactions/iosApp/Podfile.lock @@ -13,4 +13,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: a1e557981a2880940a401c85ea35aafdd5895941 -COCOAPODS: 1.12.1 +COCOAPODS: 1.13.0 diff --git a/demos/appyx-navigation/iosApp/Podfile.lock b/demos/appyx-navigation/iosApp/Podfile.lock index 1a6a2f7cc..841fe4fe1 100644 --- a/demos/appyx-navigation/iosApp/Podfile.lock +++ b/demos/appyx-navigation/iosApp/Podfile.lock @@ -13,4 +13,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: d0aa24730d1d7d4556f63c23912e284fe1f895e6 -COCOAPODS: 1.12.1 +COCOAPODS: 1.13.0 diff --git a/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt b/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt index afb42e5c3..1a2d52d7d 100644 --- a/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt +++ b/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt @@ -24,6 +24,8 @@ import androidx.compose.ui.input.key.key import androidx.compose.ui.input.key.onKeyEvent import androidx.compose.ui.input.key.type import androidx.compose.ui.layout.onSizeChanged +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.dp import androidx.compose.ui.window.CanvasBasedWindow import com.bumble.appyx.navigation.integration.ScreenSize @@ -53,8 +55,8 @@ fun main() { @OptIn(ExperimentalFoundationApi::class) @Composable -private fun ForceChangeToCodeGen(events: Channel, navigator: Navigator) { - AppyxSampleAppTheme { +private fun CakeApp(events: Channel, navigator: Navigator) { + AppyxSampleAppTheme(darkTheme = true) { val requester = remember { FocusRequester() } var hasFocus by remember { mutableStateOf(false) } @@ -73,15 +75,19 @@ private fun ForceChangeToCodeGen(events: Channel, navigator: Navigator) { .onFocusChanged { hasFocus = it.hasFocus }, color = MaterialTheme.colorScheme.background, ) { - CompositionLocalProvider(LocalNavigator provides navigator) { - WebNodeHost( - screenSize = screenSize, - onBackPressedEvents = events.receiveAsFlow(), - ) { buildContext -> - RootNode( - buildContext = buildContext, - plugins = listOf(navigator) - ) + CompositionLocalProvider(LocalDensity provides screenSize.calculateDensityFromScreenSize()) { + CompositionLocalProvider(LocalNavigator provides navigator) { + BlackContainer { + WebNodeHost( + screenSize = screenSize, + onBackPressedEvents = events.receiveAsFlow(), + ) { buildContext -> + RootNode( + buildContext = buildContext, + plugins = listOf(navigator) + ) + } + } } } } @@ -94,6 +100,34 @@ private fun ForceChangeToCodeGen(events: Channel, navigator: Navigator) { } } +private fun ScreenSize.calculateDensityFromScreenSize(): Density = + if (widthDp.value < 1500) { + console.log("Going small! ${widthDp.value}") + Density(1.2f, 1f) + } else { + console.log("Going big! ${widthDp.value}") + Density(1.8f, 1.2f) + } + +@Composable +private fun BlackContainer(content: @Composable () -> Unit) { + Box( + modifier = Modifier + .fillMaxSize() + .padding(16.dp), + contentAlignment = Alignment.Center + ) { + Box( + modifier = Modifier + .aspectRatio(0.56f) + .border(4.dp, color_primary, containerShape) + .clip(containerShape) + ) { + content() + } + } +} + private fun onKeyEvent( keyEvent: KeyEvent, events: Channel, diff --git a/demos/sandbox-appyx-navigation/iosApp/Podfile.lock b/demos/sandbox-appyx-navigation/iosApp/Podfile.lock index 14fd62ab7..6b8f524f4 100644 --- a/demos/sandbox-appyx-navigation/iosApp/Podfile.lock +++ b/demos/sandbox-appyx-navigation/iosApp/Podfile.lock @@ -13,4 +13,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: a1e557981a2880940a401c85ea35aafdd5895941 -COCOAPODS: 1.12.1 +COCOAPODS: 1.13.0 From 9d05f2096f39e3180470fd58171182c61d065375 Mon Sep 17 00:00:00 2001 From: Michael Jordan Date: Mon, 8 Jan 2024 15:27:56 +0000 Subject: [PATCH 2/6] Setting up web scaling sample --- demos/appyx-navigation/web/build.gradle.kts | 1 + .../com/bumble/appyx/navigation/Main.kt | 50 +++++++++++++------ 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/demos/appyx-navigation/web/build.gradle.kts b/demos/appyx-navigation/web/build.gradle.kts index babc8e9d8..6af10c3de 100644 --- a/demos/appyx-navigation/web/build.gradle.kts +++ b/demos/appyx-navigation/web/build.gradle.kts @@ -14,6 +14,7 @@ kotlin { val commonMain by getting { dependencies { implementation(project(":demos:common")) + implementation(project(":demos:mkdocs:appyx-components:common")) implementation(project(":demos:appyx-navigation:common")) implementation(project(":appyx-interactions:appyx-interactions")) implementation(project(":appyx-navigation:appyx-navigation")) diff --git a/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt b/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt index 1a2d52d7d..ee398d360 100644 --- a/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt +++ b/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt @@ -1,8 +1,13 @@ package com.bumble.appyx.navigation import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.border import androidx.compose.foundation.focusable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.runtime.Composable @@ -12,8 +17,10 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.focus.onFocusChanged @@ -28,6 +35,7 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.dp import androidx.compose.ui.window.CanvasBasedWindow +import com.bumble.appyx.demos.common.color_primary import com.bumble.appyx.navigation.integration.ScreenSize import com.bumble.appyx.navigation.integration.WebNodeHost import com.bumble.appyx.navigation.navigator.LocalNavigator @@ -42,13 +50,15 @@ import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.launch import org.jetbrains.skiko.wasm.onWasmReady +private val containerShape = RoundedCornerShape(8) + @OptIn(ExperimentalComposeUiApi::class) fun main() { val events: Channel = Channel() val navigator = Navigator() onWasmReady { CanvasBasedWindow("Appyx navigation demo") { - ForceChangeToCodeGen(events, navigator) + CakeApp(events, navigator) } } } @@ -56,7 +66,7 @@ fun main() { @OptIn(ExperimentalFoundationApi::class) @Composable private fun CakeApp(events: Channel, navigator: Navigator) { - AppyxSampleAppTheme(darkTheme = true) { + AppyxSampleAppTheme { val requester = remember { FocusRequester() } var hasFocus by remember { mutableStateOf(false) } @@ -75,18 +85,16 @@ private fun CakeApp(events: Channel, navigator: Navigator) { .onFocusChanged { hasFocus = it.hasFocus }, color = MaterialTheme.colorScheme.background, ) { - CompositionLocalProvider(LocalDensity provides screenSize.calculateDensityFromScreenSize()) { - CompositionLocalProvider(LocalNavigator provides navigator) { - BlackContainer { - WebNodeHost( - screenSize = screenSize, - onBackPressedEvents = events.receiveAsFlow(), - ) { buildContext -> - RootNode( - buildContext = buildContext, - plugins = listOf(navigator) - ) - } + ProvideScopeConfiguration(navigator, screenSize) { + BlackContainer { + WebNodeHost( + screenSize = screenSize, + onBackPressedEvents = events.receiveAsFlow(), + ) { buildContext -> + RootNode( + buildContext = buildContext, + plugins = listOf(navigator) + ) } } } @@ -100,6 +108,20 @@ private fun CakeApp(events: Channel, navigator: Navigator) { } } +@Composable +private fun ProvideScopeConfiguration( + navigator: Navigator, + screenSize: ScreenSize, + body: @Composable () -> Unit +) { + CompositionLocalProvider( + LocalDensity provides screenSize.calculateDensityFromScreenSize(), + LocalNavigator provides navigator, + ) { + body() + } +} + private fun ScreenSize.calculateDensityFromScreenSize(): Density = if (widthDp.value < 1500) { console.log("Going small! ${widthDp.value}") From a86edff34f5091f762b7f1dfb49294233ff3bb11 Mon Sep 17 00:00:00 2001 From: Michael Jordan Date: Mon, 8 Jan 2024 15:32:40 +0000 Subject: [PATCH 3/6] Fix merging with upstream --- demos/appyx-navigation/web/build.gradle.kts | 1 - .../com/bumble/appyx/navigation/Main.kt | 2 +- .../bumble/appyx/navigation/WebTypography.kt | 44 ------------------- 3 files changed, 1 insertion(+), 46 deletions(-) delete mode 100644 demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/WebTypography.kt diff --git a/demos/appyx-navigation/web/build.gradle.kts b/demos/appyx-navigation/web/build.gradle.kts index 80f45e811..c6fc6e539 100644 --- a/demos/appyx-navigation/web/build.gradle.kts +++ b/demos/appyx-navigation/web/build.gradle.kts @@ -14,7 +14,6 @@ kotlin { val commonMain by getting { dependencies { implementation(project(":demos:common")) - implementation(project(":demos:mkdocs:appyx-components:common")) implementation(project(":demos:appyx-navigation:common")) implementation(project(":appyx-interactions:appyx-interactions")) implementation(project(":appyx-navigation:appyx-navigation")) diff --git a/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt b/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt index bd3263295..8fc14cb4a 100644 --- a/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt +++ b/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt @@ -83,7 +83,7 @@ private fun CakeApp(events: Channel, navigator: Navigator) { .onFocusChanged { hasFocus = it.hasFocus }, color = MaterialTheme.colorScheme.background, ) { - CompositionLocalProvider(LocalNavigator provides navigator) { + ProvideScopeConfiguration(navigator, screenSize) { BlackContainer { WebNodeHost( screenSize = screenSize, diff --git a/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/WebTypography.kt b/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/WebTypography.kt deleted file mode 100644 index 82c0da1e5..000000000 --- a/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/WebTypography.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.bumble.appyx.navigation - -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.unit.sp -import com.bumble.appyx.navigation.ui.typography - -internal val webTypography = typography.copy( - bodySmall = typography.bodySmall.copy( - fontSize = 8.sp, - fontFamily = FontFamily.SansSerif, - ), - bodyMedium = typography.bodyMedium.copy( - fontSize = 10.sp, - fontFamily = FontFamily.SansSerif, - ), - bodyLarge = typography.bodyLarge.copy( - fontSize = 12.sp, - fontFamily = FontFamily.SansSerif, - ), - titleSmall = typography.titleSmall.copy( - fontSize = 8.sp, - fontFamily = FontFamily.SansSerif, - ), - titleMedium = typography.titleMedium.copy( - fontSize = 10.sp, - fontFamily = FontFamily.SansSerif, - ), - titleLarge = typography.titleLarge.copy( - fontSize = 12.sp, - fontFamily = FontFamily.SansSerif, - ), - headlineSmall = typography.headlineSmall.copy( - fontSize = 14.sp, - fontFamily = FontFamily.SansSerif, - ), - headlineMedium = typography.headlineMedium.copy( - fontSize = 16.sp, - fontFamily = FontFamily.SansSerif, - ), - headlineLarge = typography.headlineLarge.copy( - fontSize = 18.sp, - fontFamily = FontFamily.SansSerif, - ), -) From 686ce6b90574786ee347a18401a47db307d6c385 Mon Sep 17 00:00:00 2001 From: Michael Jordan Date: Mon, 8 Jan 2024 15:45:44 +0000 Subject: [PATCH 4/6] Revert version upgrade --- demos/appyx-interactions/iosApp/Podfile.lock | 2 +- demos/appyx-navigation/iosApp/Podfile.lock | 2 +- demos/sandbox-appyx-navigation/iosApp/Podfile.lock | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/demos/appyx-interactions/iosApp/Podfile.lock b/demos/appyx-interactions/iosApp/Podfile.lock index f088988a7..c14ad6c29 100644 --- a/demos/appyx-interactions/iosApp/Podfile.lock +++ b/demos/appyx-interactions/iosApp/Podfile.lock @@ -13,4 +13,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: a1e557981a2880940a401c85ea35aafdd5895941 -COCOAPODS: 1.13.0 +COCOAPODS: 1.12.1 diff --git a/demos/appyx-navigation/iosApp/Podfile.lock b/demos/appyx-navigation/iosApp/Podfile.lock index 841fe4fe1..1a6a2f7cc 100644 --- a/demos/appyx-navigation/iosApp/Podfile.lock +++ b/demos/appyx-navigation/iosApp/Podfile.lock @@ -13,4 +13,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: d0aa24730d1d7d4556f63c23912e284fe1f895e6 -COCOAPODS: 1.13.0 +COCOAPODS: 1.12.1 diff --git a/demos/sandbox-appyx-navigation/iosApp/Podfile.lock b/demos/sandbox-appyx-navigation/iosApp/Podfile.lock index 6b8f524f4..14fd62ab7 100644 --- a/demos/sandbox-appyx-navigation/iosApp/Podfile.lock +++ b/demos/sandbox-appyx-navigation/iosApp/Podfile.lock @@ -13,4 +13,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: a1e557981a2880940a401c85ea35aafdd5895941 -COCOAPODS: 1.13.0 +COCOAPODS: 1.12.1 From f4603844e10b30e69c73d9e6e80e03217815b546 Mon Sep 17 00:00:00 2001 From: Michael Jordan Date: Mon, 8 Jan 2024 15:46:45 +0000 Subject: [PATCH 5/6] Remove logging. --- .../web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt b/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt index 8fc14cb4a..6eaeb8c16 100644 --- a/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt +++ b/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt @@ -141,10 +141,8 @@ private fun ProvideScopeConfiguration( private fun ScreenSize.calculateDensityFromScreenSize(): Density = if (widthDp.value < 1500) { - console.log("Going small! ${widthDp.value}") Density(1.2f, 1f) } else { - console.log("Going big! ${widthDp.value}") Density(1.8f, 1.2f) } From 7cd90df59e6b496ca919da1d75b418d3350c4168 Mon Sep 17 00:00:00 2001 From: Michael Jordan Date: Tue, 20 Feb 2024 13:22:04 +0000 Subject: [PATCH 6/6] Attempt at scaling. --- .../com/bumble/appyx/navigation/Main.kt | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt b/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt index 6eaeb8c16..f8cbe5304 100644 --- a/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt +++ b/demos/appyx-navigation/web/src/jsMain/kotlin/com/bumble/appyx/navigation/Main.kt @@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect @@ -48,8 +49,16 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.launch +import kotlin.math.max +import kotlin.math.min private val containerShape = RoundedCornerShape(8) +private const val MAX_SCALE_RANGE_WIDTH = 2500f +private const val MIN_SCALE_RANGE_WIDTH = 500f +private const val MAX_SCALE_FONT = 1.6f +private const val MIN_SCALE_FONT = 0.8f +private const val MAX_SCALE_UI = 1.6f +private const val MIN_SCALE_UI = 0.8f @OptIn(ExperimentalComposeUiApi::class) fun main() { @@ -83,7 +92,10 @@ private fun CakeApp(events: Channel, navigator: Navigator) { .onFocusChanged { hasFocus = it.hasFocus }, color = MaterialTheme.colorScheme.background, ) { - ProvideScopeConfiguration(navigator, screenSize) { + CompositionLocalProvider( + LocalDensity provides screenSize.calculateDensityFromScreenSize(), + LocalNavigator provides navigator, + ) { BlackContainer { WebNodeHost( screenSize = screenSize, @@ -103,6 +115,8 @@ private fun CakeApp(events: Channel, navigator: Navigator) { requester.requestFocus() } } + + Text("${LocalDensity.current.density}") } } @@ -125,27 +139,17 @@ private fun BlackContainer(content: @Composable () -> Unit) { } } -@Composable -private fun ProvideScopeConfiguration( - navigator: Navigator, - screenSize: ScreenSize, - body: @Composable () -> Unit -) { - CompositionLocalProvider( - LocalDensity provides screenSize.calculateDensityFromScreenSize(), - LocalNavigator provides navigator, - ) { - body() - } +private fun ScreenSize.calculateDensityFromScreenSize(): Density { + console.log("Width: ${widthDp.value}") + val normalisedWidth = max(min(widthDp.value, MAX_SCALE_RANGE_WIDTH), MIN_SCALE_RANGE_WIDTH) + console.log("NormalisedWidth: $normalisedWidth") + val coerceValue = (normalisedWidth - MIN_SCALE_RANGE_WIDTH) / (MAX_SCALE_RANGE_WIDTH - MIN_SCALE_RANGE_WIDTH) + console.log("Coerce Value: $coerceValue") + val uiScale = MIN_SCALE_UI + coerceValue * (MAX_SCALE_UI - MIN_SCALE_UI) + val fontScale = MIN_SCALE_FONT + coerceValue * (MAX_SCALE_FONT - MIN_SCALE_FONT) + return Density(uiScale, fontScale).also { console.log(it) } } -private fun ScreenSize.calculateDensityFromScreenSize(): Density = - if (widthDp.value < 1500) { - Density(1.2f, 1f) - } else { - Density(1.8f, 1.2f) - } - private fun onKeyEvent( keyEvent: KeyEvent, events: Channel,