Add loader for quote

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

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

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

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

@ -1,28 +1,56 @@
import React from 'react';
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 (
command: string,
setHistory: (value: string) => void,
updateHistory: (index: number, value: string) => void,
clearHistory: () => void,
setCommand: React.Dispatch<React.SetStateAction<string>>,
historyIndex: number,
) => {
const args = command.split(' ');
args[0] = args[0].toLowerCase();
if (args[0] === 'clear') {
clearHistory();
setCommand('');
} else if (command === '') {
setHistory('');
setCommand('');
} else if (Object.keys(bin).indexOf(args[0]) === -1) {
setHistory(
`
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 {
const output = await bin[args[0]](args.slice(1));
setHistory(output);
setCommand('');
}
setCommand('');
};

Loading…
Cancel
Save