Move frontmatter extraction from renderer to redux (#1413)

This commit is contained in:
Erik Michelson 2021-09-02 11:15:31 +02:00 committed by GitHub
parent 7fb7c55877
commit 04e16d8880
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 680 additions and 589 deletions

View file

@ -4,7 +4,7 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import React, { Ref, useCallback, useMemo, useRef, useState } from 'react'
import React, { Ref, useCallback, useMemo, useRef } from 'react'
import { DocumentLengthLimitReachedAlert } from './document-length-limit-reached-alert'
import { useConvertMarkdownToReactDom } from './hooks/use-convert-markdown-to-react-dom'
import './markdown-renderer.scss'
@ -12,7 +12,6 @@ import { ComponentReplacer } from './replace-components/ComponentReplacer'
import { AdditionalMarkdownRendererProps, LineMarkerPosition } from './types'
import { useComponentReplacers } from './hooks/use-component-replacers'
import { useTranslation } from 'react-i18next'
import { NoteFrontmatter, RawNoteFrontmatter } from '../editor-page/note-frontmatter/note-frontmatter'
import { LineMarkers } from './replace-components/linemarker/line-number-marker'
import { useCalculateLineMarkerPosition } from './utils/calculate-line-marker-positions'
import { useExtractFirstHeadline } from './hooks/use-extract-first-headline'
@ -20,7 +19,6 @@ import { TocAst } from 'markdown-it-toc-done-right'
import { useOnRefChange } from './hooks/use-on-ref-change'
import { BasicMarkdownItConfigurator } from './markdown-it-configurator/BasicMarkdownItConfigurator'
import { ImageClickHandler } from './replace-components/image/image-replacer'
import { InvalidYamlAlert } from './invalid-yaml-alert'
import { useTrimmedContent } from './hooks/use-trimmed-content'
export interface BasicMarkdownRendererProps {
@ -29,79 +27,57 @@ export interface BasicMarkdownRendererProps {
onAfterRendering?: () => void
onFirstHeadingChange?: (firstHeading: string | undefined) => void
onLineMarkerPositionChanged?: (lineMarkerPosition: LineMarkerPosition[]) => void
onFrontmatterChange?: (frontmatter: NoteFrontmatter | undefined) => void
onTaskCheckedChange?: (lineInMarkdown: number, checked: boolean) => void
onTocChange?: (ast?: TocAst) => void
baseUrl?: string
onImageClick?: ImageClickHandler
outerContainerRef?: Ref<HTMLDivElement>
useAlternativeBreaks?: boolean
frontmatterLineOffset?: number
}
export const BasicMarkdownRenderer: React.FC<BasicMarkdownRendererProps & AdditionalMarkdownRendererProps> = ({
className,
content,
additionalReplacers,
onBeforeRendering,
onAfterRendering,
onFirstHeadingChange,
onLineMarkerPositionChanged,
onFrontmatterChange,
onTaskCheckedChange,
onTocChange,
baseUrl,
onImageClick,
outerContainerRef,
useAlternativeBreaks
useAlternativeBreaks,
frontmatterLineOffset
}) => {
const rawMetaRef = useRef<RawNoteFrontmatter>()
const markdownBodyRef = useRef<HTMLDivElement>(null)
const currentLineMarkers = useRef<LineMarkers[]>()
const hasNewYamlError = useRef(false)
const tocAst = useRef<TocAst>()
const [showYamlError, setShowYamlError] = useState(false)
const [trimmedContent, contentExceedsLimit] = useTrimmedContent(content)
const markdownIt = useMemo(
() =>
new BasicMarkdownItConfigurator({
useFrontmatter: !!onFrontmatterChange,
onParseError: (errorState) => (hasNewYamlError.current = errorState),
onRawMetaChange: (rawMeta) => (rawMetaRef.current = rawMeta),
onToc: (toc) => (tocAst.current = toc),
onLineMarkers:
onLineMarkerPositionChanged === undefined
? undefined
: (lineMarkers) => (currentLineMarkers.current = lineMarkers),
useAlternativeBreaks
useAlternativeBreaks,
offsetLines: frontmatterLineOffset
}).buildConfiguredMarkdownIt(),
[onFrontmatterChange, onLineMarkerPositionChanged, useAlternativeBreaks]
[onLineMarkerPositionChanged, useAlternativeBreaks, frontmatterLineOffset]
)
const clearFrontmatter = useCallback(() => {
hasNewYamlError.current = false
rawMetaRef.current = undefined
onBeforeRendering?.()
}, [onBeforeRendering])
const checkYamlErrorState = useCallback(() => {
setShowYamlError(hasNewYamlError.current)
onAfterRendering?.()
}, [onAfterRendering])
const baseReplacers = useComponentReplacers(onTaskCheckedChange, onImageClick, baseUrl)
const baseReplacers = useComponentReplacers(onTaskCheckedChange, onImageClick, baseUrl, frontmatterLineOffset)
const replacers = useCallback(
() => baseReplacers().concat(additionalReplacers ? additionalReplacers() : []),
[additionalReplacers, baseReplacers]
)
const markdownReactDom = useConvertMarkdownToReactDom(
trimmedContent,
markdownIt,
replacers,
clearFrontmatter,
checkYamlErrorState
)
const markdownReactDom = useConvertMarkdownToReactDom(trimmedContent, markdownIt, replacers)
useTranslation()
useCalculateLineMarkerPosition(
@ -112,17 +88,9 @@ export const BasicMarkdownRenderer: React.FC<BasicMarkdownRendererProps & Additi
)
useExtractFirstHeadline(markdownBodyRef, content, onFirstHeadingChange)
useOnRefChange(tocAst, onTocChange)
useOnRefChange(rawMetaRef, (newValue) => {
if (!newValue) {
onFrontmatterChange?.(undefined)
} else {
onFrontmatterChange?.(new NoteFrontmatter(newValue))
}
})
return (
<div ref={outerContainerRef} className={'position-relative'}>
<InvalidYamlAlert show={showYamlError} />
<DocumentLengthLimitReachedAlert show={contentExceedsLimit} />
<div
ref={markdownBodyRef}