@fileverse-dev/ddoc 3.1.7-linkCaption-1 → 3.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/index.es.js +32692 -28765
  2. package/dist/package/components/editor-bubble-menu/props.d.ts +2 -0
  3. package/dist/package/components/inline-comment/comment-card.d.ts +1 -1
  4. package/dist/package/components/inline-comment/comment-drawer.d.ts +1 -1
  5. package/dist/package/components/inline-comment/comment-dropdown.d.ts +1 -1
  6. package/dist/package/components/inline-comment/comment-floating-container.d.ts +1 -0
  7. package/dist/package/components/inline-comment/comment-floating-layout.d.ts +34 -0
  8. package/dist/package/components/inline-comment/comment-input-field.d.ts +4 -0
  9. package/dist/package/components/inline-comment/comment-reply-input.d.ts +8 -0
  10. package/dist/package/components/inline-comment/comment-section.d.ts +1 -1
  11. package/dist/package/components/inline-comment/comment-username.d.ts +1 -1
  12. package/dist/package/components/inline-comment/constants.d.ts +1 -0
  13. package/dist/package/components/inline-comment/context/types.d.ts +46 -89
  14. package/dist/package/components/inline-comment/delete-confirm-overlay.d.ts +10 -0
  15. package/dist/package/components/inline-comment/empty-comments.d.ts +4 -1
  16. package/dist/package/components/inline-comment/floating-comment/comment-floating-container.d.ts +3 -0
  17. package/dist/package/components/inline-comment/floating-comment/draft-floating-card.d.ts +3 -0
  18. package/dist/package/components/inline-comment/floating-comment/floating-auth-prompt.d.ts +1 -0
  19. package/dist/package/components/inline-comment/floating-comment/floating-card-shell.d.ts +3 -0
  20. package/dist/package/components/inline-comment/floating-comment/index.d.ts +1 -0
  21. package/dist/package/components/inline-comment/floating-comment/thread-floating-card.d.ts +3 -0
  22. package/dist/package/components/inline-comment/floating-comment/types.d.ts +34 -0
  23. package/dist/package/components/inline-comment/floating-comment-layout-utils.d.ts +78 -0
  24. package/dist/package/components/inline-comment/resize-inline-comment-textarea.d.ts +1 -0
  25. package/dist/package/components/inline-comment/types.d.ts +24 -0
  26. package/dist/package/components/inline-comment/use-anchor-registry.d.ts +34 -0
  27. package/dist/package/components/inline-comment/use-comment-card.d.ts +29 -0
  28. package/dist/package/components/inline-comment/use-comment-list-container.d.ts +17 -0
  29. package/dist/package/components/inline-comment/use-ens-status.d.ts +3 -0
  30. package/dist/package/components/inline-comment/use-floating-card-state.d.ts +36 -0
  31. package/dist/package/components/inline-comment/use-floating-comment-card-layout.d.ts +23 -0
  32. package/dist/package/components/inline-comment/use-floating-comment-card-state.d.ts +13 -0
  33. package/dist/package/components/inline-comment/use-floating-layout-engine.d.ts +26 -0
  34. package/dist/package/components/inline-comment/use-is-selected-content-deleted.d.ts +1 -0
  35. package/dist/package/components/tabs/document-tabs-sidebar.d.ts +2 -1
  36. package/dist/package/extensions/comment/comment-decoration-plugin.d.ts +70 -0
  37. package/dist/package/extensions/comment/comment.d.ts +33 -0
  38. package/dist/package/extensions/resizable-media/resizable-media-menu-util.d.ts +5 -4
  39. package/dist/package/extensions/resizable-media/resizable-media-node-view.d.ts +1 -1
  40. package/dist/package/hooks/use-tab-editor.d.ts +6 -2
  41. package/dist/package/stores/comment-store-provider.d.ts +56 -0
  42. package/dist/package/stores/comment-store.d.ts +195 -0
  43. package/dist/package/types.d.ts +16 -2
  44. package/dist/package/use-ddoc-editor.d.ts +4 -1
  45. package/dist/package/utils/comment-anchor-serialization.d.ts +5 -0
  46. package/dist/package/utils/comment-scroll-into-view.d.ts +21 -0
  47. package/dist/style.css +1 -1
  48. package/package.json +4 -3
  49. package/dist/package/components/inline-comment/context/comment-context.d.ts +0 -4
  50. package/dist/package/extensions/resizable-media/media-caption.d.ts +0 -3
