From 7c37ba9e80d250c07d55c025ab68ce7c0641ba1a Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Mon, 15 Sep 2025 20:31:11 -0700 Subject: [PATCH] html, 16:9 --- package.json | 4 +- public/vendor/C64_Pro_Mono-STYLE.woff2 | Bin 0 -> 5908 bytes src/components/layout.tsx | 21 ++++++ src/components/terminal.tsx | 8 +++ src/css/main.css | 88 +++++++++++++++++++++++++ src/js/.gitignore | 0 src/js/main.ts | 11 ++++ src/server.tsx | 39 ++++++----- tsconfig.json | 19 +++--- 9 files changed, 165 insertions(+), 25 deletions(-) create mode 100644 public/vendor/C64_Pro_Mono-STYLE.woff2 create mode 100644 src/components/layout.tsx create mode 100644 src/components/terminal.tsx create mode 100644 src/css/main.css delete mode 100644 src/js/.gitignore create mode 100644 src/js/main.ts diff --git a/package.json b/package.json index 8a5e5b8..48adeca 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "private": true, "scripts": { "start": "bun src/server.tsx", - "dev": "bun --hot src/server.tsx" + "dev": "env BUN_HOT=1 bun --hot src/server.tsx" }, "alias": { "@utils": "./src/utils.tsx", @@ -21,4 +21,4 @@ "hono": "^4.9.7", "kleur": "^4.1.5" } -} +} \ No newline at end of file diff --git a/public/vendor/C64_Pro_Mono-STYLE.woff2 b/public/vendor/C64_Pro_Mono-STYLE.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..a1b72c5576b6f3bab9ec1a14882560f73e7abbde GIT binary patch literal 5908 zcmV+v7whPEPew8T0RR9102dSh3jhEB0A)M?02aak0X4$_00000000000000000000 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 ( + + + {title || "Nose"} + + + + + + + +
+
+ {children} +
+
+ + +) \ No newline at end of file diff --git a/src/components/terminal.tsx b/src/components/terminal.tsx new file mode 100644 index 0000000..d0f4a01 --- /dev/null +++ b/src/components/terminal.tsx @@ -0,0 +1,8 @@ +import type { FC } from "hono/jsx" + +export const Terminal: FC = async () => ( + <> +

Hello NOSE!

+

This is 960×540 space.

+ +) \ No newline at end of file diff --git a/src/css/main.css b/src/css/main.css new file mode 100644 index 0000000..df4d5df --- /dev/null +++ b/src/css/main.css @@ -0,0 +1,88 @@ +@font-face { + font-family: 'C64ProMono'; + src: url('/vendor/C64_Pro_Mono-STYLE.woff2') format('woff2'); + font-weight: normal; + font-style: normal; +} + +:root { + --font-family: 'C64ProMono', monospace; + --black: #000000; + --white: #E0E0E0; + --cyan: #00A8C8; + --red: #C62828; + --green: green; + --yellow: #C4A000; + --purple: #7C3AED; + --blue: #1565C0; + --magenta: #ff66cc; +} + +.black { + color: var(--black); +} + +.white { + color: var(--white); +} + +.cyan { + color: var(--cyan); +} + +.red { + color: var(--red); +} + +.green { + color: var(--green); +} + +.yellow { + color: var(--yellow); +} + +.purple { + color: var(--purple); +} + +.blue { + color: var(--blue); +} + +.magenta { + color: var(--magenta); +} + +:fullscreen::backdrop { + background: var(--background-color); +} + +html, +body { + font-family: var(--font-family); + margin: 0; + height: 100%; + /* black bars */ + background: black; + display: flex; + justify-content: center; + align-items: center; +} + +main { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; +} + +#content { + width: 960px; + height: 540px; + background: white; + /* nearest-neighbor scaling */ + image-rendering: pixelated; + transform-origin: center center; +} \ No newline at end of file diff --git a/src/js/.gitignore b/src/js/.gitignore deleted file mode 100644 index e69de29..0000000 diff --git a/src/js/main.ts b/src/js/main.ts new file mode 100644 index 0000000..5dd101a --- /dev/null +++ b/src/js/main.ts @@ -0,0 +1,11 @@ +function resize() { + const scale = Math.min( + window.innerWidth / 960, + window.innerHeight / 540 + ); + const content = document.getElementById("content")! + content.style.transform = `scale(${scale})` +} + +window.addEventListener("resize", resize) +resize() \ No newline at end of file diff --git a/src/server.tsx b/src/server.tsx index aa8710c..25a7039 100644 --- a/src/server.tsx +++ b/src/server.tsx @@ -7,6 +7,9 @@ import { NOSE_ICON, NOSE_DIR, NOSE_BIN, NOSE_APP } from "./config" import { transpile, isFile } from "./utils" import { apps, serveApp } from "./webapp" +import { Layout } from "./components/layout" +import { Terminal } from "./components/terminal" + // // Hono setup // @@ -56,36 +59,42 @@ app.use("*", async (c, next) => { return next() }) -app.get("/", c => { +app.get("/apps", c => { const url = new URL(c.req.url) const domain = url.hostname - const port = url.port + let port = url.port + port = port && port !== "80" ? `:${port}` : "" return c.html(<>

apps

-
    {apps().map(app =>
  • {app}
  • )} +
      {apps().map(app =>
    • {app}
    • )}
    ) }) +app.get("/", c => c.html()) + // -// server shutdown +// hot mode cleanup // -// @ts-ignore -globalThis.__nose_cleanup?.() +if (process.env.BUN_HOT) { + // @ts-ignore + globalThis.__hot_reload_cleanup?.() -// @ts-ignore -globalThis.__nose_cleanup = () => { + // @ts-ignore + globalThis.__hot_reload_cleanup = () => { + } + + for (const sig of ["SIGINT", "SIGTERM"] as const) { + process.on(sig, () => { + // @ts-ignore + globalThis.__hot_reload_cleanup?.() + process.exit() + }) + } } -for (const sig of ["SIGINT", "SIGTERM"] as const) { - process.on(sig, () => { - // @ts-ignore - globalThis.__nose_cleanup?.() - process.exit() - }) -} // diff --git a/tsconfig.json b/tsconfig.json index 3806de4..9b219ed 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,37 +1,40 @@ { "compilerOptions": { // Environment setup & latest features - "lib": ["ESNext"], + "lib": [ + "ESNext", + "DOM" + ], "target": "ESNext", "module": "Preserve", "moduleDetection": "force", "jsx": "react-jsx", "jsxImportSource": "hono/jsx", "allowJs": true, - // Bundler mode "moduleResolution": "bundler", "allowImportingTsExtensions": true, "verbatimModuleSyntax": true, "noEmit": true, - // Best practices "strict": true, "skipLibCheck": true, "noFallthroughCasesInSwitch": true, "noUncheckedIndexedAccess": true, "noImplicitOverride": true, - // Some stricter flags (disabled by default) "noUnusedLocals": false, "noUnusedParameters": false, "noPropertyAccessFromIndexSignature": false, - // paths? "baseUrl": ".", "paths": { - "@utils": ["src/utils.tsx"], - "@/*": ["src/*"] + "@utils": [ + "src/utils.tsx" + ], + "@/*": [ + "src/*" + ] }, } -} +} \ No newline at end of file