doclific 0.2.0 → 0.2.2

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 (220) hide show
  1. package/LICENSE +17 -0
  2. package/dist/bin/doclific.js +36 -8
  3. package/package.json +11 -4
  4. package/readme.md +77 -0
  5. package/.gitattributes +0 -2
  6. package/.prettierignore +0 -5
  7. package/.prettierrc +0 -9
  8. package/.vscode/settings.json +0 -13
  9. package/frontend/components.json +0 -24
  10. package/frontend/eslint.config.js +0 -23
  11. package/frontend/index.html +0 -25
  12. package/frontend/package-lock.json +0 -15754
  13. package/frontend/public/logo.svg +0 -1
  14. package/frontend/src/App.tsx +0 -21
  15. package/frontend/src/components/app-sidebar.tsx +0 -393
  16. package/frontend/src/components/editor/editor-base-kit.tsx +0 -43
  17. package/frontend/src/components/editor/editor-kit.tsx +0 -93
  18. package/frontend/src/components/editor/plugins/align-base-kit.tsx +0 -16
  19. package/frontend/src/components/editor/plugins/align-kit.tsx +0 -18
  20. package/frontend/src/components/editor/plugins/autoformat-kit.tsx +0 -236
  21. package/frontend/src/components/editor/plugins/basic-blocks-base-kit.tsx +0 -35
  22. package/frontend/src/components/editor/plugins/basic-blocks-kit.tsx +0 -88
  23. package/frontend/src/components/editor/plugins/basic-marks-base-kit.tsx +0 -27
  24. package/frontend/src/components/editor/plugins/basic-marks-kit.tsx +0 -41
  25. package/frontend/src/components/editor/plugins/basic-nodes-kit.tsx +0 -6
  26. package/frontend/src/components/editor/plugins/block-menu-kit.tsx +0 -14
  27. package/frontend/src/components/editor/plugins/block-placeholder-kit.tsx +0 -17
  28. package/frontend/src/components/editor/plugins/block-selection-kit.tsx +0 -32
  29. package/frontend/src/components/editor/plugins/callout-base-kit.tsx +0 -7
  30. package/frontend/src/components/editor/plugins/callout-kit.tsx +0 -7
  31. package/frontend/src/components/editor/plugins/code-block-base-kit.tsx +0 -23
  32. package/frontend/src/components/editor/plugins/code-block-kit.tsx +0 -26
  33. package/frontend/src/components/editor/plugins/codebase-kit.tsx +0 -23
  34. package/frontend/src/components/editor/plugins/column-base-kit.tsx +0 -11
  35. package/frontend/src/components/editor/plugins/column-kit.tsx +0 -10
  36. package/frontend/src/components/editor/plugins/comment-base-kit.tsx +0 -7
  37. package/frontend/src/components/editor/plugins/comment-kit.tsx +0 -97
  38. package/frontend/src/components/editor/plugins/cursor-overlay-kit.tsx +0 -13
  39. package/frontend/src/components/editor/plugins/date-base-kit.tsx +0 -5
  40. package/frontend/src/components/editor/plugins/date-kit.tsx +0 -7
  41. package/frontend/src/components/editor/plugins/discussion-kit.tsx +0 -148
  42. package/frontend/src/components/editor/plugins/dnd-kit.tsx +0 -28
  43. package/frontend/src/components/editor/plugins/docx-kit.tsx +0 -6
  44. package/frontend/src/components/editor/plugins/emoji-kit.tsx +0 -13
  45. package/frontend/src/components/editor/plugins/excalidraw-kit.tsx +0 -9
  46. package/frontend/src/components/editor/plugins/exit-break-kit.tsx +0 -12
  47. package/frontend/src/components/editor/plugins/floating-toolbar-kit.tsx +0 -19
  48. package/frontend/src/components/editor/plugins/font-base-kit.tsx +0 -20
  49. package/frontend/src/components/editor/plugins/font-kit.tsx +0 -29
  50. package/frontend/src/components/editor/plugins/indent-base-kit.tsx +0 -19
  51. package/frontend/src/components/editor/plugins/indent-kit.tsx +0 -22
  52. package/frontend/src/components/editor/plugins/line-height-base-kit.tsx +0 -14
  53. package/frontend/src/components/editor/plugins/line-height-kit.tsx +0 -16
  54. package/frontend/src/components/editor/plugins/link-base-kit.tsx +0 -5
  55. package/frontend/src/components/editor/plugins/link-kit.tsx +0 -15
  56. package/frontend/src/components/editor/plugins/list-base-kit.tsx +0 -23
  57. package/frontend/src/components/editor/plugins/list-kit.tsx +0 -26
  58. package/frontend/src/components/editor/plugins/markdown-kit.tsx +0 -46
  59. package/frontend/src/components/editor/plugins/math-base-kit.tsx +0 -11
  60. package/frontend/src/components/editor/plugins/math-kit.tsx +0 -13
  61. package/frontend/src/components/editor/plugins/media-base-kit.tsx +0 -31
  62. package/frontend/src/components/editor/plugins/media-kit.tsx +0 -43
  63. package/frontend/src/components/editor/plugins/mention-base-kit.tsx +0 -7
  64. package/frontend/src/components/editor/plugins/mention-kit.tsx +0 -15
  65. package/frontend/src/components/editor/plugins/slash-kit.tsx +0 -18
  66. package/frontend/src/components/editor/plugins/suggestion-base-kit.tsx +0 -7
  67. package/frontend/src/components/editor/plugins/suggestion-kit.tsx +0 -90
  68. package/frontend/src/components/editor/plugins/table-base-kit.tsx +0 -20
  69. package/frontend/src/components/editor/plugins/table-kit.tsx +0 -22
  70. package/frontend/src/components/editor/plugins/toc-base-kit.tsx +0 -5
  71. package/frontend/src/components/editor/plugins/toc-kit.tsx +0 -14
  72. package/frontend/src/components/editor/plugins/toggle-base-kit.tsx +0 -7
  73. package/frontend/src/components/editor/plugins/toggle-kit.tsx +0 -11
  74. package/frontend/src/components/editor/transforms.ts +0 -194
  75. package/frontend/src/components/markdown-to-slate-demo.tsx +0 -50
  76. package/frontend/src/components/mode-toggle.tsx +0 -15
  77. package/frontend/src/components/theme-provider.tsx +0 -73
  78. package/frontend/src/components/ui/alert-dialog.tsx +0 -155
  79. package/frontend/src/components/ui/align-toolbar-button.tsx +0 -84
  80. package/frontend/src/components/ui/avatar.tsx +0 -51
  81. package/frontend/src/components/ui/block-context-menu.tsx +0 -199
  82. package/frontend/src/components/ui/block-discussion.tsx +0 -365
  83. package/frontend/src/components/ui/block-draggable.tsx +0 -512
  84. package/frontend/src/components/ui/block-list-static.tsx +0 -80
  85. package/frontend/src/components/ui/block-list.tsx +0 -87
  86. package/frontend/src/components/ui/block-selection.tsx +0 -42
  87. package/frontend/src/components/ui/block-suggestion.tsx +0 -473
  88. package/frontend/src/components/ui/blockquote-node-static.tsx +0 -11
  89. package/frontend/src/components/ui/blockquote-node.tsx +0 -13
  90. package/frontend/src/components/ui/button.tsx +0 -62
  91. package/frontend/src/components/ui/calendar.tsx +0 -218
  92. package/frontend/src/components/ui/callout-node-static.tsx +0 -36
  93. package/frontend/src/components/ui/callout-node.tsx +0 -63
  94. package/frontend/src/components/ui/caption.tsx +0 -63
  95. package/frontend/src/components/ui/checkbox.tsx +0 -30
  96. package/frontend/src/components/ui/code-block-node-static.tsx +0 -35
  97. package/frontend/src/components/ui/code-block-node.tsx +0 -287
  98. package/frontend/src/components/ui/code-node-static.tsx +0 -15
  99. package/frontend/src/components/ui/code-node.tsx +0 -17
  100. package/frontend/src/components/ui/codebase-snippet-node.tsx +0 -237
  101. package/frontend/src/components/ui/column-node-static.tsx +0 -29
  102. package/frontend/src/components/ui/column-node.tsx +0 -317
  103. package/frontend/src/components/ui/command.tsx +0 -182
  104. package/frontend/src/components/ui/comment-node-static.tsx +0 -15
  105. package/frontend/src/components/ui/comment-node.tsx +0 -45
  106. package/frontend/src/components/ui/comment-toolbar-button.tsx +0 -24
  107. package/frontend/src/components/ui/comment.tsx +0 -618
  108. package/frontend/src/components/ui/context-menu.tsx +0 -250
  109. package/frontend/src/components/ui/cursor-overlay.tsx +0 -66
  110. package/frontend/src/components/ui/date-node-static.tsx +0 -45
  111. package/frontend/src/components/ui/date-node.tsx +0 -93
  112. package/frontend/src/components/ui/dialog.tsx +0 -143
  113. package/frontend/src/components/ui/dropdown-menu.tsx +0 -255
  114. package/frontend/src/components/ui/dynamic-icon.tsx +0 -12
  115. package/frontend/src/components/ui/editor-static.tsx +0 -53
  116. package/frontend/src/components/ui/editor.tsx +0 -130
  117. package/frontend/src/components/ui/emoji-node.tsx +0 -69
  118. package/frontend/src/components/ui/emoji-toolbar-button.tsx +0 -628
  119. package/frontend/src/components/ui/equation-node-static.tsx +0 -98
  120. package/frontend/src/components/ui/equation-node.tsx +0 -235
  121. package/frontend/src/components/ui/equation-toolbar-button.tsx +0 -25
  122. package/frontend/src/components/ui/excalidraw-node.tsx +0 -36
  123. package/frontend/src/components/ui/export-toolbar-button.tsx +0 -174
  124. package/frontend/src/components/ui/file-selector.tsx +0 -339
  125. package/frontend/src/components/ui/floating-toolbar-buttons.tsx +0 -73
  126. package/frontend/src/components/ui/floating-toolbar.tsx +0 -85
  127. package/frontend/src/components/ui/font-color-toolbar-button.tsx +0 -831
  128. package/frontend/src/components/ui/font-size-toolbar-button.tsx +0 -152
  129. package/frontend/src/components/ui/heading-node-static.tsx +0 -68
  130. package/frontend/src/components/ui/heading-node.tsx +0 -58
  131. package/frontend/src/components/ui/highlight-node-static.tsx +0 -11
  132. package/frontend/src/components/ui/highlight-node.tsx +0 -13
  133. package/frontend/src/components/ui/history-toolbar-button.tsx +0 -50
  134. package/frontend/src/components/ui/hr-node-static.tsx +0 -20
  135. package/frontend/src/components/ui/hr-node.tsx +0 -33
  136. package/frontend/src/components/ui/import-toolbar-button.tsx +0 -97
  137. package/frontend/src/components/ui/indent-toolbar-button.tsx +0 -30
  138. package/frontend/src/components/ui/inline-combobox.tsx +0 -414
  139. package/frontend/src/components/ui/input.tsx +0 -21
  140. package/frontend/src/components/ui/insert-toolbar-button.tsx +0 -254
  141. package/frontend/src/components/ui/kbd-node-static.tsx +0 -15
  142. package/frontend/src/components/ui/kbd-node.tsx +0 -17
  143. package/frontend/src/components/ui/layout-header.tsx +0 -35
  144. package/frontend/src/components/ui/line-height-toolbar-button.tsx +0 -68
  145. package/frontend/src/components/ui/link-node-static.tsx +0 -21
  146. package/frontend/src/components/ui/link-node.tsx +0 -39
  147. package/frontend/src/components/ui/link-toolbar-button.tsx +0 -22
  148. package/frontend/src/components/ui/link-toolbar.tsx +0 -206
  149. package/frontend/src/components/ui/list-toolbar-button.tsx +0 -204
  150. package/frontend/src/components/ui/mark-toolbar-button.tsx +0 -19
  151. package/frontend/src/components/ui/media-audio-node-static.tsx +0 -17
  152. package/frontend/src/components/ui/media-audio-node.tsx +0 -39
  153. package/frontend/src/components/ui/media-embed-node.tsx +0 -136
  154. package/frontend/src/components/ui/media-file-node-static.tsx +0 -29
  155. package/frontend/src/components/ui/media-file-node.tsx +0 -47
  156. package/frontend/src/components/ui/media-image-node-static.tsx +0 -39
  157. package/frontend/src/components/ui/media-image-node.tsx +0 -80
  158. package/frontend/src/components/ui/media-placeholder-node.tsx +0 -249
  159. package/frontend/src/components/ui/media-preview-dialog.tsx +0 -152
  160. package/frontend/src/components/ui/media-toolbar-button.tsx +0 -225
  161. package/frontend/src/components/ui/media-toolbar.tsx +0 -115
  162. package/frontend/src/components/ui/media-upload-toast.tsx +0 -66
  163. package/frontend/src/components/ui/media-video-node-static.tsx +0 -30
  164. package/frontend/src/components/ui/media-video-node.tsx +0 -121
  165. package/frontend/src/components/ui/mention-node-static.tsx +0 -36
  166. package/frontend/src/components/ui/mention-node.tsx +0 -194
  167. package/frontend/src/components/ui/mode-toolbar-button.tsx +0 -123
  168. package/frontend/src/components/ui/more-toolbar-button.tsx +0 -80
  169. package/frontend/src/components/ui/paragraph-node-static.tsx +0 -13
  170. package/frontend/src/components/ui/paragraph-node.tsx +0 -15
  171. package/frontend/src/components/ui/popover.tsx +0 -46
  172. package/frontend/src/components/ui/resize-handle.tsx +0 -87
  173. package/frontend/src/components/ui/separator.tsx +0 -28
  174. package/frontend/src/components/ui/sheet.tsx +0 -139
  175. package/frontend/src/components/ui/sidebar.tsx +0 -726
  176. package/frontend/src/components/ui/skeleton.tsx +0 -13
  177. package/frontend/src/components/ui/slash-node.tsx +0 -233
  178. package/frontend/src/components/ui/sonner.tsx +0 -38
  179. package/frontend/src/components/ui/suggestion-node-static.tsx +0 -35
  180. package/frontend/src/components/ui/suggestion-node.tsx +0 -162
  181. package/frontend/src/components/ui/suggestion-toolbar-button.tsx +0 -25
  182. package/frontend/src/components/ui/table-icons.tsx +0 -862
  183. package/frontend/src/components/ui/table-node-static.tsx +0 -98
  184. package/frontend/src/components/ui/table-node.tsx +0 -656
  185. package/frontend/src/components/ui/table-toolbar-button.tsx +0 -264
  186. package/frontend/src/components/ui/toc-node-static.tsx +0 -92
  187. package/frontend/src/components/ui/toc-node.tsx +0 -55
  188. package/frontend/src/components/ui/toggle-node-static.tsx +0 -18
  189. package/frontend/src/components/ui/toggle-node.tsx +0 -36
  190. package/frontend/src/components/ui/toggle-toolbar-button.tsx +0 -22
  191. package/frontend/src/components/ui/toolbar.tsx +0 -387
  192. package/frontend/src/components/ui/tooltip.tsx +0 -59
  193. package/frontend/src/components/ui/turn-into-toolbar-button.tsx +0 -188
  194. package/frontend/src/hooks/use-debounce.ts +0 -18
  195. package/frontend/src/hooks/use-is-touch-device.ts +0 -24
  196. package/frontend/src/hooks/use-mobile.ts +0 -19
  197. package/frontend/src/hooks/use-mounted.ts +0 -11
  198. package/frontend/src/hooks/use-upload-file.ts +0 -128
  199. package/frontend/src/index.css +0 -128
  200. package/frontend/src/layout.tsx +0 -42
  201. package/frontend/src/lib/markdown-joiner-transform.ts +0 -239
  202. package/frontend/src/lib/orpc.ts +0 -13
  203. package/frontend/src/lib/uploadthing.ts +0 -19
  204. package/frontend/src/lib/utils.ts +0 -6
  205. package/frontend/src/main.tsx +0 -13
  206. package/frontend/src/pages/editor.tsx +0 -44
  207. package/frontend/src/types/docs.d.ts +0 -6
  208. package/frontend/src/types/global.d.ts +0 -9
  209. package/frontend/src/types/router.d.ts +0 -4
  210. package/frontend/tsconfig.app.json +0 -33
  211. package/frontend/tsconfig.json +0 -10
  212. package/frontend/tsconfig.node.json +0 -26
  213. package/frontend/vite.config.ts +0 -14
  214. package/src/bin/doclific.ts +0 -47
  215. package/src/core/codebase.ts +0 -39
  216. package/src/core/docs.ts +0 -90
  217. package/src/core/git.ts +0 -48
  218. package/src/server/index.ts +0 -55
  219. package/src/server/router.ts +0 -65
  220. package/tsconfig.json +0 -15