@@ -0,0 +1,26 @@
1
+ import { RefObject } from 'react';
2
+ import { Editor } from '@tiptap/react';
3
+ import { CommentFloatingCard } from './context/types';
4
+ import { UseAnchorRegistryResult } from './use-anchor-registry';
5
+ import { UseFloatingCardStateResult } from './use-floating-card-state';
6
+
7
+ interface UseFloatingLayoutEngineProps {
8
+ blurFloatingCard: (floatingCardId: string) => void;
9
+ closeFloatingCard: (floatingCardId: string) => void;
10
+ editor: Editor;
11
+ editorWrapperRef: RefObject<HTMLDivElement>;
12
+ floatingCardIdsKey: string;
13
+ floatingCards: CommentFloatingCard[];
14
+ focusedFloatingCardId: string | null;
15
+ isDesktopFloatingEnabled: boolean;
16
+ isHidden: boolean;
17
+ scrollContainerRef: RefObject<HTMLDivElement>;
18
+ anchorRegistry: UseAnchorRegistryResult;
19
+ floatingCardState: UseFloatingCardStateResult;
20
+ }
21
+ export interface UseFloatingLayoutEngineResult {
22
+ floatingCardListContainerRef: RefObject<HTMLDivElement>;
23
+ registerCardNode: (floatingCardId: string, node: HTMLDivElement | null) => void;
24
+ }
25
+ export declare const useFloatingLayoutEngine: ({ blurFloatingCard, closeFloatingCard, editor, editorWrapperRef, floatingCardIdsKey, floatingCards, focusedFloatingCardId, isDesktopFloatingEnabled, isHidden, scrollContainerRef, anchorRegistry, floatingCardState, }: UseFloatingLayoutEngineProps) => UseFloatingLayoutEngineResult;
26
+ export {};
@@ -0,0 +1 @@
1
+ export declare function useIsSelectedContentDeleted(commentId: string | undefined, selectedContent: string | undefined, commentTabId: string | undefined): boolean;
@@ -31,9 +31,10 @@ export interface DocumentTabsSidebarProps {
31
31
  tabConfig?: DocumentOutlineProps['tabConfig'];
32
32
  deleteTab?: (tabId: string) => void;
33
33
  isConnected?: boolean;
34
+ isFocusMode?: boolean;
34
35
  }
35
36
  export declare const DocumentTabsSidebar: ({ tabSectionContainer, ...rest }: DocumentTabsSidebarProps) => import("react/jsx-runtime").JSX.Element | null;
