1- import React , { useEffect , useMemo , useRef } from 'react' ;
1+ import React , { useEffect , useMemo , useRef , useState } from 'react' ;
22import { ITerminalOptions , Terminal } from 'xterm' ;
33import { FitAddon } from 'xterm-addon-fit' ;
44import { SearchAddon } from 'xterm-addon-search' ;
@@ -11,6 +11,7 @@ import tw, { theme as th } from 'twin.macro';
1111import 'xterm/css/xterm.css' ;
1212import useEventListener from '@/plugins/useEventListener' ;
1313import { debounce } from 'debounce' ;
14+ import { usePersistedState } from '@/plugins/usePersistedState' ;
1415
1516const theme = {
1617 background : th `colors.black` . toString ( ) ,
@@ -63,6 +64,9 @@ export default () => {
6364 const searchBar = new SearchBarAddon ( { searchAddon } ) ;
6465 const { connected, instance } = ServerContext . useStoreState ( state => state . socket ) ;
6566 const [ canSendCommands ] = usePermissions ( [ 'control.console' ] ) ;
67+ const serverId = ServerContext . useStoreState ( state => state . server . data ! . id ) ;
68+ const [ history , setHistory ] = usePersistedState < string [ ] > ( `${ serverId } :command_history` , [ ] ) ;
69+ const [ historyIndex , setHistoryIndex ] = useState ( - 1 ) ;
6670
6771 const handleConsoleOutput = ( line : string , prelude = false ) => terminal . writeln (
6872 ( prelude ? TERMINAL_PRELUDE : '' ) + line . replace ( / (?: \r \n | \r | \n ) $ / im, '' ) + '\u001b[0m' ,
@@ -77,12 +81,28 @@ export default () => {
7781 ) ;
7882
7983 const handleCommandKeydown = ( e : React . KeyboardEvent < HTMLInputElement > ) => {
80- if ( e . key !== 'Enter' || ( e . key === 'Enter' && e . currentTarget . value . length < 1 ) ) {
81- return ;
84+ if ( e . key === 'ArrowUp' ) {
85+ const newIndex = Math . min ( historyIndex + 1 , history ! . length - 1 ) ;
86+
87+ setHistoryIndex ( newIndex ) ;
88+ e . currentTarget . value = history ! [ newIndex ] || '' ;
89+ }
90+
91+ if ( e . key === 'ArrowDown' ) {
92+ const newIndex = Math . max ( historyIndex - 1 , - 1 ) ;
93+
94+ setHistoryIndex ( newIndex ) ;
95+ e . currentTarget . value = history ! [ newIndex ] || '' ;
8296 }
8397
84- instance && instance . send ( 'send command' , e . currentTarget . value ) ;
85- e . currentTarget . value = '' ;
98+ const command = e . currentTarget . value ;
99+ if ( e . key === 'Enter' && command . length > 0 ) {
100+ setHistory ( prevHistory => [ command , ...prevHistory ! ] ) ;
101+ setHistoryIndex ( - 1 ) ;
102+
103+ instance && instance . send ( 'send command' , command ) ;
104+ e . currentTarget . value = '' ;
105+ }
86106 } ;
87107
88108 useEffect ( ( ) => {
0 commit comments