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:
@@ -109,7 +109,6 @@ export const CommentEditor = forwardRef<CommentEditorRef, CommentEditorProps>(
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let cancel = false;
|
let cancel = false;
|
||||||
if (autoFocus && editorRef.current && doc) {
|
if (autoFocus && editorRef.current && doc) {
|
||||||
// fixme: the following does not work
|
|
||||||
// Wait for editor to be fully loaded before focusing
|
// Wait for editor to be fully loaded before focusing
|
||||||
editorRef.current.updateComplete
|
editorRef.current.updateComplete
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
@@ -128,6 +127,7 @@ export const CommentEditor = forwardRef<CommentEditorRef, CommentEditorProps>(
|
|||||||
block: 'center',
|
block: 'center',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// fixme: the following does not work
|
||||||
inlineEditor?.focusEnd();
|
inlineEditor?.focusEnd();
|
||||||
})
|
})
|
||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
@@ -152,6 +152,25 @@ export const CommentEditor = forwardRef<CommentEditorRef, CommentEditorProps>(
|
|||||||
return;
|
return;
|
||||||
}, [doc, onChange, snapshotHelper]);
|
}, [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(
|
const handleClickEditor = useCallback(
|
||||||
(e: React.MouseEvent) => {
|
(e: React.MouseEvent) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -165,6 +184,7 @@ export const CommentEditor = forwardRef<CommentEditorRef, CommentEditorProps>(
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
onClick={readonly ? undefined : handleClickEditor}
|
onClick={readonly ? undefined : handleClickEditor}
|
||||||
|
onKeyDown={handleKeyDown}
|
||||||
data-readonly={!!readonly}
|
data-readonly={!!readonly}
|
||||||
className={clsx(styles.container, 'comment-editor-viewport')}
|
className={clsx(styles.container, 'comment-editor-viewport')}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import {
|
|||||||
useServiceOptional,
|
useServiceOptional,
|
||||||
} from '@toeverything/infra';
|
} from '@toeverything/infra';
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
|
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
||||||
|
|
||||||
import { useAsyncCallback } from '../../hooks/affine-async-hooks';
|
import { useAsyncCallback } from '../../hooks/affine-async-hooks';
|
||||||
import { CommentEditor } from '../comment-editor';
|
import { CommentEditor } from '../comment-editor';
|
||||||
@@ -243,7 +244,7 @@ const CommentItem = ({
|
|||||||
refreshKey: 'comment-' + Date.now(),
|
refreshKey: 'comment-' + Date.now(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
show: true,
|
replaceHistory: true,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
entity.highlightComment(comment.id);
|
entity.highlightComment(comment.id);
|
||||||
@@ -251,11 +252,9 @@ const CommentItem = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const subscription = entity.commentHighlighted$
|
const subscription = entity.commentHighlighted$
|
||||||
.distinctUntilChanged()
|
.pipe(debounceTime(0), distinctUntilChanged())
|
||||||
.subscribe(id => {
|
.subscribe(id => {
|
||||||
if (id === comment.id && commentRef.current) {
|
if (id === comment.id && commentRef.current) {
|
||||||
commentRef.current.scrollIntoView({ behavior: 'smooth' });
|
|
||||||
|
|
||||||
// Auto-start reply when comment becomes highlighted, but only if not resolved
|
// Auto-start reply when comment becomes highlighted, but only if not resolved
|
||||||
if (!isReplyingToThisComment && !comment.resolved) {
|
if (!isReplyingToThisComment && !comment.resolved) {
|
||||||
entity.addReply(comment.id).catch(() => {
|
entity.addReply(comment.id).catch(() => {
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import { Entity, LiveData } from '@toeverything/infra';
|
|||||||
import { defaults, isEqual, omit } from 'lodash-es';
|
import { defaults, isEqual, omit } from 'lodash-es';
|
||||||
import { skip } from 'rxjs';
|
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 type { DocService } from '../../doc';
|
||||||
import { paramsParseOptions, preprocessParams } from '../../navigation/utils';
|
import { paramsParseOptions, preprocessParams } from '../../navigation/utils';
|
||||||
import type { WorkbenchView } from '../../workbench';
|
import type { WorkbenchView } from '../../workbench';
|
||||||
@@ -233,6 +235,18 @@ export class Editor extends Entity {
|
|||||||
}
|
}
|
||||||
// Workaround: clear selection to avoid comment editor flickering
|
// Workaround: clear selection to avoid comment editor flickering
|
||||||
selection?.clear();
|
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;
|
highlight = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user