Add Telnet Display
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -1,32 +0,0 @@
|
|||||||
export default function Page() {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<span className="flex justify-center w-[100%] text-[32px] font-bold">Work Experience</span>
|
|
||||||
<main className="grid grid-cols-2">
|
|
||||||
<section className="grid grid-rows-2 p-5 mt-10">
|
|
||||||
<div className="pl-5 w-[100%]">
|
|
||||||
<img src="https://www.hardwarestore.com/media/magestore/storepickup/images/store/gallery/s/t/Store_124_Newport_ME_112016.jpg" className="w-[50%] relative left-[25%]"/><br/>
|
|
||||||
</div>
|
|
||||||
<div className="text-center text-[30px] font-bold">
|
|
||||||
Aubuchon Hardware (Newport Maine)
|
|
||||||
<div className="text-center text-[18px] font-normal bg-slate-900 m-5 rounded-lg p-2">
|
|
||||||
At Aubuchon Hardware in Newport Maine I gained many valuable skills
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section className="grid grid-rows-2 p-5 mt-10">
|
|
||||||
<div className="pl-5 w-[100%]">
|
|
||||||
<img src="/images/bangorAASF.jpg" className="w-[50%] relative left-[25%]"/><br/>
|
|
||||||
</div>
|
|
||||||
<div className="text-center text-[30px] font-bold">
|
|
||||||
Maine Army National Guard (Bangor Maine)<br/>
|
|
||||||
126th MEDEVAC
|
|
||||||
<div className="text-center text-[18px] font-normal bg-slate-900 m-5 rounded-lg p-2">
|
|
||||||
Test
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { film1 } from "./telnet_movie"
|
||||||
|
|
||||||
|
export function TelnetDisplay() {
|
||||||
|
var film = film1.split('\n');
|
||||||
|
var LINES_PER_FRAME = 14;
|
||||||
|
var DELAY_NORMAL = 67;
|
||||||
|
var DELAY_FAST = 17;
|
||||||
|
var DELAY_VERYFAST = 1;
|
||||||
|
|
||||||
|
var g_currentFrame = 0;
|
||||||
|
var g_updateDelay = DELAY_NORMAL;
|
||||||
|
var g_frameStep = 1; //advance one frame per tick
|
||||||
|
var g_timerHandle = null;
|
||||||
|
|
||||||
|
function validateFrame(frameNumber) {
|
||||||
|
return ( frameNumber > 0 && frameNumber < Math.floor( film.length / LINES_PER_FRAME ) )
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayFrame(frameNumber) {
|
||||||
|
if( validateFrame(frameNumber) != true ) return;
|
||||||
|
|
||||||
|
var screen = document.getElementById('screen');
|
||||||
|
|
||||||
|
while(screen.firstChild) screen.removeChild( screen.firstChild );
|
||||||
|
|
||||||
|
for (var line = 1; line < 14; line++) {
|
||||||
|
var lineText = film[ (g_currentFrame * LINES_PER_FRAME) + line];
|
||||||
|
if( !lineText || lineText.length < 1 ) lineText = ' ';
|
||||||
|
|
||||||
|
var div = document.createElement('div');
|
||||||
|
div.style.whiteSpace = 'pre';
|
||||||
|
div.appendChild( document.createTextNode( lineText ) );
|
||||||
|
|
||||||
|
screen.appendChild( div );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateDisplay() {
|
||||||
|
if(g_timerHandle)
|
||||||
|
clearTimeout(g_timerHandle);
|
||||||
|
|
||||||
|
displayFrame(g_currentFrame);
|
||||||
|
|
||||||
|
if( g_frameStep != 0 ) {
|
||||||
|
var nextFrameDelay = film[ g_currentFrame * LINES_PER_FRAME ] * g_updateDelay;
|
||||||
|
|
||||||
|
var nextFrame = g_currentFrame + g_frameStep;
|
||||||
|
|
||||||
|
if(validateFrame(nextFrame) == true) g_currentFrame = nextFrame;
|
||||||
|
|
||||||
|
g_timerHandle = setTimeout( updateDisplay, nextFrameDelay );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Start() {
|
||||||
|
g_currentFrame = 0;
|
||||||
|
Play();
|
||||||
|
}
|
||||||
|
|
||||||
|
function Play() {
|
||||||
|
g_frameStep = 1;
|
||||||
|
g_updateDelay = DELAY_NORMAL;
|
||||||
|
updateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
Start();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<pre id="screen" className="">
|
||||||
|
</pre>
|
||||||
|
)
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,9 +1,17 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import moment from "moment"
|
import moment from "moment"
|
||||||
|
import { TelnetDisplay } from "./telnet";
|
||||||
|
|
||||||
var commands = {
|
const commands = {
|
||||||
"uname -a": "Hello! My name is Nicholas Pease and I am currently a junior at the University of Maine pursuing a bachelors degree in Computer Science with a minor in Military Science. This website is a collection of both project / homework completed as required by my studies and as a showcase of some of the personal projects I have worked on. I will work to keep this up to date to the best of my ability. ",
|
"uname -a": "Hello! My name is Nicholas Pease and I am currently a junior at the University of Maine pursuing a bachelors degree in Computer Science with a minor in Military Science. This website is a collection of both project / homework completed as required by my studies and as a showcase of some of the personal projects I have worked on. I will work to keep this up to date to the best of my ability. ",
|
||||||
"timedatectl": `This website was last updated on ${moment().format("dddd, MMMM Do YYYY")}.`
|
"timedatectl": `This website was last updated on ${moment().format("dddd, MMMM Do YYYY")}.`,
|
||||||
|
"poweroff": "Nice try...",
|
||||||
|
"shutdown": "Nice try...",
|
||||||
|
"sudo poweroff": "Nice try...",
|
||||||
|
"sudo shutdown": "Nice try...",
|
||||||
|
"telnet": <TelnetDisplay/>,
|
||||||
|
"telnet towel.blinkenlights.nl": <TelnetDisplay/>,
|
||||||
|
"compgen -c": `uname -a \t\ttimedatectl \t\ttelnet`
|
||||||
}
|
}
|
||||||
|
|
||||||
function Command({command, result}) {
|
function Command({command, result}) {
|
||||||
@@ -17,37 +25,6 @@ function Command({command, result}) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Terminal() {
|
|
||||||
const [text, setText] = useState("")
|
|
||||||
const [history, setHistory] = useState([<Command command="uname -a" key={"0"}/>,<Command command="timedatectl" key={"1"}/>])
|
|
||||||
const handleKeyDown = event => {
|
|
||||||
event.preventDefault()
|
|
||||||
if (event.code == "Backspace") {setText(text.slice(0, -1))}
|
|
||||||
else if (event.code == "Enter") {
|
|
||||||
if (text == "clear") {
|
|
||||||
setHistory([])
|
|
||||||
} else {
|
|
||||||
commands[text] != null? setHistory([...history, <Command command={text} key={history[history.length-1].props.key+1}/>]): `Command '${text.split(" ")[0]}' not found.`
|
|
||||||
}
|
|
||||||
setText("")
|
|
||||||
}
|
|
||||||
else if (event.code == "ArrowUp") {history.length>0? setText(history[history.length-1].props.command): ""}
|
|
||||||
else if (event.code == "ArrowDown") {setText("")}
|
|
||||||
else if (event.code == "Minus") {setText(text + "-")}
|
|
||||||
else if (isValidKey(event)) {setText(text + event.key)}
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div className="cursor-pointer outline-0 max-h-[420px] w-[100%] overflow-hidden max-lg:ml-5 max-lg:mr-5 flex flex-col-reverse p-1" onKeyDown={handleKeyDown} tabIndex={0}>
|
|
||||||
<pre className="bash text-wrap">
|
|
||||||
{history}
|
|
||||||
<div>
|
|
||||||
<span className="text-[green]">about@npease</span>:<span className="text-[blue]">~</span>$ {text}<span className="animate-blink"> </span>
|
|
||||||
</div>
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function isValidKey(event) {
|
function isValidKey(event) {
|
||||||
const charCodes = [
|
const charCodes = [
|
||||||
'KeyA', 'KeyB', 'KeyC', 'KeyD', 'KeyE', 'KeyF', 'KeyG', 'KeyH', 'KeyI', 'KeyJ',
|
'KeyA', 'KeyB', 'KeyC', 'KeyD', 'KeyE', 'KeyF', 'KeyG', 'KeyH', 'KeyI', 'KeyJ',
|
||||||
@@ -64,4 +41,37 @@ function isValidKey(event) {
|
|||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Terminal() {
|
||||||
|
const [text, setText] = useState("")
|
||||||
|
const [history, setHistory] = useState([<Command command="uname -a" key={0}/>,<Command command="timedatectl" key={1}/>,<Command command="compgen -c" key={2}/>])
|
||||||
|
const handleKeyDown = event => {
|
||||||
|
event.preventDefault()
|
||||||
|
if (event.code == "Backspace") {setText(text.slice(0, -1))}
|
||||||
|
else if (event.code == "Enter") {
|
||||||
|
if (text == "clear") {
|
||||||
|
setHistory([])
|
||||||
|
} else if (commands[text] != undefined) {
|
||||||
|
setHistory([...history, <Command command={text} key={history.length? history[history.length-1].props.key+1: 0}/>])
|
||||||
|
} else {
|
||||||
|
setHistory([...history, <Command command={text} result={`Command '${text}' not found.`} key={history.length? history[history.length-1].props.key+1: 0}/>])
|
||||||
|
}
|
||||||
|
setText("")
|
||||||
|
}
|
||||||
|
else if (event.code == "ArrowUp") {history.length>0? setText(history[history.length-1].props.command): ""}
|
||||||
|
else if (event.code == "ArrowDown") {setText("")}
|
||||||
|
else if (event.code == "Minus") {setText(text + "-")}
|
||||||
|
else if (isValidKey(event)) {setText(text + event.key)}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="cursor-pointer outline-0 max-h-[420px] w-[100%] overflow-hidden max-lg:ml-5 max-lg:mr-5 flex flex-col-reverse p-1" onKeyDown={handleKeyDown} tabIndex={0}>
|
||||||
|
<pre className="bash text-wrap">
|
||||||
|
{history}
|
||||||
|
<div>
|
||||||
|
<span className="text-[green]">about@npease</span>:<span className="text-[blue]">~</span>$ {text}<span className="animate-blink"> </span>
|
||||||
|
</div>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user