|
@@ -85,7 +85,6 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
|
|
|
const { t } = useTranslation();
|
|
const { t } = useTranslation();
|
|
|
const router = useRouter();
|
|
const router = useRouter();
|
|
|
|
|
|
|
|
- const editorRef = useRef<IEditorMethods>(null);
|
|
|
|
|
const previewRef = useRef<HTMLDivElement>(null);
|
|
const previewRef = useRef<HTMLDivElement>(null);
|
|
|
const codeMirrorEditorContainerRef = useRef<HTMLDivElement>(null);
|
|
const codeMirrorEditorContainerRef = useRef<HTMLDivElement>(null);
|
|
|
|
|
|
|
@@ -116,7 +115,8 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
|
|
|
const { mutate: mutateRemoteRevisionLastUpdatedAt } = useRemoteRevisionLastUpdatedAt();
|
|
const { mutate: mutateRemoteRevisionLastUpdatedAt } = useRemoteRevisionLastUpdatedAt();
|
|
|
const { mutate: mutateRemoteRevisionLastUpdateUser } = useRemoteRevisionLastUpdateUser();
|
|
const { mutate: mutateRemoteRevisionLastUpdateUser } = useRemoteRevisionLastUpdateUser();
|
|
|
|
|
|
|
|
- useCodeMirrorEditorMain(codeMirrorEditorContainerRef.current);
|
|
|
|
|
|
|
+ const { data: codemirrorEditor } = useCodeMirrorEditorMain(codeMirrorEditorContainerRef.current);
|
|
|
|
|
+ const { initDoc } = codemirrorEditor ?? {};
|
|
|
|
|
|
|
|
const { data: rendererOptions } = usePreviewOptions();
|
|
const { data: rendererOptions } = usePreviewOptions();
|
|
|
const { mutate: mutateIsEnabledUnsavedWarning } = useIsEnabledUnsavedWarning();
|
|
const { mutate: mutateIsEnabledUnsavedWarning } = useIsEnabledUnsavedWarning();
|
|
@@ -149,7 +149,6 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
|
|
|
|
|
|
|
|
}, [isNotFound, currentPathname, editingMarkdown, isEnabledAttachTitleHeader, templateBodyData]);
|
|
}, [isNotFound, currentPathname, editingMarkdown, isEnabledAttachTitleHeader, templateBodyData]);
|
|
|
|
|
|
|
|
- const markdownToSave = useRef<string>(initialValue);
|
|
|
|
|
const [markdownToPreview, setMarkdownToPreview] = useState<string>(initialValue);
|
|
const [markdownToPreview, setMarkdownToPreview] = useState<string>(initialValue);
|
|
|
|
|
|
|
|
const { data: socket } = useGlobalSocket();
|
|
const { data: socket } = useGlobalSocket();
|
|
@@ -172,11 +171,6 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
|
|
|
setCreatedPageRevisionIdWithAttachment(undefined);
|
|
setCreatedPageRevisionIdWithAttachment(undefined);
|
|
|
}, [router]);
|
|
}, [router]);
|
|
|
|
|
|
|
|
- useEffect(() => {
|
|
|
|
|
- markdownToSave.current = initialValue;
|
|
|
|
|
- setMarkdownToPreview(initialValue);
|
|
|
|
|
- }, [initialValue]);
|
|
|
|
|
-
|
|
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
|
if (socket == null) { return }
|
|
if (socket == null) { return }
|
|
|
|
|
|
|
@@ -204,7 +198,6 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
|
|
|
}, [grantData, isSlackEnabled, pageTags]);
|
|
}, [grantData, isSlackEnabled, pageTags]);
|
|
|
|
|
|
|
|
const setMarkdownWithDebounce = useMemo(() => debounce(100, throttle(150, (value: string, isClean: boolean) => {
|
|
const setMarkdownWithDebounce = useMemo(() => debounce(100, throttle(150, (value: string, isClean: boolean) => {
|
|
|
- markdownToSave.current = value;
|
|
|
|
|
setMarkdownToPreview(value);
|
|
setMarkdownToPreview(value);
|
|
|
|
|
|
|
|
// Displays an unsaved warning alert
|
|
// Displays an unsaved warning alert
|
|
@@ -228,7 +221,10 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
|
|
|
mutateWaitingSaveProcessing(true);
|
|
mutateWaitingSaveProcessing(true);
|
|
|
|
|
|
|
|
const { page } = await saveOrUpdate(
|
|
const { page } = await saveOrUpdate(
|
|
|
- markdownToSave.current,
|
|
|
|
|
|
|
+ // TODO: get contents from the custom hook
|
|
|
|
|
+ // refs: https://redmine.weseek.co.jp/issues/128973
|
|
|
|
|
+ // markdownToSave.current,
|
|
|
|
|
+ '',
|
|
|
{ pageId, path: currentPagePath || currentPathname, revisionId: currentRevisionId },
|
|
{ pageId, path: currentPagePath || currentPathname, revisionId: currentRevisionId },
|
|
|
options,
|
|
options,
|
|
|
);
|
|
);
|
|
@@ -305,9 +301,11 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
|
|
|
* @param {any} file
|
|
* @param {any} file
|
|
|
*/
|
|
*/
|
|
|
const uploadHandler = useCallback(async(file) => {
|
|
const uploadHandler = useCallback(async(file) => {
|
|
|
- if (editorRef.current == null) {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // TODO: implement
|
|
|
|
|
+ // refs: https://redmine.weseek.co.jp/issues/126528
|
|
|
|
|
+ // if (editorRef.current == null) {
|
|
|
|
|
+ // return;
|
|
|
|
|
+ // }
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -328,9 +326,11 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
|
|
|
if (pageId != null) {
|
|
if (pageId != null) {
|
|
|
formData.append('page_id', pageId);
|
|
formData.append('page_id', pageId);
|
|
|
}
|
|
}
|
|
|
- if (pageId == null && markdownToSave.current != null) {
|
|
|
|
|
- formData.append('page_body', markdownToSave.current);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // TODO: get contents from the custom hook
|
|
|
|
|
+ // refs: https://redmine.weseek.co.jp/issues/128973
|
|
|
|
|
+ // if (pageId == null && markdownToSave.current != null) {
|
|
|
|
|
+ // formData.append('page_body', markdownToSave.current);
|
|
|
|
|
+ // }
|
|
|
|
|
|
|
|
res = await apiPostForm('/attachments.add', formData);
|
|
res = await apiPostForm('/attachments.add', formData);
|
|
|
const attachment = res.attachment;
|
|
const attachment = res.attachment;
|
|
@@ -342,7 +342,9 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
|
|
|
// modify to "" syntax
|
|
// modify to "" syntax
|
|
|
insertText = `!${insertText}`;
|
|
insertText = `!${insertText}`;
|
|
|
}
|
|
}
|
|
|
- editorRef.current.insertText(insertText);
|
|
|
|
|
|
|
+ // TODO: implement
|
|
|
|
|
+ // refs: https://redmine.weseek.co.jp/issues/126528
|
|
|
|
|
+ // editorRef.current.insertText(insertText);
|
|
|
|
|
|
|
|
// when if created newly
|
|
// when if created newly
|
|
|
// Not using 'mutateGrant' to inherit the grant of the parent page
|
|
// Not using 'mutateGrant' to inherit the grant of the parent page
|
|
@@ -360,7 +362,9 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
|
|
|
toastError(e);
|
|
toastError(e);
|
|
|
}
|
|
}
|
|
|
finally {
|
|
finally {
|
|
|
- editorRef.current.terminateUploadingState();
|
|
|
|
|
|
|
+ // TODO: implement
|
|
|
|
|
+ // refs: https://redmine.weseek.co.jp/issues/126528
|
|
|
|
|
+ // editorRef.current.terminateUploadingState();
|
|
|
}
|
|
}
|
|
|
}, [currentPagePath, mutateCurrentPage, mutateCurrentPageId, mutateIsLatestRevision, pageId]);
|
|
}, [currentPagePath, mutateCurrentPage, mutateCurrentPageId, mutateIsLatestRevision, pageId]);
|
|
|
|
|
|
|
@@ -438,24 +442,24 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
|
|
|
* scroll Editor component by scroll event of Preview component
|
|
* scroll Editor component by scroll event of Preview component
|
|
|
* @param {number} offset
|
|
* @param {number} offset
|
|
|
*/
|
|
*/
|
|
|
- const scrollEditorByPreviewScroll = useCallback((offset: number) => {
|
|
|
|
|
- if (editorRef.current == null || previewRef.current == null) {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // const scrollEditorByPreviewScroll = useCallback((offset: number) => {
|
|
|
|
|
+ // if (editorRef.current == null || previewRef.current == null) {
|
|
|
|
|
+ // return;
|
|
|
|
|
+ // }
|
|
|
|
|
|
|
|
- // prevent circular invocation
|
|
|
|
|
- if (isOriginOfScrollSyncEditor) {
|
|
|
|
|
- isOriginOfScrollSyncEditor = false; // turn off the flag
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // // prevent circular invocation
|
|
|
|
|
+ // if (isOriginOfScrollSyncEditor) {
|
|
|
|
|
+ // isOriginOfScrollSyncEditor = false; // turn off the flag
|
|
|
|
|
+ // return;
|
|
|
|
|
+ // }
|
|
|
|
|
|
|
|
- // turn on the flag
|
|
|
|
|
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
|
|
- isOriginOfScrollSyncPreview = true;
|
|
|
|
|
|
|
+ // // turn on the flag
|
|
|
|
|
+ // // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
|
|
+ // isOriginOfScrollSyncPreview = true;
|
|
|
|
|
|
|
|
- scrollSyncHelper.scrollEditor(editorRef.current, previewRef.current, offset);
|
|
|
|
|
- }, []);
|
|
|
|
|
- const scrollEditorByPreviewScrollWithThrottle = useMemo(() => throttle(20, scrollEditorByPreviewScroll), [scrollEditorByPreviewScroll]);
|
|
|
|
|
|
|
+ // scrollSyncHelper.scrollEditor(editorRef.current, previewRef.current, offset);
|
|
|
|
|
+ // }, []);
|
|
|
|
|
+ // const scrollEditorByPreviewScrollWithThrottle = useMemo(() => throttle(20, scrollEditorByPreviewScroll), [scrollEditorByPreviewScroll]);
|
|
|
|
|
|
|
|
const afterResolvedHandler = useCallback(async() => {
|
|
const afterResolvedHandler = useCallback(async() => {
|
|
|
// get page data from db
|
|
// get page data from db
|
|
@@ -480,24 +484,29 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
|
|
|
if (initialValue == null) {
|
|
if (initialValue == null) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
- markdownToSave.current = initialValue;
|
|
|
|
|
|
|
+ // markdownToSave.current = initialValue;
|
|
|
|
|
+ initDoc?.(initialValue);
|
|
|
setMarkdownToPreview(initialValue);
|
|
setMarkdownToPreview(initialValue);
|
|
|
mutateIsEnabledUnsavedWarning(false);
|
|
mutateIsEnabledUnsavedWarning(false);
|
|
|
- }, [initialValue, mutateIsEnabledUnsavedWarning]);
|
|
|
|
|
|
|
+ }, [initDoc, initialValue, mutateIsEnabledUnsavedWarning]);
|
|
|
|
|
|
|
|
// initial caret line
|
|
// initial caret line
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
|
- if (editorRef.current != null) {
|
|
|
|
|
- editorRef.current.setCaretLine(0);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // TODO: implement
|
|
|
|
|
+ // refs: https://redmine.weseek.co.jp/issues/126516
|
|
|
|
|
+ // if (editorRef.current != null) {
|
|
|
|
|
+ // editorRef.current.setCaretLine(0);
|
|
|
|
|
+ // }
|
|
|
}, []);
|
|
}, []);
|
|
|
|
|
|
|
|
// set handler to set caret line
|
|
// set handler to set caret line
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
|
const handler = (line) => {
|
|
const handler = (line) => {
|
|
|
- if (editorRef.current != null) {
|
|
|
|
|
- editorRef.current.setCaretLine(line);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // TODO: implement
|
|
|
|
|
+ // refs: https://redmine.weseek.co.jp/issues/126516
|
|
|
|
|
+ // if (editorRef.current != null) {
|
|
|
|
|
+ // editorRef.current.setCaretLine(line);
|
|
|
|
|
+ // }
|
|
|
if (previewRef.current != null) {
|
|
if (previewRef.current != null) {
|
|
|
scrollSyncHelper.scrollPreview(previewRef.current, line);
|
|
scrollSyncHelper.scrollPreview(previewRef.current, line);
|
|
|
}
|
|
}
|
|
@@ -520,9 +529,11 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
|
|
|
|
|
|
|
|
// set handler to focus
|
|
// set handler to focus
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
|
- if (editorRef.current != null && editorMode === EditorMode.Editor) {
|
|
|
|
|
- editorRef.current.forceToFocus();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // TODO: implement
|
|
|
|
|
+ // refs: https://redmine.weseek.co.jp/issues/126516
|
|
|
|
|
+ // if (editorRef.current != null && editorMode === EditorMode.Editor) {
|
|
|
|
|
+ // editorRef.current.forceToFocus();
|
|
|
|
|
+ // }
|
|
|
}, [editorMode]);
|
|
}, [editorMode]);
|
|
|
|
|
|
|
|
// Detect indent size from contents (only when users are allowed to change it)
|
|
// Detect indent size from contents (only when users are allowed to change it)
|
|
@@ -544,9 +555,12 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
|
|
|
// when transitioning to a different page, if the initialValue is the same,
|
|
// when transitioning to a different page, if the initialValue is the same,
|
|
|
// UnControlled CodeMirror value does not reset, so explicitly set the value to initialValue
|
|
// UnControlled CodeMirror value does not reset, so explicitly set the value to initialValue
|
|
|
const onRouterChangeComplete = useCallback(() => {
|
|
const onRouterChangeComplete = useCallback(() => {
|
|
|
- editorRef.current?.setValue(initialValue);
|
|
|
|
|
- editorRef.current?.setCaretLine(0);
|
|
|
|
|
- }, [initialValue]);
|
|
|
|
|
|
|
+ initDoc?.(initialValue);
|
|
|
|
|
+
|
|
|
|
|
+ // TODO: implement
|
|
|
|
|
+ // refs: https://redmine.weseek.co.jp/issues/126516
|
|
|
|
|
+ // editorRef.current?.setCaretLine(0);
|
|
|
|
|
+ }, [initDoc, initialValue]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
|
router.events.on('routeChangeComplete', onRouterChangeComplete);
|
|
router.events.on('routeChangeComplete', onRouterChangeComplete);
|
|
@@ -588,7 +602,9 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
|
|
|
rendererOptions={rendererOptions}
|
|
rendererOptions={rendererOptions}
|
|
|
markdown={markdownToPreview}
|
|
markdown={markdownToPreview}
|
|
|
pagePath={currentPagePath}
|
|
pagePath={currentPagePath}
|
|
|
- onScroll={offset => scrollEditorByPreviewScrollWithThrottle(offset)}
|
|
|
|
|
|
|
+ // TODO: implement
|
|
|
|
|
+ // refs: https://redmine.weseek.co.jp/issues/126519
|
|
|
|
|
+ // onScroll={offset => scrollEditorByPreviewScrollWithThrottle(offset)}
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
{/*
|
|
{/*
|