|
|
|
@ -1,8 +1,51 @@
|
|
|
|
|
import React, { useEffect, useRef, useState } from 'react';
|
|
|
|
|
import { t } from 'tailchat-shared';
|
|
|
|
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|
|
|
|
import { buildRegFn, t } from 'tailchat-shared';
|
|
|
|
|
import { withKeepAliveOverlay } from './KeepAliveOverlay';
|
|
|
|
|
import { Loading } from './Loading';
|
|
|
|
|
|
|
|
|
|
interface WebviewKernelProps {
|
|
|
|
|
className?: string;
|
|
|
|
|
src: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 内置的默认webview渲染容器
|
|
|
|
|
*/
|
|
|
|
|
const DefaultWebviewKernel: React.FC<WebviewKernelProps> = React.memo(
|
|
|
|
|
(props) => {
|
|
|
|
|
const ref = useRef<HTMLIFrameElement>(null);
|
|
|
|
|
const [spinning, setSpinning] = useState(true);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const callback = () => {
|
|
|
|
|
setSpinning(false);
|
|
|
|
|
};
|
|
|
|
|
ref.current?.addEventListener('load', callback);
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
ref.current?.removeEventListener('load', callback);
|
|
|
|
|
};
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Loading
|
|
|
|
|
spinning={spinning}
|
|
|
|
|
className="w-full h-full"
|
|
|
|
|
tip={t('加载网页中...')}
|
|
|
|
|
>
|
|
|
|
|
<iframe {...props} ref={ref} />
|
|
|
|
|
</Loading>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
DefaultWebviewKernel.displayName = 'DefaultWebviewKernel';
|
|
|
|
|
|
|
|
|
|
const [getWebviewKernel, setWebviewKernel] = buildRegFn<
|
|
|
|
|
() => React.ComponentType<WebviewKernelProps>
|
|
|
|
|
>('webviewKernelComponent', () => DefaultWebviewKernel);
|
|
|
|
|
|
|
|
|
|
export { setWebviewKernel };
|
|
|
|
|
|
|
|
|
|
interface WebviewProps {
|
|
|
|
|
className?: string;
|
|
|
|
|
style?: React.CSSProperties;
|
|
|
|
@ -13,29 +56,9 @@ interface WebviewProps {
|
|
|
|
|
* 网页渲染容器
|
|
|
|
|
*/
|
|
|
|
|
export const Webview: React.FC<WebviewProps> = (props) => {
|
|
|
|
|
const ref = useRef<HTMLIFrameElement>(null);
|
|
|
|
|
const [spinning, setSpinning] = useState(true);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const callback = () => {
|
|
|
|
|
setSpinning(false);
|
|
|
|
|
};
|
|
|
|
|
ref.current?.addEventListener('load', callback);
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
ref.current?.removeEventListener('load', callback);
|
|
|
|
|
};
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Loading
|
|
|
|
|
spinning={spinning}
|
|
|
|
|
className="w-full h-full"
|
|
|
|
|
tip={t('加载网页中...')}
|
|
|
|
|
>
|
|
|
|
|
<iframe ref={ref} className="w-full h-full" src={props.url} />
|
|
|
|
|
</Loading>
|
|
|
|
|
);
|
|
|
|
|
const KernelComponent = useMemo(() => getWebviewKernel(), []);
|
|
|
|
|
|
|
|
|
|
return <KernelComponent className="w-full h-full" src={props.url} />;
|
|
|
|
|
};
|
|
|
|
|
Webview.displayName = 'Webview';
|
|
|
|
|
|
|
|
|
|