feat(editor): comment extension (#12948)
#### PR Dependency Tree * **PR #12948** 👈 * **PR #12980** 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** * Introduced inline comment functionality, allowing users to add, resolve, and highlight comments directly within text. * Added a new toolbar action for inserting comments when supported. * Inline comments are visually highlighted and can be interacted with in the editor. * **Enhancements** * Integrated a feature flag to enable or disable the comment feature. * Improved inline manager rendering to support wrapper specs for advanced formatting. * **Developer Tools** * Added mock comment provider for testing and development environments. * **Chores** * Updated dependencies and project references to support the new inline comment module. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -5,6 +5,8 @@ import {
|
||||
type ReferenceParams,
|
||||
} from '@blocksuite/affine/model';
|
||||
import {
|
||||
type CommentId,
|
||||
type CommentProvider,
|
||||
type DocModeProvider,
|
||||
type EditorSetting,
|
||||
GeneralSettingSchema,
|
||||
@@ -13,7 +15,7 @@ import {
|
||||
type ParseDocUrlService,
|
||||
type ThemeExtension,
|
||||
} from '@blocksuite/affine/shared/services';
|
||||
import { type Workspace } from '@blocksuite/affine/store';
|
||||
import type { BaseSelection, Workspace } from '@blocksuite/affine/store';
|
||||
import type { TestAffineEditorContainer } from '@blocksuite/integration-test';
|
||||
import { Signal, signal } from '@preact/signals-core';
|
||||
import { Subject } from 'rxjs';
|
||||
@@ -191,6 +193,86 @@ export function mockEditorSetting() {
|
||||
return signal;
|
||||
}
|
||||
|
||||
export function mockCommentProvider() {
|
||||
class MockCommentProvider implements CommentProvider {
|
||||
commentId = 0;
|
||||
|
||||
comments = new Map<
|
||||
CommentId,
|
||||
{
|
||||
selections: BaseSelection[];
|
||||
resolved: boolean;
|
||||
}
|
||||
>();
|
||||
|
||||
commentAddSubject = new Subject<{
|
||||
id: CommentId;
|
||||
selections: BaseSelection[];
|
||||
}>();
|
||||
|
||||
commentResolveSubject = new Subject<CommentId>();
|
||||
|
||||
commentHighlightSubject = new Subject<CommentId | null>();
|
||||
|
||||
commentDeleteSubject = new Subject<CommentId>();
|
||||
|
||||
addComment(selections: BaseSelection[]) {
|
||||
const id: CommentId = `${this.commentId++}`;
|
||||
this.comments.set(id, {
|
||||
selections,
|
||||
resolved: false,
|
||||
});
|
||||
this.commentAddSubject.next({
|
||||
id,
|
||||
selections,
|
||||
});
|
||||
}
|
||||
|
||||
resolveComment(id: CommentId) {
|
||||
const comment = this.comments.get(id);
|
||||
if (!comment) return;
|
||||
comment.resolved = true;
|
||||
this.commentResolveSubject.next(id);
|
||||
}
|
||||
|
||||
deleteComment(id: CommentId) {
|
||||
this.comments.delete(id);
|
||||
this.commentDeleteSubject.next(id);
|
||||
}
|
||||
|
||||
highlightComment(id: CommentId | null) {
|
||||
this.commentHighlightSubject.next(id);
|
||||
}
|
||||
|
||||
getComments() {
|
||||
return Array.from(this.comments.keys());
|
||||
}
|
||||
|
||||
onCommentAdded(
|
||||
callback: (id: CommentId, selections: BaseSelection[]) => void
|
||||
) {
|
||||
return this.commentAddSubject.subscribe(({ id, selections }) => {
|
||||
callback(id, selections);
|
||||
});
|
||||
}
|
||||
|
||||
onCommentResolved(callback: (id: CommentId) => void) {
|
||||
return this.commentResolveSubject.subscribe(callback);
|
||||
}
|
||||
|
||||
onCommentDeleted(callback: (id: CommentId) => void) {
|
||||
return this.commentDeleteSubject.subscribe(callback);
|
||||
}
|
||||
|
||||
onCommentHighlighted(callback: (id: CommentId | null) => void) {
|
||||
return this.commentHighlightSubject.subscribe(callback);
|
||||
}
|
||||
}
|
||||
|
||||
const provider = new MockCommentProvider();
|
||||
return provider;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
editorSetting$: Signal<EditorSetting>;
|
||||
|
||||
Reference in New Issue
Block a user