From 9071c5032d1154930de88ba2a7495287ca1e20fa Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Wed, 9 Jul 2025 15:56:34 +0800 Subject: [PATCH] fix(core): should not be able to commit comments when uploading images (#13108) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### PR Dependency Tree * **PR #13108** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) ## Summary by CodeRabbit * **Bug Fixes** * The commit button in the comment editor is now properly disabled while attachments are uploading or when the editor is empty without attachments, preventing accidental or premature submissions. * **New Features** * Attachment delete button now shows a loading state during uploads for clearer user feedback. * **Style** * Updated comment editor attachment button styles for a cleaner and more consistent appearance. --- .../affine/inlines/comment/src/inline-spec.ts | 4 +++ .../comment/comment-editor/index.tsx | 30 ++++++++++--------- .../comment/comment-editor/style.css.ts | 28 ++++------------- 3 files changed, 25 insertions(+), 37 deletions(-) diff --git a/blocksuite/affine/inlines/comment/src/inline-spec.ts b/blocksuite/affine/inlines/comment/src/inline-spec.ts index b31cb8b17..be1928f23 100644 --- a/blocksuite/affine/inlines/comment/src/inline-spec.ts +++ b/blocksuite/affine/inlines/comment/src/inline-spec.ts @@ -47,3 +47,7 @@ export const NullCommentInlineSpecExtension = match: () => false, renderer: () => html``, }); + +// reuse the same identifier +NullCommentInlineSpecExtension.identifier = + CommentInlineSpecExtension.identifier; diff --git a/packages/frontend/core/src/components/comment/comment-editor/index.tsx b/packages/frontend/core/src/components/comment/comment-editor/index.tsx index 6ad7a2b70..dbe3430a9 100644 --- a/packages/frontend/core/src/components/comment/comment-editor/index.tsx +++ b/packages/frontend/core/src/components/comment/comment-editor/index.tsx @@ -1,4 +1,4 @@ -import { IconButton, Loading } from '@affine/component'; +import { IconButton } from '@affine/component'; import { LitDocEditor, type PageEditor } from '@affine/core/blocksuite/editors'; import { SnapshotHelper } from '@affine/core/modules/comment/services/snapshot-helper'; import type { CommentAttachment } from '@affine/core/modules/comment/types'; @@ -144,6 +144,11 @@ export const CommentEditor = forwardRef( ); const isImageUploadDisabled = (attachments?.length ?? 0) >= MAX_IMAGE_COUNT; + const uploadingAttachments = attachments?.some( + att => att.status === 'uploading' + ); + const commitDisabled = + (empty && (attachments?.length ?? 0) === 0) || uploadingAttachments; const addImages = useAsyncCallback( async (files: File[]) => { @@ -296,13 +301,13 @@ export const CommentEditor = forwardRef( // upload attachments and call original onCommit const handleCommit = useAsyncCallback(async () => { - if (readonly) return; + if (readonly || commitDisabled) return; onCommit?.(); setAttachments(prev => { prev.forEach(att => att.localUrl && URL.revokeObjectURL(att.localUrl)); return []; }); - }, [readonly, onCommit, setAttachments]); + }, [readonly, commitDisabled, onCommit, setAttachments]); const focusEditor = useAsyncCallback(async () => { if (editorRef.current) { @@ -447,20 +452,17 @@ export const CommentEditor = forwardRef( onClick={e => handleImageClick(e, index)} > {!readonly && ( -
{ e.stopPropagation(); handleImageRemove(att.id); }} - > - -
- )} - {att.status === 'uploading' && ( -
- -
+ icon={} + /> )} ))} @@ -480,7 +482,7 @@ export const CommentEditor = forwardRef( diff --git a/packages/frontend/core/src/components/comment/comment-editor/style.css.ts b/packages/frontend/core/src/components/comment/comment-editor/style.css.ts index 7c1005d71..d66e6ff07 100644 --- a/packages/frontend/core/src/components/comment/comment-editor/style.css.ts +++ b/packages/frontend/core/src/components/comment/comment-editor/style.css.ts @@ -91,36 +91,18 @@ export const previewBox = style({ }, }); -export const deleteBtn = style({ +export const attachmentButton = style({ position: 'absolute', top: -6, right: -6, - width: 16, - height: 16, - borderRadius: 4, - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - border: `0.5px solid ${cssVarV2('layer/insideBorder/border')}`, - backgroundColor: cssVarV2('layer/background/primary'), - cursor: 'pointer', + background: cssVarV2('layer/background/primary'), + border: '1px solid', + borderColor: cssVarV2('layer/insideBorder/border'), selectors: { '&:hover': { - backgroundColor: cssVarV2('layer/background/error'), + background: cssVarV2('layer/background/error'), borderColor: cssVarV2('button/error'), color: cssVarV2('button/error'), }, }, }); - -export const spinnerWrapper = style({ - position: 'absolute', - top: 0, - left: 0, - width: '100%', - height: '100%', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - backgroundColor: 'rgba(255,255,255,0.6)', -});