Yuki Takei 2 лет назад
Родитель
Сommit
2867d84078

+ 38 - 37
apps/app/src/components/PageComment/CommentEditor.tsx

@@ -12,7 +12,7 @@ import {
   Button, TabContent, TabPane,
 } from 'reactstrap';
 
-import { apiPostForm } from '~/client/util/apiv1-client';
+import { apiv3Get, apiv3PostForm } from '~/client/util/apiv3-client';
 import { toastError } from '~/client/util/toastr';
 import type { IEditorMethods } from '~/interfaces/editor-methods';
 import { useSWRxPageComment, useSWRxEditingCommentsNum } from '~/stores/comment';
@@ -24,6 +24,7 @@ import {
 } from '~/stores/editor';
 import { useCurrentPagePath } from '~/stores/page';
 import { useNextThemes } from '~/stores/use-next-themes';
+import loggerFactory from '~/utils/logger';
 
 import { CustomNavTab } from '../CustomNavigation/CustomNav';
 import { NotAvailableForGuest } from '../NotAvailableForGuest';
@@ -34,6 +35,9 @@ import { CommentPreview } from './CommentPreview';
 import styles from './CommentEditor.module.scss';
 
 
+const logger = loggerFactory('growi:components:CommentEditor');
+
+
 const SlackNotification = dynamic(() => import('../SlackNotification').then(mod => mod.SlackNotification), { ssr: false });
 
 
@@ -201,48 +205,43 @@ export const CommentEditor = (props: CommentEditorProps): JSX.Element => {
     updateComment, comment, revisionId, replyTo, isSlackEnabled, slackChannels, postComment,
   ]);
 
-  const ctrlEnterHandler = useCallback((event) => {
-    if (event != null) {
-      event.preventDefault();
-    }
+  // the upload event handler
+  const uploadHandler = useCallback((files: File[]) => {
+    files.forEach(async(file) => {
+      try {
+        const { data: resLimit } = await apiv3Get('/attachment/limit', { fileSize: file.size });
 
-    postCommentHandler();
-  }, [postCommentHandler]);
+        if (!resLimit.isUploadable) {
+          throw new Error(resLimit.errorMessage);
+        }
 
-  const apiErrorHandler = useCallback((error: Error) => {
-    toastError(error.message);
-  }, []);
+        const formData = new FormData();
+        formData.append('file', file);
+        if (pageId != null) {
+          formData.append('page_id', pageId);
+        }
 
-  const uploadHandler = useCallback(async(file) => {
-    if (editorRef.current == null) { return }
+        const { data: resAdd } = await apiv3PostForm('/attachment', formData);
 
-    const pagePath = currentPagePath;
-    const endpoint = '/attachments.add';
-    const formData = new FormData();
-    formData.append('file', file);
-    formData.append('path', pagePath ?? '');
-    formData.append('page_id', pageId ?? '');
+        const attachment = resAdd.attachment;
+        const fileName = attachment.originalName;
 
-    try {
-      // TODO: typescriptize res
-      const res = await apiPostForm(endpoint, formData) as any;
-      const attachment = res.attachment;
-      const fileName = attachment.originalName;
-      let insertText = `[${fileName}](${attachment.filePathProxied})`;
-      // when image
-      if (attachment.fileFormat.startsWith('image/')) {
-        // modify to "![fileName](url)" syntax
-        insertText = `!${insertText}`;
+        let insertText = `[${fileName}](${attachment.filePathProxied})\n`;
+        // when image
+        if (attachment.fileFormat.startsWith('image/')) {
+          // modify to "![fileName](url)" syntax
+          insertText = `!${insertText}`;
+        }
+
+        codeMirrorEditor?.insertText(insertText);
       }
-      editorRef.current.insertText(insertText);
-    }
-    catch (err) {
-      apiErrorHandler(err);
-    }
-    finally {
-      editorRef.current.terminateUploadingState();
-    }
-  }, [apiErrorHandler, currentPagePath, pageId]);
+      catch (e) {
+        logger.error('failed to upload', e);
+        toastError(e);
+      }
+    });
+
+  }, [codeMirrorEditor, pageId]);
 
   const getCommentHtml = useCallback(() => {
     if (currentPagePath == null) {
@@ -334,6 +333,8 @@ export const CommentEditor = (props: CommentEditorProps): JSX.Element => {
               <CodeMirrorEditorComment
                 acceptedUploadFileType={acceptedUploadFileType}
                 onChange={onChangeHandler}
+                onSave={postCommentHandler}
+                onUpload={uploadHandler}
               />
               {/* <Editor
                 ref={editorRef}

+ 7 - 11
packages/editor/src/components/CodeMirrorEditorComment.tsx

@@ -2,12 +2,11 @@ import { useEffect } from 'react';
 
 import type { Extension } from '@codemirror/state';
 import { keymap, scrollPastEnd } from '@codemirror/view';
-import { AcceptedUploadFileType } from '@growi/core';
 
 import { GlobalCodeMirrorEditorKey } from '../consts';
 import { useCodeMirrorEditorIsolated } from '../stores';
 
-import { CodeMirrorEditor } from '.';
+import { CodeMirrorEditor, CodeMirrorEditorProps } from '.';
 
 
 const additionalExtensions: Extension[] = [
@@ -15,16 +14,12 @@ const additionalExtensions: Extension[] = [
 ];
 
 
-type Props = {
-  acceptedUploadFileType?: AcceptedUploadFileType,
-  onChange?: (value: string) => void,
-  onComment?: () => void,
-}
+type Props = CodeMirrorEditorProps & object
 
 export const CodeMirrorEditorComment = (props: Props): JSX.Element => {
   const {
     acceptedUploadFileType,
-    onComment, onChange,
+    onSave, onChange, onUpload,
   } = props;
 
   const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(GlobalCodeMirrorEditorKey.COMMENT);
@@ -36,7 +31,7 @@ export const CodeMirrorEditorComment = (props: Props): JSX.Element => {
 
   // set handler to comment with ctrl/cmd + Enter key
   useEffect(() => {
-    if (onComment == null) {
+    if (onSave == null) {
       return;
     }
 
@@ -47,7 +42,7 @@ export const CodeMirrorEditorComment = (props: Props): JSX.Element => {
         run: () => {
           const doc = codeMirrorEditor?.getDoc();
           if (doc != null) {
-            onComment();
+            onSave();
           }
           return true;
         },
@@ -57,13 +52,14 @@ export const CodeMirrorEditorComment = (props: Props): JSX.Element => {
     const cleanupFunction = codeMirrorEditor?.appendExtensions?.(keymapExtension);
 
     return cleanupFunction;
-  }, [codeMirrorEditor, onComment]);
+  }, [codeMirrorEditor, onSave]);
 
   return (
     <CodeMirrorEditor
       editorKey={GlobalCodeMirrorEditorKey.COMMENT}
       acceptedUploadFileType={acceptedUploadFileType}
       onChange={onChange}
+      onUpload={onUpload}
     />
   );
 };