Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify creation of new screens #1525

Merged
merged 1 commit into from
Sep 28, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import app.cash.redwood.lazylayout.dom.HTMLElementRedwoodLazyLayoutWidgetFactory
import app.cash.redwood.widget.asRedwoodView
import com.example.redwood.testing.presenter.HttpClient
import com.example.redwood.testing.presenter.TestApp
import com.example.redwood.testing.presenter.TestContext
import com.example.redwood.testing.widget.TestSchemaWidgetFactories
import kotlin.js.json
import kotlinx.browser.document
Expand Down Expand Up @@ -53,7 +54,8 @@ fun main() {
response.text().await()
}

val context = TestContext(client)
composition.setContent {
TestApp(client)
TestApp(context)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@ import androidx.compose.runtime.Composable
import app.cash.redwood.treehouse.TreehouseUi
import com.example.redwood.testing.presenter.HttpClient
import com.example.redwood.testing.presenter.TestApp
import com.example.redwood.testing.presenter.TestContext

class TestAppTreehouseUi(
private val httpClient: HttpClient,
httpClient: HttpClient,
) : TreehouseUi {
private val context = TestContext(httpClient)

@Composable
override fun Show() {
TestApp(httpClient)
TestApp(context)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package com.example.redwood.testing.presenter

import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.Stable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import app.cash.redwood.Modifier
Expand All @@ -30,62 +31,60 @@ import app.cash.redwood.ui.dp
import com.example.redwood.testing.compose.Button
import com.example.redwood.testing.compose.Text

private val screens = buildMap<String, @Composable TestContext.() -> Unit> {
put("Repo Search") { RepoSearch(httpClient) }
put("UI Configuration") { UiConfigurationValues() }
}

@Stable
class TestContext(
val httpClient: HttpClient,
)
Comment on lines +40 to +42
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will become a context receiver eliminating the need to explicitly pass any values in the lambdas above.


@Composable
fun TestApp(httpClient: HttpClient) {
val screen = remember { mutableStateOf<Screen?>(null) }
val activeScreen = screen.value
if (activeScreen == null) {
HomeScreen(screen)
fun TestApp(context: TestContext) {
val screenKeyState = remember { mutableStateOf<String?>(null) }
val screenKey = screenKeyState.value
if (screenKey == null) {
ScreenList(screenKeyState)
} else {
val onBack = { screen.value = null }
val onBack = { screenKeyState.value = null }
BackHandler(onBack = onBack)

Column(width = Fill, height = Fill) {
Button("Back", onClick = onBack)

// TODO This should be a Box.
Column(
width = Fill,
horizontalAlignment = Stretch,
modifier = Modifier.grow(1.0).horizontalAlignment(Stretch),
) {
activeScreen.Show(httpClient)
val content = screens[screenKey]
if (content == null) {
Text("No screen found with key '$screenKey'!")
Comment on lines +58 to +59
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about automatically falling back to home, but if we get rememberSaveable, you rename a key, and the app reloads, I want what happened to be slightly more clear.

} else {
// TODO This should be a Box.
Column(
width = Fill,
horizontalAlignment = Stretch,
modifier = Modifier.grow(1.0).horizontalAlignment(Stretch),
) {
with(context) {
content()
}
}
}
}
}
}

@Suppress("unused") // Used via reflection.
enum class Screen {
RepoSearch {
@Composable
override fun Show(httpClient: HttpClient) {
RepoSearch(httpClient)
}
},
UiConfiguration {
@Composable
override fun Show(httpClient: HttpClient) {
UiConfigurationValues()
}
},
;

@Composable
abstract fun Show(httpClient: HttpClient)
}

@Composable
private fun HomeScreen(screen: MutableState<Screen?>) {
private fun ScreenList(screen: MutableState<String?>) {
Column(
width = Fill,
height = Fill,
overflow = Overflow.Scroll,
horizontalAlignment = Stretch,
) {
Text("Test App Screens:", modifier = Modifier.margin(Margin(8.dp)))
Screen.entries.forEach {
Button(it.name, onClick = {
screen.value = it
for (key in screens.keys) {
Button(key, onClick = {
screen.value = key
})
}
}
Expand Down