Skip to content

Commit

Permalink
IS-271: fix bugs on simple mde editor (#1323)
Browse files Browse the repository at this point in the history
* feat: allow selection of images

* draft: enable hyperlink and image insertion

* fix: remove console logs and dangling props

* fix: code cleanup

* fix: remove unused var
  • Loading branch information
harishv7 authored Jun 26, 2023
1 parent b1363d3 commit 86d7a41
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 20 deletions.
64 changes: 52 additions & 12 deletions src/components/pages/EditorModals.jsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,60 @@
import HyperlinkModal from "components/HyperlinkModal"
import MediaModal from "components/media/MediaModal"
import PropTypes from "prop-types"
import { useEffect, useState } from "react"

const EditorModals = ({
onSave,
modalType,
onClose,
mediaType,
simpleMde,
lineAndCursor,
}) => {
const [linePos, setLinePos] = useState({ line: 0, ch: 0, sticky: null })

// this fixes the issue where line and cursor are being reset to 0 upon opening modals
useEffect(() => {
if (!lineAndCursor && simpleMde) {
setLinePos(lineAndCursor)
simpleMde.codemirror.setSelection(lineAndCursor)
}
if (
lineAndCursor &&
!(lineAndCursor.line === 0 && lineAndCursor.ch === 0)
) {
setLinePos(lineAndCursor)
}
}, [lineAndCursor])

const EditorModals = ({ mdeRef, onSave, modalType, onClose, mediaType }) => {
const onHyperlinkSave = (text, link) => {
const cm = mdeRef.current.simpleMde.codemirror
const cm = simpleMde.codemirror
cm.setCursor(linePos)
cm.setSelection(linePos)
cm.replaceSelection(`[${text}](${link})`)
// set state so that rerender is triggered and path is shown
onSave(mdeRef.current.simpleMde.codemirror.getValue())
onSave(simpleMde.codemirror.getValue())
onClose()
}

const onMediaSave = (data) => {
const { selectedMediaPath, altText } = data
const cm = mdeRef.current.simpleMde.codemirror
const cm = simpleMde.codemirror

cm.setCursor(linePos)
cm.setSelection(linePos)

if (mediaType === "files")
cm.replaceSelection(
`[${altText}](${selectedMediaPath.replaceAll(" ", "%20")})`
)
if (mediaType === "images")
if (mediaType === "images") {
cm.replaceSelection(
`![${altText}](${selectedMediaPath.replaceAll(" ", "%20")})`
)
}
// set state so that rerender is triggered and image is shown
onSave(mdeRef.current.simpleMde.codemirror.getValue())
onSave(simpleMde.codemirror.getValue())
onClose()
}

Expand All @@ -39,7 +70,7 @@ const EditorModals = ({ mdeRef, onSave, modalType, onClose, mediaType }) => {
)}
{modalType === "hyperlink" && (
<HyperlinkModal
text={mdeRef.current.simpleMde.codemirror.getSelection()}
text={simpleMde.codemirror.getSelection()}
onSave={onHyperlinkSave}
onClose={onClose}
/>
Expand All @@ -49,14 +80,23 @@ const EditorModals = ({ mdeRef, onSave, modalType, onClose, mediaType }) => {
}

EditorModals.propTypes = {
mdeRef: PropTypes.oneOfType([
// https://stackoverflow.com/questions/48007326/what-is-the-correct-proptype-for-a-ref-in-react
PropTypes.func,
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
]),
onSave: PropTypes.func.isRequired,
modalType: PropTypes.oneOf(["hyperlink", "media"]).isRequired,
onClose: PropTypes.func.isRequired,
simpleMde: PropTypes.shape({
codemirror: PropTypes.shape({
getSelection: PropTypes.func,
getValue: PropTypes.func,
replaceSelection: PropTypes.func,
setCursor: PropTypes.func,
}),
}),
lineAndCursor: PropTypes.shape({
line: PropTypes.number,
ch: PropTypes.number,
sticky: PropTypes.string,
xRel: PropTypes.number,
}),
}

export default EditorModals
23 changes: 19 additions & 4 deletions src/components/pages/MarkdownEditor.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import EditorModals from "components/pages/EditorModals"
import { useMemo, useState } from "react"
import { useMemo, useState, useCallback } from "react"
import SimpleMDE from "react-simplemde-editor"

import { useMarkdown } from "hooks/useMarkdown"
Expand All @@ -21,7 +21,6 @@ import {

const MarkdownEditor = ({
siteName,
mdeRef,
onChange,
value,
isDisabled,
Expand All @@ -32,6 +31,8 @@ const MarkdownEditor = ({
const { toMarkdown } = useMarkdown()
const options = useMemo(
() => ({
autoRefresh: true,
styleSelectedText: true,
toolbar: [
headingButton,
boldButton,
Expand Down Expand Up @@ -94,6 +95,18 @@ const MarkdownEditor = ({
}
})

const [simpleMdeInstance, setMdeInstance] = useState(null)

const getMdeInstanceCallback = useCallback((simpleMde) => {
setMdeInstance(simpleMde)
}, [])

const [lineAndCursor, setLineAndCursor] = useState(null)

const getLineAndCursorCallback = useCallback((position) => {
setLineAndCursor(position)
}, [])

const StatusIcon = () => {
if (isDisabled) {
return (
Expand All @@ -120,14 +133,15 @@ const MarkdownEditor = ({
<>
<EditorModals
siteName={siteName}
mdeRef={mdeRef}
modalType={editorModalType}
onSave={onChange}
onClose={() => {
setEditorModalType("")
setInsertingMediaType("")
}}
mediaType={insertingMediaType}
simpleMde={simpleMdeInstance}
lineAndCursor={lineAndCursor}
/>
<div
className={`${editorStyles.pageEditorSidebar} ${
Expand All @@ -139,10 +153,11 @@ const MarkdownEditor = ({
id="simplemde-editor"
className="h-100"
onChange={onChange}
ref={mdeRef}
value={value}
options={options}
events={events}
getMdeInstance={getMdeInstanceCallback}
getLineAndCursor={getLineAndCursorCallback}
/>
</div>
</>
Expand Down
5 changes: 1 addition & 4 deletions src/layouts/EditPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { WarningModal } from "components/WarningModal"
import DOMPurify from "dompurify"
import { marked } from "marked"
import PropTypes from "prop-types"
import { useEffect, useRef, useState } from "react"
import { useEffect, useState } from "react"

import { useCollectionHook } from "hooks/collectionHooks"
import { useGetPageHook, useUpdatePageHook } from "hooks/pageHooks"
Expand Down Expand Up @@ -98,8 +98,6 @@ const EditPage = ({ match }) => {

const { setRedirectToNotFound } = useRedirectHook()

const mdeRef = useRef()

const { data: pageData, isLoading: isLoadingPage } = useGetPageHook(params, {
onError: () => setRedirectToNotFound(siteName),
})
Expand Down Expand Up @@ -275,7 +273,6 @@ const EditPage = ({ match }) => {
{/* Editor */}
<MarkdownEditor
siteName={siteName}
mdeRef={mdeRef}
onChange={(value) => setEditorValue(value)}
value={editorValue}
isLoading={isLoadingPage}
Expand Down

0 comments on commit 86d7a41

Please sign in to comment.