Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 88 additions & 1 deletion apps/remix-ide/src/app/components/right-side-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@ export class RightSidePanel extends AbstractPanel {
highlightStamp: number
hiddenPlugin: any
isHidden: boolean
isMaximized: boolean
maximizedState: { leftPanelHidden: boolean, terminalPanelHidden: boolean }

constructor() {
super(rightSidePanel)
this.isMaximized = false
this.maximizedState = { leftPanelHidden: false, terminalPanelHidden: false }
}

onActivation() {
Expand All @@ -40,6 +44,27 @@ export class RightSidePanel extends AbstractPanel {
}
})

// Listen for terminal panel being shown - auto-restore right panel if maximized
this.on('terminal', 'terminalPanelShown', () => {
if (this.isMaximized) {
this.maximizePanel() // This will toggle and restore the panel
}
})

// Listen for file changes - auto-restore right panel if maximized when main panel is used
this.on('fileManager', 'currentFileChanged', () => {
if (this.isMaximized) {
this.maximizePanel() // This will toggle and restore the panel
}
})

// Listen for tab/app switches - auto-restore right panel if maximized (includes home tab, file tabs, etc.)
this.on('tabs', 'switchApp', () => {
if (this.isMaximized) {
this.maximizePanel() // This will toggle and restore the panel
}
})

// Initialize isHidden state from panelStates in localStorage
const panelStatesStr = window.localStorage.getItem('panelStates')
const panelStates = panelStatesStr ? JSON.parse(panelStatesStr) : {}
Expand Down Expand Up @@ -225,6 +250,68 @@ export class RightSidePanel extends AbstractPanel {
return this.isHidden
}

async maximizePanel() {
if (!this.isMaximized) {
// Store the current state of panels before maximizing
const leftPanelHidden = await this.call('sidePanel', 'isPanelHidden')
const terminalPanelHidden = await this.call('terminal', 'isPanelHidden')

this.maximizedState = { leftPanelHidden, terminalPanelHidden }

// Hide left panel if it's visible
if (!leftPanelHidden) {
await this.call('sidePanel', 'togglePanel')
}

// Hide terminal panel if it's visible
if (!terminalPanelHidden) {
await this.call('terminal', 'togglePanel')
}

// Hide main panel (center panel with editor)
const mainPanel = document.querySelector('#main-panel')
mainPanel?.classList.add('d-none')

// Make right panel take full width
const rightPanel = document.querySelector('#right-side-panel')
rightPanel?.classList.add('right-panel-maximized')

this.isMaximized = true
trackMatomoEvent(this, { category: 'topbar', action: 'rightSidePanel', name: 'maximized', isClick: false })
this.emit('rightSidePanelMaximized')
this.events.emit('rightSidePanelMaximized')
} else {
// Restore panels to their previous state
const leftPanelHidden = await this.call('sidePanel', 'isPanelHidden')
const terminalPanelHidden = await this.call('terminal', 'isPanelHidden')

// Restore left panel if it was visible before maximizing
if (!this.maximizedState.leftPanelHidden && leftPanelHidden) {
await this.call('sidePanel', 'togglePanel')
}

// Restore terminal panel if it was visible before maximizing
if (!this.maximizedState.terminalPanelHidden && terminalPanelHidden) {
await this.call('terminal', 'togglePanel')
}

// Show main panel
const mainPanel = document.querySelector('#main-panel')
mainPanel?.classList.remove('d-none')

// Remove full width from right panel
const rightPanel = document.querySelector('#right-side-panel')
rightPanel?.classList.remove('right-panel-maximized')

this.isMaximized = false
trackMatomoEvent(this, { category: 'topbar', action: 'rightSidePanel', name: 'restored', isClick: false })
this.emit('rightSidePanelRestored')
this.events.emit('rightSidePanelRestored')
}

this.renderComponent()
}

