fix(editor): time issues of comment initialization (#13031)

#### PR Dependency Tree


* **PR #13031** 👈

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 the ability to filter comments by their resolution status
(resolved, unresolved, or all) when viewing or managing comments.

* **Refactor**
* Improved the way commented text is identified and retrieved, resulting
in more reliable comment selection and filtering.
* Enhanced comment retrieval to support asynchronous data loading,
ensuring up-to-date comment information.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
L-Sun
2025-07-04 16:19:00 +08:00
committed by GitHub
parent a485ad5c45
commit eb56adea46
7 changed files with 111 additions and 68 deletions
+44 -43
View File
@@ -1,55 +1,56 @@
import { getInlineEditorByModel } from '@blocksuite/affine-rich-text';
import type { CommentId } from '@blocksuite/affine-shared/services';
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
import { type BlockStdScope, TextSelection } from '@blocksuite/std';
import type { InlineEditor } from '@blocksuite/std/inline';
import type { DeltaInsert } from '@blocksuite/store';
import { TextSelection } from '@blocksuite/std';
import type { DeltaInsert, Store } from '@blocksuite/store';
export function findAllCommentedTexts(std: BlockStdScope) {
const selections: [TextSelection, InlineEditor<AffineTextAttributes>][] = [];
std.store.getAllModels().forEach(model => {
const inlineEditor = getInlineEditorByModel(std, model);
if (!inlineEditor) return;
export function findAllCommentedTexts(
store: Store
): Map<TextSelection, CommentId> {
const result = new Map<TextSelection, CommentId>();
inlineEditor.mapDeltasInInlineRange(
{
index: 0,
length: inlineEditor.yTextLength,
},
(delta, rangeIndex) => {
if (
delta.attributes &&
Object.keys(delta.attributes).some(key => key.startsWith('comment-'))
) {
selections.push([
new TextSelection({
from: {
blockId: model.id,
index: rangeIndex,
length: delta.insert.length,
},
to: null,
}),
inlineEditor,
]);
}
store.getAllModels().forEach(model => {
if (!model.text) return;
let index = 0;
model.text.toDelta().forEach(delta => {
if (!delta.insert) return;
const length = delta.insert.length;
if (!delta.attributes) {
index += length;
return;
}
);
Object.keys(delta.attributes)
.filter(key => key.startsWith('comment-'))
.forEach(key => {
const commentId = key.replace('comment-', '');
const selection = new TextSelection({
from: {
blockId: model.id,
index,
length,
},
to: null,
});
result.set(selection, commentId);
});
index += length;
});
});
return selections;
return result;
}
export function findCommentedTexts(std: BlockStdScope, commentId: CommentId) {
return findAllCommentedTexts(std).filter(([selection, inlineEditor]) => {
const deltas = inlineEditor.getDeltasByInlineRange({
index: selection.from.index,
length: selection.from.length,
});
return deltas
.flatMap(([delta]) => extractCommentIdFromDelta(delta))
.includes(commentId);
});
export function findCommentedTexts(
store: Store,
commentId: CommentId
): TextSelection[] {
return [...findAllCommentedTexts(store).entries()]
.filter(([_, id]) => id === commentId)
.map(([selection]) => selection);
}
export function extractCommentIdFromDelta(