feat(canvas): remove setMode; host A2UI in scaffold

This commit is contained in:
Peter Steinberger
2025-12-18 13:18:24 +01:00
parent dda6d7f9e1
commit 790079c3b6
12 changed files with 174 additions and 144 deletions

View File

@@ -272,7 +272,6 @@ class NodeRuntime(context: Context) {
buildList {
add(ClawdisCanvasCommand.Show.rawValue)
add(ClawdisCanvasCommand.Hide.rawValue)
add(ClawdisCanvasCommand.SetMode.rawValue)
add(ClawdisCanvasCommand.Navigate.rawValue)
add(ClawdisCanvasCommand.Eval.rawValue)
add(ClawdisCanvasCommand.Snapshot.rawValue)
@@ -544,14 +543,9 @@ class NodeRuntime(context: Context) {
return when (command) {
ClawdisCanvasCommand.Show.rawValue -> BridgeSession.InvokeResult.ok(null)
ClawdisCanvasCommand.Hide.rawValue -> BridgeSession.InvokeResult.ok(null)
ClawdisCanvasCommand.SetMode.rawValue -> {
val mode = CanvasController.parseMode(paramsJson)
canvas.setMode(mode)
BridgeSession.InvokeResult.ok(null)
}
ClawdisCanvasCommand.Navigate.rawValue -> {
val url = CanvasController.parseNavigateUrl(paramsJson)
if (url != null) canvas.navigate(url)
canvas.navigate(url)
BridgeSession.InvokeResult.ok(null)
}
ClawdisCanvasCommand.Eval.rawValue -> {
@@ -638,7 +632,8 @@ class NodeRuntime(context: Context) {
// ignore
}
canvas.navigate(a2uiIndexUrl)
// Ensure the default canvas scaffold is loaded; A2UI is now hosted there.
canvas.navigate("")
repeat(50) {
try {
val ready = canvas.eval(a2uiReadyCheckJS)
@@ -713,8 +708,6 @@ class NodeRuntime(context: Context) {
private data class Quad<A, B, C, D>(val first: A, val second: B, val third: C, val fourth: D)
private const val a2uiIndexUrl: String = "file:///android_asset/CanvasA2UI/index.html"
private const val a2uiReadyCheckJS: String =
"""
(() => {

View File

@@ -14,11 +14,8 @@ import android.util.Base64
import kotlin.coroutines.resume
class CanvasController {
enum class Mode { CANVAS, WEB }
@Volatile private var webView: WebView? = null
@Volatile private var mode: Mode = Mode.CANVAS
@Volatile private var url: String = ""
@Volatile private var url: String? = null
private val scaffoldAssetUrl = "file:///android_asset/CanvasScaffold/scaffold.html"
@@ -27,17 +24,9 @@ class CanvasController {
reload()
}
fun setMode(mode: Mode) {
this.mode = mode
reload()
}
fun navigate(url: String) {
this.url = url
if (url.trim().isNotBlank()) {
// `canvas.navigate` is expected to show web content; default to WEB mode to match iOS.
this.mode = Mode.WEB
}
val trimmed = url.trim()
this.url = if (trimmed.isBlank() || trimmed == "/") null else trimmed
reload()
}
@@ -51,17 +40,12 @@ class CanvasController {
}
private fun reload() {
val currentMode = mode
val currentUrl = url
withWebViewOnMain { wv ->
when (currentMode) {
Mode.WEB -> {
// Match iOS behavior: if URL is missing/invalid, keep the current page (canvas scaffold).
val trimmed = currentUrl.trim()
if (trimmed.isBlank()) return@withWebViewOnMain
wv.loadUrl(trimmed)
}
Mode.CANVAS -> wv.loadUrl(scaffoldAssetUrl)
if (currentUrl == null) {
wv.loadUrl(scaffoldAssetUrl)
} else {
wv.loadUrl(currentUrl)
}
}
}
@@ -106,19 +90,9 @@ class CanvasController {
}
companion object {
fun parseMode(paramsJson: String?): Mode {
val obj = parseParamsObject(paramsJson) ?: return Mode.CANVAS
return if (obj.optString("mode", "").equals("web", ignoreCase = true)) {
Mode.WEB
} else {
Mode.CANVAS
}
}
fun parseNavigateUrl(paramsJson: String?): String? {
val obj = parseParamsObject(paramsJson) ?: return null
val url = obj.optString("url", "").trim()
return url.takeIf { it.isNotBlank() }
fun parseNavigateUrl(paramsJson: String?): String {
val obj = parseParamsObject(paramsJson)
return obj?.optString("url", "")?.trim().orEmpty()
}
fun parseEvalJs(paramsJson: String?): String? {

View File

@@ -9,7 +9,6 @@ enum class ClawdisCapability(val rawValue: String) {
enum class ClawdisCanvasCommand(val rawValue: String) {
Show("canvas.show"),
Hide("canvas.hide"),
SetMode("canvas.setMode"),
Navigate("canvas.navigate"),
Eval("canvas.eval"),
Snapshot("canvas.snapshot"),

View File

@@ -8,7 +8,6 @@ class ClawdisProtocolConstantsTest {
fun canvasCommandsUseStableStrings() {
assertEquals("canvas.show", ClawdisCanvasCommand.Show.rawValue)
assertEquals("canvas.hide", ClawdisCanvasCommand.Hide.rawValue)
assertEquals("canvas.setMode", ClawdisCanvasCommand.SetMode.rawValue)
assertEquals("canvas.navigate", ClawdisCanvasCommand.Navigate.rawValue)
assertEquals("canvas.eval", ClawdisCanvasCommand.Eval.rawValue)
assertEquals("canvas.snapshot", ClawdisCanvasCommand.Snapshot.rawValue)