rdesktop2
filip mertens 1 year ago
parent 297c476b21
commit 731aecd556
  1. 5
      apps/remix-ide/src/app/panels/terminal.js
  2. 4
      apps/remix-ide/src/app/plugins/electron/isoGitPlugin.ts
  3. 1
      apps/remixdesktop/src/plugins/fsPlugin.ts
  4. 12
      apps/remixdesktop/src/plugins/xtermPlugin.ts
  5. 1
      libs/remix-ui/app/src/lib/remix-app/remix-app.tsx
  6. 7
      libs/remix-ui/panel/src/lib/dragbar/dragbar.tsx
  7. 11
      libs/remix-ui/xterm/src/lib/components/remix-ui-xterm.tsx
  8. 130
      libs/remix-ui/xterm/src/lib/components/remix-ui-xterminals.tsx
  9. 46
      libs/remix-ui/xterm/src/lib/css/index.css

@ -9,6 +9,7 @@ import vm from 'vm'
const EventManager = require('../../lib/events')
import { CompilerImports } from '@remix-project/core-plugin' // eslint-disable-line
import { RemixUiXterminals } from '@remix-ui/xterm'
const KONSOLES = []
@ -113,7 +114,9 @@ class Terminal extends Plugin {
}
updateComponent(state) {
return <RemixUiTerminal
return isElectron() ? <RemixUiXterminals onReady={state.onReady} plugin={state.plugin}>
</RemixUiXterminals>
: <RemixUiTerminal
plugin={state.plugin}
onReady={state.onReady}
/>

@ -16,9 +16,9 @@ export class isoGitPlugin extends ElectronPlugin {
setTimeout(async () => {
const version = await this.call('isogit', 'version')
if(version){
this.call('terminal', 'log', version)
//this.call('terminal', 'log', version)
}else{
this.call('terminal', 'log', 'Git is not installed on the system. Using builtin git instead. Performance will be affected. It is better to install git on the system and configure the credentials to connect to GitHub etc.')
//this.call('terminal', 'log', 'Git is not installed on the system. Using builtin git instead. Performance will be affected. It is better to install git on the system and configure the credentials to connect to GitHub etc.')
}

@ -138,7 +138,6 @@ class FSPluginClient extends ElectronBasePluginClient {
withFileTypes: true,
...options
})
console.log('glob', files)
const result: any[] = []
for (const file of files) {

@ -55,7 +55,7 @@ const clientProfile: Profile = {
name: 'xterm',
displayName: 'xterm',
description: 'xterm plugin',
methods: ['createTerminal', 'close', 'keystroke']
methods: ['createTerminal', 'close', 'keystroke', 'getShells']
}
class XtermPluginClient extends ElectronBasePluginClient {
@ -65,13 +65,23 @@ class XtermPluginClient extends ElectronBasePluginClient {
super(webContentsId, profile)
this.onload(() => {
console.log('XtermPluginClient onload')
this.emit('loaded')
})
}
async onActivation(): Promise<void> {
console.log('XtermPluginClient onActivation')
}
async keystroke(key: string, pid: number): Promise<void> {
this.terminals[pid].write(key)
}
async getShells(): Promise<string[]> {
return [defaultShell]
}
async createTerminal(path?: string): Promise<number> {
const shell = defaultShell;

@ -91,7 +91,6 @@ const RemixApp = (props: IRemixAppUi) => {
<DragBar resetTrigger={resetTrigger} maximiseTrigger={maximiseTrigger} minWidth={285} refObject={sidePanelRef} hidden={hideSidePanel} setHideStatus={setHideSidePanel}></DragBar>
<div id="main-panel" data-id="remixIdeMainPanel" className='mainpanel d-flex'>
<RemixUIMainPanel Context={AppContext}></RemixUIMainPanel>
<RemixUiXterminals plugin={props.app.appManager}></RemixUiXterminals>
<CustomTooltip
placement="bottom"
tooltipId="overlay-tooltip-all-tabs"

@ -16,15 +16,18 @@ const DragBar = (props: IRemixDragBarUi) => {
const nodeRef = React.useRef(null) // fix for strictmode
function stopDrag (e: MouseEvent, data: any) {
console.log('stopDrag', data)
const h = window.innerHeight - data.y
props.refObject.current.setAttribute('style', `height: ${h}px;`)
setDragBarPosY(window.innerHeight - props.refObject.current.offsetHeight)
console.log('stopDrag', `height: ${h}px;`)
setDragBarPosY(props.refObject.current.offsetTop)
setDragState(false)
props.setHideStatus(false)
}
const handleResize = () => {
console.log('handleResize', props.refObject.current)
if (!props.refObject.current) return
setDragBarPosY(window.innerHeight - props.refObject.current.offsetHeight)
setDragBarPosY(props.refObject.current.offsetTop)
}
useEffect(() => {

@ -9,6 +9,10 @@ export interface RemixUiXtermProps {
send: (data: string, pid: number) => void
timeStamp: number
setTerminalRef: (pid: number, ref: any) => void
theme: {
backgroundColor: string
textColor: string
}
}
const RemixUiXterm = (props: RemixUiXtermProps) => {
@ -38,8 +42,11 @@ const RemixUiXterm = (props: RemixUiXtermProps) => {
return (
<>
<button className='btn' onClick={closeTerminal}>close</button>
<XTerm ref={xtermRef} onData={onData} onKey={onKey}></XTerm>
<button className='btn d-none' onClick={closeTerminal}>close</button>
<XTerm
options={{theme: {background: props.theme.backgroundColor , foreground: props.theme.textColor}}}
ref={xtermRef} onData={onData}
onKey={onKey}></XTerm>
</>
)

@ -2,9 +2,12 @@ import React, { useState, useEffect } from 'react' // eslint-disable-line
import { ElectronPlugin } from '@remixproject/engine-electron'
import RemixUiXterm from './remix-ui-xterm'
import '../css/index.css'
import { Tab, Tabs } from 'react-bootstrap'
import { Button, ButtonGroup, Dropdown, Tab, Tabs } from 'react-bootstrap'
import { CustomIconsToggle } from '@remix-ui/helper'
import { RemixUiTerminal } from '@remix-ui/terminal'
export interface RemixUiXterminalsProps {
plugin: ElectronPlugin
onReady: (api: any) => void
}
export interface xtermState {
@ -18,12 +21,18 @@ export interface xtermState {
export const RemixUiXterminals = (props: RemixUiXterminalsProps) => {
const [terminals, setTerminals] = useState<xtermState[]>([])
const [workingDir, setWorkingDir] = useState<string>('')
const [showOutput, setShowOutput] = useState<boolean>(true)
const [theme, setTheme] = useState<any>(themeCollection[0])
const [terminalsEnabled, setTerminalsEnabled] = useState<boolean>(false)
const [shells, setShells] = useState<string[]>([])
const { plugin } = props
useEffect(() => {
setTimeout(async () => {
plugin.on('xterm', 'loaded', async () => {
console.log('xterm loaded')
})
plugin.on('xterm', 'data', async (data: string, pid: number) => {
writeToTerminal(data, pid)
})
@ -31,17 +40,46 @@ export const RemixUiXterminals = (props: RemixUiXterminalsProps) => {
plugin.on('xterm', 'close', async (pid: number) => {
setTerminals(prevState => {
const removed = prevState.filter(xtermState => xtermState.pid !== pid)
if (removed.length > 0)
removed[removed.length - 1].hidden = false
if(removed.length === 0)
setShowOutput(true)
return [...removed]
})
})
plugin.on('fs', 'workingDirChanged', (path: string) => {
setWorkingDir(path)
setTerminalsEnabled(true)
})
plugin.on('theme', 'themeChanged', async (theme) => {
console.log('themeChanged', theme)
handleThemeChange(theme)
})
}, 5000)
const theme = await plugin.call('theme', 'currentTheme')
console.log('theme', theme)
handleThemeChange(theme)
const shells = await plugin.call('xterm', 'getShells')
console.log('shells', shells)
setShells(shells)
}, 2000)
}, [])
const handleThemeChange = (theme: any) => {
themeCollection.forEach((themeItem) => {
if (themeItem.themeName === theme.name) {
setTheme(themeItem)
console.log('setTheme', themeItem)
}
})
}
const writeToTerminal = (data: string, pid: number) => {
setTerminals(prevState => {
const terminal = prevState.find(xtermState => xtermState.pid === pid)
@ -67,7 +105,7 @@ export const RemixUiXterminals = (props: RemixUiXterminalsProps) => {
const createTerminal = async () => {
const pid = await plugin.call('xterm', 'createTerminal', workingDir)
setShowOutput(false)
setTerminals(prevState => {
// set all to hidden
prevState.forEach(xtermState => {
@ -108,28 +146,70 @@ export const RemixUiXterminals = (props: RemixUiXterminalsProps) => {
})
}
const closeTerminal = () => {
const pid = terminals.find(xtermState => xtermState.hidden === false).pid
if (pid)
plugin.call('xterm', 'close', pid)
}
const selectOutput = () => {
setShowOutput(true)
}
const showTerminal = () => {
setShowOutput(false)
if (terminals.length === 0) createTerminal()
}
return (<>
<div className='xterm-panel'>
<button className='btn btn-sm btn-secondary' onClick={() => {
createTerminal()
}}>open new terminal</button>
<div className='xterm-panel-header bg-light'>
<div className='xterm-panel-header-left p-1'>
<button className={`btn btn-sm btn-secondary mr-2 ${!showOutput ? 'xterm-btn-none' : 'xterm-btn-active'}`} onClick={selectOutput}>ouput</button>
<button className={`btn btn-sm btn-secondary ${terminalsEnabled ? '' : 'd-none'} ${showOutput ? 'xterm-btn-none' : 'xterm-btn-active'}`} onClick={showTerminal}><span className="far fa-terminal border-0 ml-1"></span></button>
</div>
<div className={`xterm-panel-header-right ${showOutput ? 'd-none' : ''}`}>
<Dropdown as={ButtonGroup}>
<button className="btn btn-sm btn-secondary" onClick={createTerminal}><span className="far fa-plus border-0 p-0 m-0"></span></button>
<div className='remix-ui-xterminals-container'>
<>
{terminals.map((xtermState, index) => {
return (<button onClick={async () => selectTerminal(xtermState)} className={`btn btn-sm btn-secondary ${xtermState.hidden ? 'xterm-btn-none' : 'xterm-btn-active'}`}>Terminal {index + 1}</button>)
<Dropdown.Toggle split variant="secondary" id="dropdown-split-basic" />
<Dropdown.Menu className='custom-dropdown-items remixui_menuwidth'>
{shells.map((shell, index) => {
return (<Dropdown.Item index={index} onClick={createTerminal}>{shell}</Dropdown.Item>)
})}
</Dropdown.Menu>
</Dropdown>
<button className="btn ml-2 btn-sm btn-secondary" onClick={closeTerminal}><span className="far fa-trash border-0 ml-1"></span></button>
</div>
</div>
<div className='remix-ui-xterminals-container'>
<>
<div className={`${!showOutput ? 'd-none' : 'd-block w-100'} `}>
<RemixUiTerminal
plugin={props.plugin}
onReady={props.onReady} />
</div>
<div className={`remix-ui-xterminals-section ${showOutput ? 'd-none' : 'd-flex'} `}>
{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 className={`xterm-terminal ${xtermState.hidden ? 'hide-xterm' : 'show-xterm'}`} key={xtermState.pid} data-id={`remixUIXT${xtermState.pid}`}>
<RemixUiXterm theme={theme} setTerminalRef={setTerminalRef} timeStamp={xtermState.timeStamp} send={send} pid={xtermState.pid} plugin={plugin}></RemixUiXterm>
</div>
)
})}
<div className='remix-ui-xterminals-buttons border-left'>
{terminals.map((xtermState, index) => {
return (<button onClick={async () => selectTerminal(xtermState)} className={`btn btn-sm mt-2 btn-secondary ${xtermState.hidden ? 'xterm-btn-none' : 'xterm-btn-active'}`}><span className="fa fa-terminal border-0 p-0 m-0"></span></button>)
})}
</div>
</div>
</>
</div>
</div>
@ -138,3 +218,29 @@ export const RemixUiXterminals = (props: RemixUiXterminalsProps) => {
</>)
}
const themeCollection = [
{ themeName: 'HackerOwl', backgroundColor: '#011628', textColor: '#babbcc',
shapeColor: '#8694a1',fillColor: '#011C32'},
{ themeName: 'Cerulean', backgroundColor: '#ffffff', textColor: '#343a40',
shapeColor: '#343a40',fillColor: '#f8f9fa'},
{ themeName: 'Cyborg', backgroundColor: '#060606', textColor: '#adafae',
shapeColor: '#adafae', fillColor: '#222222'},
{ themeName: 'Dark', backgroundColor: '#222336', textColor: '#babbcc',
shapeColor: '#babbcc',fillColor: '#2a2c3f'},
{ themeName: 'Flatly', backgroundColor: '#ffffff', textColor: '#343a40',
shapeColor: '#7b8a8b',fillColor: '#ffffff'},
{ themeName: 'Black', backgroundColor: '#1a1a1a', textColor: '#babbcc',
shapeColor: '#b5b4bc',fillColor: '#1f2020'},
{ themeName: 'Light', backgroundColor: '#eef1f6', textColor: '#3b445e',
shapeColor: '#343a40',fillColor: '#ffffff'},
{ themeName: 'Midcentury', backgroundColor: '#DBE2E0', textColor: '#11556c',
shapeColor: '#343a40',fillColor: '#eeede9'},
{ themeName: 'Spacelab', backgroundColor: '#ffffff', textColor: '#343a40',
shapeColor: '#333333', fillColor: '#eeeeee'},
{ themeName: 'Candy', backgroundColor: '#d5efff', textColor: '#11556c',
shapeColor: '#343a40',fillColor: '#fbe7f8' },
{ themeName: 'Violet', backgroundColor: '#f1eef6', textColor: '#3b445e',
shapeColor: '#343a40',fillColor: '#f8fafe' },
{ themeName: 'Pride', backgroundColor: '#f1eef6', textColor: '#343a40',
shapeColor: '#343a40',fillColor: '#f8fafe' },
]

@ -1,7 +1,12 @@
.remix-ui-xterminals-container {
overflow: scroll;
display: flex;
flex-direction: row;
}
.xterm-panel {
}
.remix-ui-xterminals-buttons {
display: flex;
flex-direction: column;
}
@ -20,3 +25,42 @@
.xterm-btn-none {
background-color: var(--secondary);
}
.xterm-terminal {
flex-grow: 1;
height: 100%;
width: 100%;
}
.xterm-panel-header-right {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-self: flex-end;
}
.xterm-panel-header {
display: flex;
flex-direction: row;
}
.xterm-panel-header-left {
display: flex;
flex-direction: row;
flex-grow: 1;
}
.remix-ui-xterminals-section {
display: flex;
flex-direction: row;
width: 100%;
z-index: 3;
}
.hide-terminals {
width: 0;
}
.show-terminals {
width: 100%;
}

Loading…
Cancel
Save