fix(core): some ux issues related to comments (#13057)

fix AF-2713

#### PR Dependency Tree


* **PR #13057** 👈

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**
* Added support for submitting comments by pressing Enter (without
Shift) in the comment editor.

* **Improvements**
* Improved comment highlight handling with smoother updates and reduced
unnecessary scrolling in the comment sidebar.
* Enhanced editor focus behavior to support highlighting comments
directly when a comment ID is provided, with automatic comment panel
activation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Peng Xiao
2025-07-07 11:23:24 +08:00
committed by GitHub
parent 2df4a60c44
commit 0d2fbaf3ea
3 changed files with 38 additions and 5 deletions

View File

@@ -109,7 +109,6 @@ export const CommentEditor = forwardRef<CommentEditorRef, CommentEditorProps>(
useEffect(() => {
let cancel = false;
if (autoFocus && editorRef.current && doc) {
// fixme: the following does not work
// Wait for editor to be fully loaded before focusing
editorRef.current.updateComplete
.then(async () => {
@@ -128,6 +127,7 @@ export const CommentEditor = forwardRef<CommentEditorRef, CommentEditorProps>(
block: 'center',
});
// fixme: the following does not work
inlineEditor?.focusEnd();
})
.catch(console.error);
@@ -152,6 +152,25 @@ export const CommentEditor = forwardRef<CommentEditorRef, CommentEditorProps>(
return;
}, [doc, onChange, snapshotHelper]);
// Add keydown handler to commit on Enter key
const handleKeyDown = useCallback(
(e: React.KeyboardEvent) => {
if (readonly) return;
// Only handle Enter if focus is within the editor
const activeElement = document.activeElement;
if (!editorRef.current?.contains(activeElement)) return;
// If Enter is pressed without Shift key, commit the comment
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
e.stopPropagation();
onCommit?.();
}
},
[onCommit, readonly]
);
const handleClickEditor = useCallback(
(e: React.MouseEvent) => {
e.stopPropagation();
@@ -165,6 +184,7 @@ export const CommentEditor = forwardRef<CommentEditorRef, CommentEditorProps>(
return (
<div
onClick={readonly ? undefined : handleClickEditor}
onKeyDown={handleKeyDown}
data-readonly={!!readonly}
className={clsx(styles.container, 'comment-editor-viewport')}
>

View File

@@ -26,6 +26,7 @@ import {
useServiceOptional,
} from '@toeverything/infra';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
import { useAsyncCallback } from '../../hooks/affine-async-hooks';
import { CommentEditor } from '../comment-editor';
@@ -243,7 +244,7 @@ const CommentItem = ({
refreshKey: 'comment-' + Date.now(),
},
{
show: true,
replaceHistory: true,
}
);
entity.highlightComment(comment.id);
@@ -251,11 +252,9 @@ const CommentItem = ({
useEffect(() => {
const subscription = entity.commentHighlighted$
.distinctUntilChanged()
.pipe(debounceTime(0), distinctUntilChanged())
.subscribe(id => {
if (id === comment.id && commentRef.current) {
commentRef.current.scrollIntoView({ behavior: 'smooth' });
// Auto-start reply when comment becomes highlighted, but only if not resolved
if (!isReplyingToThisComment && !comment.resolved) {
entity.addReply(comment.id).catch(() => {

View File

@@ -17,6 +17,8 @@ import { Entity, LiveData } from '@toeverything/infra';
import { defaults, isEqual, omit } from 'lodash-es';
import { skip } from 'rxjs';
import { CommentPanelService } from '../../comment/services/comment-panel-service';
import { DocCommentManagerService } from '../../comment/services/doc-comment-manager';
import type { DocService } from '../../doc';
import { paramsParseOptions, preprocessParams } from '../../navigation/utils';
import type { WorkbenchView } from '../../workbench';
@@ -233,6 +235,18 @@ export class Editor extends Entity {
}
// Workaround: clear selection to avoid comment editor flickering
selection?.clear();
// highlight comment
setTimeout(() => {
const commentManager = this.framework.get(DocCommentManagerService);
const commentPanelService = this.framework.get(CommentPanelService);
const commentEntity = commentManager.get(this.doc.id);
commentPanelService.openCommentPanel();
commentEntity.obj.highlightComment(commentId);
commentEntity.release();
}, 0);
// do not highlight block
highlight = false;
}