parent
cb32ecbd31
commit
f4e3dfc01d
@ -0,0 +1,15 @@ |
|||||||
|
import { ElectronPlugin } from '@remixproject/engine-electron'; |
||||||
|
|
||||||
|
export class xtermPlugin extends ElectronPlugin { |
||||||
|
constructor(){ |
||||||
|
super({ |
||||||
|
displayName: 'xterm', |
||||||
|
name: 'xterm', |
||||||
|
description: 'xterm', |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
onActivation(){ |
||||||
|
console.log('xtermPlugin Activated') |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,3 @@ |
|||||||
|
export * from './lib/components/remix-ui-xterm' |
||||||
|
export * from './lib/components/remix-ui-filedialog' |
||||||
|
export * from './lib/components/remix-ui-xterminals' |
@ -0,0 +1,39 @@ |
|||||||
|
import { Plugin } from "@remixproject/engine" |
||||||
|
import React, { useEffect, useState } from "react" |
||||||
|
|
||||||
|
interface RemixUIFileDialogInterface { |
||||||
|
plugin: Plugin |
||||||
|
} |
||||||
|
|
||||||
|
export const RemixUIFileDialog = (props: RemixUIFileDialogInterface) => { |
||||||
|
const { plugin } = props |
||||||
|
const [files, setFiles] = useState<string[]>([]) |
||||||
|
const [workingDir, setWorkingDir] = useState<string>('') |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
plugin.on('fs', 'workingDirChanged', async (path: string) => { |
||||||
|
console.log('workingDirChanged') |
||||||
|
setWorkingDir(path) |
||||||
|
await readdir() |
||||||
|
}) |
||||||
|
}, []) |
||||||
|
|
||||||
|
const readdir = async () => { |
||||||
|
const files = await plugin.call('fs', 'readdir', '/') |
||||||
|
console.log('files', files) |
||||||
|
setFiles(files) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
<h1>RemixUIFileDialog</h1> |
||||||
|
<button onClick={() => plugin.call('fs', 'setWorkingDir')}>open</button> |
||||||
|
<button onClick={async () => await readdir()}>read</button> |
||||||
|
<hr></hr> |
||||||
|
{workingDir} |
||||||
|
<hr></hr> |
||||||
|
|
||||||
|
{files.map(file => <div key={file}>{file}</div>)} |
||||||
|
</> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
import React, { useState, useEffect, forwardRef } from 'react' // eslint-disable-line
|
||||||
|
import { ElectronPlugin } from '@remixproject/engine-electron' |
||||||
|
import { XTerm } from 'xterm-for-react' |
||||||
|
|
||||||
|
|
||||||
|
export interface RemixUiXtermProps { |
||||||
|
plugin: ElectronPlugin |
||||||
|
pid: number |
||||||
|
send: (data: string, pid: number) => void |
||||||
|
timeStamp: number |
||||||
|
setTerminalRef: (pid: number, ref: any) => void |
||||||
|
} |
||||||
|
|
||||||
|
const RemixUiXterm = (props: RemixUiXtermProps) => { |
||||||
|
const { plugin, pid, send, timeStamp } = props |
||||||
|
const xtermRef = React.useRef(null) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
console.log('remix-ui-xterm ref', xtermRef.current) |
||||||
|
props.setTerminalRef(pid, xtermRef.current) |
||||||
|
}, [xtermRef.current]) |
||||||
|
|
||||||
|
const onKey = (event: { key: string; domEvent: KeyboardEvent }) => { |
||||||
|
send(event.key, pid) |
||||||
|
} |
||||||
|
|
||||||
|
const onData = (data: string) => { |
||||||
|
console.log('onData', data) |
||||||
|
} |
||||||
|
|
||||||
|
const closeTerminal = () => { |
||||||
|
plugin.call('xterm', 'close', pid) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
<XTerm ref={xtermRef} onData={onData} onKey={onKey}></XTerm> |
||||||
|
<button onClick={closeTerminal}>close</button> |
||||||
|
</> |
||||||
|
) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
export default RemixUiXterm |
@ -0,0 +1,103 @@ |
|||||||
|
import React, { useState, useEffect } from 'react' // eslint-disable-line
|
||||||
|
import { ElectronPlugin } from '@remixproject/engine-electron' |
||||||
|
import RemixUiXterm from './remix-ui-xterm' |
||||||
|
|
||||||
|
export interface RemixUiXterminalsProps { |
||||||
|
plugin: ElectronPlugin |
||||||
|
} |
||||||
|
|
||||||
|
export interface xtermState { |
||||||
|
pid: number |
||||||
|
queue: string |
||||||
|
timeStamp: number |
||||||
|
ref: any |
||||||
|
} |
||||||
|
|
||||||
|
export const RemixUiXterminals = (props: RemixUiXterminalsProps) => { |
||||||
|
const [terminals, setTerminals] = useState<xtermState[]>([]) |
||||||
|
const [workingDir, setWorkingDir] = useState<string>('') |
||||||
|
const { plugin } = props |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
setTimeout(async () => { |
||||||
|
plugin.on('xterm', 'loaded', async () => { |
||||||
|
}) |
||||||
|
plugin.on('xterm', 'data', async (data: string, pid: number) => { |
||||||
|
writeToTerminal(data, pid) |
||||||
|
}) |
||||||
|
|
||||||
|
plugin.on('xterm', 'close', async (pid: number) => { |
||||||
|
setTerminals(prevState => { |
||||||
|
return prevState.filter(xtermState => xtermState.pid !== pid) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
plugin.on('fs', 'workingDirChanged', (path: string) => { |
||||||
|
setWorkingDir(path) |
||||||
|
}) |
||||||
|
}, 5000) |
||||||
|
}, []) |
||||||
|
|
||||||
|
const writeToTerminal = (data: string, pid: number) => { |
||||||
|
setTerminals(prevState => { |
||||||
|
const terminal = prevState.find(xtermState => xtermState.pid === pid) |
||||||
|
if (terminal.ref && terminal.ref.terminal) { |
||||||
|
terminal.ref.terminal.write(data) |
||||||
|
}else { |
||||||
|
terminal.queue += data |
||||||
|
} |
||||||
|
return [...prevState] |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
console.log('terminals', terminals) |
||||||
|
}, [terminals]) |
||||||
|
|
||||||
|
const send = (data: string, pid: number) => { |
||||||
|
plugin.call('xterm', 'keystroke', data, pid) |
||||||
|
} |
||||||
|
|
||||||
|
const createTerminal = async () => { |
||||||
|
const pid = await plugin.call('xterm', 'createTerminal', workingDir) |
||||||
|
|
||||||
|
setTerminals(prevState => { |
||||||
|
return [...prevState, { |
||||||
|
pid: pid, |
||||||
|
queue: '', |
||||||
|
timeStamp: Date.now(), |
||||||
|
ref: null |
||||||
|
}] |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const setTerminalRef = (pid: number, ref: any) => { |
||||||
|
console.log('setTerminalRef', pid, ref) |
||||||
|
setTerminals(prevState => { |
||||||
|
const terminal = prevState.find(xtermState => xtermState.pid === pid) |
||||||
|
terminal.ref = ref |
||||||
|
if(terminal.queue) { |
||||||
|
ref.terminal.write(terminal.queue) |
||||||
|
terminal.queue = '' |
||||||
|
} |
||||||
|
return [...prevState] |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
return (<> |
||||||
|
<button onClick={() => { |
||||||
|
createTerminal() |
||||||
|
}}>create terminal</button> |
||||||
|
|
||||||
|
{terminals.map((xtermState) => { |
||||||
|
return ( |
||||||
|
<div key={xtermState.pid} data-id={`remixUIXT${xtermState.pid}`}>{xtermState.pid} |
||||||
|
<RemixUiXterm setTerminalRef={setTerminalRef} timeStamp={xtermState.timeStamp} send={send} pid={xtermState.pid} plugin={plugin}></RemixUiXterm> |
||||||
|
</div> |
||||||
|
) |
||||||
|
})} |
||||||
|
</>) |
||||||
|
} |
||||||
|
|
Loading…
Reference in new issue