@@ -112,7 +112,9 @@ export default ({
112112
113113 const sendHistoryRef = useRef ( JSON . parse ( window . sessionStorage . chatHistory || '[]' ) )
114114 const [ isInputFocused , setIsInputFocused ] = useState ( false )
115- const spellCheckEnabled = false
115+ const [ spellCheckEnabled , setSpellCheckEnabled ] = useState ( false )
116+ const [ preservedInputValue , setPreservedInputValue ] = useState ( '' )
117+ const [ inputKey , setInputKey ] = useState ( 0 )
116118 const pingHistoryRef = useRef ( JSON . parse ( window . localStorage . pingHistory || '[]' ) )
117119
118120 const [ completePadText , setCompletePadText ] = useState ( '' )
@@ -237,12 +239,16 @@ export default ({
237239 if ( opened ) {
238240 completeRequestValue . current = ''
239241 resetCompletionItems ( )
242+ } else {
243+ setPreservedInputValue ( '' )
240244 }
241245 } , [ opened ] )
242246
243247 const onMainInputChange = ( ) => {
244248 const lastWord = chatInput . current . value . slice ( 0 , chatInput . current . selectionEnd ?? chatInput . current . value . length ) . split ( ' ' ) . at ( - 1 ) !
245- if ( lastWord . startsWith ( '@' ) && getPingComplete ) {
249+ const isCommand = chatInput . current . value . startsWith ( '/' )
250+
251+ if ( lastWord . startsWith ( '@' ) && getPingComplete && ! isCommand ) {
246252 setCompletePadText ( lastWord )
247253 void fetchPingCompletions ( true , lastWord . slice ( 1 ) )
248254 return
@@ -322,6 +328,29 @@ export default ({
322328 return completeValue
323329 }
324330
331+ const handleSlashCommand = ( ) => {
332+ remountInput ( '/' )
333+ }
334+
335+ const handleAcceptFirstCompletion = ( ) => {
336+ if ( completionItems . length > 0 ) {
337+ acceptComplete ( completionItems [ 0 ] )
338+ }
339+ }
340+
341+ const remountInput = ( newValue ?: string ) => {
342+ if ( newValue !== undefined ) {
343+ setPreservedInputValue ( newValue )
344+ }
345+ setInputKey ( k => k + 1 )
346+ }
347+
348+ useEffect ( ( ) => {
349+ if ( preservedInputValue && chatInput . current ) {
350+ chatInput . current . focus ( )
351+ }
352+ } , [ inputKey ] ) // Changed from spellCheckEnabled to inputKey
353+
325354 return (
326355 < >
327356 < div
@@ -386,8 +415,53 @@ export default ({
386415 </ div >
387416
388417 < div className = { `chat-wrapper chat-input-wrapper ${ usingTouch ? 'input-mobile' : '' } ` } hidden = { ! opened } >
389- { /* close button */ }
390- { usingTouch && < Button icon = { pixelartIcons . close } onClick = { ( ) => onClose ?.( ) } /> }
418+ { usingTouch && (
419+ < >
420+ < Button
421+ icon = { pixelartIcons . close }
422+ onClick = { ( ) => onClose ?.( ) }
423+ style = { {
424+ width : 20 ,
425+ flexShrink : 0 ,
426+ } }
427+ />
428+
429+ { ( chatInput . current ?. value && ! chatInput . current . value . startsWith ( '/' ) ) ? (
430+ // TOGGLE SPELL CHECK
431+ < Button
432+ style = { {
433+ width : 20 ,
434+ flexShrink : 0 ,
435+ } }
436+ overlayColor = { spellCheckEnabled ? '#00ff00' : '#ff0000' }
437+ icon = { pixelartIcons [ 'text-wrap' ] }
438+ onClick = { ( ) => {
439+ setPreservedInputValue ( chatInput . current ?. value || '' )
440+ setSpellCheckEnabled ( ! spellCheckEnabled )
441+ remountInput ( )
442+ } }
443+ />
444+ ) : (
445+ // SLASH COMMAND
446+ < Button
447+ style = { {
448+ width : 20 ,
449+ flexShrink : 0 ,
450+ } }
451+ label = { chatInput . current ?. value ? undefined : '/' }
452+ icon = { chatInput . current ?. value ? pixelartIcons [ 'arrow-right' ] : undefined }
453+ onClick = { ( ) => {
454+ const inputValue = chatInput . current . value
455+ if ( ! inputValue ) {
456+ handleSlashCommand ( )
457+ } else if ( completionItems . length > 0 ) {
458+ handleAcceptFirstCompletion ( )
459+ }
460+ } }
461+ />
462+ ) }
463+ </ >
464+ ) }
391465 < div className = "chat-input" >
392466 { isInputFocused && completionItems ?. length ? (
393467 < div className = "chat-completions" >
@@ -431,9 +505,10 @@ export default ({
431505 /> }
432506 < input
433507 maxLength = { chatVanillaRestrictions ? 256 : undefined }
434- defaultValue = ''
508+ defaultValue = { preservedInputValue }
435509 // ios doesn't support toggling autoCorrect on the fly so we need to re-create the input
436- key = { spellCheckEnabled ? 'true' : 'false' }
510+ key = { `${ inputKey } ` }
511+ autoCapitalize = { preservedInputValue ? 'off' : 'on' }
437512 ref = { chatInput }
438513 type = "text"
439514 className = "chat-input"
0 commit comments