highlight () {
// If the right side panel is hidden, unhide it when a pinned icon is clicked
if (this.isHidden) {
Expand Down Expand Up @@ -262,7 +349,7 @@ export class RightSidePanel extends AbstractPanel {
}

updateComponent(state: any) {
return <RemixPluginPanel header={<RemixUIPanelHeader plugins={state.plugins} pinView={this.pinView.bind(this)} unPinView={this.unPinView.bind(this)} togglePanel={this.togglePanel.bind(this)}></RemixUIPanelHeader>} { ...state } />
return <RemixPluginPanel header={<RemixUIPanelHeader plugins={state.plugins} pinView={this.pinView.bind(this)} unPinView={this.unPinView.bind(this)} togglePanel={this.togglePanel.bind(this)} maximizePanel={this.maximizePanel.bind(this)} isMaximized={this.isMaximized}></RemixUIPanelHeader>} { ...state } />
}

renderComponent() {
Expand Down
4 changes: 4 additions & 0 deletions libs/remix-ui/app/src/lib/remix-app/style/remix-app.css
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ pre {
transition : width 0.25s;
padding-bottom : 1.4rem;
}
.right-panel-maximized {
width : 100% !important;
flex : 1;
}
.highlightcode {
position : absolute;
z-index : 20;
Expand Down
17 changes: 16 additions & 1 deletion libs/remix-ui/panel/src/lib/plugins/panel-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ export interface RemixPanelProps {
plugins: Record<string, PluginRecord>,
pinView?: (profile: PluginRecord['profile'], view: PluginRecord['view']) => void,
unPinView?: (profile: PluginRecord['profile']) => void,
togglePanel?: () => void
togglePanel?: () => void,
maximizePanel?: () => void,
isMaximized?: boolean
}
const RemixUIPanelHeader = (props: RemixPanelProps) => {
const [plugin, setPlugin] = useState<PluginRecord>()
Expand Down Expand Up @@ -45,6 +47,10 @@ const RemixUIPanelHeader = (props: RemixPanelProps) => {
props.togglePanel && props.togglePanel()
}

const maximizePanelHandler = () => {
props.maximizePanel && props.maximizePanel()
}

const tooltipChild = <i className={`px-1 ms-2 pt-1 pb-2 ${!toggleExpander ? 'fas fa-angle-right' : 'fas fa-angle-down bg-light'}`} aria-hidden="true"></i>

const FilePanelHeading = () => {
Expand Down Expand Up @@ -99,6 +105,15 @@ const RemixUIPanelHeader = (props: RemixPanelProps) => {
<div className="codicon codicon-layout-sidebar-left-dock ms-2 fs-6 fw-bold lh-1" style={{ marginTop: '2px' }}></div>
</CustomTooltip>
</div>
<CustomTooltip placement="bottom-end" tooltipText={props.isMaximized ? "Minimize Panel" : "Maximize Panel"}>
<div
className="codicon-screen-icon ms-2"
onClick={maximizePanelHandler}
data-id="maximizeRightSidePanel"
>
{props.isMaximized ? '\ueb4d' : '\ueb4c' /* Actual icons were not being rendered, so used unicode for codicon-screen-full & codicon-screen-normal icons*/ }
</div>
</CustomTooltip>
<CustomTooltip placement="bottom-end" tooltipText="Hide Panel">
<div
className="codicon codicon-close ms-2 fs-5 fw-bold"
Expand Down
18 changes: 18 additions & 0 deletions libs/remix-ui/panel/src/lib/plugins/panel.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,24 @@
flex: auto;
}

@font-face {
font-family: 'codicon-vscode';
font-display: block;
src: url('~@vscode/codicons/dist/codicon.ttf') format('truetype');
}

.codicon-screen-icon {
font: normal normal normal 20px/1 'codicon-vscode';
display: inline-block;
text-decoration: none;
text-rendering: auto;
text-align: center;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
user-select: none;
cursor: pointer;
}

.swapitTitle {
margin: 0;
text-transform: uppercase;
Expand Down