Restructure Communicator (#1510)

Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Tilman Vatteroth 2021-09-26 11:09:46 +02:00 committed by GitHub
parent e6830598d5
commit f1e91b4574
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 680 additions and 569 deletions

View file

@ -3,18 +3,27 @@
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import equal from 'fast-deep-equal'
import React, { Fragment, useCallback, useEffect, useRef, useState } from 'react'
import { useApplicationState } from '../../../hooks/common/use-application-state'
import { useIsDarkModeActivated } from '../../../hooks/common/use-is-dark-mode-activated'
import { isTestMode } from '../../../utils/test-modes'
import { RendererProps } from '../../render-page/markdown-document'
import { ImageDetails, RendererType } from '../../render-page/rendering-message'
import { useIFrameEditorToRendererCommunicator } from '../render-context/iframe-editor-to-renderer-communicator-context-provider'
import { ScrollState } from '../synced-scroll/scroll-props'
import {
CommunicationMessageType,
OnFirstHeadingChangeMessage,
OnHeightChangeMessage,
OnTaskCheckboxChangeMessage,
RendererType,
SetScrollStateMessage
} from '../../render-page/window-post-message-communicator/rendering-message'
import { useEditorToRendererCommunicator } from '../render-context/editor-to-renderer-communicator-context-provider'
import { useOnIframeLoad } from './hooks/use-on-iframe-load'
import { ShowOnPropChangeImageLightbox } from './show-on-prop-change-image-lightbox'
import { CommunicatorImageLightbox } from './communicator-image-lightbox'
import { setRendererStatus } from '../../../redux/renderer-status/methods'
import { useEditorReceiveHandler } from '../../render-page/window-post-message-communicator/hooks/use-editor-receive-handler'
import { useIsRendererReady } from '../../render-page/window-post-message-communicator/hooks/use-is-renderer-ready'
import { useSendDarkModeStatusToRenderer } from './hooks/use-send-dark-mode-status-to-renderer'
import { useSendMarkdownToRenderer } from './hooks/use-send-markdown-to-renderer'
import { useSendScrollState } from './hooks/use-send-scroll-state'
export interface RenderIframeProps extends RendererProps {
rendererType: RendererType
@ -33,16 +42,12 @@ export const RenderIframe: React.FC<RenderIframeProps> = ({
rendererType,
forcedDarkMode
}) => {
const savedDarkMode = useIsDarkModeActivated()
const darkMode = forcedDarkMode ?? savedDarkMode
const [lightboxDetails, setLightboxDetails] = useState<ImageDetails | undefined>(undefined)
const frameReference = useRef<HTMLIFrameElement>(null)
const frontmatterInfo = useApplicationState((state) => state.noteDetails.frontmatterRendererInfo)
const rendererOrigin = useApplicationState((state) => state.config.iframeCommunication.rendererOrigin)
const renderPageUrl = `${rendererOrigin}render`
const resetRendererReady = useCallback(() => setRendererStatus(false), [])
const iframeCommunicator = useIFrameEditorToRendererCommunicator()
const iframeCommunicator = useEditorToRendererCommunicator()
const rendererReady = useIsRendererReady()
const onIframeLoad = useOnIframeLoad(
frameReference,
iframeCommunicator,
@ -52,8 +57,6 @@ export const RenderIframe: React.FC<RenderIframeProps> = ({
)
const [frameHeight, setFrameHeight] = useState<number>(0)
const rendererReady = useApplicationState((state) => state.rendererStatus.rendererReady)
useEffect(
() => () => {
iframeCommunicator.unregisterEventListener()
@ -62,76 +65,59 @@ export const RenderIframe: React.FC<RenderIframeProps> = ({
[iframeCommunicator]
)
useEffect(() => {
iframeCommunicator.onFirstHeadingChange(onFirstHeadingChange)
return () => iframeCommunicator.onFirstHeadingChange(undefined)
}, [iframeCommunicator, onFirstHeadingChange])
useEditorReceiveHandler(
CommunicationMessageType.ON_FIRST_HEADING_CHANGE,
useCallback(
(values: OnFirstHeadingChangeMessage) => onFirstHeadingChange?.(values.firstHeading),
[onFirstHeadingChange]
)
)
useEffect(() => {
iframeCommunicator.onSetScrollState(onScroll)
return () => iframeCommunicator.onSetScrollState(undefined)
}, [iframeCommunicator, onScroll])
useEditorReceiveHandler(
CommunicationMessageType.SET_SCROLL_STATE,
useCallback((values: SetScrollStateMessage) => onScroll?.(values.scrollState), [onScroll])
)
useEffect(() => {
iframeCommunicator.onSetScrollSourceToRenderer(onMakeScrollSource)
return () => iframeCommunicator.onSetScrollSourceToRenderer(undefined)
}, [iframeCommunicator, onMakeScrollSource])
useEditorReceiveHandler(
CommunicationMessageType.SET_SCROLL_SOURCE_TO_RENDERER,
useCallback(() => onMakeScrollSource?.(), [onMakeScrollSource])
)
useEffect(() => {
iframeCommunicator.onTaskCheckboxChange(onTaskCheckedChange)
return () => iframeCommunicator.onTaskCheckboxChange(undefined)
}, [iframeCommunicator, onTaskCheckedChange])
useEditorReceiveHandler(
CommunicationMessageType.ON_TASK_CHECKBOX_CHANGE,
useCallback(
(values: OnTaskCheckboxChangeMessage) => onTaskCheckedChange?.(values.lineInMarkdown, values.checked),
[onTaskCheckedChange]
)
)
useEffect(() => {
iframeCommunicator.onImageClicked(setLightboxDetails)
return () => iframeCommunicator.onImageClicked(undefined)
}, [iframeCommunicator])
useEditorReceiveHandler(
CommunicationMessageType.ON_HEIGHT_CHANGE,
useCallback((values: OnHeightChangeMessage) => setFrameHeight?.(values.height), [setFrameHeight])
)
useEffect(() => {
iframeCommunicator.onHeightChange(setFrameHeight)
return () => iframeCommunicator.onHeightChange(undefined)
}, [iframeCommunicator])
useEffect(() => {
iframeCommunicator.onRendererReady(() => {
iframeCommunicator.sendSetBaseConfiguration({
baseUrl: window.location.toString(),
rendererType
useEditorReceiveHandler(
CommunicationMessageType.RENDERER_READY,
useCallback(() => {
iframeCommunicator.enableCommunication()
iframeCommunicator.sendMessageToOtherSide({
type: CommunicationMessageType.SET_BASE_CONFIGURATION,
baseConfiguration: {
baseUrl: window.location.toString(),
rendererType
}
})
setRendererStatus(true)
})
return () => iframeCommunicator.onRendererReady(undefined)
}, [iframeCommunicator, rendererType])
}, [iframeCommunicator, rendererType])
)
useEffect(() => {
if (rendererReady) {
iframeCommunicator.sendSetDarkmode(darkMode)
}
}, [darkMode, iframeCommunicator, rendererReady])
const oldScrollState = useRef<ScrollState | undefined>(undefined)
useEffect(() => {
if (rendererReady && !equal(scrollState, oldScrollState.current)) {
oldScrollState.current = scrollState
iframeCommunicator.sendScrollState(scrollState)
}
}, [iframeCommunicator, rendererReady, scrollState])
useEffect(() => {
if (rendererReady) {
iframeCommunicator.sendSetMarkdownContent(markdownContent)
}
}, [iframeCommunicator, markdownContent, rendererReady])
useEffect(() => {
if (rendererReady && frontmatterInfo !== undefined) {
iframeCommunicator.sendSetFrontmatterInfo(frontmatterInfo)
}
}, [iframeCommunicator, rendererReady, frontmatterInfo])
useSendScrollState(scrollState)
useSendDarkModeStatusToRenderer(forcedDarkMode)
useSendMarkdownToRenderer(markdownContent)
return (
<Fragment>
<ShowOnPropChangeImageLightbox details={lightboxDetails} />
<CommunicatorImageLightbox />
<iframe
style={{ height: `${frameHeight}px` }}
data-cy={'documentIframe'}