diff --git a/src/main/preload.ts b/src/main/preload.ts index e274836..1287cb2 100644 --- a/src/main/preload.ts +++ b/src/main/preload.ts @@ -5,7 +5,8 @@ import { contextBridge, ipcRenderer, IpcRendererEvent } from 'electron'; export type Channels = | 'mount-webview' | 'update-webview-rect' - | 'clear-webview'; + | 'hide-all-webview' + | 'clear-all-webview'; const electronHandler = { ipcRenderer: { diff --git a/src/main/webviewManager.ts b/src/main/webviewManager.ts index 54c62c9..f9ccf43 100644 --- a/src/main/webviewManager.ts +++ b/src/main/webviewManager.ts @@ -1,6 +1,11 @@ import { BrowserView, BrowserWindow, ipcMain, Rectangle } from 'electron'; -const webviewMap = new Map(); +interface WebviewInfo { + view: BrowserView; + hidden: boolean; +} + +const webviewMap = new Map(); /** * fix rect into correct size @@ -16,6 +21,8 @@ function fixRect(rect: Rectangle): Rectangle { export function initWebviewManager(win: BrowserWindow) { ipcMain.on('mount-webview', (e, info) => { + console.log('[mount-webview] info:', info); + const key = info.key; const url = info.url; if (!url) { @@ -23,12 +30,12 @@ export function initWebviewManager(win: BrowserWindow) { } if (webviewMap.has(key)) { - win.setTopBrowserView(webviewMap.get(key)!); + const webview = webviewMap.get(key)!; + win.setTopBrowserView(webview.view); + webview.view.setBounds(fixRect(info.rect)); return; } - console.log('[mount-webview] info:', info); - const view = new BrowserView({ webPreferences: { nodeIntegration: false, @@ -37,19 +44,27 @@ export function initWebviewManager(win: BrowserWindow) { win.addBrowserView(view); view.setBounds(fixRect(info.rect)); view.webContents.loadURL(url); - webviewMap.set(key, view); + webviewMap.set(key, { view, hidden: false }); }); ipcMain.on('update-webview-rect', (e, info) => { console.log('[update-webview-rect] info:', info); - Array.from(webviewMap.values()).forEach((view) => { + Array.from(webviewMap.values()).forEach(({ view }) => { view.setBounds(fixRect(info.rect)); }); }); - ipcMain.on('clear-webview', (e) => { - console.log('[clear-webview]'); + ipcMain.on('hide-all-webview', (e) => { + console.log('[hide-all-webview]'); + + Array.from(webviewMap.values()).forEach((webview) => { + hideWebView(webview); + }); + }); + + ipcMain.on('clear-all-webview', (e) => { + console.log('[clear-all-webview]'); win.getBrowserViews().forEach((view) => { win.removeBrowserView(view); @@ -58,3 +73,37 @@ export function initWebviewManager(win: BrowserWindow) { webviewMap.clear(); }); } + +const HIDDEN_OFFSET = 3000; + +/** + * Show webview with remove offset in y + */ +function showWebView(webview: WebviewInfo) { + if (webview.hidden === false) { + return; + } + + webview.hidden = false; + const oldBounds = webview.view.getBounds(); + webview.view.setBounds({ + ...oldBounds, + y: oldBounds.y - HIDDEN_OFFSET, + }); +} + +/** + * Hide webview with append offset in y + */ +function hideWebView(webview: WebviewInfo) { + if (webview.hidden === true) { + return; + } + + webview.hidden = true; + const oldBounds = webview.view.getBounds(); + webview.view.setBounds({ + ...oldBounds, + y: oldBounds.y + HIDDEN_OFFSET, + }); +} diff --git a/src/renderer/components/ClearWebsiteBtn.tsx b/src/renderer/components/ClearWebsiteBtn.tsx index 63c2206..43bfab4 100644 --- a/src/renderer/components/ClearWebsiteBtn.tsx +++ b/src/renderer/components/ClearWebsiteBtn.tsx @@ -11,7 +11,7 @@ export const ClearWebsiteBtn: React.FC = React.memo(() => { long={true} onClick={() => { setSelectedNode(null); - window.electron.ipcRenderer.sendMessage('clear-webview'); + window.electron.ipcRenderer.sendMessage('clear-all-webview'); }} > Clear Website diff --git a/src/renderer/components/SideTree.tsx b/src/renderer/components/SideTree.tsx index 7c59f88..c3188c1 100644 --- a/src/renderer/components/SideTree.tsx +++ b/src/renderer/components/SideTree.tsx @@ -5,6 +5,7 @@ import { generateFakeNode, WebsiteTreeNode, useTreeStore } from '../store/tree'; import { AddWebsiteBtn } from './AddWebsiteBtn'; import styled from 'styled-components'; import { ClearWebsiteBtn } from './ClearWebsiteBtn'; +import { stopPropagation } from '../utils/dom'; const StyledTree = styled(Tree)` margin-top: 0.5rem; @@ -64,7 +65,8 @@ export const SideTree: React.FC = React.memo(() => { { + onClick={(e) => { + stopPropagation(e); if (props.dataRef && props.dataRef.key) { deleteTreeNode(props.dataRef.key); } diff --git a/src/renderer/store/tree.ts b/src/renderer/store/tree.ts index 6b567a1..0b9182c 100644 --- a/src/renderer/store/tree.ts +++ b/src/renderer/store/tree.ts @@ -139,6 +139,10 @@ export const useTreeStore = create()( }, deleteTreeNode: (key: string) => { set((state) => { + if (state.selectedNode && state.selectedNode.key === key) { + state.selectedNode = null; + } + deleteTreeNode(state.treeData, key); }); }, diff --git a/src/renderer/utils/dom.ts b/src/renderer/utils/dom.ts new file mode 100644 index 0000000..ce3a6fe --- /dev/null +++ b/src/renderer/utils/dom.ts @@ -0,0 +1,6 @@ +// react stopPropagation +export function stopPropagation(e: React.BaseSyntheticEvent) { + if (e && e.stopPropagation) { + e.stopPropagation(); + } +}