Skip to content

Commit

Permalink
switch to external panel library
Browse files Browse the repository at this point in the history
  • Loading branch information
aolsenjazz committed Jan 14, 2024
1 parent fe0e37f commit 54b9e23
Show file tree
Hide file tree
Showing 23 changed files with 421 additions and 43 deletions.
16 changes: 16 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
"react": "^18.2.0",
"react-compound-slider": "^3.4.0",
"react-dom": "^18.2.0",
"react-resizable-panels": "^0.0.55",
"react-router-dom": "^6.4.0",
"react-tooltip": "^5.7.5",
"regenerator-runtime": "^0.13.9"
Expand Down
7 changes: 7 additions & 0 deletions src/main/ipc-channels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,10 @@ export const TRANSLATOR = {
GET_TRANSLATOR_OVERRIDE: 'get-translator-override',
REQUEST_OVERRIDES: 'request-overrides',
};

export const LAYOUT = {
GET_LAYOUT: 'get-layout',
SET_LAYOUT: 'set-layout',
GET_LAYOUT_ITEM: 'get-layout-item',
SET_LAYOUT_ITEM: 'set-layout-item',
};
19 changes: 18 additions & 1 deletion src/main/ipc-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import { SupportedDeviceConfig } from '@shared/hardware-config';

import { ProjectProvider as pp } from './project-provider';
import { wp } from './window-provider';
import { HOST, CONFIG } from './ipc-channels';
import { HOST, CONFIG, LAYOUT } from './ipc-channels';
import { LayoutParams, Store } from './store';

const { MainWindow } = wp;

Expand Down Expand Up @@ -52,3 +53,19 @@ ipcMain.on(
}
}
);

ipcMain.on(LAYOUT.GET_LAYOUT, (e: Event) => {
e.returnValue = Store.getLayoutParams();
});

ipcMain.on(LAYOUT.SET_LAYOUT, (e: Event, lp: LayoutParams) => {
e.returnValue = Store.setLayoutParams(lp);
});

ipcMain.on(LAYOUT.GET_LAYOUT_ITEM, (e: Event, s: string) => {
e.returnValue = Store.getLayoutItem(s);
});

ipcMain.on(LAYOUT.SET_LAYOUT_ITEM, (e: Event, s: string, v: string) => {
e.returnValue = Store.setLayoutItem(s, v);
});
27 changes: 27 additions & 0 deletions src/main/preload/preload-layout-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ipcRenderer } from 'electron';

import { LayoutParams } from '../store';
import { LAYOUT } from '../ipc-channels';

/**
* Expose functions to store layout parameters in between session
*/
export const layoutService = {
getLayoutParams(): LayoutParams {
return ipcRenderer.sendSync(LAYOUT.GET_LAYOUT);
},

setLayoutParams(lp: LayoutParams): void {
return ipcRenderer.sendSync(LAYOUT.SET_LAYOUT, lp);
},

getItem(s: string): string | null {
return ipcRenderer.sendSync(LAYOUT.GET_LAYOUT_ITEM, s);
},

setItem(s: string, v: string): void {
return ipcRenderer.sendSync(LAYOUT.SET_LAYOUT_ITEM, s, v);
},
};

export type LayoutService = typeof layoutService;
2 changes: 2 additions & 0 deletions src/main/preload/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { contextBridge, ipcRenderer } from 'electron';

import { configService } from './preload-config-service';
import { hostService } from './preload-host-service';
import { layoutService } from './preload-layout-service';

// the frontend uses a lot of listeners. because of this, this number gets
// pretty high. If it complains, make sure that we're not leaking memory,
Expand All @@ -16,3 +17,4 @@ ipcRenderer.setMaxListeners(1000);

contextBridge.exposeInMainWorld('ConfigService', configService);
contextBridge.exposeInMainWorld('HostService', hostService);
contextBridge.exposeInMainWorld('LayoutService', layoutService);
39 changes: 39 additions & 0 deletions src/main/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import ElectronStore from 'electron-store';

const store = new ElectronStore();

type PanelParams = {
open: boolean;
};

export type LayoutParams = {
leftPanel: PanelParams;
rightPanel: PanelParams;
};

export const Store = {
getLayoutItem(s: string) {
return store.get(s);
},

setLayoutItem(s: string, v: string) {
store.set(s, v);
},

getLayoutParams(): LayoutParams {
const defaultLayoutParams = {
leftPanel: {
show: true,
},
rightPanel: {
show: true,
},
};

return (store.get('layout') as LayoutParams) || defaultLayoutParams;
},

setLayoutParams(lp: LayoutParams) {
store.set('layout', lp);
},
};
23 changes: 10 additions & 13 deletions src/renderer/App.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { DeviceProvider } from '@context/selected-device-context';
import { SelectedInputsProvider } from '@context/selected-inputs-context';
import { PanelProvider } from '@context/panel-context';

