diff --git a/src/css/terminal.css b/src/css/terminal.css index fd5c3d8..3fa8169 100644 --- a/src/css/terminal.css +++ b/src/css/terminal.css @@ -160,4 +160,19 @@ #scrollback .output { white-space: pre-wrap; +} + +#statusline { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + padding: 2px 8px; + + background: var(--c64-light-gray); + color: var(--c64-dark-blue); + + font-size: 14px; + display: flex; + justify-content: space-between; } \ No newline at end of file diff --git a/src/html/terminal.tsx b/src/html/terminal.tsx index 3cc5b09..6fce011 100644 --- a/src/html/terminal.tsx +++ b/src/html/terminal.tsx @@ -34,5 +34,7 @@ export const Terminal: FC = async () => (
  • **** NOSE PLUTO V{new Date().getMonth() + 1}.{new Date().getDate()} ****
  • VRAM 000KB
  • + +
    root: /
    ) \ No newline at end of file diff --git a/src/js/commands.ts b/src/js/commands.ts index 8e9d043..117ba49 100644 --- a/src/js/commands.ts +++ b/src/js/commands.ts @@ -38,5 +38,4 @@ export function cacheCommands(cmds: string[]) { commands.push(...cmds) commands.push(...Object.keys(browserCommands)) commands.sort() - console.log("CMDS", commands) } \ No newline at end of file diff --git a/src/js/dispatch.ts b/src/js/dispatch.ts index 477251f..8435c78 100644 --- a/src/js/dispatch.ts +++ b/src/js/dispatch.ts @@ -4,6 +4,7 @@ import { handleOutput } from "./scrollback" import { handleStreamStart, handleStreamAppend, handleStreamReplace, handleStreamEnd } from "./stream" import { handleGameStart } from "./game" import { browserCommands } from "./commands" +import { handleSessionUpdate } from "./session" // message received from server export async function dispatchMessage(msg: Message) { @@ -26,6 +27,8 @@ export async function dispatchMessage(msg: Message) { await handleGameStart(msg); break case "ui:mode": browserCommands.mode?.(msg.data as string); break + case "session:update": + handleSessionUpdate(msg); break default: console.error("unknown message type", msg) } diff --git a/src/js/session.ts b/src/js/session.ts index 5f980e8..160f5e1 100644 --- a/src/js/session.ts +++ b/src/js/session.ts @@ -2,6 +2,22 @@ // Each browser tab is a shell session. This means you can run multiple sessions // in the same browser. +import type { Message } from "@/shared/types" import { randomId } from "../shared/utils" +import { $ } from "./dom" -export const sessionId = randomId() \ No newline at end of file +export const sessionId = randomId() +export const projectName = $("project-name") as HTMLSpanElement +export const projectCwd = $("project-cwd") as HTMLSpanElement + +export function handleSessionUpdate(msg: Message) { + const data = msg.data as Record + + if (data.project) { + projectName.textContent = data.project + } + + if (data.cwd) { + projectCwd.textContent = data.cwd + } +} \ No newline at end of file diff --git a/src/session.ts b/src/session.ts index db1e1e3..65be714 100644 --- a/src/session.ts +++ b/src/session.ts @@ -2,6 +2,7 @@ // Session storage. 1 browser tab = 1 session import { AsyncLocalStorage } from "async_hooks" +import { send } from "./websocket" export type Session = { taskId?: string @@ -35,6 +36,12 @@ export function sessionSet(key: keyof Session, value: any) { const store = ALS.getStore() if (!store) throw "sessionSet() called outside of ALS.run" store[key] = value + + if (!store.ws) return + send(store.ws, { + type: "session:update", + data: { [key]: value } + }) } export function sessionStore(sessionId: string, taskId?: string, ws?: any): Session { diff --git a/src/shared/types.ts b/src/shared/types.ts index 4129e37..f0d0819 100644 --- a/src/shared/types.ts +++ b/src/shared/types.ts @@ -3,7 +3,7 @@ export type Message = { id?: string type: MessageType data?: CommandResult | CommandOutput -} +} | SessionUpdateMessage export type MessageType = "error" | "input" | "output" | "commands" | "save-file" | "game:start" @@ -20,3 +20,8 @@ export type CommandResult = { status: "ok" | "error" output: CommandOutput } + +type SessionUpdateMessage = { + type: "session:update", + data: Record +} \ No newline at end of file