index.html 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. <!doctype html>
  2. <meta charset="utf-8" />
  3. <meta name="viewport" content="width=device-width, initial-scale=1" />
  4. <title>Moltbot Canvas</title>
  5. <style>
  6. html, body { height: 100%; margin: 0; background: #000; color: #fff; font: 16px/1.4 -apple-system, BlinkMacSystemFont, system-ui, Segoe UI, Roboto, Helvetica, Arial, sans-serif; }
  7. .wrap { min-height: 100%; display: grid; place-items: center; padding: 24px; }
  8. .card { width: min(720px, 100%); background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.10); border-radius: 16px; padding: 18px 18px 14px; }
  9. .title { display: flex; align-items: baseline; gap: 10px; }
  10. h1 { margin: 0; font-size: 22px; letter-spacing: 0.2px; }
  11. .sub { opacity: 0.75; font-size: 13px; }
  12. .row { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
  13. button { appearance: none; border: 1px solid rgba(255,255,255,0.14); background: rgba(255,255,255,0.10); color: #fff; padding: 10px 12px; border-radius: 12px; font-weight: 600; cursor: pointer; }
  14. button:active { transform: translateY(1px); }
  15. .ok { color: #24e08a; }
  16. .bad { color: #ff5c5c; }
  17. .log { margin-top: 14px; opacity: 0.85; font: 12px/1.4 ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace; white-space: pre-wrap; background: rgba(0,0,0,0.35); border: 1px solid rgba(255,255,255,0.08); padding: 10px; border-radius: 12px; }
  18. </style>
  19. <div class="wrap">
  20. <div class="card">
  21. <div class="title">
  22. <h1>Moltbot Canvas</h1>
  23. <div class="sub">Interactive test page (auto-reload enabled)</div>
  24. </div>
  25. <div class="row">
  26. <button id="btn-hello">Hello</button>
  27. <button id="btn-time">Time</button>
  28. <button id="btn-photo">Photo</button>
  29. <button id="btn-dalek">Dalek</button>
  30. </div>
  31. <div id="status" class="sub" style="margin-top: 10px;"></div>
  32. <div id="log" class="log">Ready.</div>
  33. </div>
  34. </div>
  35. <script>
  36. (() => {
  37. const logEl = document.getElementById("log");
  38. const statusEl = document.getElementById("status");
  39. const log = (msg) => { logEl.textContent = String(msg); };
  40. const hasIOS = () =>
  41. !!(
  42. window.webkit &&
  43. window.webkit.messageHandlers &&
  44. (window.webkit.messageHandlers.moltbotCanvasA2UIAction ||
  45. window.webkit.messageHandlers.clawdbotCanvasA2UIAction)
  46. );
  47. const hasAndroid = () =>
  48. !!(
  49. (window.moltbotCanvasA2UIAction &&
  50. typeof window.moltbotCanvasA2UIAction.postMessage === "function") ||
  51. (window.clawdbotCanvasA2UIAction &&
  52. typeof window.clawdbotCanvasA2UIAction.postMessage === "function")
  53. );
  54. const legacySend = typeof window.clawdbotSendUserAction === "function" ? window.clawdbotSendUserAction : undefined;
  55. if (!window.moltbotSendUserAction && legacySend) {
  56. window.moltbotSendUserAction = legacySend;
  57. }
  58. if (!window.clawdbotSendUserAction && typeof window.moltbotSendUserAction === "function") {
  59. window.clawdbotSendUserAction = window.moltbotSendUserAction;
  60. }
  61. const hasHelper = () =>
  62. typeof window.moltbotSendUserAction === "function" ||
  63. typeof window.clawdbotSendUserAction === "function";
  64. statusEl.innerHTML =
  65. "Bridge: " +
  66. (hasHelper() ? "<span class='ok'>ready</span>" : "<span class='bad'>missing</span>") +
  67. " · iOS=" + (hasIOS() ? "yes" : "no") +
  68. " · Android=" + (hasAndroid() ? "yes" : "no");
  69. window.addEventListener("moltbot:a2ui-action-status", (ev) => {
  70. const d = ev && ev.detail || {};
  71. log("Action status: id=" + (d.id || "?") + " ok=" + String(!!d.ok) + (d.error ? (" error=" + d.error) : ""));
  72. });
  73. function send(name, sourceComponentId) {
  74. if (!hasHelper()) {
  75. log("No action bridge found. Ensure you're viewing this on an iOS/Android Moltbot node canvas.");
  76. return;
  77. }
  78. const sendUserAction =
  79. typeof window.moltbotSendUserAction === "function"
  80. ? window.moltbotSendUserAction
  81. : window.clawdbotSendUserAction;
  82. const ok = sendUserAction({
  83. name,
  84. surfaceId: "main",
  85. sourceComponentId,
  86. context: { t: Date.now() },
  87. });
  88. log(ok ? ("Sent action: " + name) : ("Failed to send action: " + name));
  89. }
  90. document.getElementById("btn-hello").onclick = () => send("hello", "demo.hello");
  91. document.getElementById("btn-time").onclick = () => send("time", "demo.time");
  92. document.getElementById("btn-photo").onclick = () => send("photo", "demo.photo");
  93. document.getElementById("btn-dalek").onclick = () => send("dalek", "demo.dalek");
  94. })();
  95. </script>