36
- export declare const TabSidebar: ({ tabs, activeTabId, setActiveTabId, showTOC, setShowTOC, hasToC, isPreviewMode, editor, items, setItems, orientation, createTab, renameTab, duplicateTab, orderTab, tabCommentCounts, isVersionHistoryMode, tabConfig, deleteTab, isConnected, }: DocumentTabsSidebarProps) => import("react/jsx-runtime").JSX.Element;
37
+ export declare const TabSidebar: ({ tabs, activeTabId, setActiveTabId, showTOC, setShowTOC, hasToC, isPreviewMode, editor, items, setItems, orientation, createTab, renameTab, duplicateTab, orderTab, tabCommentCounts, isVersionHistoryMode, tabConfig, deleteTab, isConnected, isFocusMode, }: DocumentTabsSidebarProps) => import("react/jsx-runtime").JSX.Element;
37
38
  export declare const DdocTab: ({ tab, tabIndex, tabCount, handleEmojiChange, handleNameChange, onClick, editor, tocItem, setTocItems, orientation, activeTabId, duplicateTab, commentCount, moveTabUp, moveTabDown, isPreviewMode, isVersionHistoryMode, tabConfig, onDelete, showOutline, onShowOutlineChange, isConnected, }: {
38
39
  tab: Tab;
39
40
  tabIndex: number;
@@ -0,0 +1,70 @@
1
+ import { Extension, Editor } from '@tiptap/core';
2
+ import { EditorState, PluginKey } from '@tiptap/pm/state';
3
+ import { Transform } from '@tiptap/pm/transform';
4
+ import { DecorationSet } from '@tiptap/pm/view';
5
+
6
+ import * as Y from 'yjs';
7
+ export interface CommentAnchor {
8
+ id: string;
9
+ anchorFrom: Y.RelativePosition;
10
+ anchorTo: Y.RelativePosition;
11
+ resolved: boolean;
12
+ deleted: boolean;
13
+ }
14
+ interface CommentDecorationPluginState {
15
+ decorations: DecorationSet;
16
+ }
17
+ type CommentAnchorRange = {
18
+ from: number;
19
+ to: number;
20
+ };
21
+ type CommentAnchorRelativeRange = {
22
+ anchorFrom: Y.RelativePosition;
23
+ anchorTo: Y.RelativePosition;
24
+ };
25
+ export type CommentAnchorTransactionChange = {
26
+ id: string;
27
+ type: 'unchanged';
28
+ } | {
29
+ id: string;
30
+ type: 'deleted';
31
+ } | ({
32
+ id: string;
33
+ type: 'edited';
34
+ } & CommentAnchorRange & CommentAnchorRelativeRange);
35
+ export declare const commentDecorationPluginKey: PluginKey<CommentDecorationPluginState>;
36
+ export declare function resolveCommentAnchorRangeInState(anchor: Pick<CommentAnchor, 'anchorFrom' | 'anchorTo'>, state: EditorState): CommentAnchorRange | null;
37
+ export declare function resolveCommentAnchorRangeForAnalysis(anchor: Pick<CommentAnchor, 'id' | 'anchorFrom' | 'anchorTo'>, state: EditorState): CommentAnchorRange | null;
38
+ /**
39
+ * Analyze transaction changes to classify each active anchor's mutation status.
40
+ *
41
+ * This is the core transaction analysis function that determines
42
+ * whether each anchor remains unchanged, gets edited, or is deleted.
43
+ *
44
+ * Classification rules (in order):
45
+ * 1. Skip deleted or resolved anchors → 'unchanged'
46
+ * 2. If anchor has no old position → 'unchanged'
47
+ * 3. If no changed ranges touch the anchor → 'unchanged'
48
+ * 4. If any changed range fully covers the anchor → 'deleted' (full-span replacement)
49
+ * 5. If combined changed ranges fully cover the anchor → 'deleted' (multi-step removal)
50
+ * 6. If anchor maps through transform → check if position or content changed:
51
+ * a. If both unchanged → 'unchanged'
52
+ * b. Otherwise → 'edited' (return new position and relative anchor)
53
+ * 7. If mapping fails → 'deleted'
54
+ */
55
+ export declare function analyzeCommentAnchorTransactionChanges(anchors: CommentAnchor[], oldState: EditorState, newState: EditorState, transform: Transform): CommentAnchorTransactionChange[];
56
+ export interface CommentDecorationOptions {
57
+ getAnchors: () => CommentAnchor[];
58
+ getActiveCommentId: () => string | null;
59
+ }
60
+ export declare const CommentDecorationExtension: Extension<CommentDecorationOptions, any>;
61
+ /**
62
+ * Public helper functions for comment anchor creation and inspection.
63
+ * These are consumed by the draft-creation flow and transaction-analysis layer.
64
+ */
65
+ export declare function createCommentAnchorFromEditor(editor: Editor, from: number, to: number): CommentAnchorRelativeRange | null;
66
+ export declare function createCommentAnchorFromSelection(editor: Editor): CommentAnchorRelativeRange | null;
67
+ export declare function triggerDecorationRebuild(editor: Editor): void;
68
+ export declare function getCommentAtPosition(editor: Editor, pos: number, getAnchors: () => CommentAnchor[]): CommentAnchor | null;
69
+ export declare function getCommentAnchorRange(editor: Editor, commentId: string, getAnchors: () => CommentAnchor[]): CommentAnchorRange | null;
70
+ export {};
@@ -1,5 +1,7 @@
1
1
  import { Mark, Range } from '@tiptap/core';
2
2
  import { Mark as PMMark } from '@tiptap/pm/model';
3
+ import { PluginKey, EditorState } from '@tiptap/pm/state';
4
+ import { DecorationSet } from '@tiptap/pm/view';
3
5
 
4
6
  declare module '@tiptap/core' {
5
7
  interface Commands<ReturnType> {
@@ -28,6 +30,18 @@ declare module '@tiptap/core' {
28
30
  * Unset comment active
29
31
  */
30
32
  unsetCommentActive: () => ReturnType;
33
+ /**
34
+ * Add a local draft anchor that tracks through transactions.
35
+ */
36
+ setDraftComment: (draftId: string) => ReturnType;
37
+ /**
38
+ * Remove a local draft anchor.
39
+ */
40
+ unsetDraftComment: (draftId: string) => ReturnType;
41
+ /**
42
+ * Replace a draft anchor with a persisted comment mark.
43
+ */
44
+ promoteDraftComment: (draftId: string, commentId: string) => ReturnType;
31
45
  };
32
46
  }
33
47
  }
@@ -35,6 +49,10 @@ export interface MarkWithRange {
35
49
  mark: PMMark;
36
50
  range: Range;
37
51
  }
52
+ export interface CommentMarkMatch {
53
+ commentId: string;
54
+ resolved: boolean;
55
+ }
38
56
  export interface CommentOptions {
39
57
  HTMLAttributes: Record<string, any>;
40
58
  onCommentActivated: (commentId: string) => void;
@@ -45,6 +63,20 @@ export interface CommentOptions {
45
63
  export interface CommentStorage {
46
64
  activeCommentId: string | null;
47
65
  }
66
+ export interface DraftCommentRange {
67
+ draftId: string;
68
+ from: number;
69
+ to: number;
70
+ }
71
+ interface DraftCommentPluginState {
72
+ decorations: DecorationSet;
73
+ drafts: Map<string, DraftCommentRange>;
74
+ }
75
+ export declare const draftCommentPluginKey: PluginKey<DraftCommentPluginState>;
76
+ export declare const getDraftCommentState: (state: EditorState) => DraftCommentPluginState | undefined;
77
+ export declare const getDraftCommentRange: (state: EditorState, draftId: string) => DraftCommentRange | null;
78
+ export declare const getCommentMarkAtPosition: (state: EditorState, pos: number) => CommentMarkMatch | null;
79
+ export declare const getCommentMarkRange: (state: EditorState, commentId: string) => Range | null;
48
80
  export interface IComment {
49
81
  id?: string;
50
82
  tabId?: string;
@@ -63,3 +95,4 @@ export interface IComment {
63
95
  version?: string;
64
96
  }
65
97
  export declare const CommentExtension: Mark<CommentOptions, CommentStorage>;
98
+ export {};
@@ -1,17 +1,18 @@
1
- import { Attrs, Node as ProseMirrorNode } from '@tiptap/pm/model';
2
- import { Editor } from '@tiptap/core';
1
+ import { Attrs } from '@tiptap/pm/model';
3
2
 
4
3
  interface ResizableMediaAttributes {
5
4
  dataAlign: string;
6
5
  dataFloat: null | string;
6
+ showCaptionInput?: boolean;
7
+ caption?: string;
7
8
  }
8
9
  type UpdateAttributes = (attrs: Partial<ResizableMediaAttributes>) => void;
9
- type Action = (updateAttributes: UpdateAttributes, editor?: Editor, getPos?: (() => number | undefined) | boolean) => void;
10
+ type Action = (updateAttributes: UpdateAttributes) => void;
10
11
  interface ResizableMediaAction {
11
12
  tooltip: string;
12
13
  icon?: string;
13
14
  action?: Action;
14
- isActive?: (attrs: Attrs, node?: ProseMirrorNode) => boolean;
15
+ isActive?: (attrs: Attrs) => boolean;
15
16
  delete?: (d: () => void) => void;
16
17
  }
17
18
  export declare const resizableMediaActions: ResizableMediaAction[];
@@ -4,4 +4,4 @@ import { IpfsImageFetchPayload } from '../../types.ts';
4
4
  export declare const getResizableMediaNodeView: (ipfsImageFetchFn: (_data: IpfsImageFetchPayload) => Promise<{
5
5
  url: string;
6
6
  file: File;
7
- }>, fetchV1ImageFn: (url: string) => Promise<ArrayBuffer | undefined>) => ({ node, updateAttributes, deleteNode, selected, editor, getPos, }: NodeViewProps) => import("react/jsx-runtime").JSX.Element;
7
+ }>, fetchV1ImageFn: (url: string) => Promise<ArrayBuffer | undefined>) => ({ node, updateAttributes, deleteNode, selected }: NodeViewProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,7 @@
1
1
  import { Dispatch, MutableRefObject, SetStateAction } from 'react';
2
- import { DdocProps, ThemeKey } from '../types';
2
+ import { DdocProps, SerializedCommentAnchor, ThemeKey } from '../types';
3
3
  import { AnyExtension, Editor } from '@tiptap/react';
4
+ import { CommentAnchor } from '../extensions/comment/comment-decoration-plugin';
4
5
  import { ToCItemType } from '../components/toc/types';
5
6
  import { CollabConnectionConfig, CollaborationProps } from '../sync-local/types';
6
7
 
@@ -17,6 +18,7 @@ interface UseTabEditorArgs {
17
18
  isSyncing?: boolean;
18
19
  awareness?: any;
19
20
  disableInlineComment?: boolean;
21
+ isFocusMode?: boolean;
20
22
  onCommentInteraction?: DdocProps['onCommentInteraction'];
21
23
  onError?: DdocProps['onError'];
22
24
  ipfsImageUploadFn?: DdocProps['ipfsImageUploadFn'];
@@ -47,8 +49,9 @@ interface UseTabEditorArgs {
47
49
  activeTabId: string;
48
50
  theme?: ThemeKey;
49
51
  editorRef?: MutableRefObject<Editor | null>;
52
+ initialCommentAnchors?: SerializedCommentAnchor[];
50
53
  }
51
- export declare const useTabEditor: ({ ydoc, isVersionMode, hasTabState, versionId, isPreviewMode, initialContent, collaboration, isReady, isSyncing, awareness, disableInlineComment, onCommentInteraction, onError, ipfsImageUploadFn, metadataProxyUrl, onCopyHeadingLink, ipfsImageFetchFn, fetchV1ImageFn, isConnected, activeModel, maxTokens, isAIAgentEnabled, setCharacterCount, setWordCount, setPageCount, setIsContentLoading, setIsCollabContentLoading, unFocused, zoomLevel, isPresentationMode, onInvalidContentError, ignoreCorruptedData, onCollaboratorChange, onConnect, hasCollabContentInitialised, initialiseYjsIndexedDbProvider, externalExtensions, isContentLoading, activeTabId, theme, editorRef, }: UseTabEditorArgs) => {
54
+ export declare const useTabEditor: ({ ydoc, isVersionMode, hasTabState, versionId, isPreviewMode, initialContent, collaboration, isReady, isSyncing, awareness, disableInlineComment, isFocusMode, onCommentInteraction, onError, ipfsImageUploadFn, metadataProxyUrl, onCopyHeadingLink, ipfsImageFetchFn, fetchV1ImageFn, isConnected, activeModel, maxTokens, isAIAgentEnabled, setCharacterCount, setWordCount, setPageCount, setIsContentLoading, setIsCollabContentLoading, unFocused, zoomLevel, isPresentationMode, onInvalidContentError, ignoreCorruptedData, onCollaboratorChange, onConnect, hasCollabContentInitialised, initialiseYjsIndexedDbProvider, externalExtensions, isContentLoading, activeTabId, theme, editorRef, initialCommentAnchors, }: UseTabEditorArgs) => {
52
55
  editor: Editor | null;
53
56
  ref: import('react').RefObject<HTMLDivElement>;
54
57
  slides: string[];
@@ -59,5 +62,6 @@ export declare const useTabEditor: ({ ydoc, isVersionMode, hasTabState, versionI
59
62
  setActiveCommentId: Dispatch<SetStateAction<string | null>>;
60
63
  focusCommentWithActiveId: (id: string) => void;
61
64
  isContentLoading: boolean | undefined;
65
+ commentAnchorsRef: MutableRefObject<CommentAnchor[]>;
62
66
  };
63
67
  export {};
@@ -0,0 +1,56 @@
1
+ import { default as React } from 'react';
2
+ import { Editor } from '@tiptap/core';
3
+ import { IComment } from '../extensions/comment';
4
+ import { CommentAnchor } from '../extensions/comment/comment-decoration-plugin';
5
+ import { CommentMutationMeta, SerializedCommentAnchor } from '../types';
6
+
7
+ import * as Y from 'yjs';
8
+ export interface CommentStoreProviderProps {
9
+ children: React.ReactNode;
10
+ editor: Editor | null;
11
+ ydoc: Y.Doc;
12
+ isFocusMode?: boolean;
13
+ setActiveCommentId: (id: string | null) => void;
14
+ focusCommentWithActiveId: (id: string) => void;
15
+ setInitialComments?: React.Dispatch<React.SetStateAction<IComment[]>>;
16
+ onNewComment?: (comment: IComment, meta?: CommentMutationMeta) => void;
17
+ onEditComment?: (commentId: string, meta?: CommentMutationMeta) => void;
18
+ onEditReply?: (commentId: string, replyId: string, meta?: CommentMutationMeta) => void;
19
+ onCommentReply?: (activeCommentId: string, reply: IComment) => void;
20
+ onResolveComment?: (commentId: string, meta?: CommentMutationMeta) => void;
21
+ onUnresolveComment?: (commentId: string, meta?: CommentMutationMeta) => void;
22
+ onDeleteComment?: (commentId: string, meta?: CommentMutationMeta) => void;
23
+ onInlineComment?: () => void;
24
+ onComment?: () => void;
25
+ setCommentDrawerOpen?: (open: boolean) => void;
26
+ connectViaWallet?: () => Promise<void>;
27
+ connectViaUsername?: (username: string) => Promise<void>;
28
+ ensResolutionUrl: string;
29
+ commentAnchorsRef?: React.MutableRefObject<CommentAnchor[]>;
30
+ initialCommentAnchors?: SerializedCommentAnchor[];
31
+ initialComments: IComment[];
32
+ username: string | null;
33
+ activeCommentId: string | null;
34
+ activeTabId: string;
35
+ isConnected?: boolean;
36
+ isLoading?: boolean;
37
+ isDDocOwner?: boolean;
38
+ setUsername?: React.Dispatch<React.SetStateAction<string>>;
39
+ }
40
+ export declare const CommentStoreProvider: ({ children, editor, ydoc, isFocusMode, setActiveCommentId, focusCommentWithActiveId, setInitialComments, onNewComment, onEditComment, onEditReply, onCommentReply, onResolveComment, onUnresolveComment, onDeleteComment, onInlineComment, onComment, setCommentDrawerOpen, connectViaWallet, connectViaUsername, ensResolutionUrl, commentAnchorsRef, initialCommentAnchors, setUsername: setUsernameProp, initialComments, username, activeCommentId, activeTabId, isConnected, isLoading, isDDocOwner, }: CommentStoreProviderProps) => import("react/jsx-runtime").JSX.Element;
41
+ interface CommentRefsContextType {
42
+ commentsSectionRef: React.RefObject<HTMLDivElement>;
43
+ replySectionRef: React.RefObject<HTMLDivElement>;
44
+ portalRef: React.RefObject<HTMLDivElement>;
45
+ buttonRef: React.RefObject<HTMLDivElement>;
46
+ dropdownRef: React.RefObject<HTMLDivElement>;
47
+ mobileDraftRef: React.RefObject<HTMLDivElement>;
48
+ }
49
+ export declare const useCommentRefs: () => CommentRefsContextType;
50
+ interface CommentAnchorsContextType {
51
+ activeCommentAnchorIds: Set<string>;
52
+ activeCommentAnchorIdsTabId: string | null;
53
+ hasRenderedCommentAnchor: (commentId: string) => boolean;
54
+ }
55
+ export declare const useCommentAnchors: () => CommentAnchorsContextType;
56
+ export {};
@@ -0,0 +1,195 @@
1
+ import { Editor } from '@tiptap/react';
2
+ import { default as React } from 'react';
3
+ import { CommentAnchor } from '../extensions/comment/comment-decoration-plugin';
4
+ import { CommentFloatingCard, EnsCache, InlineCommentData, InlineCommentDraft, InlineDraftLocation } from '../components/inline-comment/context/types';
5
+ import { EnsStatus } from '../components/inline-comment/types';
6
+ import { IComment } from '../extensions/comment';
7
+ import { CommentMutationMeta, CommentMutationType } from '../types';
8
+
9
+ import * as Y from 'yjs';
10
+ export interface CommentExternalDeps {
11
+ editor: Editor | null;
12
+ ydoc: Y.Doc;
13
+ setActiveCommentId: (id: string | null) => void;
14
+ focusCommentWithActiveId: (id: string) => void;
15
+ setInitialComments?: React.Dispatch<React.SetStateAction<IComment[]>>;
16
+ setUsername?: React.Dispatch<React.SetStateAction<string>>;
17
+ onNewComment?: (comment: IComment, meta?: CommentMutationMeta) => void;
18
+ onEditComment?: (commentId: string, meta?: CommentMutationMeta) => void;
19
+ onEditReply?: (commentId: string, replyId: string, meta?: CommentMutationMeta) => void;
20
+ onCommentReply?: (activeCommentId: string, reply: IComment) => void;
21
+ onResolveComment?: (commentId: string, meta?: CommentMutationMeta) => void;
22
+ onUnresolveComment?: (commentId: string, meta?: CommentMutationMeta) => void;
23
+ onDeleteComment?: (commentId: string, meta?: CommentMutationMeta) => void;
24
+ onInlineComment?: () => void;
25
+ onComment?: () => void;
26
+ setCommentDrawerOpen?: (open: boolean) => void;
27
+ connectViaWallet?: () => Promise<void>;
28
+ connectViaUsername?: (username: string) => Promise<void>;
29
+ ensResolutionUrl: string;
30
+ commentAnchorsRef?: React.MutableRefObject<CommentAnchor[]>;
31
+ refreshCommentAnchorState?: () => void;
32
+ }
33
+ type FloatingCardsUpdater = React.SetStateAction<CommentFloatingCard[]>;
34
+ type InlineCommentDataUpdater = Partial<InlineCommentData> | ((prev: InlineCommentData) => Partial<InlineCommentData> | InlineCommentData);
35
+ type InlineDraftRecordMap = Record<string, InlineCommentDraft>;
36
+ type CreateInlineDraftOptions = {
37
+ location?: InlineDraftLocation;
38
+ tabId?: string;
39
+ allowEmptySelection?: boolean;
40
+ };
41
+ type CommentEditRequest = {
42
+ requestId: string;
43
+ kind: 'comment' | 'reply';
44
+ commentId: string;
45
+ replyId?: string;
46
+ text: string;
47
+ };
48
+ type ReplyEditTarget = {
49
+ kind: 'comment' | 'reply';
50
+ commentId: string;
51
+ replyId?: string;
52
+ originalText: string;
53
+ };
54
+ type CommentEditCompletion = {
55
+ nonce: number;
56
+ kind: 'comment' | 'reply';
57
+ commentId: string;
58
+ replyId?: string;
59
+ };
60
+ type FocusCommentInEditorOptions = {
61
+ source?: 'explicit-ui' | 'passive';
62
+ };
63
+ type ReconcileFloatingThreadsForActiveTabOptions = {
64
+ hydrationReady: boolean;
65
+ };
66
+ export declare const EXPLICIT_COMMENT_FOCUS_META = "inlineCommentExplicitFocus";
67
+ export interface CommentStoreState {
68
+ initialComments: IComment[];
69
+ tabComments: IComment[];
70
+ activeComments: IComment[];
71
+ activeComment: IComment | undefined;
72
+ activeCommentIndex: number;
73
+ username: string | null;
74
+ activeCommentId: string | null;
75
+ activeTabId: string;
76
+ isConnected: boolean;
77
+ isLoading: boolean;
78
+ isDDocOwner: boolean;
79
+ onComment: (() => void) | null;
80
+ setCommentDrawerOpen: ((open: boolean) => void) | null;
81
+ connectViaWallet: (() => Promise<void>) | null;
82
+ connectViaUsername: ((username: string) => Promise<void>) | null;
83
+ isCommentActive: boolean;
84
+ isCommentResolved: boolean;
85
+ showResolved: boolean;
86
+ reply: string;
87
+ comment: string;
88
+ openReplyId: string | null;
89
+ selectedText: string;
90
+ isCommentOpen: boolean;
91
+ isBubbleMenuSuppressed: boolean;
92
+ inlineCommentData: InlineCommentData;
93
+ floatingCards: CommentFloatingCard[];
94
+ pendingPrehydrationFloatingThreadIds: string[];
95
+ inlineDrafts: InlineDraftRecordMap;
96
+ activeDraftId: string | null;
97
+ isDesktopFloatingEnabled: boolean;
98
+ ensCache: EnsCache;
99
+ inProgressFetch: string[];
100
+ editRequest: CommentEditRequest | null;
101
+ replyEditTarget: ReplyEditTarget | null;
102
+ editCompletion: CommentEditCompletion | null;
103
+ _externalDepsRef: React.RefObject<CommentExternalDeps | null> | null;
104
+ setExternalDepsRef: (ref: React.RefObject<CommentExternalDeps | null>) => void;
105
+ _recomputeDerived: () => void;
106
+ setInitialComments: (comments: IComment[]) => void;
107
+ setUsername: (username: string | null) => void;
108
+ setActiveCommentId: (id: string | null) => void;
109
+ setActiveTabId: (tabId: string) => void;
110
+ setIsConnected: (connected: boolean) => void;
111
+ setIsLoading: (loading: boolean) => void;
112
+ setIsDDocOwner: (isOwner: boolean) => void;
113
+ setOnComment: (fn: (() => void) | null) => void;
114
+ setCommentDrawerOpenFn: (fn: ((open: boolean) => void) | null) => void;
115
+ setConnectViaWallet: (fn: (() => Promise<void>) | null) => void;
116
+ setConnectViaUsername: (fn: ((username: string) => Promise<void>) | null) => void;
117
+ setIsCommentActive: (active: boolean) => void;
118
+ setIsCommentResolved: (resolved: boolean) => void;
119
+ getTabComments: () => IComment[];
120
+ getActiveComment: () => IComment | undefined;
121
+ getActiveComments: () => IComment[];
122
+ getActiveCommentIndex: () => number;
123
+ getIsCommentActive: () => boolean;
124
+ getIsCommentResolved: () => boolean;
125
+ setShowResolved: (show: boolean) => void;
126
+ setReply: (reply: string) => void;
127
+ setComment: (comment: string) => void;
128
+ setOpenReplyId: (id: string | null) => void;
129
+ setSelectedText: (text: string) => void;
130
+ setIsCommentOpen: (open: boolean) => void;
131
+ setIsBubbleMenuSuppressed: (suppressed: boolean) => void;
132
+ setInlineCommentData: (data: InlineCommentDataUpdater) => void;
133
+ setFloatingCards: (floatingCards: FloatingCardsUpdater) => void;
134
+ clearFloatingCards: () => void;
135
+ setActiveDraftId: (draftId: string | null) => void;
136
+ setIsDesktopFloatingEnabled: (enabled: boolean) => void;
137
+ toggleResolved: () => void;
138
+ clearEditRequest: (requestId: string) => void;
139
+ setReplyEditTarget: (target: ReplyEditTarget | null) => void;
140
+ cancelReplyEdit: () => void;
141
+ handleInput: (e: React.FormEvent<HTMLTextAreaElement>, content: string) => void;
142
+ handleReplyChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
143
+ handleCommentChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
144
+ handleCommentKeyDown: (e: React.KeyboardEvent<HTMLTextAreaElement>, tabId?: string) => void;
145
+ handleReplyKeyDown: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;
146
+ handleReplySubmit: () => void;
147
+ handleCommentSubmit: (tabId?: string) => void;
148
+ handleInlineComment: () => void;
149
+ addComment: (content?: string, usernameProp?: string) => string | undefined;
150
+ createFloatingDraft: (options?: CreateInlineDraftOptions) => string | null;
151
+ updateInlineDraftText: (draftId: string, value: string) => void;
152
+ cancelInlineDraft: (draftId: string) => void;
153
+ submitInlineDraft: (draftId: string) => void;
154
+ updateFloatingDraftText: (draftId: string, value: string) => void;
155
+ cancelFloatingDraft: (draftId: string) => void;
156
+ submitFloatingDraft: (draftId: string) => void;
157
+ openFloatingThread: (commentId: string) => void;
158
+ closeFloatingCard: (floatingCardId: string) => void;
159
+ blurFloatingCard: (floatingCardId: string) => void;
160
+ focusFloatingCard: (floatingCardId: string) => void;
161
+ removeInvalidFloatingDrafts: () => void;
162
+ reconcileFloatingThreadsForActiveTab: (options: ReconcileFloatingThreadsForActiveTabOptions) => void;
163
+ syncFloatingThreadCardWithActiveComment: () => void;
164
+ submitPendingFloatingDrafts: () => void;
165
+ /**
166
+ * Apply anchor edits to local comment state.
167
+ * Called after transaction analysis identifies edited anchors.
168
+ * Updates selectedContent for each affected comment
169
+ * so thread display stays in sync immediately, before consumer rehydration.
170
+ */
171
+ applyCommentAnchorEdits: (edits: Array<{
172
+ commentId: string;
173
+ selectedContent: string;
174
+ }>) => void;
175
+ resolveComment: (commentId: string) => void;
176
+ unresolveComment: (commentId: string) => void;
177
+ deleteComment: (commentId: string, options?: {
178
+ skipExternalCallback?: boolean;
179
+ }) => void;
180
+ deleteReply: (commentId: string, replyId: string) => void;
181
+ requestEditComment: (commentId: string) => void;
182
+ requestEditReply: (commentId: string, replyId: string) => void;
183
+ editCommentContent: (commentId: string, content: string) => void;
184
+ editReplyContent: (commentId: string, replyId: string, content: string) => void;
185
+ handleAddReply: (activeCommentId: string, replyContent: string, replyCallback?: (activeCommentId: string, reply: IComment) => void) => void;
186
+ focusCommentInEditor: (commentId: string, options?: FocusCommentInEditorOptions) => void;
187
+ onPrevComment: () => void;
188
+ onNextComment: () => void;
189
+ getEnsStatus: (walletAddress: string, setEnsStatus: React.Dispatch<React.SetStateAction<EnsStatus>>) => void;
190
+ createMutationMeta: (type: CommentMutationType, mutate: () => boolean) => CommentMutationMeta | undefined;
191
+ }
192
+ export declare const createCommentStore: () => import('zustand').StoreApi<CommentStoreState>;
193
+ export declare const CommentStoreContext: React.Context<import('zustand').StoreApi<CommentStoreState> | null>;
194
+ export declare function useCommentStore<T>(selector: (state: CommentStoreState) => T): T;
195
+ export {};
@@ -19,10 +19,21 @@ export type InlineCommentData = {
19
19
  highlightedTextContent: string;
20
20
  handleClick: boolean;
21
21
  };
22
- export type CommentMutationType = 'create' | 'resolve' | 'unresolve' | 'delete';
22
+ export type CommentMutationType = 'create' | 'edit' | 'resolve' | 'unresolve' | 'delete';
23
23
  export interface CommentMutationMeta {
24
24
  type: CommentMutationType;
25
- updateChunk: string;
25
+ updateChunk?: string;
26
+ anchorFrom?: string;
27
+ anchorTo?: string;
28
+ selectedContent?: string;
29
+ content?: string;
30
+ }
31
+ export interface SerializedCommentAnchor {
32
+ id: string;
33
+ anchorFrom: string;
34
+ anchorTo: string;
35
+ resolved: boolean;
36
+ deleted: boolean;
26
37
  }
27
38
  export interface CommentAccountProps {
28
39
  isConnected?: boolean;
@@ -107,9 +118,12 @@ export interface DdocProps extends CommentAccountProps {
107
118
  commentDrawerOpen?: boolean;
108
119
  setCommentDrawerOpen?: React.Dispatch<SetStateAction<boolean>>;
109
120
  initialComments?: IComment[];
121
+ initialCommentAnchors?: SerializedCommentAnchor[];
110
122
  setInitialComments?: React.Dispatch<SetStateAction<IComment[]>>;
111
123
  onCommentReply?: (activeCommentId: string, reply: IComment) => void;
112
124
  onNewComment?: (newComment: IComment, meta?: CommentMutationMeta) => void;
125
+ onEditComment?: (activeCommentId: string, meta?: CommentMutationMeta) => void;
126
+ onEditReply?: (activeCommentId: string, replyId: string, meta?: CommentMutationMeta) => void;
113
127
  onResolveComment?: (activeCommentId: string, meta?: CommentMutationMeta) => void;
114
128
  onUnresolveComment?: (activeCommentId: string, meta?: CommentMutationMeta) => void;
115
129
  onDeleteComment?: (activeCommentId: string, meta?: CommentMutationMeta) => void;
@@ -1,7 +1,9 @@
1
1
  import { DdocProps } from './types';
2
2
  import { Editor } from '@tiptap/react';
3
3
 
4
- export declare const useDdocEditor: ({ isPreviewMode, initialContent, versionHistoryState, collaboration, onChange, onCollaboratorChange, onCommentInteraction, onError, setCharacterCount, setWordCount, setPageCount, ipfsImageUploadFn, ddocId, enableIndexeddbSync, unFocused, theme, zoomLevel, onInvalidContentError, ignoreCorruptedData, isPresentationMode, metadataProxyUrl, extensions: externalExtensions, onCopyHeadingLink, ipfsImageFetchFn, fetchV1ImageFn, isConnected, activeModel, maxTokens, isAIAgentEnabled, onIndexedDbError, disableInlineComment, ...rest }: Partial<DdocProps>) => {
4
+ export declare const useDdocEditor: ({ isPreviewMode, initialContent, versionHistoryState, collaboration, onChange, onCollaboratorChange, onCommentInteraction, onError, setCharacterCount, setWordCount, setPageCount, ipfsImageUploadFn, ddocId, enableIndexeddbSync, unFocused, isFocusMode, theme, zoomLevel, onInvalidContentError, ignoreCorruptedData, isPresentationMode, metadataProxyUrl, extensions: externalExtensions, onCopyHeadingLink, ipfsImageFetchFn, fetchV1ImageFn, isConnected, activeModel, maxTokens, isAIAgentEnabled, onIndexedDbError, disableInlineComment, initialCommentAnchors, ...rest }: Partial<DdocProps> & {
5
+ isFocusMode?: boolean;
6
+ }) => {
5
7
  ydoc: import('yjs').Doc;
6
8
  awareness: import('y-protocols/awareness.js').Awareness | null;
7
9
  refreshYjsIndexedDbProvider: () => Promise<void>;
@@ -38,4 +40,5 @@ export declare const useDdocEditor: ({ isPreviewMode, initialContent, versionHis
38
40
  activeCommentId: string | null;
39
41
  setActiveCommentId: import('react').Dispatch<import('react').SetStateAction<string | null>>;
40
42
  focusCommentWithActiveId: (id: string) => void;
43
+ commentAnchorsRef: import('react').MutableRefObject<import('./extensions/comment/comment-decoration-plugin').CommentAnchor[]>;
41
44
  };
@@ -0,0 +1,5 @@
1
+ import { CommentAnchor } from '../extensions/comment/comment-decoration-plugin';
2
+ import { SerializedCommentAnchor } from '../types';
3
+
4
+ export declare const getSerializedCommentAnchorsKey: (anchors?: SerializedCommentAnchor[]) => string | null;
5
+ export declare const deserializeCommentAnchors: (anchors?: SerializedCommentAnchor[]) => CommentAnchor[];
@@ -0,0 +1,21 @@
1
+ import { MutableRefObject } from 'react';
2
+ import { Editor } from '@tiptap/react';
3
+ import { CommentAnchor } from '../extensions/comment/comment-decoration-plugin';
4
+
5
+ export declare const MOBILE_COMMENT_DRAWER_CANVAS_OFFSET_VAR = "--mobile-comment-drawer-canvas-offset";
6
+ type CommentSelectionRange = {
7
+ from: number;
8
+ to: number;
9
+ };
10
+ export declare const clearMobileCommentDrawerCanvasOffset: (editorRoot?: HTMLElement | null) => void;
11
+ export declare const resolveCommentSelectionRange: ({ editor, commentId, commentAnchorsRef, }: {
12
+ editor: Editor;
13
+ commentId: string;
14
+ commentAnchorsRef?: MutableRefObject<CommentAnchor[]>;
15
+ }) => CommentSelectionRange | null;
16
+ export declare const scrollCommentSelectionRangeIntoView: ({ editor, selectionRange, behavior, }: {
17
+ editor: Editor;
18
+ selectionRange: CommentSelectionRange;
19
+ behavior?: ScrollBehavior;
20
+ }) => void;
21
+ export {};