fix tabs view

pull/5370/head
filip mertens 3 years ago
parent 38758f9171
commit e73b1b6c47
  1. 15
      apps/remix-ide/src/app.js
  2. 3
      apps/remix-ide/src/app/components/main-panel.tsx
  3. 2
      apps/remix-ide/src/app/components/panel.ts
  4. 49
      apps/remix-ide/src/app/panels/layout.ts
  5. 3
      apps/remix-ide/src/app/panels/main-view.js
  6. 21
      apps/remix-ide/src/app/panels/tab-proxy.js
  7. 2
      libs/remix-ui/app/src/lib/remix-app/context/context.tsx
  8. 2
      libs/remix-ui/app/src/lib/remix-app/remix-app.tsx
  9. 90
      libs/remix-ui/panel/src/lib/main/main-panel.tsx
  10. 25
      libs/remix-ui/panel/src/lib/plugins/panel-plugin.tsx
  11. 14
      libs/remix-ui/panel/src/lib/plugins/panel.css
  12. 438
      package-lock.json

@ -20,6 +20,7 @@ import { OffsetToLineColumnConverter, CompilerMetadata, CompilerArtefacts, Fetch
import migrateFileSystem from './migrateFileSystem' import migrateFileSystem from './migrateFileSystem'
import Registry from './app/state/registry' import Registry from './app/state/registry'
import { ConfigPlugin } from './app/plugins/config' import { ConfigPlugin } from './app/plugins/config'
import { Layout } from './app/panels/layout'
const isElectron = require('is-electron') const isElectron = require('is-electron')
@ -161,8 +162,10 @@ class AppComponent {
const contextualListener = new EditorContextListener() const contextualListener = new EditorContextListener()
const configPlugin = new ConfigPlugin() const configPlugin = new ConfigPlugin()
self.layout = new Layout()
self.engine.register([ self.engine.register([
self.layout,
configPlugin, configPlugin,
blockchain, blockchain,
contentImport, contentImport,
@ -252,11 +255,11 @@ class AppComponent {
filePanel.slitherHandle filePanel.slitherHandle
]) ])
self.panels = { self.layout.panels = {
main: appPanel, tabs: { plugin:tabProxy, active: true },
editor: editor, editor: { plugin:editor, active: true },
terminal: terminal, main: { plugin:appPanel, active: false },
tabs: tabProxy terminal: { plugin:terminal, active: true },
} }
} }
@ -275,7 +278,7 @@ class AppComponent {
console.log('couldn\'t register iframe plugins', e.message) console.log('couldn\'t register iframe plugins', e.message)
} }
await self.appManager.activatePlugin(['editor']) await self.appManager.activatePlugin(['layout', 'editor'])
await self.appManager.activatePlugin(['theme', 'fileManager', 'compilerMetadata', 'compilerArtefacts', 'network', 'web3Provider', 'offsetToLineColumnConverter']) await self.appManager.activatePlugin(['theme', 'fileManager', 'compilerMetadata', 'compilerArtefacts', 'network', 'web3Provider', 'offsetToLineColumnConverter'])
await self.appManager.activatePlugin(['mainPanel']) await self.appManager.activatePlugin(['mainPanel'])
await self.appManager.activatePlugin(['mainPanel', 'menuicons', 'tabs']) await self.appManager.activatePlugin(['mainPanel', 'menuicons', 'tabs'])

@ -9,7 +9,7 @@ const profile = {
displayName: 'Main Panel', displayName: 'Main Panel',
description: '', description: '',
version: packageJson.version, version: packageJson.version,
methods: ['addView', 'removeView'] methods: ['addView', 'removeView', 'showContent']
} }
export class MainPanel extends AbstractPanel { export class MainPanel extends AbstractPanel {
@ -18,6 +18,7 @@ export class MainPanel extends AbstractPanel {
super(profile) super(profile)
this.element = document.createElement('div') this.element = document.createElement('div')
this.element.setAttribute('data-id', 'mainPanelPluginsContainer') this.element.setAttribute('data-id', 'mainPanelPluginsContainer')
this.element.setAttribute('style', 'height: 100%; width: 100%;')
// this.config = config // this.config = config
} }

@ -33,7 +33,7 @@ export class AbstractPanel extends HostPlugin {
profile: profile, profile: profile,
view: view, view: view,
active: false, active: false,
class: 'plugItIn' class: 'plugItIn active'
} }
} }

