parent
6fe5393ab6
commit
1544160810
@ -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…
Reference in new issue