Nodes: handle canvas.* commands on iOS/Android

This commit is contained in:
Peter Steinberger
2025-12-18 01:17:23 +00:00
parent 22516437b7
commit 21a27e3b65
4 changed files with 18 additions and 19 deletions

View File

@@ -422,11 +422,11 @@ class NodeRuntime(context: Context) {
} }
private suspend fun handleInvoke(command: String, paramsJson: String?): BridgeSession.InvokeResult { private suspend fun handleInvoke(command: String, paramsJson: String?): BridgeSession.InvokeResult {
if (command.startsWith("screen.") || command.startsWith("camera.")) { if (command.startsWith("canvas.") || command.startsWith("camera.")) {
if (!isForeground.value) { if (!isForeground.value) {
return BridgeSession.InvokeResult.error( return BridgeSession.InvokeResult.error(
code = "NODE_BACKGROUND_UNAVAILABLE", code = "NODE_BACKGROUND_UNAVAILABLE",
message = "NODE_BACKGROUND_UNAVAILABLE: screen/camera commands require foreground", message = "NODE_BACKGROUND_UNAVAILABLE: canvas/camera commands require foreground",
) )
} }
} }
@@ -438,19 +438,19 @@ class NodeRuntime(context: Context) {
} }
return when (command) { return when (command) {
"screen.show" -> BridgeSession.InvokeResult.ok(null) "canvas.show" -> BridgeSession.InvokeResult.ok(null)
"screen.hide" -> BridgeSession.InvokeResult.ok(null) "canvas.hide" -> BridgeSession.InvokeResult.ok(null)
"screen.setMode" -> { "canvas.setMode" -> {
val mode = CanvasController.parseMode(paramsJson) val mode = CanvasController.parseMode(paramsJson)
canvas.setMode(mode) canvas.setMode(mode)
BridgeSession.InvokeResult.ok(null) BridgeSession.InvokeResult.ok(null)
} }
"screen.navigate" -> { "canvas.navigate" -> {
val url = CanvasController.parseNavigateUrl(paramsJson) val url = CanvasController.parseNavigateUrl(paramsJson)
if (url != null) canvas.navigate(url) if (url != null) canvas.navigate(url)
BridgeSession.InvokeResult.ok(null) BridgeSession.InvokeResult.ok(null)
} }
"screen.eval" -> { "canvas.eval" -> {
val js = val js =
CanvasController.parseEvalJs(paramsJson) CanvasController.parseEvalJs(paramsJson)
?: return BridgeSession.InvokeResult.error( ?: return BridgeSession.InvokeResult.error(
@@ -468,7 +468,7 @@ class NodeRuntime(context: Context) {
} }
BridgeSession.InvokeResult.ok("""{"result":${result.toJsonString()}}""") BridgeSession.InvokeResult.ok("""{"result":${result.toJsonString()}}""")
} }
"screen.snapshot" -> { "canvas.snapshot" -> {
val maxWidth = CanvasController.parseSnapshotMaxWidth(paramsJson) val maxWidth = CanvasController.parseSnapshotMaxWidth(paramsJson)
val base64 = val base64 =
try { try {

View File

@@ -185,7 +185,7 @@ class BridgeSessionTest {
writer.flush() writer.flush()
// Ask the node to invoke something; handler will throw. // Ask the node to invoke something; handler will throw.
writer.write("""{"type":"invoke","id":"i1","command":"screen.snapshot","paramsJSON":null}""") writer.write("""{"type":"invoke","id":"i1","command":"canvas.snapshot","paramsJSON":null}""")
writer.write("\n") writer.write("\n")
writer.flush() writer.flush()

View File

@@ -265,16 +265,15 @@ final class NodeAppModel {
} }
private func handleInvoke(_ req: BridgeInvokeRequest) async -> BridgeInvokeResponse { private func handleInvoke(_ req: BridgeInvokeRequest) async -> BridgeInvokeResponse {
// Alias for "canvas" capability: accept canvas.* commands and map them to screen.*. let command = req.command
let command = ClawdisInvokeCommandAliases.canonicalizeCanvasToScreen(req.command)
if command.hasPrefix("screen.") || command.hasPrefix("camera."), self.isBackgrounded { if command.hasPrefix("canvas.") || command.hasPrefix("camera."), self.isBackgrounded {
return BridgeInvokeResponse( return BridgeInvokeResponse(
id: req.id, id: req.id,
ok: false, ok: false,
error: ClawdisNodeError( error: ClawdisNodeError(
code: .backgroundUnavailable, code: .backgroundUnavailable,
message: "NODE_BACKGROUND_UNAVAILABLE: screen/camera commands require foreground")) message: "NODE_BACKGROUND_UNAVAILABLE: canvas/camera commands require foreground"))
} }
if command.hasPrefix("camera."), !self.isCameraEnabled() { if command.hasPrefix("camera."), !self.isCameraEnabled() {

View File

@@ -6,12 +6,12 @@ public enum ClawdisScreenMode: String, Codable, Sendable {
} }
public enum ClawdisScreenCommand: String, Codable, Sendable { public enum ClawdisScreenCommand: String, Codable, Sendable {
case show = "screen.show" case show = "canvas.show"
case hide = "screen.hide" case hide = "canvas.hide"
case setMode = "screen.setMode" case setMode = "canvas.setMode"
case navigate = "screen.navigate" case navigate = "canvas.navigate"
case evalJS = "screen.eval" case evalJS = "canvas.eval"
case snapshot = "screen.snapshot" case snapshot = "canvas.snapshot"
} }
public struct ClawdisScreenNavigateParams: Codable, Sendable, Equatable { public struct ClawdisScreenNavigateParams: Codable, Sendable, Equatable {