@ -1,15 +1,62 @@
import { Plugin } from '@remixproject/engine' import { Plugin } from '@remixproject/engine'
import { Profile } from '@remixproject/plugin-utils' import { Profile } from '@remixproject/plugin-utils'
import { EventEmitter } from 'events'
import { TabProxy } from './tab-proxy'
const EventManager = require('../../lib/events') const EventManager = require('../../lib/events')
const profile: Profile = { const profile: Profile = {
name: 'layout', name: 'layout',
description: 'layout' description: 'layout'
} }
interface panelState {
active: boolean
plugin: Plugin
}
interface panels {
tabs: panelState
editor: panelState
main: panelState
terminal: panelState
}
export class Layout extends Plugin { export class Layout extends Plugin {
event: any event: any
panels: panels
constructor() { constructor() {
super(profile) super(profile)
this.event = new EventManager() this.event = new EventEmitter()
}
onActivation(): void {
console.log('layout plugin activated')
this.on('fileManager', 'currentFileChanged', () => {
console.log('layout plugin currentFileChanged')
this.panels.editor.active = true
this.panels.main.active = false
this.event.emit('change', null)
})
this.on('tabs', 'openFile', () => {
console.log('layout plugin currentFileChanged')
this.panels.editor.active = true
this.panels.main.active = false
this.event.emit('change', null)
})
this.on('tabs', 'switchApp', (name: string) => {
console.log('layout plugin switchApp', name)
this.call('mainPanel', 'showContent', name)
this.panels.editor.active = false
this.panels.main.active = true
this.event.emit('change', null)
})
this.on('tabs', 'closeApp', (name: string) => {
console.log('layout plugin closeapp', name)
this.panels.editor.active = true
this.panels.main.active = false
this.event.emit('change', null)
})
this.on('tabs', 'tabCountChanged', (count) => {
// if (!count) this.editor.displayEmptyReadOnlySession()
})
} }
} }

@ -126,6 +126,9 @@ export class MainView {
self._view.editor.style.height = `${mainPanelHeight}px` self._view.editor.style.height = `${mainPanelHeight}px`
self._view.mainPanel.style.height = `${mainPanelHeight}px` self._view.mainPanel.style.height = `${mainPanelHeight}px`
self._view.terminal.style.height = `${delta}px` // - menu bar height self._view.terminal.style.height = `${delta}px` // - menu bar height
self._view.editor.height = `${mainPanelHeight}px`
self._view.mainPanel.height = `${mainPanelHeight}px`
self._view.terminal.height = `${delta}px` // - menu bar height
self.editor.resize((document.querySelector('#editorWrap') || {}).checked) self.editor.resize((document.querySelector('#editorWrap') || {}).checked)
self._components.terminal.scroll2bottom() self._components.terminal.scroll2bottom()
} }

@ -22,6 +22,7 @@ export class TabProxy extends Plugin {
this._view = {} this._view = {}
this._handlers = {} this._handlers = {}
this.loadedTabs = [] this.loadedTabs = []
this.el = document.createElement('div')
} }
onActivation () { onActivation () {
@ -72,10 +73,12 @@ export class TabProxy extends Plugin {
this.addTab(workspacePath, '', () => { this.addTab(workspacePath, '', () => {
this.fileManager.open(file) this.fileManager.open(file)
this.event.emit('openFile', file) this.event.emit('openFile', file)
this.emit('openFile', file)
}, },
() => { () => {
this.fileManager.closeFile(file) this.fileManager.closeFile(file)
this.event.emit('closeFile', file) this.event.emit('closeFile', file)
this.emit('closeFile', file)
}) })
this.tabsApi.activateTab(workspacePath) this.tabsApi.activateTab(workspacePath)
} else { } else {
@ -88,10 +91,12 @@ export class TabProxy extends Plugin {
this.addTab(path, '', () => { this.addTab(path, '', () => {
this.fileManager.open(file) this.fileManager.open(file)
this.event.emit('openFile', file) this.event.emit('openFile', file)
this.emit('openFile', file)
}, },
() => { () => {
this.fileManager.closeFile(file) this.fileManager.closeFile(file)
this.event.emit('closeFile', file) this.event.emit('closeFile', file)
this.emit('closeFile', file)
}) })
this.tabsApi.activateTab(path) this.tabsApi.activateTab(path)
} }
@ -132,9 +137,9 @@ export class TabProxy extends Plugin {
this.addTab( this.addTab(
name, name,
displayName, displayName,
() => this.event.emit('switchApp', name), () => this.emit('switchApp', name),
() => { () => {
this.event.emit('closeApp', name) this.emit('closeApp', name)
this.call('manager', 'deactivatePlugin', name) this.call('manager', 'deactivatePlugin', name)
}, },
icon icon
@ -149,7 +154,7 @@ export class TabProxy extends Plugin {
} }
focus (name) { focus (name) {
this.event.emit('switchApp', name) this.emit('switchApp', name)
this.tabsApi.activateTab(name) this.tabsApi.activateTab(name)
} }
@ -199,11 +204,13 @@ export class TabProxy extends Plugin {
() => { () => {
this.fileManager.closeFile(newName) this.fileManager.closeFile(newName)
this.event.emit('closeFile', newName) this.event.emit('closeFile', newName)
this.emit('closeFile', newName)
}) })
this.removeTab(oldName) this.removeTab(oldName)
} }
addTab (name, title, switchTo, close, icon) { addTab (name, title, switchTo, close, icon) {
console.log('add tab', name)
if (this._handlers[name]) return this.renderComponent() if (this._handlers[name]) return this.renderComponent()
var slash = name.split('/') var slash = name.split('/')
@ -281,11 +288,12 @@ export class TabProxy extends Plugin {
} }
renderComponent () { renderComponent () {
const onSelect = (index) => { const onSelect = (index) => {
if (this.loadedTabs[index]) { if (this.loadedTabs[index]) {
const name = this.loadedTabs[index].name const name = this.loadedTabs[index].name
if (this._handlers[name]) this._handlers[name].switchTo() if (this._handlers[name]) this._handlers[name].switchTo()
this.event.emit('tabCountChanged', this.loadedTabs.length) this.emit('tabCountChanged', this.loadedTabs.length)
} }
} }
@ -293,7 +301,7 @@ export class TabProxy extends Plugin {
if (this.loadedTabs[index]) { if (this.loadedTabs[index]) {
const name = this.loadedTabs[index].name const name = this.loadedTabs[index].name
if (this._handlers[name]) this._handlers[name].close() if (this._handlers[name]) this._handlers[name].close()
this.event.emit('tabCountChanged', this.loadedTabs.length) this.emit('tabCountChanged', this.loadedTabs.length)
} }
} }
@ -308,8 +316,7 @@ export class TabProxy extends Plugin {
} }
renderTabsbar () { renderTabsbar () {
this.el = document.createElement('div')
this.renderComponent()
return this.el return this.el
} }
} }

