From 238b3c4dd6e4114cad8e9b8e50d8746c9f47861a Mon Sep 17 00:00:00 2001 From: Chris Wanstrath <2+defunkt@users.noreply.github.com> Date: Tue, 7 Oct 2025 18:34:41 -0700 Subject: [PATCH] move mode() to backend browser command --- bin/mode.ts | 19 +++++++++++++++++++ src/commands.ts | 1 + src/js/commands.ts | 28 +++++++--------------------- src/js/game.ts | 9 +++++---- src/js/session.ts | 4 ++-- src/js/shell.ts | 12 +++++++----- src/webapp.ts | 1 + 7 files changed, 42 insertions(+), 32 deletions(-) create mode 100644 bin/mode.ts diff --git a/bin/mode.ts b/bin/mode.ts new file mode 100644 index 0000000..9fe7625 --- /dev/null +++ b/bin/mode.ts @@ -0,0 +1,19 @@ +/// +// Swap UI between cinema mode (fix 16:9) and 100% height. + +import { content } from "@/js/dom" +import { focusInput } from "@/js/focus" +import { resize } from "@/js/resize" +import { send } from "@/js/websocket" + +export default function (mode?: string) { + if (!mode) { + mode = document.body.dataset.mode === "tall" ? "cinema" : "tall" + send({ type: "session:update", data: { "ui:mode": mode } }) + } + + content.style.display = "" + document.body.dataset.mode = mode + resize() + focusInput() +} \ No newline at end of file diff --git a/src/commands.ts b/src/commands.ts index ed6fced..3ed3b99 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -81,6 +81,7 @@ export async function commandSource(name: string): Promise { export async function loadCommandModule(cmd: string) { const path = commandPath(cmd) if (!path) return + console.log("-> import", path + "?t+" + Date.now()) return await import(path + "?t+" + Date.now()) } diff --git a/src/js/commands.ts b/src/js/commands.ts index 87249b1..1105058 100644 --- a/src/js/commands.ts +++ b/src/js/commands.ts @@ -1,32 +1,18 @@ //// -// temporary hack for browser commands +// Keep track of all NOSE commands. -import type { CommandOutput, Commands } from "../shared/types" -import { content } from "./dom" -import { focusInput } from "./focus" -import { resize } from "./resize" -import { send } from "./websocket" +import type { Commands } from "../shared/types" +import { runCommand } from "./shell" export const commands: Commands = {} -// TODO: convert to bin/shell "browser" commands -export const browserCommands: Record void | Promise | CommandOutput> = { - mode: (mode?: string) => { - if (!mode) { - mode = document.body.dataset.mode === "tall" ? "cinema" : "tall" - send({ type: "session:update", data: { "ui:mode": mode } }) - } - - content.style.display = "" - document.body.dataset.mode = mode - resize() - focusInput() - }, -} - export function cacheCommands(cmds: Commands) { for (const key in commands) delete commands[key] Object.assign(commands, cmds) +} + +export async function mode(mode?: string) { + await runCommand(mode ? `mode ${mode}` : "mode") } \ No newline at end of file diff --git a/src/js/game.ts b/src/js/game.ts index 847869a..9ef1434 100644 --- a/src/js/game.ts +++ b/src/js/game.ts @@ -4,8 +4,8 @@ import { focusInput } from "./focus" import { $$ } from "./dom" import { randomId } from "../shared/utils" import { setStatus, addOutput, insert } from "./scrollback" -import { browserCommands } from "./commands" import { sessionId } from "./session" +import { mode } from "./commands" const FPS = 30 const HEIGHT = 540 @@ -35,7 +35,8 @@ export async function handleGameStart(msg: GameStartMessage) { let game try { - game = await import(`/source/${name}?session=${sessionId}`) + console.log("-> import", `/source/${name}?session=${sessionId}&t=${Date.now()}`) + game = await import(`/source/${name}?session=${sessionId}&t=${Date.now()}`) } catch (err: any) { setStatus(msgId, "error") addOutput(msgId, `Error: ${err.message ? err.message : err}`) @@ -43,7 +44,7 @@ export async function handleGameStart(msg: GameStartMessage) { } if (document.body.dataset.mode === "tall") { - browserCommands.mode?.() + mode() oldMode = "tall" } @@ -143,7 +144,7 @@ function endGame() { window.removeEventListener("keyup", handleKeyup) window.removeEventListener("resize", resizeCanvas) - if (oldMode === "tall") browserCommands.mode?.() + if (oldMode === "tall") mode() const main = document.querySelector("main") main?.classList.remove("game") diff --git a/src/js/session.ts b/src/js/session.ts index b9e86cb..55b03aa 100644 --- a/src/js/session.ts +++ b/src/js/session.ts @@ -3,10 +3,10 @@ // in the same browser. import type { SessionStartMessage, SessionUpdateMessage } from "@/shared/types" -import { browserCommands } from "./commands" import { randomId } from "../shared/utils" import { apps } from "./webapp" import { $ } from "./dom" +import { mode } from "./commands" export const sessionId = randomId() export const projectName = $("project-name") as HTMLAnchorElement @@ -25,7 +25,7 @@ export function handleSessionStart(msg: SessionStartMessage) { sessionStore.set("hostname", msg.data.hostname) updateProjectName(msg.data.project) updateCwd(msg.data.cwd) - browserCommands.mode?.(msg.data.mode) + mode(msg.data.mode) } export function handleSessionUpdate(msg: SessionUpdateMessage) { diff --git a/src/js/shell.ts b/src/js/shell.ts index 0764a7d..2889536 100644 --- a/src/js/shell.ts +++ b/src/js/shell.ts @@ -6,7 +6,7 @@ import { addInput, setStatus, addOutput } from "./scrollback" import { send } from "./websocket" import { randomId } from "../shared/utils" import { addToHistory } from "./history" -import { browserCommands, commands } from "./commands" +import { commands } from "./commands" export async function runCommand(input: string) { if (!input.trim()) return @@ -24,14 +24,16 @@ export async function runCommand(input: string) { const [cmd = "", ...args] = input.split(" ") if (commands[cmd]?.type === "browser") { + console.log("-> import", `/source/${cmd}?t=${Date.now()}`) const mod = await import(`/source/${cmd}?t=${Date.now()}`) + if (!mod.default) { + addOutput(id, `no default export in ${cmd}`) + setStatus(id, "error") + return + } const result = mod.default(...args) if (result) addOutput(id, result) setStatus(id, "ok") - } else if (browserCommands[cmd]) { - const result = await browserCommands[cmd](...args) - if (result) addOutput(id, result) - setStatus(id, "ok") } else { send({ id, type: "input", data: input } as InputMessage) } diff --git a/src/webapp.ts b/src/webapp.ts index 8ef2635..af346f7 100644 --- a/src/webapp.ts +++ b/src/webapp.ts @@ -73,6 +73,7 @@ async function findApp(name: string): Promise { async function loadApp(path: string): Promise { if (!await Bun.file(path).exists()) return + console.log("-> import", path + `?t+${Date.now()}`) const mod = await import(path + `?t=${Date.now()}`) if (mod?.default) return mod.default as App