Skip to content

Commit

Permalink
Add a code load status snackbar for Android Compose UI frontend (#1528)
Browse files Browse the repository at this point in the history
iOS to follow.
  • Loading branch information
JakeWharton authored Sep 29, 2023
1 parent 659328e commit 7ff0488
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public fun <A : AppService> TreehouseContent(
widgetSystem: WidgetSystem<@Composable () -> Unit>,
codeListener: CodeListener = CodeListener(),
contentSource: TreehouseContentSource<A>,
modifier: Modifier = Modifier,
) {
val onBackPressedDispatcher = platformOnBackPressedDispatcher()

Expand Down Expand Up @@ -87,7 +88,7 @@ public fun <A : AppService> TreehouseContent(
}

Box(
modifier = Modifier.onSizeChanged { size ->
modifier = modifier.onSizeChanged { size ->
viewportSize = with(Density(density.density.toDouble())) {
Size(size.width.toDp().value.redwoodDp, size.height.toDp().value.redwoodDp)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@ package com.example.redwood.emojisearch.android.composeui
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Scaffold
import androidx.compose.material.SnackbarDuration.Indefinite
import androidx.compose.material.SnackbarHost
import androidx.compose.material.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.NoLiveLiterals
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.Modifier
import androidx.core.view.WindowCompat
import app.cash.redwood.compose.AndroidUiDispatcher.Companion.Main
import app.cash.redwood.layout.composeui.ComposeUiRedwoodLayoutWidgetFactory
Expand All @@ -41,13 +47,16 @@ import com.example.redwood.emojisearch.treehouse.EmojiSearchPresenter
import com.example.redwood.emojisearch.widget.EmojiSearchProtocolNodeFactory
import com.example.redwood.emojisearch.widget.EmojiSearchWidgetFactories
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.launch
import okhttp3.OkHttpClient

@NoLiveLiterals
class EmojiSearchActivity : ComponentActivity() {
private val scope: CoroutineScope = CoroutineScope(Main)
private val snackbarHostState = SnackbarHostState()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand All @@ -68,13 +77,46 @@ class EmojiSearchActivity : ComponentActivity() {
)
}

val view = ComposeView(this)
view.setContent {
setContent {
EmojiSearchTheme {
TreehouseContent(treehouseApp, widgetSystem, contentSource = treehouseContentSource)
Scaffold(
snackbarHost = { SnackbarHost(snackbarHostState) },
) { contentPadding ->
TreehouseContent(
treehouseApp = treehouseApp,
widgetSystem = widgetSystem,
contentSource = treehouseContentSource,
modifier = Modifier.padding(contentPadding),
)
}
}
}
setContentView(view)
}

val appEventListener: EventListener = object : EventListener() {
private var success = true
private var snackbarJob: Job? = null

override fun codeLoadFailed(app: TreehouseApp<*>, manifestUrl: String?, exception: Exception, startValue: Any?) {
Log.w("Treehouse", "codeLoadFailed", exception)
if (success) {
// Only show the Snackbar on the first transition from success.
success = false
snackbarJob = scope.launch {
snackbarHostState.showSnackbar(
message = "Unable to load guest code from server",
actionLabel = "Dismiss",
duration = Indefinite,
)
}
}
}

override fun codeLoadSuccess(app: TreehouseApp<*>, manifestUrl: String?, manifest: ZiplineManifest, zipline: Zipline, startValue: Any?) {
Log.i("Treehouse", "codeLoadSuccess")
success = true
snackbarJob?.cancel()
}
}

private fun createTreehouseApp(): TreehouseApp<EmojiSearchPresenter> {
Expand Down Expand Up @@ -109,13 +151,3 @@ class EmojiSearchActivity : ComponentActivity() {
super.onDestroy()
}
}

val appEventListener: EventListener = object : EventListener() {
override fun codeLoadFailed(app: TreehouseApp<*>, manifestUrl: String?, exception: Exception, startValue: Any?) {
Log.w("Treehouse", "codeLoadFailed", exception)
}

override fun codeLoadSuccess(app: TreehouseApp<*>, manifestUrl: String?, manifest: ZiplineManifest, zipline: Zipline, startValue: Any?) {
Log.i("Treehouse", "codeLoadSuccess")
}
}

0 comments on commit 7ff0488

Please sign in to comment.