From 7ff97d6e083d26a6bf197b3e8d56103ff67383e8 Mon Sep 17 00:00:00 2001 From: "zokutyou2@gmail.com" Date: Thu, 15 Jul 2021 22:19:46 +0900 Subject: [PATCH] change CommandBar component into typescript, autoscroll overflowed result to bottom --- web/src/js/components/CommandBar.tsx | 110 ++++++++++++++++++--------- 1 file changed, 75 insertions(+), 35 deletions(-) diff --git a/web/src/js/components/CommandBar.tsx b/web/src/js/components/CommandBar.tsx index 7126fa17d..a4ccda8fb 100644 --- a/web/src/js/components/CommandBar.tsx +++ b/web/src/js/components/CommandBar.tsx @@ -1,11 +1,29 @@ -import React, { useState, useEffect, Component } from 'react' +import React, { useState, useEffect, useRef } from 'react' import classnames from 'classnames' import { Key, fetchApi } from '../utils' import Filt from '../filt/command' -function getAvailableCommands(commands, input = "") { - if (!commands) return null - let availableCommands = [] +type CommandHelpProps = { + nextArgs: string[], + currentArg: number, + help: string, + description: string, + availableCommands: string[], +} + +type CommandResult = { + "id": number, + "command": string, + "result": string, +} + +type ResultProps = { + results: CommandResult[], +} + +function getAvailableCommands(commands, input: string = "") { + if (!commands) return [] + let availableCommands: string[] = [] for (const [command, args] of Object.entries(commands)) { if (command.startsWith(input)) { availableCommands.push(command) @@ -14,19 +32,43 @@ function getAvailableCommands(commands, input = "") { return availableCommands } -export function CommandHelp({nextArgs, currentArg, help, description, availableCommands}){ - let results = [] - for (let i = 0; i < nextArgs.length; i++) { +export function Results({results}: ResultProps) { + const resultElement= useRef(null!); + + useEffect(() => { + if (resultElement) { + resultElement.current?.addEventListener('DOMNodeInserted', event => { + const { currentTarget: target } = event; + target.scroll({ top: target.scrollHeight, behavior: 'auto' }); + }); + } + }, []) + + return ( +
+ {results.map(result => ( +
+
$ {result.command}
+ {result.result} +
+ ))} +
+ ) +} + +export function CommandHelp({nextArgs, currentArg, help, description, availableCommands}: CommandHelpProps){ + let argumentSuggestion: JSX.Element[] = [] + for (let i: number = 0; i < nextArgs.length; i++) { if (i==currentArg) { - results.push({nextArgs[i]}) + argumentSuggestion.push({nextArgs[i]}) continue } - results.push({nextArgs[i]} ) + argumentSuggestion.push({nextArgs[i]} ) } return (
- { results.length > 0 &&
Argument suggestion: {results}
} + { argumentSuggestion.length > 0 &&
Argument suggestion: {argumentSuggestion}
} { help?.includes("->") &&
Signature help: {help}
} { description &&
# {description}
}
Available Commands:

{JSON.stringify(availableCommands)}

@@ -35,21 +77,21 @@ export function CommandHelp({nextArgs, currentArg, help, description, availableC } export default function CommandBar() { - const [input, setInput] = useState("") - const [originalInput, setOriginalInput] = useState("") - const [currentCompletion, setCurrentCompletion] = useState(0) - const [completionCandidate, setCompletionCandidate] = useState([]) + const [input, setInput] = useState("") + const [originalInput, setOriginalInput] = useState("") + const [currentCompletion, setCurrentCompletion] = useState(0) + const [completionCandidate, setCompletionCandidate] = useState([]) - const [availableCommands, setAvailableCommands] = useState([]) + const [availableCommands, setAvailableCommands] = useState([]) const [allCommands, setAllCommands] = useState({}) - const [nextArgs, setNextArgs] = useState([]) - const [currentArg, setCurrentArg] = useState(0) - const [signatureHelp, setSignatureHelp] = useState("") - const [description, setDescription] = useState("") + const [nextArgs, setNextArgs] = useState([]) + const [currentArg, setCurrentArg] = useState(0) + const [signatureHelp, setSignatureHelp] = useState("") + const [description, setDescription] = useState("") - const [results, setResults] = useState([]) - const [history, setHistory] = useState([]) - const [currentPos, setCurrentPos] = useState(0) + const [results, setResults] = useState([]) + const [history, setHistory] = useState([]) + const [currentPos, setCurrentPos] = useState(0) useEffect(() => { fetchApi('/commands', { method: 'GET' }) @@ -57,13 +99,13 @@ export default function CommandBar() { .then(data => { setAllCommands(data["commands"]) setCompletionCandidate(getAvailableCommands(data["commands"])) - setAvailableCommands(getAvailableCommands(data["commands"])) + setAvailableCommands(Object.keys(data["commands"])) }) }, []) - const parseCommand = (originalInput, input) => { - const parts = Filt.parse(input) - const originalParts = Filt.parse(originalInput) + const parseCommand = (originalInput: string, input: string) => { + const parts: string[] = Filt.parse(input) + const originalParts: string[] = Filt.parse(originalInput) setSignatureHelp(allCommands[parts[0]]?.signature_help) setDescription(allCommands[parts[0]]?.description) @@ -71,7 +113,7 @@ export default function CommandBar() { setCompletionCandidate(getAvailableCommands(allCommands, originalParts[0])) setAvailableCommands(getAvailableCommands(allCommands, parts[0])) - const nextArgs = allCommands[parts[0]]?.args + const nextArgs: string[] = allCommands[parts[0]]?.args if (nextArgs) { setNextArgs([parts[0], ...nextArgs]) @@ -114,6 +156,7 @@ export default function CommandBar() { setInput("") setOriginalInput("") + setCurrentCompletion(0) setCompletionCandidate(availableCommands) } if (e.keyCode === Key.UP) { @@ -139,6 +182,10 @@ export default function CommandBar() { } const onKeyUp = (e) => { + if (!input) { + setAvailableCommands(Object.keys(allCommands)) + return + } parseCommand(originalInput, input) e.stopPropagation() } @@ -148,14 +195,7 @@ export default function CommandBar() {
Command Result
-
- {results.map(result => ( -
-
$ {result.command}
- {result.result} -
- ))} -
+