Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline (Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/* packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
152 lines
4.8 KiB
HTML
152 lines
4.8 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<title>Rakazo computer</title>
|
|
<style>
|
|
html,
|
|
body,
|
|
#screen {
|
|
margin: 0;
|
|
height: 100%;
|
|
width: 100%;
|
|
background: #0e0e10;
|
|
overflow: hidden;
|
|
}
|
|
#mobile-controls {
|
|
position: fixed;
|
|
right: max(12px, env(safe-area-inset-right));
|
|
top: calc(
|
|
var(--mobile-visual-top, 0px) + var(--mobile-visual-height, 100dvh) - 60px -
|
|
env(safe-area-inset-bottom)
|
|
);
|
|
z-index: 2;
|
|
display: flex;
|
|
gap: 8px;
|
|
}
|
|
#mobile-keyboard,
|
|
#mobile-trackpad {
|
|
box-sizing: border-box;
|
|
width: 48px;
|
|
height: 48px;
|
|
padding: 11px;
|
|
border: 1px solid color-mix(in srgb, currentColor 35%, transparent);
|
|
border-radius: 12px;
|
|
background: Canvas;
|
|
color: CanvasText;
|
|
box-shadow: 0 2px 10px color-mix(in srgb, CanvasText 25%, transparent);
|
|
}
|
|
#mobile-keyboard.active,
|
|
#mobile-trackpad.active {
|
|
outline: 3px solid Highlight;
|
|
outline-offset: 1px;
|
|
}
|
|
#mobile-keyboard svg,
|
|
#mobile-trackpad svg {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
#screen.trackpad-active {
|
|
touch-action: none;
|
|
}
|
|
#mobile-keyboard-input {
|
|
position: fixed;
|
|
left: -40px;
|
|
width: 1px;
|
|
height: 1px;
|
|
border: 0;
|
|
opacity: 0;
|
|
}
|
|
.mobile-keyboard-open #screen {
|
|
position: fixed;
|
|
top: var(--mobile-visual-top, 0px);
|
|
left: 0;
|
|
height: var(--mobile-visual-height, 100dvh);
|
|
}
|
|
</style>
|
|
<script type="module">
|
|
import { attachHostClipboardPaste } from "./clipboard-bridge.js";
|
|
import Keyboard from "./core/input/keyboard.js";
|
|
import KeyTable from "./core/input/keysym.js";
|
|
import keysyms from "./core/input/keysymdef.js";
|
|
import RFB from "./core/rfb.js";
|
|
import { attachMobileKeyboard, attachMobileTrackpad, isTouchBrowser } from "./mobile-keyboard.js";
|
|
|
|
function query(name, fallback) {
|
|
const match = `${document.location.href}${window.location.hash}`.match(
|
|
new RegExp(`.*[?&]${name}=([^&#]*)`),
|
|
);
|
|
return match ? decodeURIComponent(match[1]) : fallback;
|
|
}
|
|
|
|
function flag(name) {
|
|
const value = String(query(name, "false")).toLowerCase();
|
|
return value === "1" || value === "true" || value === "yes";
|
|
}
|
|
|
|
const path = String(query("path", "websockify")).replace(/^\//, "");
|
|
const prefix = window.location.pathname.replace(/[^/]+$/, "");
|
|
const protocol = window.location.protocol === "https:" ? "wss" : "ws";
|
|
const url = `${protocol}://${window.location.host}${prefix}${path}`;
|
|
const rfb = new RFB(document.getElementById("screen"), url);
|
|
rfb.viewOnly = flag("view_only");
|
|
rfb.scaleViewport = true;
|
|
rfb.clipViewport = false;
|
|
if (!rfb.viewOnly) attachHostClipboardPaste(rfb);
|
|
if (!rfb.viewOnly && isTouchBrowser()) {
|
|
attachMobileKeyboard(rfb, {
|
|
button: document.getElementById("mobile-keyboard"),
|
|
input: document.getElementById("mobile-keyboard-input"),
|
|
Keyboard,
|
|
backspaceKeysym: KeyTable.XK_BackSpace,
|
|
lookupKeysym: keysyms.lookup,
|
|
});
|
|
attachMobileTrackpad(rfb, {
|
|
button: document.getElementById("mobile-trackpad"),
|
|
surface: document.getElementById("screen"),
|
|
});
|
|
}
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<div id="screen"></div>
|
|
<div id="mobile-controls">
|
|
<button
|
|
id="mobile-keyboard"
|
|
type="button"
|
|
aria-label="Show keyboard"
|
|
aria-pressed="false"
|
|
title="Show keyboard"
|
|
hidden
|
|
>
|
|
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<rect x="2" y="4" width="20" height="16" rx="2" />
|
|
<path d="M6 8h.01M10 8h.01M14 8h.01M18 8h.01M6 12h.01M10 12h.01M14 12h.01M18 12h.01M6 16h12" />
|
|
</svg>
|
|
</button>
|
|
<button
|
|
id="mobile-trackpad"
|
|
type="button"
|
|
aria-label="Use trackpad"
|
|
aria-pressed="false"
|
|
title="Use trackpad"
|
|
hidden
|
|
>
|
|
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M9 11V5a2 2 0 0 1 4 0v5" />
|
|
<path d="M13 10V4a2 2 0 0 1 4 0v7" />
|
|
<path d="M17 10V6a2 2 0 0 1 4 0v7c0 5-3 8-8 8h-1c-3 0-5-1-7-4l-2-3a2 2 0 0 1 3-2l3 2" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
<textarea
|
|
id="mobile-keyboard-input"
|
|
aria-label="Remote computer keyboard input"
|
|
autocapitalize="off"
|
|
autocomplete="off"
|
|
spellcheck="false"
|
|
tabindex="-1"
|
|
></textarea>
|
|
</body>
|
|
</html>
|