|
|
@@ -12,17 +12,19 @@ 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';
|
|
|
import {
|
|
|
- useCurrentUser, useIsSlackConfigured,
|
|
|
- useIsUploadAllFileAllowed, useIsUploadEnabled,
|
|
|
+ useCurrentUser, useIsSlackConfigured, useAcceptedUploadFileType,
|
|
|
} from '~/stores/context';
|
|
|
-import { useSWRxSlackChannels, useIsSlackEnabled, useIsEnabledUnsavedWarning } from '~/stores/editor';
|
|
|
+import {
|
|
|
+ useSWRxSlackChannels, useIsSlackEnabled, useIsEnabledUnsavedWarning,
|
|
|
+} 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';
|
|
|
@@ -30,9 +32,13 @@ import { NotAvailableForReadOnlyUser } from '../NotAvailableForReadOnlyUser';
|
|
|
|
|
|
import { CommentPreview } from './CommentPreview';
|
|
|
|
|
|
+import '@growi/editor/dist/style.css';
|
|
|
import styles from './CommentEditor.module.scss';
|
|
|
|
|
|
|
|
|
+const logger = loggerFactory('growi:components:CommentEditor');
|
|
|
+
|
|
|
+
|
|
|
const SlackNotification = dynamic(() => import('../SlackNotification').then(mod => mod.SlackNotification), { ssr: false });
|
|
|
|
|
|
|
|
|
@@ -70,10 +76,9 @@ export const CommentEditor = (props: CommentEditorProps): JSX.Element => {
|
|
|
const { data: currentPagePath } = useCurrentPagePath();
|
|
|
const { update: updateComment, post: postComment } = useSWRxPageComment(pageId);
|
|
|
const { data: isSlackEnabled, mutate: mutateIsSlackEnabled } = useIsSlackEnabled();
|
|
|
+ const { data: acceptedUploadFileType } = useAcceptedUploadFileType();
|
|
|
const { data: slackChannelsData } = useSWRxSlackChannels(currentPagePath);
|
|
|
const { data: isSlackConfigured } = useIsSlackConfigured();
|
|
|
- const { data: isUploadAllFileAllowed } = useIsUploadAllFileAllowed();
|
|
|
- const { data: isUploadEnabled } = useIsUploadEnabled();
|
|
|
const { mutate: mutateIsEnabledUnsavedWarning } = useIsEnabledUnsavedWarning();
|
|
|
const {
|
|
|
increment: incrementEditingCommentsNum,
|
|
|
@@ -201,48 +206,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 "" syntax
|
|
|
- insertText = `!${insertText}`;
|
|
|
+ let insertText = `[${fileName}](${attachment.filePathProxied})\n`;
|
|
|
+ // when image
|
|
|
+ if (attachment.fileFormat.startsWith('image/')) {
|
|
|
+ // modify to "" 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) {
|
|
|
@@ -325,8 +325,6 @@ export const CommentEditor = (props: CommentEditorProps): JSX.Element => {
|
|
|
</Button>
|
|
|
);
|
|
|
|
|
|
- const isUploadable = isUploadEnabled || isUploadAllFileAllowed;
|
|
|
-
|
|
|
return (
|
|
|
<>
|
|
|
<div className="comment-write">
|
|
|
@@ -334,7 +332,10 @@ export const CommentEditor = (props: CommentEditorProps): JSX.Element => {
|
|
|
<TabContent activeTab={activeTab}>
|
|
|
<TabPane tabId="comment_editor">
|
|
|
<CodeMirrorEditorComment
|
|
|
+ acceptedUploadFileType={acceptedUploadFileType}
|
|
|
onChange={onChangeHandler}
|
|
|
+ onSave={postCommentHandler}
|
|
|
+ onUpload={uploadHandler}
|
|
|
/>
|
|
|
{/* <Editor
|
|
|
ref={editorRef}
|