Add loader for quote

pull/58/head
Astradus 2 months ago
parent 6fe5393ab6
commit 1544160810

@ -11,15 +11,19 @@ export const useHistory = (defaultValue: Array<History>) => {
command, command,
lastCommandIndex, lastCommandIndex,
setHistory: (value: string) => setHistory: (value: string) =>
setHistory([ setHistory((prev) => [
...history, ...prev,
{ {
id: history.length, id: prev.length,
date: new Date(), date: new Date(),
command, command,
output: value, output: value,
}, },
]), ]),
updateHistory: (index: number, value: string) =>
setHistory((prev) =>
prev.map((entry, i) => (i === index ? { ...entry, output: value } : entry)),
),
setCommand, setCommand,
setLastCommandIndex, setLastCommandIndex,
clearHistory: () => setHistory([]), clearHistory: () => setHistory([]),

@ -12,6 +12,7 @@ export const Input = ({
lastCommandIndex, lastCommandIndex,
setCommand, setCommand,
setHistory, setHistory,
updateHistory,
setLastCommandIndex, setLastCommandIndex,
clearHistory, clearHistory,
}) => { }) => {
@ -40,7 +41,14 @@ export const Input = ({
if (event.key === 'Enter' || event.code === '13') { if (event.key === 'Enter' || event.code === '13') {
event.preventDefault(); event.preventDefault();
setLastCommandIndex(0); setLastCommandIndex(0);
await shell(command, setHistory, clearHistory, setCommand); await shell(
command,
setHistory,
updateHistory,
clearHistory,
setCommand,
history.length,
);
containerRef.current.scrollTo(0, containerRef.current.scrollHeight); containerRef.current.scrollTo(0, containerRef.current.scrollHeight);
} }

@ -7,7 +7,7 @@ import { History } from '../components/history/History';
import { banner } from '../utils/bin/commands'; import { banner } from '../utils/bin/commands';
interface IndexPageProps { interface IndexPageProps {
inputRef: React.MutableRefObject<HTMLInputElement>; inputRef: React.RefObject<HTMLInputElement>;
} }
const IndexPage: React.FC<IndexPageProps> = ({ inputRef }) => { const IndexPage: React.FC<IndexPageProps> = ({ inputRef }) => {
@ -18,6 +18,7 @@ const IndexPage: React.FC<IndexPageProps> = ({ inputRef }) => {
lastCommandIndex, lastCommandIndex,
setCommand, setCommand,
setHistory, setHistory,
updateHistory,
clearHistory, clearHistory,
setLastCommandIndex, setLastCommandIndex,
} = useHistory([]); } = useHistory([]);
@ -53,6 +54,7 @@ const IndexPage: React.FC<IndexPageProps> = ({ inputRef }) => {
lastCommandIndex={lastCommandIndex} lastCommandIndex={lastCommandIndex}
setCommand={setCommand} setCommand={setCommand}
setHistory={setHistory} setHistory={setHistory}
updateHistory={updateHistory}
setLastCommandIndex={setLastCommandIndex} setLastCommandIndex={setLastCommandIndex}
clearHistory={clearHistory} clearHistory={clearHistory}
/> />

@ -1,28 +1,56 @@
import React from 'react'; import React from 'react';
import * as bin from './bin'; import * as bin from './bin';
// Braille frames that read as a single-cell grid of dots appearing to spin.
const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
// Commands that fetch from a remote API and may take a moment to respond.
const asyncCommands = ['quote', 'readme'];
export const shell = async ( export const shell = async (
command: string, command: string,
setHistory: (value: string) => void, setHistory: (value: string) => void,
updateHistory: (index: number, value: string) => void,
clearHistory: () => void, clearHistory: () => void,
setCommand: React.Dispatch<React.SetStateAction<string>>, setCommand: React.Dispatch<React.SetStateAction<string>>,
historyIndex: number,
) => { ) => {
const args = command.split(' '); const args = command.split(' ');
args[0] = args[0].toLowerCase(); args[0] = args[0].toLowerCase();
if (args[0] === 'clear') { if (args[0] === 'clear') {
clearHistory(); clearHistory();
setCommand('');
} else if (command === '') { } else if (command === '') {
setHistory(''); setHistory('');
setCommand('');
} else if (Object.keys(bin).indexOf(args[0]) === -1) { } else if (Object.keys(bin).indexOf(args[0]) === -1) {
setHistory( setHistory(
` `
shell: command not found: ${args[0]}. Try 'help' to get started.`, shell: command not found: ${args[0]}. Try 'help' to get started.`,
); );
setCommand('');
} else if (asyncCommands.includes(args[0])) {
// Show a spinner and clear the prompt so the user can keep working while
// the request is in flight. The output lands in its own history entry, so
// running other commands meanwhile won't clobber it.
let frame = 0;
setHistory(spinnerFrames[frame]);
setCommand('');
const spinner = setInterval(() => {
frame = (frame + 1) % spinnerFrames.length;
updateHistory(historyIndex, spinnerFrames[frame]);
}, 80);
try {
const output = await bin[args[0]](args.slice(1));
updateHistory(historyIndex, output);
} finally {
clearInterval(spinner);
}
} else { } else {
const output = await bin[args[0]](args.slice(1)); const output = await bin[args[0]](args.slice(1));
setHistory(output); setHistory(output);
setCommand('');
} }
setCommand('');
}; };

Loading…
Cancel
Save