cherry-studio/src/renderer/src/components/MinApp/WebviewContainer.tsx

87 lines
2.4 KiB
TypeScript

import { WebviewTag } from 'electron'
import { memo, useEffect, useRef } from 'react'
/**
* WebviewContainer is a component that renders a webview element.
* It is used in the MinAppPopupContainer component.
* The webcontent can be remain in memory
*/
const WebviewContainer = memo(
({
appid,
url,
onSetRefCallback,
onLoadedCallback,
onNavigateCallback
}: {
appid: string
url: string
onSetRefCallback: (appid: string, element: WebviewTag | null) => void
onLoadedCallback: (appid: string) => void
onNavigateCallback: (appid: string, url: string) => void
}) => {
const webviewRef = useRef<WebviewTag | null>(null)
const setRef = (appid: string) => {
onSetRefCallback(appid, null)
return (element: WebviewTag | null) => {
onSetRefCallback(appid, element)
if (element) {
webviewRef.current = element
} else {
webviewRef.current = null
}
}
}
useEffect(() => {
if (!webviewRef.current) return
const handleLoaded = () => {
onLoadedCallback(appid)
}
const handleNavigate = (event: any) => {
onNavigateCallback(appid, event.url)
}
webviewRef.current.addEventListener('did-finish-load', handleLoaded)
webviewRef.current.addEventListener('did-navigate-in-page', handleNavigate)
// we set the url when the webview is ready
webviewRef.current.src = url
return () => {
webviewRef.current?.removeEventListener('did-finish-load', handleLoaded)
webviewRef.current?.removeEventListener('did-navigate-in-page', handleNavigate)
}
// because the appid and url are enough, no need to add onLoadedCallback
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [appid, url])
//remove the tag of CherryStudio and Electron
const userAgent = navigator.userAgent.replace(/CherryStudio\/\S+\s/, '').replace(/Electron\/\S+\s/, '')
return (
<webview
key={appid}
ref={setRef(appid)}
style={WebviewStyle}
allowpopups={'true' as any}
partition="persist:webview"
useragent={userAgent}
/>
)
}
)
const WebviewStyle: React.CSSProperties = {
width: 'calc(100vw - var(--sidebar-width))',
height: 'calc(100vh - var(--navbar-height))',
backgroundColor: 'var(--color-background)',
display: 'inline-flex'
}
export default WebviewContainer