xterm panels

rdesktop2
filip mertens 1 year ago
parent e0a2f62f71
commit 9c3283c017
  1. 1
      apps/remixdesktop/src/plugins/xtermPlugin.ts
  2. 2
      libs/remix-ui/panel/src/lib/main/main-panel.css
  3. 3
      libs/remix-ui/xterm/src/lib/components/remix-ui-xterm.tsx
  4. 82
      libs/remix-ui/xterm/src/lib/components/remix-ui-xterminals.tsx
  5. 19
      libs/remix-ui/xterm/src/lib/css/index.css

@ -86,6 +86,7 @@ class XtermPluginClient extends ElectronBasePluginClient {
}); });
ptyProcess.onData((data: string) => { ptyProcess.onData((data: string) => {
console.log('onData', data)
this.sendData(data, ptyProcess.pid); this.sendData(data, ptyProcess.pid);
}) })
this.terminals[ptyProcess.pid] = ptyProcess this.terminals[ptyProcess.pid] = ptyProcess

@ -1,7 +1,7 @@
.mainview { .mainview {
display : flex; display : flex;
flex-direction : column; flex-direction : column;
height : 100%; height : 70%;
width : 100%; width : 100%;
position : relative; position : relative;
} }

@ -38,8 +38,9 @@ const RemixUiXterm = (props: RemixUiXtermProps) => {
return ( return (
<> <>
<button className='btn' onClick={closeTerminal}>close</button>
<XTerm ref={xtermRef} onData={onData} onKey={onKey}></XTerm> <XTerm ref={xtermRef} onData={onData} onKey={onKey}></XTerm>
<button onClick={closeTerminal}>close</button>
</> </>
) )

@ -12,6 +12,7 @@ export interface xtermState {
queue: string queue: string
timeStamp: number timeStamp: number
ref: any ref: any
hidden: boolean
} }
export const RemixUiXterminals = (props: RemixUiXterminalsProps) => { export const RemixUiXterminals = (props: RemixUiXterminalsProps) => {
@ -21,30 +22,34 @@ export const RemixUiXterminals = (props: RemixUiXterminalsProps) => {
useEffect(() => { useEffect(() => {
setTimeout(async () => { setTimeout(async () => {
plugin.on('xterm', 'loaded', async () => { plugin.on('xterm', 'loaded', async () => {
}) })
plugin.on('xterm', 'data', async (data: string, pid: number) => { plugin.on('xterm', 'data', async (data: string, pid: number) => {
writeToTerminal(data, pid) writeToTerminal(data, pid)
}) })
plugin.on('xterm', 'close', async (pid: number) => { plugin.on('xterm', 'close', async (pid: number) => {
setTerminals(prevState => { setTerminals(prevState => {
return prevState.filter(xtermState => xtermState.pid !== pid) const removed = prevState.filter(xtermState => xtermState.pid !== pid)
removed[removed.length-1].hidden = false
return [...removed]
})
}) })
})
plugin.on('fs', 'workingDirChanged', (path: string) => { plugin.on('fs', 'workingDirChanged', (path: string) => {
setWorkingDir(path) setWorkingDir(path)
}) })
}, 5000) }, 5000)
}, []) }, [])
const writeToTerminal = (data: string, pid: number) => { const writeToTerminal = (data: string, pid: number) => {
setTerminals(prevState => { setTerminals(prevState => {
const terminal = prevState.find(xtermState => xtermState.pid === pid) const terminal = prevState.find(xtermState => xtermState.pid === pid)
if (terminal.ref && terminal.ref.terminal) { if (terminal.ref && terminal.ref.terminal) {
console.log('writing to terminal', terminal, data)
terminal.ref.terminal.write(data) terminal.ref.terminal.write(data)
}else { } else {
console.log('no terminal ref', terminal)
terminal.queue += data terminal.queue += data
} }
return [...prevState] return [...prevState]
@ -64,11 +69,16 @@ export const RemixUiXterminals = (props: RemixUiXterminalsProps) => {
const pid = await plugin.call('xterm', 'createTerminal', workingDir) const pid = await plugin.call('xterm', 'createTerminal', workingDir)
setTerminals(prevState => { setTerminals(prevState => {
// set all to hidden
prevState.forEach(xtermState => {
xtermState.hidden = true
})
return [...prevState, { return [...prevState, {
pid: pid, pid: pid,
queue: '', queue: '',
timeStamp: Date.now(), timeStamp: Date.now(),
ref: null ref: null,
hidden: false
}] }]
}) })
} }
@ -78,7 +88,7 @@ export const RemixUiXterminals = (props: RemixUiXterminalsProps) => {
setTerminals(prevState => { setTerminals(prevState => {
const terminal = prevState.find(xtermState => xtermState.pid === pid) const terminal = prevState.find(xtermState => xtermState.pid === pid)
terminal.ref = ref terminal.ref = ref
if(terminal.queue) { if (terminal.queue) {
ref.terminal.write(terminal.queue) ref.terminal.write(terminal.queue)
terminal.queue = '' terminal.queue = ''
} }
@ -86,24 +96,44 @@ export const RemixUiXterminals = (props: RemixUiXterminalsProps) => {
}) })
} }
const selectTerminal = (state: xtermState) => {
setTerminals(prevState => {
// set all to hidden
prevState.forEach(xtermState => {
xtermState.hidden = true
})
const terminal = prevState.find(xtermState => xtermState.pid === state.pid)
terminal.hidden = false
return [...prevState]
})
}
return (<> return (<>
<button className='btn border' onClick={() => { <div className='xterm-panel'>
<button className='btn btn-sm btn-secondary' onClick={() => {
createTerminal() createTerminal()
}}>open terminal</button> }}>open new terminal</button>
<div className='remix-ui-xterminals-container'> <div className='remix-ui-xterminals-container'>
{terminals.map((xtermState) => { <>
return ( {terminals.map((xtermState, index) => {
<div key={xtermState.pid} data-id={`remixUIXT${xtermState.pid}`}>
<RemixUiXterm setTerminalRef={setTerminalRef} timeStamp={xtermState.timeStamp} send={send} pid={xtermState.pid} plugin={plugin}></RemixUiXterm> return (<button onClick={async () => selectTerminal(xtermState)} className={`btn btn-sm btn-secondary ${xtermState.hidden ? 'xterm-btn-none' : 'xterm-btn-active'}`}>Terminal {index + 1}</button>)
</div> })}
) {terminals.map((xtermState) => {
})} return (
<div className={xtermState.hidden ? 'hide-xterm' : 'show-xterm'} key={xtermState.pid} data-id={`remixUIXT${xtermState.pid}`}>
<RemixUiXterm setTerminalRef={setTerminalRef} timeStamp={xtermState.timeStamp} send={send} pid={xtermState.pid} plugin={plugin}></RemixUiXterm>
</div>
)
})}
</>
</div> </div>
</div>
</>) </>)
} }

@ -1,3 +1,22 @@
.remix-ui-xterminals-container { .remix-ui-xterminals-container {
overflow: scroll; overflow: scroll;
}
.xterm-panel {
display: flex;
flex-direction: column;
}
.hide-xterm{
display: none;
}
.show-xterm{
display: block;
}
.xterm-btn-active {
background-color: var(--primary);
}
.xterm-btn-none {
background-color: var(--secondary);
} }
Loading…
Cancel
Save