Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<HomeScreens> = rememberRouter(HomeScreens::class) { pagesOf(Stack, Pages, Slot) }
val pager: Router<HomeScreens> = rememberRouter { pagesOf(Stack, Pages, Slot) }

Scaffold(
bottomBar = {
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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<PagesScreens> = rememberRouter {
Pages(
items = List(10) { PagesScreens(it) },
selectedIndex = 0,
Expand Down Expand Up @@ -63,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)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,8 @@ import io.github.xxfast.decompose.router.slot.rememberRouter
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SlotScreen() {
val dialogRouter: Router<DialogScreens> = rememberRouter(DialogScreens::class) { null }
val bottomSheetRouter: Router<BottomSheetScreens> =
rememberRouter(BottomSheetScreens::class) { null }
val dialogRouter: Router<DialogScreens> = rememberRouter { null }
val bottomSheetRouter: Router<BottomSheetScreens> = rememberRouter { null }

Scaffold(
topBar = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import io.github.xxfast.decompose.router.stack.rememberRouter
@OptIn(ExperimentalDecomposeApi::class)
@Composable
fun StackScreen() {
val router: Router<StackScreens> = rememberRouter(StackScreens::class) { listOf(List) }
val router: Router<StackScreens> = rememberRouter { listOf(List) }

RoutedContent(
router = router,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,32 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.serializerOrNull
import kotlin.reflect.KClass

@OptIn(ExperimentalDecomposeApi::class)
class Router<C: Any> internal constructor(
private val navigation: PagesNavigation<C>,
val pages: State<ChildPages<C, RouterContext>>,
) : PagesNavigation<C> 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 <reified C: @Serializable Any> rememberRouter(
key: Any = C::class,
handleBackButton: Boolean = true,
noinline initialPages: () -> Pages<C>,
): Router<C> = rememberRouter(
type = C::class,
key = key,
handleBackButton = handleBackButton,
initialPages = initialPages
)

@Deprecated(message = "Use rememberRouter with reified type parameter")
@OptIn(InternalSerializationApi::class)
@Composable
fun <C: @Serializable Any> rememberRouter(
type: KClass<C>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,27 @@ class Router<C : Any> internal constructor(
val slot: State<ChildSlot<C, RouterContext>>,
): SlotNavigation<C> 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 <reified C: @Serializable Any> rememberRouter(
key: Any = C::class,
handleBackButton: Boolean = true,
noinline initialConfiguration: () -> C?,
): Router<C> = rememberRouter(
type = C::class,
key = key,
handleBackButton = handleBackButton,
initialConfiguration = initialConfiguration
)

@Deprecated(message = "Use rememberRouter with reified type parameter")
@OptIn(InternalSerializationApi::class)
@Composable
fun <C : @Serializable Any> rememberRouter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,28 @@ class Router<C: Any> internal constructor(
val stack: State<ChildStack<C, RouterContext>>,
) : StackNavigation<C> by navigation

// TODO: Add this back to API once this [issue](https://github.com/JetBrains/compose-multiplatform/issues/2900) is fixed
//@Composable
//inline fun <reified C: @Serializable Any> rememberRouter(
// key: Any = C::class,
// handleBackButton: Boolean = true,
// noinline initialStack: () -> List<C>,
//): Router<C> = 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 <reified C: @Serializable Any> rememberRouter(
key: Any = C::class,
handleBackButton: Boolean = true,
noinline initialStack: () -> List<C>,
): Router<C> = 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 <C: @Serializable Any> rememberRouter(
Expand Down
Loading