This commit is contained in:
Chris Wanstrath 2025-09-30 23:17:45 -07:00
parent 0ba73b6dac
commit b411ce7013
5 changed files with 51 additions and 40 deletions

View File

@ -140,11 +140,9 @@ input[type="file"]::file-selector-button {
cursor: pointer;
}
input[type="file"] {
color: var(--c64-dark-blue);
}
input[type="submit"] {
input[type="file"],
input[type="submit"],
button {
color: var(--c64-dark-blue);
padding: 5px;
}

25
src/js/drop.ts Normal file
View File

@ -0,0 +1,25 @@
export function initDrop() {
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
document.body.addEventListener(eventName, preventDefaults, false);
})
document.body.addEventListener("drop", handleDrop)
}
function preventDefaults(e: Event) {
e.preventDefault()
e.stopPropagation()
}
function handleDrop(e: DragEvent) {
const fileInput = document.querySelector("input[type=file]") as HTMLInputElement
const files = e.dataTransfer?.files ?? []
if (files.length > 0) {
const dt = new DataTransfer()
Array.from(files).forEach(f => dt.items.add(f))
fileInput.files = dt.files
fileInput.dispatchEvent(new Event('change', { bubbles: true }))
}
}

View File

@ -1,5 +1,6 @@
import { initCompletion } from "./completion.js"
import { initCursor } from "./cursor.js"
import { initDrop } from "./drop.js"
import { initEditor } from "./editor.js"
import { initFocus } from "./focus.js"
import { initForm } from "./form.js"
@ -14,6 +15,7 @@ import { startConnection } from "./websocket.js"
initCompletion()
initCursor()
initDrop()
initFocus()
initForm()
initEditor()

View File

@ -100,7 +100,7 @@ app.on(["GET", "POST"], ["/cmd/:name"], async c => {
if (!mod || !mod[method])
return c.json({ status: "error", output: `No ${method} export in ${cmd}` }, 500)
return c.json(await runCommandFn(sessionId, async () => mod[method](c)))
return c.json(await runCommandFn({ sessionId }, async () => mod[method](c)))
} catch (e: any) {
return c.json({ status: "error", output: e.message || e.toString() }, 500)
}

View File

@ -15,66 +15,52 @@ export async function runCommand(sessionId: string, taskId: string, input: strin
if (!commandExists(cmd))
return { status: "error", output: `${cmd} not found` }
let status: "ok" | "error" = "ok"
let output: CommandOutput = ""
return runCommandFn({ sessionId, taskId, ws }, async () => exec(cmd, args))
}
export async function runCommandFn(
{ sessionId, taskId, ws }: { sessionId: string, taskId?: string, ws?: any },
fn: () => Promise<CommandResult>
): Promise<CommandResult> {
try {
const state = getState(sessionId, taskId, ws)
try {
[status, output] = await ALS.run(state, async () => await exec(cmd, args))
return processExecOutput(await ALS.run(state, async () => fn()))
} catch (err) {
status = "error"
output = errorMessage(err)
return { status: "error", output: errorMessage(err) }
}
return { status, output }
}
export async function runCommandFn(sessionId: string, fn: () => Promise<CommandResult>) {
let status: "ok" | "error" = "ok"
let output: CommandOutput = ""
const state = getState(sessionId)
try {
const execOutput = await ALS.run(state, async () => await fn())
;[status, output] = processExecOutput(execOutput)
} catch (err) {
status = "error"
output = errorMessage(err)
}
return { status, output }
}
async function exec(cmd: string, args: string[]): Promise<["ok" | "error", CommandOutput]> {
async function exec(cmd: string, args: string[]): Promise<CommandResult> {
const module = await loadCommandModule(cmd)
if (module?.game)
return ["ok", { game: cmd }]
return { status: "ok", output: { game: cmd } }
if (!module || !module.default)
return ["error", `${cmd} has no default export`]
return { status: "error", output: `${cmd} has no default export` }
return processExecOutput(await module.default(...args))
return await module.default(...args)
}
export function processExecOutput(output: string | any): ["ok" | "error", CommandOutput] {
export function processExecOutput(output: string | any): CommandResult {
if (typeof output === "string") {
return ["ok", output]
return { status: "ok", output }
} else if (typeof output === "object") {
if (output.error) {
return ["error", output.error]
return { status: "error", output: output.error }
} else if (isJSX(output)) {
return ["ok", { html: output.toString() }]
return { status: "ok", output: { html: output.toString() } }
} else if (output.html && isJSX(output.html)) {
output.html = output.html.toString()
return ["ok", output]
return { status: "ok", output }
} else {
return ["ok", output]
return { status: "ok", output }
}
} else if (output === undefined) {
return ["ok", ""]
return { status: "ok", output: "" }
} else {
return ["ok", String(output)]
return { status: "ok", output: String(output) }
}
}