Added markdown-file import (#645)

* Added markdown-file import

* Reset file input after read, don't add unnecessary blank lines

* Add cypress-file-upload dependency

* Add cypress tests for md file importing

* Added CHANGELOG entry
This commit is contained in:
Erik Michelson 2020-10-09 21:26:04 +02:00 committed by GitHub
parent c1d4ac1014
commit 729ad652b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 113 additions and 7 deletions

View file

@ -6,16 +6,15 @@ import { ConnectionIndicator } from './connection-indicator/connection-indicator
import { DocumentInfoButton } from './document-info/document-info-button'
import { EditorMenu } from './menus/editor-menu'
import { ExportMenu } from './menus/export-menu'
import { ImportMenu } from './menus/import-menu'
import { ImportMenu, ImportProps } from './menus/import-menu'
import { PermissionButton } from './permissions/permission-button'
import { RevisionButton } from './revisions/revision-button'
export interface DocumentBarProps {
title: string
noteContent: string
}
export const DocumentBar: React.FC<DocumentBarProps> = ({ title, noteContent }) => {
export const DocumentBar: React.FC<DocumentBarProps & ImportProps> = ({ title, noteContent, updateNoteContent }) => {
useTranslation()
return (
@ -28,7 +27,7 @@ export const DocumentBar: React.FC<DocumentBarProps> = ({ title, noteContent })
<PermissionButton/>
</div>
<div className="ml-auto navbar-nav">
<ImportMenu/>
<ImportMenu updateNoteContent={updateNoteContent} noteContent={noteContent}/>
<ExportMenu title={title} noteContent={noteContent}/>
<EditorMenu noteTitle={title}/>
<ConnectionIndicator/>

View file

@ -0,0 +1,45 @@
import React, { Fragment, useCallback, useRef } from 'react'
import { Dropdown } from 'react-bootstrap'
import { Trans } from 'react-i18next'
import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon'
import { ImportProps } from '../menus/import-menu'
export const ImportFile: React.FC<ImportProps> = ({ noteContent, updateNoteContent }) => {
const fileInputReference = useRef<HTMLInputElement>(null)
const doImport = useCallback(() => {
const fileInput = fileInputReference.current
if (!fileInput) {
return
}
fileInput.addEventListener('change', () => {
if (!fileInput.files || fileInput.files.length < 1) {
return
}
const file = fileInput.files[0]
const fileReader = new FileReader()
fileReader.addEventListener('load', () => {
const newContent = fileReader.result as string
if (noteContent.length === 0) {
updateNoteContent(newContent)
} else {
updateNoteContent(noteContent + '\n' + newContent)
}
})
fileReader.addEventListener('loadend', () => {
fileInput.value = ''
})
fileReader.readAsText(file)
})
fileInput.click()
}, [fileInputReference, noteContent, updateNoteContent])
return (
<Fragment>
<input type='file' ref={fileInputReference} className='d-none' accept='.md, text/markdown, text/plain'/>
<Dropdown.Item className='small import-md-file' onClick={doImport}>
<ForkAwesomeIcon icon='file-text-o' className={'mx-2'}/>
<Trans i18nKey='editor.import.file'/>
</Dropdown.Item>
</Fragment>
)
}

View file

@ -2,8 +2,14 @@ import React from 'react'
import { Dropdown } from 'react-bootstrap'
import { Trans } from 'react-i18next'
import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon'
import { ImportFile } from '../import/import-file'
export const ImportMenu: React.FC = () => {
export interface ImportProps {
noteContent: string
updateNoteContent: (content: string) => void
}
export const ImportMenu: React.FC<ImportProps> = ({ updateNoteContent, noteContent }) => {
return (
<Dropdown className='small mx-1' alignRight={true}>
<Dropdown.Toggle variant='light' size='sm' id='editor-menu-import' className=''>
@ -27,6 +33,7 @@ export const ImportMenu: React.FC = () => {
<ForkAwesomeIcon icon='clipboard' className={'mx-2'}/>
<Trans i18nKey='editor.import.clipboard'/>
</Dropdown.Item>
<ImportFile updateNoteContent={updateNoteContent} noteContent={noteContent}/>
</Dropdown.Menu>
</Dropdown>
)

View file

@ -115,7 +115,7 @@ export const Editor: React.FC = () => {
<DocumentTitle title={documentTitle}/>
<div className={'d-flex flex-column vh-100'}>
<AppBar/>
<DocumentBar title={documentTitle} noteContent={markdownContent}/>
<DocumentBar title={documentTitle} noteContent={markdownContent} updateNoteContent={(newContent) => setMarkdownContent(newContent)}/>
<Splitter
showLeft={editorMode === EditorMode.EDITOR || editorMode === EditorMode.BOTH}
left={