Skip to content

Commit 15fdb08

Browse files
committed
feat: Add auto-save functionality to MarkdownEditor
1 parent 34ac2fd commit 15fdb08

File tree

6 files changed

+72
-47
lines changed

6 files changed

+72
-47
lines changed

packages/markdown-editor/src/components/markdown-editor/markdown-editor.tsx

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,89 @@
11
import cn from 'clsx'
2-
import { useRef } from 'react'
2+
import { useEffect, useRef, useState } from 'react'
33
import { Toolbar } from './toolbar'
44
import { useCodemirror } from '@/hooks'
5+
import { useRouter } from 'next/router'
6+
import { saveExecute } from './toolbar/commands/save'
7+
import toast, { ToastOptions } from 'react-hot-toast'
8+
import { CustomEventDetail } from '@/types'
9+
import { markdownCustomEventName } from '@/index'
510

611
interface MarkdownEditorProps {}
712

813
export const MarkdownEditor = ({}: MarkdownEditorProps) => {
14+
const router = useRouter()
15+
const [isAutoSave, setAutoSave] = useState<boolean>(false)
16+
const [isFocus, setIsFocus] = useState<boolean>(false)
917
const codemirror = useRef<HTMLDivElement | null>(null)
1018
const { state, view } = useCodemirror(codemirror, {
1119
autoFocus: true,
1220
minHeight: '100%',
1321
maxHeight: '100%',
1422
})
1523

24+
// router 이동시 isFocus 초기화
25+
useEffect(() => {
26+
if (!isFocus) return
27+
setIsFocus(false)
28+
}, [router.asPath])
29+
30+
// 라우터 변경 시 자동 저장
31+
useEffect(() => {
32+
if (!view) return
33+
if (!isFocus) return
34+
const handleRouteChange = () => {
35+
setAutoSave(true)
36+
saveExecute(view)
37+
}
38+
router.events.on('beforeHistoryChange', handleRouteChange)
39+
return () => {
40+
router.events.off('beforeHistoryChange', handleRouteChange)
41+
}
42+
}, [router, view])
43+
44+
// 저장 되고 나면 toast 메시지
45+
useEffect(() => {
46+
const updateItemResult = (e: CustomEventInit<CustomEventDetail['updateItemResultEvent']>) => {
47+
if (!e.detail) return
48+
if (isAutoSave) {
49+
setAutoSave(false)
50+
return
51+
}
52+
53+
const { result } = e.detail
54+
55+
const commonOption: ToastOptions = {
56+
className: cn('dark:nx-bg-[#333] dark:nx-text-[#f0f0f0]'),
57+
style: {
58+
fontSize: '17px',
59+
},
60+
duration: 700,
61+
}
62+
63+
const mapper = {
64+
success: () =>
65+
toast.success('글이 저장 되었습니다', {
66+
position: 'bottom-right',
67+
...commonOption,
68+
}),
69+
error: () =>
70+
toast.error('글 저장에 실패했습니다', {
71+
position: 'bottom-right',
72+
...commonOption,
73+
}),
74+
}
75+
mapper[result]()
76+
}
77+
78+
window.addEventListener(markdownCustomEventName.updateItemResultEvent, updateItemResult)
79+
return () => {
80+
window.removeEventListener(markdownCustomEventName.updateItemResultEvent, updateItemResult)
81+
}
82+
}, [])
83+
1684
const onClick = () => {
1785
view?.focus()
86+
setIsFocus(true)
1887
}
1988

2089
return (

packages/markdown-editor/src/components/markdown-editor/toolbar/commands/save.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ export function saveExecute(view: EditorView) {
4747
if (prevDoc.has(currentUrl) && prevDoc.get(currentUrl) === doc) {
4848
return
4949
}
50-
prevDoc.set(currentUrl, doc)
5150

51+
prevDoc.set(currentUrl, doc)
52+
console.log('save!')
5253
const event = new CustomEvent<CustomEventDetail['updateItemEvent']>(
5354
markdownCustomEventName.updateItemEvent,
5455
{

packages/markdown-editor/src/hooks/use-auto-save.ts

Whitespace-only changes.

packages/markdown-editor/src/layouts/layout.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { Main } from './main'
77
import { ModalProvider } from '@/contexts/modal'
88
import { Potals } from '@/components/potals'
99
import { Toaster } from 'react-hot-toast'
10-
import { EventProvider } from '@/providers'
1110

1211
type NextraDocLayoutProps = NextraThemeLayoutProps & {
1312
editorValue: string
@@ -17,7 +16,6 @@ export function Layout({ children, editorValue, ...context }: NextraDocLayoutPro
1716
return (
1817
<ConfigProvider value={context}>
1918
<Toaster />
20-
<EventProvider />
2119
<ModalProvider>
2220
<SidebarProvider>
2321
<MarkdownEditorProvider value={{ editorValue }}>

packages/markdown-editor/src/providers/event-provider.tsx

Lines changed: 0 additions & 42 deletions
This file was deleted.

packages/markdown-editor/src/providers/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)