@ -1,5 +1,5 @@
import React from 'react' import React from 'react'
const AppContext = React.createContext(null) const AppContext = React.createContext<{layout: any, settings: any, showMatamo: boolean, appManager: any}>(null)
export default AppContext export default AppContext

@ -70,7 +70,7 @@ const RemixApp = (props: IRemixAppUi) => {
} }
return ( return (
<AppContext.Provider value={{ settings: props.app.settings, showMatamo: props.app.showMatamo, appManager: props.app.appManager, panels: props.app.panels }}> <AppContext.Provider value={{ settings: props.app.settings, showMatamo: props.app.showMatamo, appManager: props.app.appManager, layout: props.app.layout }}>
<RemixSplashScreen hide={appReady}></RemixSplashScreen> <RemixSplashScreen hide={appReady}></RemixSplashScreen>
<AlertModal></AlertModal> <AlertModal></AlertModal>
<MatomoDialog hide={!appReady}></MatomoDialog> <MatomoDialog hide={!appReady}></MatomoDialog>

@ -1,52 +1,78 @@
import AppContext from 'libs/remix-ui/app/src/lib/remix-app/context/context' import AppContext from 'libs/remix-ui/app/src/lib/remix-app/context/context'
import { editor } from 'monaco-editor'
import React, { useContext, useEffect, useRef, useState } from 'react' // eslint-disable-line import React, { useContext, useEffect, useRef, useState } from 'react' // eslint-disable-line
import RemixUIPanelPlugin from '../plugins/panel-plugin'
import { PluginRecord } from '../types' import { PluginRecord } from '../types'
import './main-panel.css' import './main-panel.css'
const RemixUIMainPanel = () => { const RemixUIMainPanel = () => {
const appContext = useContext(AppContext) const appContext = useContext(AppContext)
const tabsRef = useRef<HTMLDivElement>(null) const [plugins, setPlugins] = useState<PluginRecord[]>([])
const editorRef = useRef<HTMLDivElement>(null)
const mainPanelRef = useRef<HTMLDivElement>(null) const mainPanelRef = useRef<HTMLDivElement>(null)
const tabsRef = useRef<HTMLDivElement>(null)
const terminalRef = useRef<HTMLDivElement>(null) const terminalRef = useRef<HTMLDivElement>(null)
const editorRef = useRef<HTMLDivElement>(null)
useEffect(() => { const refs = [tabsRef, editorRef, mainPanelRef, terminalRef]
console.log(appContext) const _adjustLayout = (delta: number) => {
const limitDown = 32
const containerHeight = window.innerHeight
const tmp = delta - limitDown
delta = tmp > 0 ? tmp : 0
let mainPanelHeight = containerHeight - delta
mainPanelHeight = mainPanelHeight < 0 ? 0 : mainPanelHeight
//self.editor.resize((document.querySelector('#editorWrap') || {}).checked)
editorRef.current?.setAttribute('style', `height: ${mainPanelHeight}px`)
terminalRef.current?.setAttribute('style', `height: ${delta}px`)
mainPanelRef.current?.setAttribute('style', `height: ${mainPanelHeight}px`)
// appContext.panels.editor.resize((document.querySelector('#editorWrap') || {}).checked)
appContext.layout.panels.terminal.plugin.scroll2bottom()
}
const renderPanels = () => {
//console.log(appContext)
if (appContext) { if (appContext) {
console.log(appContext) console.log(appContext)
tabsRef.current.appendChild(appContext.panels.tabs.renderTabsbar()) const pluginPanels: PluginRecord[] = []
editorRef.current.appendChild(appContext.panels.editor.render()) Object.values(appContext.layout.panels).map((panel: any) => {
mainPanelRef.current.appendChild(appContext.panels.main.render()) pluginPanels.push({
terminalRef.current.appendChild(appContext.panels.terminal.render()) profile: panel.plugin.profile,
console.log(appContext.panels.main.render()) active: panel.active,
view: panel.plugin.profile.name === 'tabs' ? panel.plugin.renderTabsbar(): panel.plugin.render(),
const plugins: PluginRecord[] = [ class: panel.plugin.profile.name
{ })
profile: appContext.panels.tabs.profile, })
active: true, // console.log(pluginPanels)
view: appContext.panels.tabs.renderTabsbar() setPlugins(pluginPanels)
}
]
}
}, [])
const components = { appContext.layout.panels.terminal.plugin.event.register('resize', (delta: number) =>
tabs: <div ref={tabsRef}></div>, _adjustLayout(delta)
editor: <div ref={editorRef}></div>, )
main: <div ref={mainPanelRef}></div>, }
terminal: <div ref={terminalRef}></div>
} }
useEffect(() => {
renderPanels()
console.log(appContext.layout)
appContext.layout.event.on('change',() => {
console.log('change')
renderPanels()
})
}, [])
return (
return (<div className='mainview'> <div className="mainview">
{ components.tabs } {Object.values(plugins).map((pluginRecord, i) => {
{ components.editor } return (
{ components.main } <RemixUIPanelPlugin
{ components.terminal } ref={refs[i]}
</div>) key={pluginRecord.profile.name}
pluginRecord={pluginRecord}
/>
)
})}
</div>
)
} }
export default RemixUIMainPanel export default RemixUIMainPanel

@ -1,26 +1,37 @@
import React, { useEffect, useRef, useState } from 'react' // eslint-disable-line import React, { forwardRef, useEffect, useRef, useState } from 'react' // eslint-disable-line
import { PluginRecord } from '../types' import { PluginRecord } from '../types'
import './panel.css' import './panel.css'
interface panelPLuginProps { interface panelPLuginProps {
pluginRecord: PluginRecord pluginRecord: PluginRecord
} }
const RemixUIPanelPlugin = (props: panelPLuginProps) => { const RemixUIPanelPlugin = (props: panelPLuginProps, panelRef: any) => {
const PanelRef = useRef<HTMLDivElement>(null) const localRef = useRef<HTMLDivElement>(null)
const [view, setView] = useState<JSX.Element | HTMLDivElement>() const [view, setView] = useState<JSX.Element | HTMLDivElement>()
useEffect(() => { useEffect(() => {
if (PanelRef.current) { console.log(panelRef)
const ref:any = panelRef? panelRef : localRef
if (ref.current) {
if (props.pluginRecord.view) { if (props.pluginRecord.view) {
if (React.isValidElement(props.pluginRecord.view)) { if (React.isValidElement(props.pluginRecord.view)) {
setView(props.pluginRecord.view) setView(props.pluginRecord.view)
} else { } else {
PanelRef.current.appendChild(props.pluginRecord.view) ref.current.appendChild(props.pluginRecord.view)
} }
} }
} }
}, []) }, [])
return <div className={props.pluginRecord.active ? `${props.pluginRecord.class} active` : 'd-none'} ref={PanelRef}>{view}</div> return (
<div
className={
props.pluginRecord.active ? `${props.pluginRecord.class}` : 'd-none'
}
ref={panelRef || localRef}
>
{view}
</div>
)
} }
export default RemixUIPanelPlugin export default forwardRef(RemixUIPanelPlugin)

@ -80,3 +80,17 @@ iframe {
height: 100%; height: 100%;
overflow-y: hidden; overflow-y: hidden;
} }
#editorView {
height: 100%;
width: 100%;
border: 0;
display: block;
}
#mainPanel {
height: 100%;
width: 100%;
border: 0;
display: block;
}

438
package-lock.json generated

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save