mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-10-19 05:40:16 -04:00
Add context for iframe communicator in editor page (#1146)
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
6e43ec99a3
commit
af887877aa
3 changed files with 58 additions and 27 deletions
|
@ -4,7 +4,7 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { Fragment, useCallback, useRef, useState } from 'react'
|
import React, { useCallback, useMemo, useRef, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
import { useApplyDarkMode } from '../../hooks/common/use-apply-dark-mode'
|
import { useApplyDarkMode } from '../../hooks/common/use-apply-dark-mode'
|
||||||
|
@ -34,6 +34,7 @@ import { RendererType } from '../render-page/rendering-message'
|
||||||
import { useEditorModeFromUrl } from './hooks/useEditorModeFromUrl'
|
import { useEditorModeFromUrl } from './hooks/useEditorModeFromUrl'
|
||||||
import { UiNotifications } from '../notifications/ui-notifications'
|
import { UiNotifications } from '../notifications/ui-notifications'
|
||||||
import { useNotificationTest } from './use-notification-test'
|
import { useNotificationTest } from './use-notification-test'
|
||||||
|
import { IframeCommunicatorContextProvider } from './render-context/iframe-communicator-context-provider'
|
||||||
|
|
||||||
export interface EditorPagePathParams {
|
export interface EditorPagePathParams {
|
||||||
id: string
|
id: string
|
||||||
|
@ -86,31 +87,16 @@ export const EditorPage: React.FC = () => {
|
||||||
|
|
||||||
useNotificationTest()
|
useNotificationTest()
|
||||||
|
|
||||||
return (
|
const leftPane = useMemo(() =>
|
||||||
<Fragment>
|
|
||||||
<UiNotifications/>
|
|
||||||
<MotdBanner/>
|
|
||||||
<div className={ 'd-flex flex-column vh-100' }>
|
|
||||||
<AppBar mode={ AppBarMode.EDITOR }/>
|
|
||||||
|
|
||||||
<div className={ 'container' }>
|
|
||||||
<ErrorWhileLoadingNoteAlert show={ error }/>
|
|
||||||
<LoadingNoteAlert show={ loading }/>
|
|
||||||
</div>
|
|
||||||
<ShowIf condition={ !error && !loading }>
|
|
||||||
<div className={ 'flex-fill d-flex h-100 w-100 overflow-hidden flex-row' }>
|
|
||||||
<Splitter
|
|
||||||
showLeft={ editorMode === EditorMode.EDITOR || editorMode === EditorMode.BOTH }
|
|
||||||
left={
|
|
||||||
<EditorPane
|
<EditorPane
|
||||||
onContentChange={ setNoteMarkdownContent }
|
onContentChange={ setNoteMarkdownContent }
|
||||||
content={ markdownContent }
|
content={ markdownContent }
|
||||||
scrollState={ scrollState.editorScrollState }
|
scrollState={ scrollState.editorScrollState }
|
||||||
onScroll={ onEditorScroll }
|
onScroll={ onEditorScroll }
|
||||||
onMakeScrollSource={ setEditorToScrollSource }/>
|
onMakeScrollSource={ setEditorToScrollSource }/>
|
||||||
}
|
, [markdownContent, onEditorScroll, scrollState.editorScrollState, setEditorToScrollSource])
|
||||||
showRight={ editorMode === EditorMode.PREVIEW || editorMode === EditorMode.BOTH }
|
|
||||||
right={
|
const rightPane = useMemo(() =>
|
||||||
<RenderIframe
|
<RenderIframe
|
||||||
frameClasses={ 'h-100 w-100' }
|
frameClasses={ 'h-100 w-100' }
|
||||||
markdownContent={ markdownContent }
|
markdownContent={ markdownContent }
|
||||||
|
@ -121,13 +107,33 @@ export const EditorPage: React.FC = () => {
|
||||||
onScroll={ onMarkdownRendererScroll }
|
onScroll={ onMarkdownRendererScroll }
|
||||||
scrollState={ scrollState.rendererScrollState }
|
scrollState={ scrollState.rendererScrollState }
|
||||||
rendererType={ RendererType.DOCUMENT }/>
|
rendererType={ RendererType.DOCUMENT }/>
|
||||||
}
|
, [markdownContent, onMarkdownRendererScroll, scrollState.rendererScrollState,
|
||||||
|
setRendererToScrollSource])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IframeCommunicatorContextProvider>
|
||||||
|
<UiNotifications/>
|
||||||
|
<MotdBanner/>
|
||||||
|
<div className={ 'd-flex flex-column vh-100' }>
|
||||||
|
<AppBar mode={ AppBarMode.EDITOR }/>
|
||||||
|
<div className={ 'container' }>
|
||||||
|
<ErrorWhileLoadingNoteAlert show={ error }/>
|
||||||
|
<LoadingNoteAlert show={ loading }/>
|
||||||
|
</div>
|
||||||
|
<ShowIf condition={ !error && !loading }>
|
||||||
|
<div className={ 'flex-fill d-flex h-100 w-100 overflow-hidden flex-row' }>
|
||||||
|
<Splitter
|
||||||
|
showLeft={ editorMode === EditorMode.EDITOR || editorMode === EditorMode.BOTH }
|
||||||
|
left={ leftPane }
|
||||||
|
showRight={ editorMode === EditorMode.PREVIEW || editorMode === EditorMode.BOTH }
|
||||||
|
right={ rightPane }
|
||||||
containerClassName={ 'overflow-hidden' }/>
|
containerClassName={ 'overflow-hidden' }/>
|
||||||
<Sidebar/>
|
<Sidebar/>
|
||||||
</div>
|
</div>
|
||||||
</ShowIf>
|
</ShowIf>
|
||||||
</div>
|
</div>
|
||||||
</Fragment>
|
</IframeCommunicatorContextProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default EditorPage
|
export default EditorPage
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { useContext, useMemo } from 'react'
|
||||||
|
import { IframeEditorToRendererCommunicator } from '../../render-page/iframe-editor-to-renderer-communicator'
|
||||||
|
|
||||||
|
const IFrameEditorToRendererCommunicatorContext = React.createContext<IframeEditorToRendererCommunicator | undefined>(undefined)
|
||||||
|
|
||||||
|
export const useIFrameCommunicator: () => IframeEditorToRendererCommunicator | undefined = () => useContext(IFrameEditorToRendererCommunicatorContext)
|
||||||
|
|
||||||
|
export const useContextOrStandaloneIframeCommunicator: () => IframeEditorToRendererCommunicator = () => {
|
||||||
|
const contextCommunicator = useIFrameCommunicator()
|
||||||
|
return useMemo(() => contextCommunicator ? contextCommunicator : new IframeEditorToRendererCommunicator(), [contextCommunicator])
|
||||||
|
}
|
||||||
|
|
||||||
|
export const IframeCommunicatorContextProvider: React.FC = ({ children }) => {
|
||||||
|
const currentIFrameCommunicator = useMemo<IframeEditorToRendererCommunicator>(() => new IframeEditorToRendererCommunicator(), [])
|
||||||
|
|
||||||
|
return <IFrameEditorToRendererCommunicatorContext.Provider value={ currentIFrameCommunicator }>
|
||||||
|
{ children }
|
||||||
|
</IFrameEditorToRendererCommunicatorContext.Provider>
|
||||||
|
}
|
|
@ -4,14 +4,14 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
import equal from 'fast-deep-equal'
|
import equal from 'fast-deep-equal'
|
||||||
import React, { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import React, { Fragment, useCallback, useEffect, useRef, useState } from 'react'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
import { useIsDarkModeActivated } from '../../../hooks/common/use-is-dark-mode-activated'
|
import { useIsDarkModeActivated } from '../../../hooks/common/use-is-dark-mode-activated'
|
||||||
import { ApplicationState } from '../../../redux'
|
import { ApplicationState } from '../../../redux'
|
||||||
import { isTestMode } from '../../../utils/is-test-mode'
|
import { isTestMode } from '../../../utils/is-test-mode'
|
||||||
import { IframeEditorToRendererCommunicator } from '../../render-page/iframe-editor-to-renderer-communicator'
|
|
||||||
import { RendererProps } from '../../render-page/markdown-document'
|
import { RendererProps } from '../../render-page/markdown-document'
|
||||||
import { ImageDetails, RendererType } from '../../render-page/rendering-message'
|
import { ImageDetails, RendererType } from '../../render-page/rendering-message'
|
||||||
|
import { useContextOrStandaloneIframeCommunicator } from '../render-context/iframe-communicator-context-provider'
|
||||||
import { ScrollState } from '../synced-scroll/scroll-props'
|
import { ScrollState } from '../synced-scroll/scroll-props'
|
||||||
import { useOnIframeLoad } from './hooks/use-on-iframe-load'
|
import { useOnIframeLoad } from './hooks/use-on-iframe-load'
|
||||||
import { ShowOnPropChangeImageLightbox } from './show-on-prop-change-image-lightbox'
|
import { ShowOnPropChangeImageLightbox } from './show-on-prop-change-image-lightbox'
|
||||||
|
@ -46,7 +46,7 @@ export const RenderIframe: React.FC<RenderIframeProps> = (
|
||||||
const rendererOrigin = useSelector((state: ApplicationState) => state.config.iframeCommunication.rendererOrigin)
|
const rendererOrigin = useSelector((state: ApplicationState) => state.config.iframeCommunication.rendererOrigin)
|
||||||
const renderPageUrl = `${ rendererOrigin }/render`
|
const renderPageUrl = `${ rendererOrigin }/render`
|
||||||
const resetRendererReady = useCallback(() => setRendererReady(false), [])
|
const resetRendererReady = useCallback(() => setRendererReady(false), [])
|
||||||
const iframeCommunicator = useMemo(() => new IframeEditorToRendererCommunicator(), [])
|
const iframeCommunicator = useContextOrStandaloneIframeCommunicator()
|
||||||
const onIframeLoad = useOnIframeLoad(frameReference, iframeCommunicator, rendererOrigin, renderPageUrl, resetRendererReady)
|
const onIframeLoad = useOnIframeLoad(frameReference, iframeCommunicator, rendererOrigin, renderPageUrl, resetRendererReady)
|
||||||
const [frameHeight, setFrameHeight] = useState<number>(0)
|
const [frameHeight, setFrameHeight] = useState<number>(0)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue