terminal prompt needs to be recyclable

This commit is contained in:
2025-02-03 03:01:06 -05:00
parent 390ff9bccf
commit 49a62df236
14 changed files with 179 additions and 116 deletions

View File

@ -0,0 +1,21 @@
import { working_dir } from "./fs"
function ls() {
}
function pwd() {
}
function cat() {
}
const commands = {
["ls"]: ls,
["pwd"]: pwd,
["cat"]: cat,
}
export { commands }

View File

@ -1,17 +1,32 @@
let working_dir = "user"
const enum EntryType {
Directory,
File
}
type File = string
type Entry<T> = {
readonly inner: T,
readonly type: EntryType
}
function Entry<T = File>(inner: T): Entry<T> {
const type = typeof inner == "object" ? EntryType.Directory : EntryType.File
return { inner: inner, type: type }
}
const user = {
["about_me"]: {},
["services"]: {}
["about_me.txt"]: Entry(""),
["services.txt"]: Entry("")
}
const home = {
["user"]: user
["user"]: Entry(user)
}
const root = {
["bin"]: {},
["home"]: {}
["bin"]: Entry({}),
["home"]: Entry(home)
}
const fs = {
["/"]: root
["/"]: Entry(root)
}
export { fs }
export { fs, working_dir }

View File

@ -1,45 +0,0 @@
import { TermEvents } from "./terminal"
let working_fs_dir = "user"
function GetWorkingDir(): string {
if (working_fs_dir === "user") {
return "~"
}
return working_fs_dir
}
function ls() {
}
function Prompt() {
const cyan_user = <span className="cyan">user</span>
const green_dir = <span className="green">{GetWorkingDir()}</span>
return <p>{cyan_user}@host {green_dir}{"> "}</p>
}
function ShellEvents() {
const shell_input = document.getElementById("shell-input")
if (shell_input) {
shell_input.addEventListener("keydown", (keyboard_event) => {
if (keyboard_event.key === "Enter") {
console.log("woah its the enter key")
}
})
}
}
function ShellPrompt() {
return <div className="shell-prompt">
<Prompt/>
<input id="shell-input" type="text" spellCheck={false}/>
</div>
}
export default function Shell() {
const shell_prompt = ShellPrompt()
TermEvents()
ShellEvents()
return shell_prompt
}

View File

@ -0,0 +1,15 @@
const red = (s: string) => <span className="red">{s}</span>
const green = (s: string) => <span className="green">{s}</span>
const blue = (s: string) => <span className="blue">{s}</span>
const cyan = (s: string) => <span className="cyan">{s}</span>
export default function rgb(s: string, Ru8: number, Gu8: number, Bu8: number) {
return <span style={{color: `rgb(${Ru8},${Gu8},${Bu8})`}}>{s}</span>
}
export {
red,
green,
blue,
cyan
}

View File

@ -0,0 +1,10 @@
import { working_dir } from "../fs"
import rgb, { cyan, green } from "./color"
const GetWorkingDir = () => working_dir === "user" ? "~" : working_dir
export default function Prompt() {
const user = cyan("user")
const dir = green(GetWorkingDir())
return <p>{user}@host {dir}{"> "}</p>
}

View File

@ -0,0 +1,10 @@
const terminal_window = document.querySelector("main");
export function TermEvents() {
if (terminal_window) {
// terminal_window.addEventListener("click", (_event) => {
// const shell_input = document.getElementById("shell-input")
// if (shell_input) { shell_input.focus() }
// })
}
}

View File

@ -1,10 +0,0 @@
const terminal_window = document.querySelector("main");
export function TermEvents() {
if (terminal_window) {
terminal_window.addEventListener("click", (_event) => {
const shell_input = document.getElementById("shell-input")
if (shell_input) { shell_input.focus() }
})
}
}

View File

@ -0,0 +1,33 @@
import type { JSX } from "react/jsx-dev-runtime"
import { TermEvents } from "./term_events"
import { createRoot } from "react-dom/client"
import { useState } from "react"
import Prompt from "./shell/prompt"
const active_shell_prompt = ShellPrompt()
function ShellEvents() {
const shell_input = document.querySelector("main")
if (shell_input) {
const [prompts, newPrompt] = useState([])
shell_input.addEventListener("keydown", (keyboard_event) => {
if (keyboard_event.key == "Enter") {
}
})
}
}
function ShellPrompt() {
return <div className="shell-prompt">
<Prompt/>
<input id="shell-input" type="text" spellCheck={false} autoFocus/>
</div>
}
export default function Shell() {
TermEvents()
ShellEvents()
return active_shell_prompt
}

View File

