mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-22 16:48:23 +01:00
webview fixes (#83)
This commit is contained in:
parent
f1c8d63ab2
commit
4d4e026749
@ -281,6 +281,12 @@ function createBrowserWindow(clientId: string, waveWindow: WaveWindow): WaveBrow
|
|||||||
});
|
});
|
||||||
win.webContents.on("will-navigate", shNavHandler);
|
win.webContents.on("will-navigate", shNavHandler);
|
||||||
win.webContents.on("will-frame-navigate", shFrameNavHandler);
|
win.webContents.on("will-frame-navigate", shFrameNavHandler);
|
||||||
|
win.webContents.on("did-attach-webview", (event, wc) => {
|
||||||
|
wc.setWindowOpenHandler((details) => {
|
||||||
|
win.webContents.send("webview-new-window", wc.id, details);
|
||||||
|
return { action: "deny" };
|
||||||
|
});
|
||||||
|
});
|
||||||
win.on(
|
win.on(
|
||||||
"resize",
|
"resize",
|
||||||
debounce(400, (e) => mainResizeHandler(e, waveWindow.oid, win))
|
debounce(400, (e) => mainResizeHandler(e, waveWindow.oid, win))
|
||||||
@ -418,10 +424,21 @@ electron.ipcMain.on("isDevServer", (event) => {
|
|||||||
event.returnValue = isDevServer;
|
event.returnValue = isDevServer;
|
||||||
});
|
});
|
||||||
|
|
||||||
electron.ipcMain.on("getPlatform", (event) => {
|
electron.ipcMain.on("getPlatform", (event, url) => {
|
||||||
event.returnValue = unamePlatform;
|
event.returnValue = unamePlatform;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Listen for the open-external event from the renderer process
|
||||||
|
electron.ipcMain.on("open-external", (event, url) => {
|
||||||
|
if (url && typeof url === "string") {
|
||||||
|
electron.shell.openExternal(url).catch((err) => {
|
||||||
|
console.error(`Failed to open URL ${url}:`, err);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.error("Invalid URL received in open-external event:", url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
electron.ipcMain.on("download", (event, payload) => {
|
electron.ipcMain.on("download", (event, payload) => {
|
||||||
const window = electron.BrowserWindow.fromWebContents(event.sender);
|
const window = electron.BrowserWindow.fromWebContents(event.sender);
|
||||||
const baseName = payload.filePath.split(/[\\/]/).pop();
|
const baseName = payload.filePath.split(/[\\/]/).pop();
|
||||||
@ -535,7 +552,6 @@ async function appMain() {
|
|||||||
}
|
}
|
||||||
const ready = await waveSrvReady;
|
const ready = await waveSrvReady;
|
||||||
console.log("wavesrv ready signal received", ready, Date.now() - startTs, "ms");
|
console.log("wavesrv ready signal received", ready, Date.now() - startTs, "ms");
|
||||||
|
|
||||||
console.log("get client data");
|
console.log("get client data");
|
||||||
let clientData = await services.ClientService.GetClientData();
|
let clientData = await services.ClientService.GetClientData();
|
||||||
console.log("client data ready");
|
console.log("client data ready");
|
||||||
|
@ -12,4 +12,17 @@ contextBridge.exposeInMainWorld("api", {
|
|||||||
showContextMenu: (menu, position) => ipcRenderer.send("contextmenu-show", menu, position),
|
showContextMenu: (menu, position) => ipcRenderer.send("contextmenu-show", menu, position),
|
||||||
onContextMenuClick: (callback) => ipcRenderer.on("contextmenu-click", callback),
|
onContextMenuClick: (callback) => ipcRenderer.on("contextmenu-click", callback),
|
||||||
downloadFile: (filePath) => ipcRenderer.send("download", { filePath }),
|
downloadFile: (filePath) => ipcRenderer.send("download", { filePath }),
|
||||||
|
openExternal: (url) => {
|
||||||
|
if (url && typeof url === "string") {
|
||||||
|
ipcRenderer.send("open-external", url);
|
||||||
|
} else {
|
||||||
|
console.error("Invalid URL passed to openExternal:", url);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Custom event for "new-window"
|
||||||
|
ipcRenderer.on("webview-new-window", (e, webContentsId, details) => {
|
||||||
|
const event = new CustomEvent("new-window", { detail: details });
|
||||||
|
document.getElementById("webview").dispatchEvent(event);
|
||||||
});
|
});
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import { Button } from "@/app/element/button";
|
import { Button } from "@/app/element/button";
|
||||||
|
import { getApi } from "@/app/store/global";
|
||||||
import { WebviewTag } from "electron";
|
import { WebviewTag } from "electron";
|
||||||
import React, { useEffect, useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
@ -23,10 +24,15 @@ const WebView = ({ parentRef, initialUrl }: WebViewProps) => {
|
|||||||
const historyStack = useRef<string[]>([]);
|
const historyStack = useRef<string[]>([]);
|
||||||
const historyIndex = useRef<number>(-1);
|
const historyIndex = useRef<number>(-1);
|
||||||
|
|
||||||
useEffect(() => {
|
const getWebViewHeight = () => {
|
||||||
const inputHeight = inputRef.current?.getBoundingClientRect().height + 25;
|
const inputHeight = inputRef.current?.getBoundingClientRect().height;
|
||||||
const parentHeight = parentRef.current?.getBoundingClientRect().height;
|
const parentHeight = parentRef.current?.getBoundingClientRect().height;
|
||||||
setWebViewHeight(parentHeight - inputHeight);
|
return parentHeight - (inputHeight + 35);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const webviewHeight = getWebViewHeight();
|
||||||
|
setWebViewHeight(webviewHeight);
|
||||||
|
|
||||||
historyStack.current.push(initialUrl);
|
historyStack.current.push(initialUrl);
|
||||||
historyIndex.current = 0;
|
historyIndex.current = 0;
|
||||||
@ -57,8 +63,8 @@ const WebView = ({ parentRef, initialUrl }: WebViewProps) => {
|
|||||||
// Handle new-window event
|
// Handle new-window event
|
||||||
webview.addEventListener("new-window", (event: any) => {
|
webview.addEventListener("new-window", (event: any) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const newUrl = event.url;
|
const newUrl = event.detail.url;
|
||||||
webview.src = newUrl;
|
getApi().openExternal(newUrl);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Suppress errors
|
// Suppress errors
|
||||||
@ -100,21 +106,31 @@ const WebView = ({ parentRef, initialUrl }: WebViewProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleResize = () => {
|
const handleResize = () => {
|
||||||
const parentHeight = parentRef.current?.getBoundingClientRect().height;
|
const webviewHeight = getWebViewHeight();
|
||||||
setWebViewHeight(parentHeight);
|
setWebViewHeight(webviewHeight);
|
||||||
};
|
};
|
||||||
|
|
||||||
const parentElement = parentRef.current;
|
const parentElement = parentRef.current;
|
||||||
if (parentElement) {
|
if (parentElement) {
|
||||||
parentElement.addEventListener("keydown", handleKeyDown);
|
parentElement.addEventListener("keydown", handleKeyDown);
|
||||||
}
|
}
|
||||||
window.addEventListener("resize", handleResize);
|
|
||||||
|
// Use ResizeObserver to observe changes in the height of parentRef
|
||||||
|
const resizeObserver = new ResizeObserver((entries) => {
|
||||||
|
for (let entry of entries) {
|
||||||
|
if (entry.target === parentElement) {
|
||||||
|
handleResize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
resizeObserver.observe(parentElement);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (parentElement) {
|
if (parentElement) {
|
||||||
parentElement.removeEventListener("keydown", handleKeyDown);
|
parentElement.removeEventListener("keydown", handleKeyDown);
|
||||||
}
|
}
|
||||||
window.removeEventListener("resize", handleResize);
|
resizeObserver.disconnect();
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@ -221,7 +237,13 @@ const WebView = ({ parentRef, initialUrl }: WebViewProps) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<webview className="webview" ref={webviewRef} src={url} style={{ height: webViewHeight }}></webview>
|
<webview
|
||||||
|
id="webview"
|
||||||
|
className="webview"
|
||||||
|
ref={webviewRef}
|
||||||
|
src={url}
|
||||||
|
style={{ height: webViewHeight }}
|
||||||
|
></webview>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
1
frontend/types/custom.d.ts
vendored
1
frontend/types/custom.d.ts
vendored
@ -37,6 +37,7 @@ declare global {
|
|||||||
onNavigate: (callback: (url: string) => void) => void;
|
onNavigate: (callback: (url: string) => void) => void;
|
||||||
onIframeNavigate: (callback: (url: string) => void) => void;
|
onIframeNavigate: (callback: (url: string) => void) => void;
|
||||||
downloadFile: (path: string) => void;
|
downloadFile: (path: string) => void;
|
||||||
|
openExternal: (url: string) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ElectronContextMenuItem = {
|
type ElectronContextMenuItem = {
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
"base64-js": "^1.5.1",
|
"base64-js": "^1.5.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"dayjs": "^1.11.11",
|
"dayjs": "^1.11.11",
|
||||||
"electron": "^30.1.0",
|
"electron": "^31.1.0",
|
||||||
"html-to-image": "^1.11.11",
|
"html-to-image": "^1.11.11",
|
||||||
"immer": "^10.1.1",
|
"immer": "^10.1.1",
|
||||||
"jotai": "^2.8.0",
|
"jotai": "^2.8.0",
|
||||||
|
10
yarn.lock
10
yarn.lock
@ -6499,16 +6499,16 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"electron@npm:^30.1.0":
|
"electron@npm:^31.1.0":
|
||||||
version: 30.1.0
|
version: 31.1.0
|
||||||
resolution: "electron@npm:30.1.0"
|
resolution: "electron@npm:31.1.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@electron/get": "npm:^2.0.0"
|
"@electron/get": "npm:^2.0.0"
|
||||||
"@types/node": "npm:^20.9.0"
|
"@types/node": "npm:^20.9.0"
|
||||||
extract-zip: "npm:^2.0.1"
|
extract-zip: "npm:^2.0.1"
|
||||||
bin:
|
bin:
|
||||||
electron: cli.js
|
electron: cli.js
|
||||||
checksum: 10c0/e17c5fdf275f8cd457086adfa05db7507d08dd9264024d80eae8e55eb01927d062b63223a1a15b3ac024ebe2c34cc4b3ceb5cc0ac3ded4721c4ac9be4e5fe33c
|
checksum: 10c0/b9ae6f9d1a13e15cf0b7981f1231dc2c79f3465c4db822750daf6f2533524fe2ddf6f0b173c8d0c3549ef6bf21a9ff3eb362838b06deb4f795e71d5e5a307f16
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -12336,7 +12336,7 @@ __metadata:
|
|||||||
base64-js: "npm:^1.5.1"
|
base64-js: "npm:^1.5.1"
|
||||||
clsx: "npm:^2.1.1"
|
clsx: "npm:^2.1.1"
|
||||||
dayjs: "npm:^1.11.11"
|
dayjs: "npm:^1.11.11"
|
||||||
electron: "npm:^30.1.0"
|
electron: "npm:^31.1.0"
|
||||||
electron-vite: "npm:^2.2.0"
|
electron-vite: "npm:^2.2.0"
|
||||||
eslint: "npm:^9.2.0"
|
eslint: "npm:^9.2.0"
|
||||||
eslint-config-prettier: "npm:^9.1.0"
|
eslint-config-prettier: "npm:^9.1.0"
|
||||||
|
Loading…
Reference in New Issue
Block a user