@@ -1,365 +0,0 @@
1
- import React from 'react';
2
-
3
- import type { PlateElementProps, RenderNodeWrapper } from 'platejs/react';
4
-
5
- import { getDraftCommentKey } from '@platejs/comment';
6
- import { CommentPlugin } from '@platejs/comment/react';
7
- import { getTransientSuggestionKey } from '@platejs/suggestion';
8
- import { SuggestionPlugin } from '@platejs/suggestion/react';
9
- import {
10
- MessageSquareTextIcon,
11
- MessagesSquareIcon,
12
- PencilLineIcon,
13
- } from 'lucide-react';
14
- import {
15
- type AnyPluginConfig,
16
- type NodeEntry,
17
- type Path,
18
- type TCommentText,
19
- type TElement,
20
- type TSuggestionText,
21
- PathApi,
22
- TextApi,
23
- } from 'platejs';
24
- import { useEditorPlugin, useEditorRef, usePluginOption } from 'platejs/react';
25
-
26
- import { Button } from '@/components/ui/button';
27
- import {
28
- Popover,
29
- PopoverAnchor,
30
- PopoverContent,
31
- PopoverTrigger,
32
- } from '@/components/ui/popover';
33
- import { commentPlugin } from '@/components/editor/plugins/comment-kit';
34
- import {
35
- type TDiscussion,
36
- discussionPlugin,
37
- } from '@/components/editor/plugins/discussion-kit';
38
- import { suggestionPlugin } from '@/components/editor/plugins/suggestion-kit';
39
-
40
- import {
41
- BlockSuggestionCard,
42
- isResolvedSuggestion,
43
- useResolveSuggestion,
44
- } from './block-suggestion';
45
- import { Comment, CommentCreateForm } from './comment';
46
-
47
- export const BlockDiscussion: RenderNodeWrapper<AnyPluginConfig> = (props) => {
48
- const { editor, element } = props;
49
-
50
- const commentsApi = editor.getApi(CommentPlugin).comment;
51
- const blockPath = editor.api.findPath(element);
52
-
53
- // avoid duplicate in table or column
54
- if (!blockPath || blockPath.length > 1) return;
55
-
56
- const draftCommentNode = commentsApi.node({ at: blockPath, isDraft: true });
57
-
58
- const commentNodes = [...commentsApi.nodes({ at: blockPath })];
59
-
60
- const suggestionNodes = [
61
- ...editor.getApi(SuggestionPlugin).suggestion.nodes({ at: blockPath }),
62
- ].filter(([node]) => !node[getTransientSuggestionKey()]);
63
-
64
- if (
65
- commentNodes.length === 0 &&
66
- suggestionNodes.length === 0 &&
67
- !draftCommentNode
68
- ) {
69
- return;
70
- }
71
-
72
- return (props) => (
73
- <BlockCommentContent
74
- blockPath={blockPath}
75
- commentNodes={commentNodes}
76
- draftCommentNode={draftCommentNode}
77
- suggestionNodes={suggestionNodes}
78
- {...props}
79
- />
80
- );
81
- };
82
-
83
- const BlockCommentContent = ({
84
- blockPath,
85
- children,
86
- commentNodes,
87
- draftCommentNode,
88
- suggestionNodes,
89
- }: PlateElementProps & {
90
- blockPath: Path;
91
- commentNodes: NodeEntry<TCommentText>[];
92
- draftCommentNode: NodeEntry<TCommentText> | undefined;
93
- suggestionNodes: NodeEntry<TElement | TSuggestionText>[];
94
- }) => {
95
- const editor = useEditorRef();
96
- const resolvedSuggestions = useResolveSuggestion(suggestionNodes, blockPath);
97
- const resolvedDiscussions = useResolvedDiscussion(commentNodes, blockPath);
98
-
99
- const suggestionsCount = resolvedSuggestions.length;
100
- const discussionsCount = resolvedDiscussions.length;
101
- const totalCount = suggestionsCount + discussionsCount;
102
-
103
- const activeSuggestionId = usePluginOption(suggestionPlugin, 'activeId');
104
- const activeSuggestion =
105
- activeSuggestionId &&
106
- resolvedSuggestions.find((s) => s.suggestionId === activeSuggestionId);
107
-
108
- const commentingBlock = usePluginOption(commentPlugin, 'commentingBlock');
109
- const activeCommentId = usePluginOption(commentPlugin, 'activeId');
110
- const isCommenting = activeCommentId === getDraftCommentKey();
111
- const activeDiscussion =
112
- activeCommentId &&
113
- resolvedDiscussions.find((d) => d.id === activeCommentId);
114
-
115
- const noneActive = !activeSuggestion && !activeDiscussion;
116
-
117
- const sortedMergedData = [
118
- ...resolvedDiscussions,
119
- ...resolvedSuggestions,
120
- ].sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
121
-
122
- const selected =
123
- resolvedDiscussions.some((d) => d.id === activeCommentId) ||
124
- resolvedSuggestions.some((s) => s.suggestionId === activeSuggestionId);
125
-
126
- const [_open, setOpen] = React.useState(selected);
127
-
128
- // in some cases, we may comment the multiple blocks
129
- const commentingCurrent =
130
- !!commentingBlock && PathApi.equals(blockPath, commentingBlock);
131
-
132
- const open =
133
- _open ||
134
- selected ||
135
- (isCommenting && !!draftCommentNode && commentingCurrent);
136
-
137
- const anchorElement = React.useMemo(() => {
138
- let activeNode: NodeEntry | undefined;
139
-
140
- if (activeSuggestion) {
141
- activeNode = suggestionNodes.find(
142
- ([node]) =>
143
- TextApi.isText(node) &&
144
- editor.getApi(SuggestionPlugin).suggestion.nodeId(node) ===
145
- activeSuggestion.suggestionId
146
- );
147
- }
148
-
149
- if (activeCommentId) {
150
- if (activeCommentId === getDraftCommentKey()) {
151
- activeNode = draftCommentNode;
152
- } else {
153
- activeNode = commentNodes.find(
154
- ([node]) =>
155
- editor.getApi(commentPlugin).comment.nodeId(node) ===
156
- activeCommentId
157
- );
158
- }
159
- }
160
-
161
- if (!activeNode) return null;
162
-
163
- return editor.api.toDOMNode(activeNode[0])!;
164
- // eslint-disable-next-line react-hooks/exhaustive-deps
165
- }, [
166
- open,
167
- activeSuggestion,
168
- activeCommentId,
169
- editor.api,
170
- suggestionNodes,
171
- draftCommentNode,
172
- commentNodes,
173
- ]);
174
-
175
- if (suggestionsCount + resolvedDiscussions.length === 0 && !draftCommentNode)
176
- return <div className="w-full">{children}</div>;
177
-
178
- return (
179
- <div className="flex w-full justify-between">
180
- <Popover
181
- open={open}
182
- onOpenChange={(_open_) => {
183
- if (!_open_ && isCommenting && draftCommentNode) {
184
- editor.tf.unsetNodes(getDraftCommentKey(), {
185
- at: [],
186
- mode: 'lowest',
187
- match: (n) => n[getDraftCommentKey()],
188
- });
189
- }
190
- setOpen(_open_);
191
- }}
192
- >
193
- <div className="w-full">{children}</div>
194
- {anchorElement && (
195
- <PopoverAnchor
196
- asChild
197
- className="w-full"
198
- virtualRef={{ current: anchorElement }}
199
- />
200
- )}
201
-
202
- <PopoverContent
203
- className="max-h-[min(50dvh,calc(-24px+var(--radix-popper-available-height)))] w-[380px] min-w-[130px] max-w-[calc(100vw-24px)] overflow-y-auto p-0 data-[state=closed]:opacity-0"
204
- onCloseAutoFocus={(e) => e.preventDefault()}
205
- onOpenAutoFocus={(e) => e.preventDefault()}
206
- align="center"
207
- side="bottom"
208
- >
209
- {isCommenting ? (
210
- <CommentCreateForm className="p-4" focusOnMount />
211
- ) : noneActive ? (
212
- sortedMergedData.map((item, index) =>
213
- isResolvedSuggestion(item) ? (
214
- <BlockSuggestionCard
215
- key={item.suggestionId}
216
- idx={index}
217
- isLast={index === sortedMergedData.length - 1}
218
- suggestion={item}
219
- />
220
- ) : (
221
- <BlockComment
222
- key={item.id}
223
- discussion={item}
224
- isLast={index === sortedMergedData.length - 1}
225
- />
226
- )
227
- )
228
- ) : (
229
- <>
230
- {activeSuggestion && (
231
- <BlockSuggestionCard
232
- key={activeSuggestion.suggestionId}
233
- idx={0}
234
- isLast={true}
235
- suggestion={activeSuggestion}
236
- />
237
- )}
238
-
239
- {activeDiscussion && (
240
- <BlockComment discussion={activeDiscussion} isLast={true} />
241
- )}
242
- </>
243
- )}
244
- </PopoverContent>
245
-
246
- {totalCount > 0 && (
247
- <div className="relative left-0 size-0 select-none">
248
- <PopoverTrigger asChild>
249
- <Button
250
- variant="ghost"
251
- className="!px-1.5 mt-1 ml-1 flex h-6 gap-1 py-0 text-muted-foreground/80 hover:text-muted-foreground/80 data-[active=true]:bg-muted"
252
- data-active={open}
253
- contentEditable={false}
254
- >
255
- {suggestionsCount > 0 && discussionsCount === 0 && (
256
- <PencilLineIcon className="size-4 shrink-0" />
257
- )}
258
-
259
- {suggestionsCount === 0 && discussionsCount > 0 && (
260
- <MessageSquareTextIcon className="size-4 shrink-0" />
261
- )}
262
-
263
- {suggestionsCount > 0 && discussionsCount > 0 && (
264
- <MessagesSquareIcon className="size-4 shrink-0" />
265
- )}
266
-
267
- <span className="font-semibold text-xs">{totalCount}</span>
268
- </Button>
269
- </PopoverTrigger>
270
- </div>
271
- )}
272
- </Popover>
273
- </div>
274
- );
275
- };
276
-
277
- function BlockComment({
278
- discussion,
279
- isLast,
280
- }: {
281
- discussion: TDiscussion;
282
- isLast: boolean;
283
- }) {
284
- const [editingId, setEditingId] = React.useState<string | null>(null);
285
-
286
- return (
287
- <React.Fragment key={discussion.id}>
288
- <div className="p-4">
289
- {discussion.comments.map((comment, index) => (
290
- <Comment
291
- key={comment.id ?? index}
292
- comment={comment}
293
- discussionLength={discussion.comments.length}
294
- documentContent={discussion?.documentContent}
295
- editingId={editingId}
296
- index={index}
297
- setEditingId={setEditingId}
298
- showDocumentContent
299
- />
300
- ))}
301
- <CommentCreateForm discussionId={discussion.id} />
302
- </div>
303
-
304
- {!isLast && <div className="h-px w-full bg-muted" />}
305
- </React.Fragment>
306
- );
307
- }
308
-
309
- const useResolvedDiscussion = (
310
- commentNodes: NodeEntry<TCommentText>[],
311
- blockPath: Path
312
- ) => {
313
- const { api, getOption, setOption } = useEditorPlugin(commentPlugin);
314
-
315
- const discussions = usePluginOption(discussionPlugin, 'discussions');
316
-
317
- commentNodes.forEach(([node]) => {
318
- const id = api.comment.nodeId(node);
319
- const map = getOption('uniquePathMap');
320
-
321
- if (!id) return;
322
-
323
- const previousPath = map.get(id);
324
-
325
- // If there are no comment nodes in the corresponding path in the map, then update it.
326
- if (PathApi.isPath(previousPath)) {
327
- const nodes = api.comment.node({ id, at: previousPath });
328
-
329
- if (!nodes) {
330
- setOption('uniquePathMap', new Map(map).set(id, blockPath));
331
- return;
332
- }
333
-
334
- return;
335
- }
336
- // TODO: fix throw error
337
- setOption('uniquePathMap', new Map(map).set(id, blockPath));
338
- });
339
-
340
- const commentsIds = new Set(
341
- commentNodes.map(([node]) => api.comment.nodeId(node)).filter(Boolean)
342
- );
343
-
344
- const resolvedDiscussions = discussions
345
- .map((d: TDiscussion) => ({
346
- ...d,
347
- createdAt: new Date(d.createdAt),
348
- }))
349
- .filter((item: TDiscussion) => {
350
- /** If comment cross blocks just show it in the first block */
351
- const commentsPathMap = getOption('uniquePathMap');
352
- const firstBlockPath = commentsPathMap.get(item.id);
353
-
354
- if (!firstBlockPath) return false;
355
- if (!PathApi.equals(firstBlockPath, blockPath)) return false;
356
-
357
- return (
358
- api.comment.has({ id: item.id }) &&
359
- commentsIds.has(item.id) &&
360
- !item.isResolved
361
- );
362
- });
363
-
364
- return resolvedDiscussions;
365
- };