You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-07-03 23:50:33 +02:00
Chore: Refactor mobile plugin logic into locations more consistent with other parts of the app (#10636)
This commit is contained in:
@ -0,0 +1,132 @@
|
||||
import * as React from 'react';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { PluginHtmlContents, ViewInfo } from '@joplin/lib/services/plugins/reducer';
|
||||
import ExtendedWebView, { WebViewControl } from '../../../components/ExtendedWebView';
|
||||
import { ViewStyle } from 'react-native';
|
||||
import usePlugin from '@joplin/lib/hooks/usePlugin';
|
||||
import shim from '@joplin/lib/shim';
|
||||
import useDialogMessenger from './hooks/useDialogMessenger';
|
||||
import useWebViewSetup from './hooks/useWebViewSetup';
|
||||
import { DialogWebViewApi } from '../types';
|
||||
|
||||
interface Props {
|
||||
themeId: number;
|
||||
pluginHtmlContents: PluginHtmlContents;
|
||||
viewInfo: ViewInfo;
|
||||
style: ViewStyle;
|
||||
onLoadEnd: ()=> void;
|
||||
setDialogControl: (dialogControl: DialogWebViewApi)=> void;
|
||||
}
|
||||
|
||||
const PluginUserWebView = (props: Props) => {
|
||||
const viewInfo = props.viewInfo;
|
||||
const view = viewInfo.view;
|
||||
const pluginId = viewInfo.plugin.id;
|
||||
const viewId = view.id;
|
||||
const plugin = usePlugin(pluginId);
|
||||
const [webViewLoadCount, setWebViewLoadCount] = useState(0);
|
||||
|
||||
const webviewRef = useRef<WebViewControl>(null);
|
||||
|
||||
const messageChannelId = `dialog-messenger-${pluginId}-${viewId}`;
|
||||
const messenger = useDialogMessenger({
|
||||
pluginId,
|
||||
viewId,
|
||||
webviewRef,
|
||||
messageChannelId,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
// Because of how messenger.remoteApi handles message forwarding (property names
|
||||
// are not known), we need to send methods individually and can't use an object
|
||||
// spread or send messenger.remoteApi.
|
||||
props.setDialogControl({
|
||||
includeCssFiles: messenger.remoteApi.includeCssFiles,
|
||||
includeJsFiles: messenger.remoteApi.includeJsFiles,
|
||||
setThemeCss: messenger.remoteApi.setThemeCss,
|
||||
getFormData: messenger.remoteApi.getFormData,
|
||||
getContentSize: messenger.remoteApi.getContentSize,
|
||||
});
|
||||
}, [messenger, props.setDialogControl]);
|
||||
|
||||
useWebViewSetup({
|
||||
themeId: props.themeId,
|
||||
dialogControl: messenger.remoteApi,
|
||||
scriptPaths: view.scripts ?? [],
|
||||
pluginBaseDir: plugin.baseDir,
|
||||
webViewLoadCount,
|
||||
});
|
||||
|
||||
const htmlContent = props.pluginHtmlContents[pluginId]?.[viewId] ?? '';
|
||||
const html = `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
|
||||
<title>Plugin Dialog</title>
|
||||
<style>
|
||||
body {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
color: var(--joplin-color);
|
||||
|
||||
/* -apple-system-body allows for correct font scaling on iOS devices */
|
||||
font: -apple-system-body;
|
||||
font-family: var(--joplin-font-family, sans-serif);
|
||||
}
|
||||
|
||||
/* We need "display: flex" in order to accurately get the content size */
|
||||
/* including margin and padding of children */
|
||||
#joplin-plugin-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="joplin-plugin-content">
|
||||
${htmlContent}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
const injectedJs = useMemo(() => {
|
||||
return `
|
||||
if (!window.backgroundPageLoaded) {
|
||||
${shim.injectedJs('pluginBackgroundPage')}
|
||||
pluginBackgroundPage.initializeDialogWebView(
|
||||
${JSON.stringify(messageChannelId)}
|
||||
);
|
||||
|
||||
window.backgroundPageLoaded = true;
|
||||
}
|
||||
`;
|
||||
}, [messageChannelId]);
|
||||
|
||||
const onWebViewLoaded = useCallback(() => {
|
||||
setWebViewLoadCount(webViewLoadCount + 1);
|
||||
props.onLoadEnd();
|
||||
messenger.onWebViewLoaded();
|
||||
}, [messenger, setWebViewLoadCount, webViewLoadCount, props.onLoadEnd]);
|
||||
|
||||
return (
|
||||
<ExtendedWebView
|
||||
style={props.style}
|
||||
baseDirectory={plugin.baseDir}
|
||||
webviewInstanceId='joplin__PluginDialogWebView'
|
||||
html={html}
|
||||
hasPluginScripts={true}
|
||||
injectedJavaScript={injectedJs}
|
||||
onMessage={messenger.onWebViewMessage}
|
||||
onLoadEnd={onWebViewLoaded}
|
||||
ref={webviewRef}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default PluginUserWebView;
|
Reference in New Issue
Block a user