mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-23 11:37:02 -04:00
Move frontmatter extraction from renderer to redux (#1413)
This commit is contained in:
parent
7fb7c55877
commit
04e16d8880
34 changed files with 680 additions and 589 deletions
|
@ -14,7 +14,7 @@ import { EditorViewMode } from './editor-view-mode'
|
|||
import { HelpButton } from './help-button/help-button'
|
||||
import { NavbarBranding } from './navbar-branding'
|
||||
import { SyncScrollButtons } from './sync-scroll-buttons/sync-scroll-buttons'
|
||||
import { NoteType } from '../note-frontmatter/note-frontmatter'
|
||||
import { NoteType } from '../../common/note-frontmatter/types'
|
||||
import { SlideModeButton } from './slide-mode-button'
|
||||
import { ReadOnlyModeButton } from './read-only-mode-button'
|
||||
import { NewNoteButton } from './new-note-button'
|
||||
|
|
|
@ -13,7 +13,7 @@ import { CopyableField } from '../../../common/copyable/copyable-field/copyable-
|
|||
import { CommonModal } from '../../../common/modals/common-modal'
|
||||
import { ShowIf } from '../../../common/show-if/show-if'
|
||||
import { EditorPagePathParams } from '../../editor-page'
|
||||
import { NoteType } from '../../note-frontmatter/note-frontmatter'
|
||||
import { NoteType } from '../../../common/note-frontmatter/types'
|
||||
import { useApplicationState } from '../../../../hooks/common/use-application-state'
|
||||
|
||||
export interface ShareModalProps {
|
||||
|
|
|
@ -11,8 +11,7 @@ import { useDocumentTitleWithNoteTitle } from '../../hooks/common/use-document-t
|
|||
import { useNoteMarkdownContent } from '../../hooks/common/use-note-markdown-content'
|
||||
import {
|
||||
setCheckboxInMarkdownContent,
|
||||
setNoteFrontmatter,
|
||||
setNoteMarkdownContent,
|
||||
setNoteContent,
|
||||
updateNoteTitleByFirstHeading
|
||||
} from '../../redux/note-details/methods'
|
||||
import { MotdBanner } from '../common/motd-banner/motd-banner'
|
||||
|
@ -50,6 +49,7 @@ export const EditorPage: React.FC = () => {
|
|||
const markdownContent = useNoteMarkdownContent()
|
||||
const scrollSource = useRef<ScrollSource>(ScrollSource.EDITOR)
|
||||
|
||||
const documentContent = useApplicationState((state) => state.noteDetails.documentContent)
|
||||
const editorMode: EditorMode = useApplicationState((state) => state.editorConfig.editorMode)
|
||||
const editorSyncScroll: boolean = useApplicationState((state) => state.editorConfig.syncScroll)
|
||||
|
||||
|
@ -98,14 +98,14 @@ export const EditorPage: React.FC = () => {
|
|||
const leftPane = useMemo(
|
||||
() => (
|
||||
<EditorPane
|
||||
onContentChange={setNoteMarkdownContent}
|
||||
content={markdownContent}
|
||||
onContentChange={setNoteContent}
|
||||
content={documentContent}
|
||||
scrollState={scrollState.editorScrollState}
|
||||
onScroll={onEditorScroll}
|
||||
onMakeScrollSource={setEditorToScrollSource}
|
||||
/>
|
||||
),
|
||||
[markdownContent, onEditorScroll, scrollState.editorScrollState, setEditorToScrollSource]
|
||||
[documentContent, onEditorScroll, scrollState.editorScrollState, setEditorToScrollSource]
|
||||
)
|
||||
|
||||
const rightPane = useMemo(
|
||||
|
@ -116,7 +116,6 @@ export const EditorPage: React.FC = () => {
|
|||
onMakeScrollSource={setRendererToScrollSource}
|
||||
onFirstHeadingChange={updateNoteTitleByFirstHeading}
|
||||
onTaskCheckedChange={setCheckboxInMarkdownContent}
|
||||
onFrontmatterChange={setNoteFrontmatter}
|
||||
onScroll={onMarkdownRendererScroll}
|
||||
scrollState={scrollState.rendererScrollState}
|
||||
rendererType={RendererType.DOCUMENT}
|
||||
|
|
|
@ -1,189 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import yaml from 'js-yaml'
|
||||
import MarkdownIt from 'markdown-it'
|
||||
import frontmatter from 'markdown-it-front-matter'
|
||||
import { NoteFrontmatter, RawNoteFrontmatter } from './note-frontmatter'
|
||||
|
||||
describe('yaml frontmatter', () => {
|
||||
const testFrontmatter = (input: string): NoteFrontmatter => {
|
||||
let processedFrontmatter: NoteFrontmatter | undefined = undefined
|
||||
const md = new MarkdownIt('default', {
|
||||
html: true,
|
||||
breaks: true,
|
||||
langPrefix: '',
|
||||
typographer: true
|
||||
})
|
||||
md.use(frontmatter, (rawMeta: string) => {
|
||||
const parsedFrontmatter = yaml.load(rawMeta) as RawNoteFrontmatter | undefined
|
||||
expect(parsedFrontmatter).not.toBe(undefined)
|
||||
if (parsedFrontmatter === undefined) {
|
||||
fail('Parsed frontmatter is undefined')
|
||||
}
|
||||
processedFrontmatter = new NoteFrontmatter(parsedFrontmatter)
|
||||
})
|
||||
|
||||
md.render(input)
|
||||
|
||||
if (processedFrontmatter === undefined) {
|
||||
fail('NoteFrontmatter is undefined')
|
||||
}
|
||||
|
||||
return processedFrontmatter
|
||||
}
|
||||
|
||||
it('should parse "title"', () => {
|
||||
const noteFrontmatter = testFrontmatter(`---
|
||||
title: test
|
||||
___
|
||||
`)
|
||||
|
||||
expect(noteFrontmatter.title).toEqual('test')
|
||||
})
|
||||
|
||||
it('should parse "robots"', () => {
|
||||
const noteFrontmatter = testFrontmatter(`---
|
||||
robots: index, follow
|
||||
___
|
||||
`)
|
||||
|
||||
expect(noteFrontmatter.robots).toEqual('index, follow')
|
||||
})
|
||||
|
||||
it('should parse the deprecated tags syntax', () => {
|
||||
const noteFrontmatter = testFrontmatter(`---
|
||||
tags: test123, abc
|
||||
___
|
||||
`)
|
||||
|
||||
expect(noteFrontmatter.tags).toEqual(['test123', 'abc'])
|
||||
expect(noteFrontmatter.deprecatedTagsSyntax).toEqual(true)
|
||||
})
|
||||
|
||||
it('should parse the tags list syntax', () => {
|
||||
const noteFrontmatter = testFrontmatter(`---
|
||||
tags:
|
||||
- test123
|
||||
- abc
|
||||
___
|
||||
`)
|
||||
|
||||
expect(noteFrontmatter.tags).toEqual(['test123', 'abc'])
|
||||
expect(noteFrontmatter.deprecatedTagsSyntax).toEqual(false)
|
||||
})
|
||||
|
||||
it('should parse the tag inline-list syntax', () => {
|
||||
const noteFrontmatter = testFrontmatter(`---
|
||||
tags: ['test123', 'abc']
|
||||
___
|
||||
`)
|
||||
|
||||
expect(noteFrontmatter.tags).toEqual(['test123', 'abc'])
|
||||
expect(noteFrontmatter.deprecatedTagsSyntax).toEqual(false)
|
||||
})
|
||||
|
||||
it('should parse "breaks"', () => {
|
||||
const noteFrontmatter = testFrontmatter(`---
|
||||
breaks: false
|
||||
___
|
||||
`)
|
||||
|
||||
expect(noteFrontmatter.breaks).toEqual(false)
|
||||
})
|
||||
|
||||
/*
|
||||
it('slideOptions nothing', () => {
|
||||
testFrontmatter(`---
|
||||
slideOptions:
|
||||
___
|
||||
`,
|
||||
{
|
||||
slideOptions: null
|
||||
},
|
||||
{
|
||||
slideOptions: {
|
||||
theme: 'white',
|
||||
transition: 'none'
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('slideOptions.theme only', () => {
|
||||
testFrontmatter(`---
|
||||
slideOptions:
|
||||
theme: sky
|
||||
___
|
||||
`,
|
||||
{
|
||||
slideOptions: {
|
||||
theme: 'sky',
|
||||
transition: undefined
|
||||
}
|
||||
},
|
||||
{
|
||||
slideOptions: {
|
||||
theme: 'sky',
|
||||
transition: 'none'
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('slideOptions full', () => {
|
||||
testFrontmatter(`---
|
||||
slideOptions:
|
||||
transition: zoom
|
||||
theme: sky
|
||||
___
|
||||
`,
|
||||
{
|
||||
slideOptions: {
|
||||
theme: 'sky',
|
||||
transition: 'zoom'
|
||||
}
|
||||
},
|
||||
{
|
||||
slideOptions: {
|
||||
theme: 'sky',
|
||||
transition: 'zoom'
|
||||
}
|
||||
})
|
||||
})
|
||||
*/
|
||||
|
||||
it('should parse an empty opengraph object', () => {
|
||||
const noteFrontmatter = testFrontmatter(`---
|
||||
opengraph:
|
||||
___
|
||||
`)
|
||||
|
||||
expect(noteFrontmatter.opengraph).toEqual(new Map<string, string>())
|
||||
})
|
||||
|
||||
it('should parse an opengraph title', () => {
|
||||
const noteFrontmatter = testFrontmatter(`---
|
||||
opengraph:
|
||||
title: Testtitle
|
||||
___
|
||||
`)
|
||||
|
||||
expect(noteFrontmatter.opengraph.get('title')).toEqual('Testtitle')
|
||||
})
|
||||
|
||||
it('should opengraph values', () => {
|
||||
const noteFrontmatter = testFrontmatter(`---
|
||||
opengraph:
|
||||
title: Testtitle
|
||||
image: https://dummyimage.com/48.png
|
||||
image:type: image/png
|
||||
___
|
||||
`)
|
||||
|
||||
expect(noteFrontmatter.opengraph.get('title')).toEqual('Testtitle')
|
||||
expect(noteFrontmatter.opengraph.get('image')).toEqual('https://dummyimage.com/48.png')
|
||||
expect(noteFrontmatter.opengraph.get('image:type')).toEqual('image/png')
|
||||
})
|
||||
})
|
|
@ -1,286 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
// import { RevealOptions } from 'reveal.js'
|
||||
|
||||
export interface RawNoteFrontmatter {
|
||||
title: string | undefined
|
||||
description: string | undefined
|
||||
tags: string | string[] | undefined
|
||||
robots: string | undefined
|
||||
lang: string | undefined
|
||||
dir: string | undefined
|
||||
breaks: boolean | undefined
|
||||
GA: string | undefined
|
||||
disqus: string | undefined
|
||||
type: string | undefined
|
||||
slideOptions: unknown
|
||||
opengraph: { [key: string]: string } | null
|
||||
}
|
||||
|
||||
export const ISO6391 = [
|
||||
'aa',
|
||||
'ab',
|
||||
'af',
|
||||
'am',
|
||||
'ar',
|
||||
'ar-ae',
|
||||
'ar-bh',
|
||||
'ar-dz',
|
||||
'ar-eg',
|
||||
'ar-iq',
|
||||
'ar-jo',
|
||||
'ar-kw',
|
||||
'ar-lb',
|
||||
'ar-ly',
|
||||
'ar-ma',
|
||||
'ar-om',
|
||||
'ar-qa',
|
||||
'ar-sa',
|
||||
'ar-sy',
|
||||
'ar-tn',
|
||||
'ar-ye',
|
||||
'as',
|
||||
'ay',
|
||||
'de-at',
|
||||
'de-ch',
|
||||
'de-li',
|
||||
'de-lu',
|
||||
'div',
|
||||
'dz',
|
||||
'el',
|
||||
'en',
|
||||
'en-au',
|
||||
'en-bz',
|
||||
'en-ca',
|
||||
'en-gb',
|
||||
'en-ie',
|
||||
'en-jm',
|
||||
'en-nz',
|
||||
'en-ph',
|
||||
'en-tt',
|
||||
'en-us',
|
||||
'en-za',
|
||||
'en-zw',
|
||||
'eo',
|
||||
'es',
|
||||
'es-ar',
|
||||
'es-bo',
|
||||
'es-cl',
|
||||
'es-co',
|
||||
'es-cr',
|
||||
'es-do',
|
||||
'es-ec',
|
||||
'es-es',
|
||||
'es-gt',
|
||||
'es-hn',
|
||||
'es-mx',
|
||||
'es-ni',
|
||||
'es-pa',
|
||||
'es-pe',
|
||||
'es-pr',
|
||||
'es-py',
|
||||
'es-sv',
|
||||
'es-us',
|
||||
'es-uy',
|
||||
'es-ve',
|
||||
'et',
|
||||
'eu',
|
||||
'fa',
|
||||
'fi',
|
||||
'fj',
|
||||
'fo',
|
||||
'fr',
|
||||
'fr-be',
|
||||
'fr-ca',
|
||||
'fr-ch',
|
||||
'fr-lu',
|
||||
'fr-mc',
|
||||
'fy',
|
||||
'ga',
|
||||
'gd',
|
||||
'gl',
|
||||
'gn',
|
||||
'gu',
|
||||
'ha',
|
||||
'he',
|
||||
'hi',
|
||||
'hr',
|
||||
'hu',
|
||||
'hy',
|
||||
'ia',
|
||||
'id',
|
||||
'ie',
|
||||
'ik',
|
||||
'in',
|
||||
'is',
|
||||
'it',
|
||||
'it-ch',
|
||||
'iw',
|
||||
'ja',
|
||||
'ji',
|
||||
'jw',
|
||||
'ka',
|
||||
'kk',
|
||||
'kl',
|
||||
'km',
|
||||
'kn',
|
||||
'ko',
|
||||
'kok',
|
||||
'ks',
|
||||
'ku',
|
||||
'ky',
|
||||
'kz',
|
||||
'la',
|
||||
'ln',
|
||||
'lo',
|
||||
'ls',
|
||||
'lt',
|
||||
'lv',
|
||||
'mg',
|
||||
'mi',
|
||||
'mk',
|
||||
'ml',
|
||||
'mn',
|
||||
'mo',
|
||||
'mr',
|
||||
'ms',
|
||||
'mt',
|
||||
'my',
|
||||
'na',
|
||||
'nb-no',
|
||||
'ne',
|
||||
'nl',
|
||||
'nl-be',
|
||||
'nn-no',
|
||||
'no',
|
||||
'oc',
|
||||
'om',
|
||||
'or',
|
||||
'pa',
|
||||
'pl',
|
||||
'ps',
|
||||
'pt',
|
||||
'pt-br',
|
||||
'qu',
|
||||
'rm',
|
||||
'rn',
|
||||
'ro',
|
||||
'ro-md',
|
||||
'ru',
|
||||
'ru-md',
|
||||
'rw',
|
||||
'sa',
|
||||
'sb',
|
||||
'sd',
|
||||
'sg',
|
||||
'sh',
|
||||
'si',
|
||||
'sk',
|
||||
'sl',
|
||||
'sm',
|
||||
'sn',
|
||||
'so',
|
||||
'sq',
|
||||
'sr',
|
||||
'ss',
|
||||
'st',
|
||||
'su',
|
||||
'sv',
|
||||
'sv-fi',
|
||||
'sw',
|
||||
'sx',
|
||||
'syr',
|
||||
'ta',
|
||||
'te',
|
||||
'tg',
|
||||
'th',
|
||||
'ti',
|
||||
'tk',
|
||||
'tl',
|
||||
'tn',
|
||||
'to',
|
||||
'tr',
|
||||
'ts',
|
||||
'tt',
|
||||
'tw',
|
||||
'uk',
|
||||
'ur',
|
||||
'us',
|
||||
'uz',
|
||||
'vi',
|
||||
'vo',
|
||||
'wo',
|
||||
'xh',
|
||||
'yi',
|
||||
'yo',
|
||||
'zh',
|
||||
'zh-cn',
|
||||
'zh-hk',
|
||||
'zh-mo',
|
||||
'zh-sg',
|
||||
'zh-tw',
|
||||
'zu'
|
||||
] as const
|
||||
|
||||
export enum NoteType {
|
||||
DOCUMENT = '',
|
||||
SLIDE = 'slide'
|
||||
}
|
||||
|
||||
export enum NoteTextDirection {
|
||||
LTR = 'ltr',
|
||||
RTL = 'rtl'
|
||||
}
|
||||
|
||||
export class NoteFrontmatter {
|
||||
title: string
|
||||
description: string
|
||||
tags: string[]
|
||||
deprecatedTagsSyntax: boolean
|
||||
robots: string
|
||||
lang: typeof ISO6391[number]
|
||||
dir: NoteTextDirection
|
||||
breaks: boolean
|
||||
GA: string
|
||||
disqus: string
|
||||
type: NoteType
|
||||
// slideOptions: RevealOptions
|
||||
opengraph: Map<string, string>
|
||||
|
||||
constructor(rawData: RawNoteFrontmatter) {
|
||||
this.title = rawData.title ?? ''
|
||||
this.description = rawData.description ?? ''
|
||||
this.robots = rawData.robots ?? ''
|
||||
this.breaks = rawData.breaks ?? true
|
||||
this.GA = rawData.GA ?? ''
|
||||
this.disqus = rawData.disqus ?? ''
|
||||
this.lang = (rawData.lang ? ISO6391.find((lang) => lang === rawData.lang) : undefined) ?? 'en'
|
||||
this.type =
|
||||
(rawData.type ? Object.values(NoteType).find((type) => type === rawData.type) : undefined) ?? NoteType.DOCUMENT
|
||||
this.dir =
|
||||
(rawData.dir ? Object.values(NoteTextDirection).find((dir) => dir === rawData.dir) : undefined) ??
|
||||
NoteTextDirection.LTR
|
||||
|
||||
/* this.slideOptions = (rawData?.slideOptions as RevealOptions) ?? {
|
||||
transition: 'none',
|
||||
theme: 'white'
|
||||
} */
|
||||
if (typeof rawData?.tags === 'string') {
|
||||
this.tags = rawData?.tags?.split(',').map((entry) => entry.trim()) ?? []
|
||||
this.deprecatedTagsSyntax = true
|
||||
} else if (typeof rawData?.tags === 'object') {
|
||||
this.tags = rawData?.tags?.filter((tag) => tag !== null) ?? []
|
||||
this.deprecatedTagsSyntax = false
|
||||
} else {
|
||||
this.tags = []
|
||||
this.deprecatedTagsSyntax = false
|
||||
}
|
||||
this.opengraph = rawData?.opengraph
|
||||
? new Map<string, string>(Object.entries(rawData.opengraph))
|
||||
: new Map<string, string>()
|
||||
}
|
||||
}
|
|
@ -25,7 +25,6 @@ export interface RenderIframeProps extends RendererProps {
|
|||
export const RenderIframe: React.FC<RenderIframeProps> = ({
|
||||
markdownContent,
|
||||
onTaskCheckedChange,
|
||||
onFrontmatterChange,
|
||||
scrollState,
|
||||
onFirstHeadingChange,
|
||||
onScroll,
|
||||
|
@ -39,6 +38,7 @@ export const RenderIframe: React.FC<RenderIframeProps> = ({
|
|||
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), [])
|
||||
|
@ -67,11 +67,6 @@ export const RenderIframe: React.FC<RenderIframeProps> = ({
|
|||
return () => iframeCommunicator.onFirstHeadingChange(undefined)
|
||||
}, [iframeCommunicator, onFirstHeadingChange])
|
||||
|
||||
useEffect(() => {
|
||||
iframeCommunicator.onFrontmatterChange(onFrontmatterChange)
|
||||
return () => iframeCommunicator.onFrontmatterChange(undefined)
|
||||
}, [iframeCommunicator, onFrontmatterChange])
|
||||
|
||||
useEffect(() => {
|
||||
iframeCommunicator.onSetScrollState(onScroll)
|
||||
return () => iframeCommunicator.onSetScrollState(undefined)
|
||||
|
@ -128,6 +123,12 @@ export const RenderIframe: React.FC<RenderIframeProps> = ({
|
|||
}
|
||||
}, [iframeCommunicator, markdownContent, rendererReady])
|
||||
|
||||
useEffect(() => {
|
||||
if (rendererReady && frontmatterInfo !== undefined) {
|
||||
iframeCommunicator.sendSetFrontmatterInfo(frontmatterInfo)
|
||||
}
|
||||
}, [iframeCommunicator, rendererReady, frontmatterInfo])
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<ShowOnPropChangeImageLightbox details={lightboxDetails} />
|
||||
|
|
|
@ -10,14 +10,13 @@ import { Trans, useTranslation } from 'react-i18next'
|
|||
import links from '../../../links.json'
|
||||
import { TranslatedExternalLink } from '../../common/links/translated-external-link'
|
||||
import { ShowIf } from '../../common/show-if/show-if'
|
||||
import { useApplicationState } from '../../../hooks/common/use-application-state'
|
||||
import { CommonModalProps } from '../../common/modals/common-modal'
|
||||
|
||||
export const YamlArrayDeprecationAlert: React.FC = () => {
|
||||
export const YamlArrayDeprecationAlert: React.FC<Partial<CommonModalProps>> = ({ show }) => {
|
||||
useTranslation()
|
||||
const yamlDeprecatedTags = useApplicationState((state) => state.noteDetails.frontmatter.deprecatedTagsSyntax)
|
||||
|
||||
return (
|
||||
<ShowIf condition={yamlDeprecatedTags}>
|
||||
<ShowIf condition={!!show}>
|
||||
<Alert data-cy={'yamlArrayDeprecationAlert'} className={'text-wrap'} variant='warning' dir='auto'>
|
||||
<span className={'text-wrap'}>
|
||||
<span className={'text-wrap'}>
|
||||
|
|
|
@ -8,17 +8,17 @@ import React, { useCallback } from 'react'
|
|||
import sanitize from 'sanitize-filename'
|
||||
import { store } from '../../../redux'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useNoteMarkdownContent } from '../../../hooks/common/use-note-markdown-content'
|
||||
import { download } from '../../common/download/download'
|
||||
import { SidebarButton } from './sidebar-button'
|
||||
import { useApplicationState } from '../../../hooks/common/use-application-state'
|
||||
|
||||
export const ExportMarkdownSidebarEntry: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
const markdownContent = useNoteMarkdownContent()
|
||||
const documentContent = useApplicationState((state) => state.noteDetails.documentContent)
|
||||
const onClick = useCallback(() => {
|
||||
const sanitized = sanitize(store.getState().noteDetails.noteTitle)
|
||||
download(markdownContent, `${sanitized !== '' ? sanitized : t('editor.untitledNote')}.md`, 'text/markdown')
|
||||
}, [markdownContent, t])
|
||||
download(documentContent, `${sanitized !== '' ? sanitized : t('editor.untitledNote')}.md`, 'text/markdown')
|
||||
}, [documentContent, t])
|
||||
|
||||
return (
|
||||
<SidebarButton data-cy={'menu-export-markdown'} onClick={onClick} icon={'file-text'}>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import React, { Fragment, useCallback, useRef } from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useNoteMarkdownContent } from '../../../hooks/common/use-note-markdown-content'
|
||||
import { setNoteMarkdownContent } from '../../../redux/note-details/methods'
|
||||
import { setNoteContent } from '../../../redux/note-details/methods'
|
||||
import { SidebarButton } from './sidebar-button'
|
||||
import { UploadInput } from './upload-input'
|
||||
|
||||
|
@ -21,7 +21,7 @@ export const ImportMarkdownSidebarEntry: React.FC = () => {
|
|||
const fileReader = new FileReader()
|
||||
fileReader.addEventListener('load', () => {
|
||||
const newContent = fileReader.result as string
|
||||
setNoteMarkdownContent(markdownContent.length === 0 ? newContent : `${markdownContent}\n${newContent}`)
|
||||
setNoteContent(markdownContent.length === 0 ? newContent : `${markdownContent}\n${newContent}`)
|
||||
})
|
||||
fileReader.addEventListener('loadend', () => {
|
||||
resolve()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue