From c5e790c11d239f74b09d88509dad9e7f260c62b4 Mon Sep 17 00:00:00 2001 From: xxfast Date: Mon, 25 Nov 2024 11:31:21 +1100 Subject: [PATCH 1/3] Add new inline remember variants --- .../decompose/router/screens/HomeScreen.kt | 3 +-- .../router/screens/pages/PagesScreen.kt | 11 +++------ .../router/screens/slot/SlotScreen.kt | 5 ++-- .../router/screens/stack/StackScreen.kt | 2 +- .../xxfast/decompose/router/pages/Router.kt | 23 +++++++++++++++++-- .../xxfast/decompose/router/slot/Router.kt | 21 +++++++++++++++++ .../xxfast/decompose/router/stack/Router.kt | 22 +++++++++++------- 7 files changed, 63 insertions(+), 24 deletions(-) diff --git a/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/HomeScreen.kt b/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/HomeScreen.kt index 09e8db1..f07c1c3 100644 --- a/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/HomeScreen.kt +++ b/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/HomeScreen.kt @@ -29,10 +29,9 @@ import io.github.xxfast.decompose.router.screens.pages.PagesScreen import io.github.xxfast.decompose.router.screens.slot.SlotScreen import io.github.xxfast.decompose.router.screens.stack.StackScreen -@OptIn(ExperimentalDecomposeApi::class, ExperimentalFoundationApi::class) @Composable fun HomeScreen() { - val pager: Router = rememberRouter(HomeScreens::class) { pagesOf(Stack, Pages, Slot) } + val pager: Router = rememberRouter { pagesOf(Stack, Pages, Slot) } Scaffold( bottomBar = { diff --git a/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/pages/PagesScreen.kt b/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/pages/PagesScreen.kt index 94889db..5e3f862 100644 --- a/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/pages/PagesScreen.kt +++ b/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/pages/PagesScreen.kt @@ -1,6 +1,5 @@ package io.github.xxfast.decompose.router.screens.pages -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize @@ -20,21 +19,17 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp -import com.arkivanov.decompose.ExperimentalDecomposeApi import com.arkivanov.decompose.router.pages.Pages import com.arkivanov.decompose.router.pages.selectFirst import io.github.xxfast.decompose.router.pages.RoutedContent +import io.github.xxfast.decompose.router.pages.Router import io.github.xxfast.decompose.router.pages.rememberRouter import io.github.xxfast.decompose.router.screens.PAGER -@OptIn( - ExperimentalDecomposeApi::class, - ExperimentalFoundationApi::class, - ExperimentalMaterial3Api::class -) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun PagesScreen() { - val router = rememberRouter(PagesScreens::class) { + val router: Router = rememberRouter { Pages( items = List(10) { PagesScreens(it) }, selectedIndex = 0, diff --git a/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/slot/SlotScreen.kt b/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/slot/SlotScreen.kt index bc8e2c2..6de9d6f 100644 --- a/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/slot/SlotScreen.kt +++ b/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/slot/SlotScreen.kt @@ -37,9 +37,8 @@ import io.github.xxfast.decompose.router.slot.rememberRouter @OptIn(ExperimentalMaterial3Api::class) @Composable fun SlotScreen() { - val dialogRouter: Router = rememberRouter(DialogScreens::class) { null } - val bottomSheetRouter: Router = - rememberRouter(BottomSheetScreens::class) { null } + val dialogRouter: Router = rememberRouter { null } + val bottomSheetRouter: Router = rememberRouter { null } Scaffold( topBar = { diff --git a/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/stack/StackScreen.kt b/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/stack/StackScreen.kt index 9638862..4e8ce0f 100644 --- a/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/stack/StackScreen.kt +++ b/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/stack/StackScreen.kt @@ -22,7 +22,7 @@ import io.github.xxfast.decompose.router.stack.rememberRouter @OptIn(ExperimentalDecomposeApi::class) @Composable fun StackScreen() { - val router: Router = rememberRouter(StackScreens::class) { listOf(List) } + val router: Router = rememberRouter { listOf(List) } RoutedContent( router = router, diff --git a/decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/pages/Router.kt b/decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/pages/Router.kt index 1e81105..ec5d50f 100644 --- a/decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/pages/Router.kt +++ b/decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/pages/Router.kt @@ -19,13 +19,32 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.serializerOrNull import kotlin.reflect.KClass -@OptIn(ExperimentalDecomposeApi::class) class Router internal constructor( private val navigation: PagesNavigation, val pages: State>, ) : PagesNavigation by navigation -@OptIn(ExperimentalDecomposeApi::class, InternalSerializationApi::class) +/*** + * Creates a router that retains pages of [C] configuration + * @param key + * @param initialPages initial list of pages + * @param handleBackButton should the router handle back button + */ +@Suppress("DEPRECATION") // For migration purposes +@Composable +inline fun rememberRouter( + key: Any = C::class, + handleBackButton: Boolean = true, + noinline initialPages: () -> Pages, +): Router = rememberRouter( + type = C::class, + key = key, + handleBackButton = handleBackButton, + initialPages = initialPages +) + +@Deprecated(message = "Use rememberRouter with reified type parameter") +@OptIn(InternalSerializationApi::class) @Composable fun rememberRouter( type: KClass, diff --git a/decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/slot/Router.kt b/decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/slot/Router.kt index e4614b1..e1bafa3 100644 --- a/decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/slot/Router.kt +++ b/decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/slot/Router.kt @@ -22,6 +22,27 @@ class Router internal constructor( val slot: State>, ): SlotNavigation by navigation + +/*** + * Creates a router that retains a slot of [C] configuration + * @param key + * @param initialConfiguration initial configuration + * @param handleBackButton should the router handle back button + */ +@Suppress("DEPRECATION") // For migration purposes +@Composable +inline fun rememberRouter( + key: Any = C::class, + handleBackButton: Boolean = true, + noinline initialConfiguration: () -> C?, +): Router = rememberRouter( + type = C::class, + key = key, + handleBackButton = handleBackButton, + initialConfiguration = initialConfiguration +) + +@Deprecated(message = "Use rememberRouter with reified type parameter") @OptIn(InternalSerializationApi::class) @Composable fun rememberRouter( diff --git a/decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/stack/Router.kt b/decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/stack/Router.kt index 2e68c9b..ba96c9c 100644 --- a/decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/stack/Router.kt +++ b/decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/stack/Router.kt @@ -26,22 +26,28 @@ class Router internal constructor( val stack: State>, ) : StackNavigation by navigation -// TODO: Add this back to API once this [issue](https://github.com/JetBrains/compose-multiplatform/issues/2900) is fixed -//@Composable -//inline fun rememberRouter( -// key: Any = C::class, -// handleBackButton: Boolean = true, -// noinline initialStack: () -> List, -//): Router = rememberRouter(C::class, key, handleBackButton, initialStack) +/*** + * Creates a router that retains a stack of [C] configuration + * @param key + * @param initialStack initial stack of configurations + * @param handleBackButton should the router handle back button + */ +@Suppress("DEPRECATION") // For migration purposes +@Composable +inline fun rememberRouter( + key: Any = C::class, + handleBackButton: Boolean = true, + noinline initialStack: () -> List, +): Router = rememberRouter(C::class, key, handleBackButton, initialStack = initialStack) /*** * Creates a router that retains a stack of [C] configuration - * * @param type configuration class type * @param key * @param initialStack initial stack of configurations * @param handleBackButton should the router handle back button */ +@Deprecated(message = "Use rememberRouter with reified type parameter") @OptIn(InternalSerializationApi::class) @Composable fun rememberRouter( From 7541a59bb041a986914bf8cd9a1f4ed7a59250fc Mon Sep 17 00:00:00 2001 From: xxfast Date: Mon, 25 Nov 2024 11:59:22 +1100 Subject: [PATCH 2/3] Fix nested test to match 5th page exactly --- .../github/xxfast/decompose/router/app/TestNestedRouters.kt | 4 ++-- .../github/xxfast/decompose/router/app/TestPagesRouters.kt | 6 +++--- .../xxfast/decompose/router/screens/pages/PagesScreen.kt | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/androidInstrumentedTest/kotlin/io/github/xxfast/decompose/router/app/TestNestedRouters.kt b/app/src/androidInstrumentedTest/kotlin/io/github/xxfast/decompose/router/app/TestNestedRouters.kt index 43f215a..e4482b5 100644 --- a/app/src/androidInstrumentedTest/kotlin/io/github/xxfast/decompose/router/app/TestNestedRouters.kt +++ b/app/src/androidInstrumentedTest/kotlin/io/github/xxfast/decompose/router/app/TestNestedRouters.kt @@ -41,7 +41,7 @@ class TestNestedRouters { // Go to pages and swipe to the 5th page onNode(bottomNavPagesItem).performClick() onNode(pager).performScrollToIndex(5) - onNode(hasText("5")).assertExists() + onNode(hasText("Page #5")).assertExists() // Go to slots, open the bottom sheet and verify if it is visible onNode(bottomNavSlotItem).performClick() @@ -58,7 +58,7 @@ class TestNestedRouters { onNode(bottomNavStackItem).performClick() onNode(details).assertExists().assertTextContains("Item@", substring = true) onNode(bottomNavPagesItem).performClick() - onNode(hasText("5")).assertExists() + onNode(hasText("Page #5")).assertExists() onNode(bottomNavSlotItem).performClick() onNode(buttonBottomSheet).performClick() activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT diff --git a/app/src/androidInstrumentedTest/kotlin/io/github/xxfast/decompose/router/app/TestPagesRouters.kt b/app/src/androidInstrumentedTest/kotlin/io/github/xxfast/decompose/router/app/TestPagesRouters.kt index 2505540..dfbbb3a 100644 --- a/app/src/androidInstrumentedTest/kotlin/io/github/xxfast/decompose/router/app/TestPagesRouters.kt +++ b/app/src/androidInstrumentedTest/kotlin/io/github/xxfast/decompose/router/app/TestPagesRouters.kt @@ -21,14 +21,14 @@ class TestPagesRouters { // Go to pages and swipe to the 5th page onNode(bottomNavPagesItem).performClick() onNode(pager).performScrollToIndex(5) - onNode(hasText("5")).assertExists() + onNode(hasText("Page #5")).assertExists() // Verify pages screens are restored activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE onNode(pager).assertExists() - onNode(hasText("5")).assertExists() + onNode(hasText("Page #5")).assertExists() activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT onNode(pager).assertExists() - onNode(hasText("5")).assertExists() + onNode(hasText("Page #5")).assertExists() } } diff --git a/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/pages/PagesScreen.kt b/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/pages/PagesScreen.kt index 5e3f862..67537eb 100644 --- a/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/pages/PagesScreen.kt +++ b/app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/pages/PagesScreen.kt @@ -58,8 +58,8 @@ fun PagesScreen() { Card(modifier = Modifier.padding(16.dp)) { Box(modifier = Modifier.fillMaxSize()) { Text( - text = page.index.toString(), - style = MaterialTheme.typography.displayLarge, + text = "Page #${page.index}", + style = MaterialTheme.typography.displayMedium, modifier = Modifier.align(Alignment.Center) ) } From 66171689be91ce208751ae4c2b80c4f29e60dc43 Mon Sep 17 00:00:00 2001 From: xxfast Date: Mon, 25 Nov 2024 12:36:30 +1100 Subject: [PATCH 3/3] Disable instrumentation tests for api 25 --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3036f2a..028d513 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -106,6 +106,7 @@ jobs: sudo udevadm trigger --name-match=kvm - name: Instrumentation tests + continue-on-error: ${{ matrix.api-level == 25}} # TODO: Figure out why this fails on API 25 uses: reactivecircus/android-emulator-runner@v2 with: api-level: ${{ matrix.api-level }}