mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-18 23:07:02 +08:00
fix(core): should not be able to comment with empty content (#13061)
fix AF-2712 #### PR Dependency Tree * **PR #13061** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * The comment editor now disables the commit button when the editor is empty, preventing accidental submissions. * The commit action is now triggered by pressing Enter together with CMD/CTRL, instead of Enter without Shift. * **Style** * The disabled state styling for the commit button now matches the native HTML `disabled` attribute for improved consistency. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -93,6 +93,8 @@ export const CommentEditor = forwardRef<CommentEditorRef, CommentEditorProps>(
|
|||||||
const snapshotHelper = useService(SnapshotHelper);
|
const snapshotHelper = useService(SnapshotHelper);
|
||||||
const editorRef = useRef<PageEditor>(null);
|
const editorRef = useRef<PageEditor>(null);
|
||||||
|
|
||||||
|
const [empty, setEmpty] = useState(true);
|
||||||
|
|
||||||
useImperativeHandle(
|
useImperativeHandle(
|
||||||
ref,
|
ref,
|
||||||
() => ({
|
() => ({
|
||||||
@@ -138,12 +140,15 @@ export const CommentEditor = forwardRef<CommentEditorRef, CommentEditorProps>(
|
|||||||
}, [autoFocus, doc]);
|
}, [autoFocus, doc]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (doc && onChange) {
|
if (doc) {
|
||||||
const subscription = doc.slots.blockUpdated.subscribe(() => {
|
const subscription = doc.slots.blockUpdated.subscribe(() => {
|
||||||
const snapshot = snapshotHelper.getSnapshot(doc);
|
if (onChange) {
|
||||||
if (snapshot) {
|
const snapshot = snapshotHelper.getSnapshot(doc);
|
||||||
onChange?.(snapshot);
|
if (snapshot) {
|
||||||
|
onChange?.(snapshot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
setEmpty(snapshotHelper.isDocEmpty(doc));
|
||||||
});
|
});
|
||||||
return () => {
|
return () => {
|
||||||
subscription?.unsubscribe();
|
subscription?.unsubscribe();
|
||||||
@@ -152,7 +157,7 @@ export const CommentEditor = forwardRef<CommentEditorRef, CommentEditorProps>(
|
|||||||
return;
|
return;
|
||||||
}, [doc, onChange, snapshotHelper]);
|
}, [doc, onChange, snapshotHelper]);
|
||||||
|
|
||||||
// Add keydown handler to commit on Enter key
|
// Add keydown handler to commit on CMD/CTRL + Enter key
|
||||||
const handleKeyDown = useCallback(
|
const handleKeyDown = useCallback(
|
||||||
(e: React.KeyboardEvent) => {
|
(e: React.KeyboardEvent) => {
|
||||||
if (readonly) return;
|
if (readonly) return;
|
||||||
@@ -161,8 +166,8 @@ export const CommentEditor = forwardRef<CommentEditorRef, CommentEditorProps>(
|
|||||||
const activeElement = document.activeElement;
|
const activeElement = document.activeElement;
|
||||||
if (!editorRef.current?.contains(activeElement)) return;
|
if (!editorRef.current?.contains(activeElement)) return;
|
||||||
|
|
||||||
// If Enter is pressed without Shift key, commit the comment
|
// If Enter is pressed with CMD/CTRL key, commit the comment
|
||||||
if (e.key === 'Enter' && !e.shiftKey) {
|
if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
onCommit?.();
|
onCommit?.();
|
||||||
@@ -194,7 +199,11 @@ export const CommentEditor = forwardRef<CommentEditorRef, CommentEditorProps>(
|
|||||||
{doc && <LitDocEditor ref={editorRef} specs={specs} doc={doc} />}
|
{doc && <LitDocEditor ref={editorRef} specs={specs} doc={doc} />}
|
||||||
{!readonly && (
|
{!readonly && (
|
||||||
<div className={styles.footer}>
|
<div className={styles.footer}>
|
||||||
<button onClick={onCommit} className={styles.commitButton}>
|
<button
|
||||||
|
onClick={onCommit}
|
||||||
|
className={styles.commitButton}
|
||||||
|
disabled={empty}
|
||||||
|
>
|
||||||
<ArrowUpBigIcon />
|
<ArrowUpBigIcon />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export const commitButton = style({
|
|||||||
height: '28px',
|
height: '28px',
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
selectors: {
|
selectors: {
|
||||||
'&[data-disabled="true"]': {
|
'&[disabled]': {
|
||||||
background: cssVarV2('button/disable'),
|
background: cssVarV2('button/disable'),
|
||||||
cursor: 'default',
|
cursor: 'default',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
MarkdownAdapter,
|
MarkdownAdapter,
|
||||||
} from '@blocksuite/affine/shared/adapters';
|
} from '@blocksuite/affine/shared/adapters';
|
||||||
import {
|
import {
|
||||||
|
type BlockModel,
|
||||||
type DocSnapshot,
|
type DocSnapshot,
|
||||||
nanoid,
|
nanoid,
|
||||||
type Store,
|
type Store,
|
||||||
@@ -152,4 +153,31 @@ export class SnapshotHelper extends Service {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isDocEmpty(store?: Store): boolean {
|
||||||
|
if (!store) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkBlock = (block: BlockModel) => {
|
||||||
|
if (block.text && block.text.length > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const children = block.children;
|
||||||
|
for (const child of children) {
|
||||||
|
if (!checkBlock(child)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const blocks = store.blocks.peek();
|
||||||
|
for (const block of Object.values(blocks)) {
|
||||||
|
if (!checkBlock(block.model)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user