fix(ui): возвращать фокус терминала после включения поля
This commit is contained in:
1 parent
55df77296a
commit
b1f8326304
6 files changed
+57
-10
No files matched your search
@@ -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>){
|
||||
|
||||
Reference in new issue
Block a user