html, 16:9
This commit is contained in:
parent
ab3877ff51
commit
7c37ba9e80
|
|
@ -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",
|
||||
|
|
|
|||
BIN
public/vendor/C64_Pro_Mono-STYLE.woff2
vendored
Normal file
BIN
public/vendor/C64_Pro_Mono-STYLE.woff2
vendored
Normal file
Binary file not shown.
21
src/components/layout.tsx
Normal file
21
src/components/layout.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import type { FC } from "hono/jsx"
|
||||
|
||||
export const Layout: FC = async ({ children, title }) => (
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{title || "Nose"}</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="color-scheme" content="light dark" />
|
||||
<link rel="stylesheet" href="/css/main.css" />
|
||||
<script src="/js/main.js" async></script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div id="content">
|
||||
{children}
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
8
src/components/terminal.tsx
Normal file
8
src/components/terminal.tsx
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import type { FC } from "hono/jsx"
|
||||
|
||||
export const Terminal: FC = async () => (
|
||||
<>
|
||||
<h1>Hello NOSE!</h1>
|
||||
<p>This is 960×540 space.</p>
|
||||
</>
|
||||
)
|
||||
88
src/css/main.css
Normal file
88
src/css/main.css
Normal file
|
|
@ -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;
|
||||
}
|
||||
0
src/js/.gitignore
vendored
0
src/js/.gitignore
vendored
11
src/js/main.ts
Normal file
11
src/js/main.ts
Normal file
|
|
@ -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()
|
||||
|
|
@ -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,38 +59,44 @@ 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(<>
|
||||
<h1>apps</h1>
|
||||
<ul>{apps().map(app => <li><a href={`http://${app}.${domain}:${port}`}>{app}</a></li>)}
|
||||
<ul>{apps().map(app => <li><a href={`http://${app}.${domain}${port}`}>{app}</a></li>)}
|
||||
</ul>
|
||||
</>)
|
||||
})
|
||||
|
||||
app.get("/", c => c.html(<Layout><Terminal /></Layout>))
|
||||
|
||||
//
|
||||
// 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) {
|
||||
for (const sig of ["SIGINT", "SIGTERM"] as const) {
|
||||
process.on(sig, () => {
|
||||
// @ts-ignore
|
||||
globalThis.__nose_cleanup?.()
|
||||
globalThis.__hot_reload_cleanup?.()
|
||||
process.exit()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// server start
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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/*"
|
||||
]
|
||||
},
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user