@ -0,0 +1,21 @@
---
import { Links } from "../../ts/links"
---
<p>Welcome to rhpidfyre.io!</p>
<div class="return"></div>
<p>This is a personal website by rhpidfyre / Brandon.</p>
<p>You can find my services here or learn about me.</p>
<div class="return"></div>
<p>You can also contribute or view the source code of my website via the links:</p>
<p>{"<"}<a href={Links.RepoGitea} target="_blank">{Links.RepoGitea}</a>{">."}</p>
<p>{"<"}<a href={Links.RepoGithub} target="_blank">{Links.RepoGithub}</a>{">."}</p>
<div class="return"></div>
<p>You can get started with the command: <span class="bold">help</span></p>
<div class="return"></div>
<noscript>
<p><span class="red">=================================================</span></p>
<p><span class="red">JavaScript is disabled, functionality will be limited. :(</span></p>
<p><span class="red">But, you will not be limited at exploring my services which you can find by navigating towards the top-right.</span></p>
<p><span class="red">=================================================</span></p>
</noscript>

View File

@ -25,15 +25,7 @@ const {title} = Astro.props
<style is:global lang="scss">
@forward "../scss/fonts";
@forward "../scss/terminal";
* {
font-family: 'Terminus', monospace;
font-size: 15px;
letter-spacing: 2px;
cursor: text;
text-wrap: nowrap;
}
:root {
color-scheme: dark;
@ -58,7 +50,6 @@ const {title} = Astro.props
a {
color: white;
cursor: unset;
&:hover, &:active, &:link { text-decoration: none; }
}
</style>

View File

@ -1,64 +1,27 @@
---
import Webpage from '../layouts/Webpage.astro';
import { Links } from '../ts/links';
import Shell from '../components/react/shell';
import Motd from '../components/terminal/motd.astro';
import Terminal from '../components/react/terminal';
---
<Webpage title="Home">
<main>
<p>Welcome to rhpidfyre.io!</p>
<div class="return"></div>
<p>This is a personal website by rhpidfyre / Brandon.</p>
<p>You can find my services here or learn about me.</p>
<div class="return"></div>
<p>You can also contribute or view the source code of my website via the links:</p>
<p>{"<"}<a href={Links.RepoGitea} target="_blank">{Links.RepoGitea}</a>{">."}</p>
<p>{"<"}<a href={Links.RepoGithub} target="_blank">{Links.RepoGithub}</a>{">."}</p>
<div class="return"></div>
<p>You can get started with the command: help</p>
<div class="return"></div>
<noscript>
<p><span class="red">=================================================</span></p>
<p><span class="red">JavaScript is disabled, functionality will be limited. :(</span></p>
<p><span class="red">But, you will not be limited at exploring my services which you can find by navigating towards the top-right.</span></p>
<p><span class="red">=================================================</span></p>
</noscript>
<Shell client:only/>
<Motd/>
<Terminal client:only/>
</main>
</Webpage>
<style lang="scss" is:global>
@use "../scss/variables";
@mixin text-styles {
.red { color: rgb(200, 0, 0); }
.green { color: rgb(0, 200, 0); }
.blue { color: rgb(0, 0, 200); }
.cyan { color: rgb(18,167,148); }
}
.shell-prompt { display: flex; }
@use "../scss/terminal";
main {
@include terminal.formatting;
width: 100vw;
height: calc(99.3vh - variables.$header-Y - variables.$footer-Y);
padding: 5px;
overflow-y: auto;
p {
@include text-styles;
font-size: 1.2rem;
margin: 5px;
a {
font-size: inherit;
&:hover { text-decoration: underline; }
}
span { font-size: inherit }
}
.return {
margin-top: 25px;
}
}
input {
font-size: 1.2rem;

View File

@ -5,3 +5,13 @@
font-weight: 500;
src: url('/Terminus.woff2') format('woff2');
}
* {
font: {
family: 'Terminus', monospace;
size: 15px;
};
letter-spacing: 2px;
text-wrap: nowrap;
cursor: text;
}

View File

@ -0,0 +1,29 @@
@mixin color-matrix {
.red { color: rgb(200, 0, 0); }
.green { color: rgb(0, 200, 0); }
.blue { color: rgb(0, 0, 200); }
.cyan { color: rgb(18,167,148); }
}
@mixin text-styles {
.bold { font-weight: bold; }
}
@mixin formatting {
.return { margin-top: 25px; }
.shell-prompt { display: flex; }
p {
@include color-matrix;
@include text-styles;
font-size: 1.2rem;
margin: 5px;
span { font-size: inherit; }
a {
font-size: inherit;
&:hover { text-decoration: underline; }
}
}
}