fix(ui): возвращать фокус терминала после включения поля

This commit is contained in:
Denozordec committed 2026-10-04 23:19:14 +07:00
1 parent 55df77296a
commit b1f8326304
6 files changed
+57 -10

No files matched your search

+8 -2
View File
@@ -179,9 +179,15 @@ function Terminal({server,isLive,backendUrl,canExecute,blockedReason}:{server:Te
const [lines,setLines]=useState<TermLine[]>([{id:0,kind:"info",text:isLive?"REST: каждое выполнение — отдельный запрос; соединение с устройством пока не проверено.":"Демо: команды возвращают синтетические данные."}])
const [input,setInput]=useState(""),[history,setHistory]=useState<string[]>([]),[histIdx,setHistIdx]=useState(-1),[executing,setExecuting]=useState(false),[error,setError]=useState<string|null>(null),[completed,setCompleted]=useState<string|null>(null)
const nextId=useRef(1),lock=useRef(false),reader=useRef<{alive:boolean;controller:AbortController|null}>({alive:true,controller:null})
const inputRef=useRef<HTMLInputElement>(null),scrollRef=useRef<HTMLDivElement>(null),followOutput=useRef(true)
const inputRef=useRef<HTMLInputElement>(null),scrollRef=useRef<HTMLDivElement>(null),followOutput=useRef(true),pendingFocus=useRef(false)
useEffect(()=>{const state=reader.current;state.alive=true;return()=>{state.alive=false;state.controller?.abort()}},[])
useEffect(()=>{if(followOutput.current)scrollRef.current?.scrollTo({top:scrollRef.current.scrollHeight,behavior:"auto"})},[lines])
// Focus only after React has committed the re-enabled input.
useEffect(()=>{
if(executing||!pendingFocus.current)return
pendingFocus.current=false
if(reader.current.alive&&!inputRef.current?.disabled)inputRef.current?.focus()
},[executing,lines])
function append(kind:TermLine["kind"],text:string) {
const added=text.split("\n").map(text=>({id:nextId.current++,kind,text}))
setLines(previous=>{const merged=[...previous.filter(line=>line.id!==-1),...added];return merged.length>1000||previous.some(line=>line.id===-1)?[{id:-1,kind:"info",text:"Показаны последние 1000 строк; ранний вывод удалён."},...merged.slice(-1000)]:merged})
@@ -205,7 +211,7 @@ function Terminal({server,isLive,backendUrl,canExecute,blockedReason}:{server:Te
append("error",message);setError(message)
} finally {
window.clearTimeout(timer);lock.current=false
if(reader.current.alive){setExecuting(false);reader.current.controller=null;requestAnimationFrame(()=>inputRef.current?.focus())}
if(reader.current.alive){pendingFocus.current=true;setExecuting(false);reader.current.controller=null}
}
}
function handleKey(e:React.KeyboardEvent<HTMLInputElement>){