import * as React from 'react'; import useOnMessage, { HandleMessageCallback, OnMarkForDownloadCallback } from './hooks/useOnMessage'; import { useRef, useCallback } from 'react'; import { View, ViewStyle } from 'react-native'; import ExtendedWebView from '../ExtendedWebView'; import { WebViewControl } from '../ExtendedWebView/types'; import useOnResourceLongPress from './hooks/useOnResourceLongPress'; import useRerenderHandler, { ResourceInfo } from './hooks/useRerenderHandler'; import useSource from './hooks/useSource'; import { PluginStates } from '@joplin/lib/services/plugins/reducer'; import { MarkupLanguage } from '@joplin/renderer'; import shim from '@joplin/lib/shim'; import CommandService from '@joplin/lib/services/CommandService'; import { AppState } from '../../utils/types'; import { connect } from 'react-redux'; import useWebViewSetup from '../../contentScripts/rendererBundle/useWebViewSetup'; interface Props { themeId: number; style: ViewStyle; fontSize: number; noteBody: string; noteMarkupLanguage: MarkupLanguage; highlightedKeywords: string[]; noteResources: Record; paddingBottom: number; initialScroll: number|null; noteHash: string; onCheckboxChange?: HandleMessageCallback; onRequestEditResource?: HandleMessageCallback; onMarkForDownload?: OnMarkForDownloadCallback; onScroll: (scrollTop: number)=> void; onLoadEnd?: ()=> void; pluginStates: PluginStates; } const onJoplinLinkClick = async (message: string) => { try { await CommandService.instance().execute('openItem', message); } catch (error) { await shim.showErrorDialog(error.message); } }; function NoteBodyViewer(props: Props) { const webviewRef = useRef(null); const onScroll = useCallback(async (scrollTop: number) => { props.onScroll(scrollTop); }, [props.onScroll]); const onResourceLongPress = useOnResourceLongPress( { onJoplinLinkClick, onRequestEditResource: props.onRequestEditResource, }, ); const onPostMessage = useOnMessage(props.noteBody, { onMarkForDownload: props.onMarkForDownload, onJoplinLinkClick, onRequestEditResource: props.onRequestEditResource, onCheckboxChange: props.onCheckboxChange, onResourceLongPress, }); const { api: renderer, pageSetup, webViewEventHandlers } = useWebViewSetup({ webviewRef, onBodyScroll: onScroll, onPostMessage, pluginStates: props.pluginStates, themeId: props.themeId, }); useRerenderHandler({ renderer, fontSize: props.fontSize, noteBody: props.noteBody, noteMarkupLanguage: props.noteMarkupLanguage, themeId: props.themeId, highlightedKeywords: props.highlightedKeywords, noteResources: props.noteResources, noteHash: props.noteHash, initialScroll: props.initialScroll, paddingBottom: props.paddingBottom, }); const onLoadEnd = useCallback(() => { webViewEventHandlers.onLoadEnd(); if (props.onLoadEnd) props.onLoadEnd(); }, [props.onLoadEnd, webViewEventHandlers]); const { html, js } = useSource(pageSetup, props.themeId); return ( ); } export default connect((state: AppState) => ({ themeId: state.settings.theme, fontSize: state.settings['style.viewer.fontSize'], pluginStates: state.pluginService.plugins, }))(NoteBodyViewer);