import TitleBar from './components/TitleBar';
import DeviceList from './components/DeviceList';
import DevicePanel from './components/DevicePanel';
import ConfigPanel from './components/ConfigPanel';

import './styles/App.global.css';
import MainContent from './components/MainContent';

/**
* When dragging a file over a chrome window, normally the cursor will change to indicate
Expand All @@ -20,15 +19,13 @@ document.body.ondragover = (event) => {

export default function App() {
return (
<DeviceProvider>
<SelectedInputsProvider>
<TitleBar />
<div id="main-content">
<DeviceList />
<DevicePanel />
<ConfigPanel />
</div>
</SelectedInputsProvider>
</DeviceProvider>
<PanelProvider>
<DeviceProvider>
<SelectedInputsProvider>
<TitleBar />
<MainContent />
</SelectedInputsProvider>
</DeviceProvider>
</PanelProvider>
);
}
11 changes: 11 additions & 0 deletions src/renderer/assets/drawer_left_closed.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/renderer/assets/drawer_left_open.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/renderer/assets/drawer_right_closed.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/renderer/assets/drawer_right_open.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
93 changes: 93 additions & 0 deletions src/renderer/components/MainContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { useEffect, useRef } from 'react';
import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';

import { PanelState, usePanels } from '@context/panel-context';

import DeviceList from './DeviceList';
import ConfigPanel from './ConfigPanel';
import DevicePanel from './DevicePanel';

type ImperativePanelActions = {
collapse: () => void;
expand: () => void;
};

function usePanelEffect(
panelRef: React.MutableRefObject<null>,
panelState: PanelState
) {
useEffect(() => {
const { collapsed, requiresUpdate } = panelState;
const ref = panelRef.current;
if (ref && collapsed && requiresUpdate) {
(ref as ImperativePanelActions).collapse();
} else if (ref && !collapsed && requiresUpdate) {
(ref as ImperativePanelActions).expand();
}
}, [panelRef, panelState]);
}

const { LayoutService } = window;

export default function MainContent() {
const { panel1State, setPanel1, panel2State, setPanel2 } = usePanels();

const deviceListPanelRef = useRef(null);
const configPanelRef = useRef(null);

usePanelEffect(deviceListPanelRef, panel1State);
usePanelEffect(configPanelRef, panel2State);

return (
<div id="main-content">
<PanelGroup
direction="horizontal"
className="main-content"
storage={LayoutService}
autoSaveId="main-content"
disablePointerEventsDuringResize
>
<Panel
minSize={25}
defaultSize={25}
maxSize={50}
ref={deviceListPanelRef}
id="device-list"
onCollapse={(collapsed) => setPanel1(collapsed, false)}
collapsible
>
<DeviceList />
</Panel>
<PanelResizeHandle
className="drag-handle"
style={{
borderRight: '1px solid #dbd4d1',
backgroundColor: '#f4f0f1',
}}
/>
<Panel minSize={25} id="main" order={1}>
<DevicePanel />
</Panel>
<PanelResizeHandle
className="drag-handle"
style={{
borderLeft: '1px solid #dbd4d1',
backgroundColor: '#f4f0f1',
}}
/>
<Panel
minSize={30}
ref={configPanelRef}
maxSize={50}
defaultSize={25}
id="history"
order={2}
onCollapse={(collapsed) => setPanel2(collapsed, false)}
collapsible
>
<ConfigPanel />
</Panel>
</PanelGroup>
</div>
);
}
28 changes: 28 additions & 0 deletions src/renderer/components/TitleBar/DrawerToggles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import DrawerRightClosed from '@assets/drawer_right_closed.svg';
import DrawerRightOpen from '@assets/drawer_right_open.svg';
import DrawerLeftClosed from '@assets/drawer_left_closed.svg';
import DrawerLeftOpen from '@assets/drawer_left_open.svg';
import { usePanels } from '../../context/panel-context';

export default function DrawerToggles() {
const { panel1State, setPanel1, panel2State, setPanel2 } = usePanels();

return (
<div className="drawer-toggles">
<img
src={panel1State.collapsed ? DrawerLeftClosed : DrawerLeftOpen}
alt={panel1State.collapsed ? 'close left drawer' : 'show left drawer'}
onClick={() => setPanel1(!panel1State.collapsed, true)}
height="18"
role="presentation"
/>
<img
src={panel2State.collapsed ? DrawerRightClosed : DrawerRightOpen}
alt={panel2State.collapsed ? 'close right drawer' : 'show right drawer'}
height={18}
onClick={() => setPanel2(!panel2State.collapsed, true)}
role="presentation"
/>
</div>
);
}
Loading

0 comments on commit 54b9e23

Please sign in to comment.