@weavy/uikit-react 14.0.4 → 15.0.1

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 (360) hide show
  1. package/.vscode/settings.json +2 -0
  2. package/changelog.md +10 -0
  3. package/dist/cjs/client/WeavyClient.d.ts +1 -0
  4. package/dist/cjs/components/Attachment.d.ts +5 -5
  5. package/dist/cjs/components/Blob.d.ts +9 -0
  6. package/dist/cjs/components/Comment.d.ts +18 -0
  7. package/dist/cjs/components/CommentCount.d.ts +7 -0
  8. package/dist/cjs/components/CommentEdit.d.ts +16 -0
  9. package/dist/cjs/components/CommentPlaceholder.d.ts +8 -0
  10. package/dist/cjs/components/CommentTrashed.d.ts +15 -0
  11. package/dist/cjs/components/CommentView.d.ts +18 -0
  12. package/dist/cjs/components/Comments.d.ts +8 -0
  13. package/dist/cjs/components/ConversationListItem.d.ts +1 -1
  14. package/dist/cjs/components/Dropzone.d.ts +10 -0
  15. package/dist/cjs/components/Editor.d.ts +25 -0
  16. package/dist/cjs/components/Embed.d.ts +8 -0
  17. package/dist/cjs/components/FileItem.d.ts +41 -0
  18. package/dist/cjs/components/FileList.d.ts +11 -0
  19. package/dist/cjs/components/FileVersions.d.ts +9 -0
  20. package/dist/cjs/components/Files.d.ts +4 -0
  21. package/dist/cjs/components/Image.d.ts +3 -3
  22. package/dist/cjs/components/MeetingCard.d.ts +1 -1
  23. package/dist/cjs/components/Meetings.d.ts +2 -1
  24. package/dist/cjs/components/Poll.d.ts +8 -0
  25. package/dist/cjs/components/PollOption.d.ts +10 -0
  26. package/dist/cjs/components/Post.d.ts +21 -0
  27. package/dist/cjs/components/PostEdit.d.ts +17 -0
  28. package/dist/cjs/components/PostList.d.ts +6 -0
  29. package/dist/cjs/components/PostPlaceholder.d.ts +8 -0
  30. package/dist/cjs/components/PostTrashed.d.ts +14 -0
  31. package/dist/cjs/components/PostView.d.ts +21 -0
  32. package/dist/cjs/components/Posts.d.ts +4 -0
  33. package/dist/cjs/components/Preview.d.ts +1 -3
  34. package/dist/cjs/components/PreviewFiles.d.ts +10 -0
  35. package/dist/cjs/components/Reactions.d.ts +6 -2
  36. package/dist/cjs/components/SearchUsers.d.ts +2 -1
  37. package/dist/cjs/contexts/CloudFilesContext.d.ts +9 -0
  38. package/dist/cjs/hooks/useApps.d.ts +1 -0
  39. package/dist/cjs/hooks/useCloudFiles.d.ts +3 -0
  40. package/dist/cjs/hooks/useCommentList.d.ts +1 -0
  41. package/dist/cjs/hooks/useEmbeds.d.ts +5 -0
  42. package/dist/cjs/hooks/useFileList.d.ts +1 -0
  43. package/dist/cjs/hooks/useFileUploader.d.ts +8 -0
  44. package/dist/cjs/hooks/useFileVersions.d.ts +2 -0
  45. package/dist/cjs/hooks/useInfiniteScroll.d.ts +4 -0
  46. package/dist/cjs/hooks/useIsFirstRender.d.ts +2 -0
  47. package/dist/cjs/hooks/useMutateApps.d.ts +5 -0
  48. package/dist/cjs/hooks/useMutateComment.d.ts +10 -0
  49. package/dist/cjs/hooks/useMutateConversationName.d.ts +1 -1
  50. package/dist/cjs/hooks/useMutateDeleteReaction.d.ts +3 -1
  51. package/dist/cjs/hooks/useMutateEditComment.d.ts +10 -0
  52. package/dist/cjs/hooks/useMutateEditPost.d.ts +10 -0
  53. package/dist/cjs/hooks/useMutateExternalBlobs.d.ts +2 -2
  54. package/dist/cjs/hooks/useMutateFile.d.ts +26 -0
  55. package/dist/cjs/hooks/useMutateFileRename.d.ts +5 -0
  56. package/dist/cjs/hooks/useMutateFileSubscribe.d.ts +7 -0
  57. package/dist/cjs/hooks/useMutateFileTrash.d.ts +10 -0
  58. package/dist/cjs/hooks/useMutateFileVersion.d.ts +7 -0
  59. package/dist/cjs/hooks/useMutateFiles.d.ts +2 -0
  60. package/dist/cjs/hooks/useMutateLeaveConversation.d.ts +4 -0
  61. package/dist/cjs/hooks/useMutateMessage.d.ts +2 -2
  62. package/dist/cjs/hooks/useMutatePost.d.ts +10 -0
  63. package/dist/cjs/hooks/useMutateReaction.d.ts +3 -1
  64. package/dist/cjs/hooks/useMutateRead.d.ts +1 -1
  65. package/dist/cjs/hooks/useMutateReplaceReaction.d.ts +6 -0
  66. package/dist/cjs/hooks/useMutateRestoreComment.d.ts +5 -0
  67. package/dist/cjs/hooks/useMutateRestorePost.d.ts +4 -0
  68. package/dist/cjs/hooks/useMutateStarred.d.ts +4 -0
  69. package/dist/cjs/hooks/useMutateSubscribe.d.ts +4 -0
  70. package/dist/cjs/hooks/useMutateTrashComment.d.ts +5 -0
  71. package/dist/cjs/hooks/useMutateTrashPost.d.ts +4 -0
  72. package/dist/cjs/hooks/useMutateTyping.d.ts +2 -0
  73. package/dist/cjs/hooks/useMutateUnsubscribe.d.ts +4 -0
  74. package/dist/cjs/hooks/useMutateVote.d.ts +5 -0
  75. package/dist/cjs/hooks/usePost.d.ts +1 -0
  76. package/dist/cjs/hooks/usePosts.d.ts +1 -0
  77. package/dist/cjs/hooks/usePostsList.d.ts +1 -0
  78. package/dist/cjs/hooks/useReactionList.d.ts +1 -0
  79. package/dist/cjs/hooks/useSessionState.d.ts +2 -0
  80. package/dist/cjs/hooks/useUnload.d.ts +2 -0
  81. package/dist/cjs/hooks/useUpdateEffect.d.ts +3 -0
  82. package/dist/cjs/hooks/useVotes.d.ts +1 -0
  83. package/dist/cjs/index.d.ts +3 -1
  84. package/dist/cjs/index.js +28 -6
  85. package/dist/cjs/index.js.map +1 -1
  86. package/dist/cjs/types/ConversationListItem.d.ts +1 -0
  87. package/dist/cjs/types/Files.d.ts +7 -0
  88. package/dist/cjs/types/Message.d.ts +2 -2
  89. package/dist/cjs/types/Posts.d.ts +4 -0
  90. package/dist/cjs/types/interfaces.d.ts +9 -0
  91. package/dist/cjs/types/types.d.ts +138 -22
  92. package/dist/cjs/ui/Dropdown.d.ts +18 -2
  93. package/dist/cjs/ui/Icon.d.ts +10 -2
  94. package/dist/cjs/ui/Overlay.d.ts +3 -1
  95. package/dist/cjs/ui/Sheet.d.ts +14 -0
  96. package/dist/cjs/ui/Spinner.d.ts +2 -1
  97. package/dist/cjs/utils/cacheUtils.d.ts +14 -0
  98. package/dist/cjs/utils/fileUtilities.d.ts +10 -1
  99. package/dist/cjs/utils/mentions.d.ts +6 -0
  100. package/dist/cjs/utils/openUrl.d.ts +1 -0
  101. package/dist/css/weavy-chat.css +637 -218
  102. package/dist/css/weavy-files.css +3046 -0
  103. package/dist/css/weavy-messenger.css +643 -213
  104. package/dist/css/weavy-posts.css +2773 -0
  105. package/dist/css/weavy.css +1749 -308
  106. package/dist/esm/client/WeavyClient.d.ts +1 -0
  107. package/dist/esm/components/Attachment.d.ts +5 -5
  108. package/dist/esm/components/Blob.d.ts +9 -0
  109. package/dist/esm/components/Comment.d.ts +18 -0
  110. package/dist/esm/components/CommentCount.d.ts +7 -0
  111. package/dist/esm/components/CommentEdit.d.ts +16 -0
  112. package/dist/esm/components/CommentPlaceholder.d.ts +8 -0
  113. package/dist/esm/components/CommentTrashed.d.ts +15 -0
  114. package/dist/esm/components/CommentView.d.ts +18 -0
  115. package/dist/esm/components/Comments.d.ts +8 -0
  116. package/dist/esm/components/ConversationListItem.d.ts +1 -1
  117. package/dist/esm/components/Dropzone.d.ts +10 -0
  118. package/dist/esm/components/Editor.d.ts +25 -0
  119. package/dist/esm/components/Embed.d.ts +8 -0
  120. package/dist/esm/components/FileItem.d.ts +41 -0
  121. package/dist/esm/components/FileList.d.ts +11 -0
  122. package/dist/esm/components/FileVersions.d.ts +9 -0
  123. package/dist/esm/components/Files.d.ts +4 -0
  124. package/dist/esm/components/Image.d.ts +3 -3
  125. package/dist/esm/components/MeetingCard.d.ts +1 -1
  126. package/dist/esm/components/Meetings.d.ts +2 -1
  127. package/dist/esm/components/Poll.d.ts +8 -0
  128. package/dist/esm/components/PollOption.d.ts +10 -0
  129. package/dist/esm/components/Post.d.ts +21 -0
  130. package/dist/esm/components/PostEdit.d.ts +17 -0
  131. package/dist/esm/components/PostList.d.ts +6 -0
  132. package/dist/esm/components/PostPlaceholder.d.ts +8 -0
  133. package/dist/esm/components/PostTrashed.d.ts +14 -0
  134. package/dist/esm/components/PostView.d.ts +21 -0
  135. package/dist/esm/components/Posts.d.ts +4 -0
  136. package/dist/esm/components/Preview.d.ts +1 -3
  137. package/dist/esm/components/PreviewFiles.d.ts +10 -0
  138. package/dist/esm/components/Reactions.d.ts +6 -2
  139. package/dist/esm/components/SearchUsers.d.ts +2 -1
  140. package/dist/esm/contexts/CloudFilesContext.d.ts +9 -0
  141. package/dist/esm/hooks/useApps.d.ts +1 -0
  142. package/dist/esm/hooks/useCloudFiles.d.ts +3 -0
  143. package/dist/esm/hooks/useCommentList.d.ts +1 -0
  144. package/dist/esm/hooks/useEmbeds.d.ts +5 -0
  145. package/dist/esm/hooks/useFileList.d.ts +1 -0
  146. package/dist/esm/hooks/useFileUploader.d.ts +8 -0
  147. package/dist/esm/hooks/useFileVersions.d.ts +2 -0
  148. package/dist/esm/hooks/useInfiniteScroll.d.ts +4 -0
  149. package/dist/esm/hooks/useIsFirstRender.d.ts +2 -0
  150. package/dist/esm/hooks/useMutateApps.d.ts +5 -0
  151. package/dist/esm/hooks/useMutateComment.d.ts +10 -0
  152. package/dist/esm/hooks/useMutateConversationName.d.ts +1 -1
  153. package/dist/esm/hooks/useMutateDeleteReaction.d.ts +3 -1
  154. package/dist/esm/hooks/useMutateEditComment.d.ts +10 -0
  155. package/dist/esm/hooks/useMutateEditPost.d.ts +10 -0
  156. package/dist/esm/hooks/useMutateExternalBlobs.d.ts +2 -2
  157. package/dist/esm/hooks/useMutateFile.d.ts +26 -0
  158. package/dist/esm/hooks/useMutateFileRename.d.ts +5 -0
  159. package/dist/esm/hooks/useMutateFileSubscribe.d.ts +7 -0
  160. package/dist/esm/hooks/useMutateFileTrash.d.ts +10 -0
  161. package/dist/esm/hooks/useMutateFileVersion.d.ts +7 -0
  162. package/dist/esm/hooks/useMutateFiles.d.ts +2 -0
  163. package/dist/esm/hooks/useMutateLeaveConversation.d.ts +4 -0
  164. package/dist/esm/hooks/useMutateMessage.d.ts +2 -2
  165. package/dist/esm/hooks/useMutatePost.d.ts +10 -0
  166. package/dist/esm/hooks/useMutateReaction.d.ts +3 -1
  167. package/dist/esm/hooks/useMutateRead.d.ts +1 -1
  168. package/dist/esm/hooks/useMutateReplaceReaction.d.ts +6 -0
  169. package/dist/esm/hooks/useMutateRestoreComment.d.ts +5 -0
  170. package/dist/esm/hooks/useMutateRestorePost.d.ts +4 -0
  171. package/dist/esm/hooks/useMutateStarred.d.ts +4 -0
  172. package/dist/esm/hooks/useMutateSubscribe.d.ts +4 -0
  173. package/dist/esm/hooks/useMutateTrashComment.d.ts +5 -0
  174. package/dist/esm/hooks/useMutateTrashPost.d.ts +4 -0
  175. package/dist/esm/hooks/useMutateTyping.d.ts +2 -0
  176. package/dist/esm/hooks/useMutateUnsubscribe.d.ts +4 -0
  177. package/dist/esm/hooks/useMutateVote.d.ts +5 -0
  178. package/dist/esm/hooks/usePost.d.ts +1 -0
  179. package/dist/esm/hooks/usePosts.d.ts +1 -0
  180. package/dist/esm/hooks/usePostsList.d.ts +1 -0
  181. package/dist/esm/hooks/useReactionList.d.ts +1 -0
  182. package/dist/esm/hooks/useSessionState.d.ts +2 -0
  183. package/dist/esm/hooks/useUnload.d.ts +2 -0
  184. package/dist/esm/hooks/useUpdateEffect.d.ts +3 -0
  185. package/dist/esm/hooks/useVotes.d.ts +1 -0
  186. package/dist/esm/index.d.ts +3 -1
  187. package/dist/esm/index.js +28 -6
  188. package/dist/esm/index.js.map +1 -1
  189. package/dist/esm/types/ConversationListItem.d.ts +1 -0
  190. package/dist/esm/types/Files.d.ts +7 -0
  191. package/dist/esm/types/Message.d.ts +2 -2
  192. package/dist/esm/types/Posts.d.ts +4 -0
  193. package/dist/esm/types/interfaces.d.ts +9 -0
  194. package/dist/esm/types/types.d.ts +138 -22
  195. package/dist/esm/ui/Dropdown.d.ts +18 -2
  196. package/dist/esm/ui/Icon.d.ts +10 -2
  197. package/dist/esm/ui/Overlay.d.ts +3 -1
  198. package/dist/esm/ui/Sheet.d.ts +14 -0
  199. package/dist/esm/ui/Spinner.d.ts +2 -1
  200. package/dist/esm/utils/cacheUtils.d.ts +14 -0
  201. package/dist/esm/utils/fileUtilities.d.ts +10 -1
  202. package/dist/esm/utils/mentions.d.ts +6 -0
  203. package/dist/esm/utils/openUrl.d.ts +1 -0
  204. package/dist/index.d.ts +50 -6
  205. package/package.json +8 -2
  206. package/src/client/WeavyClient.ts +35 -1
  207. package/src/components/Attachment.tsx +20 -13
  208. package/src/components/Blob.tsx +28 -0
  209. package/src/components/Comment.tsx +43 -0
  210. package/src/components/CommentCount.tsx +15 -0
  211. package/src/components/CommentEdit.tsx +48 -0
  212. package/src/components/CommentPlaceholder.tsx +34 -0
  213. package/src/components/CommentTrashed.tsx +45 -0
  214. package/src/components/CommentView.tsx +142 -0
  215. package/src/components/Comments.tsx +78 -0
  216. package/src/components/Conversation.tsx +85 -31
  217. package/src/components/ConversationList.tsx +12 -41
  218. package/src/components/ConversationListItem.tsx +125 -74
  219. package/src/components/Dropzone.tsx +26 -0
  220. package/src/components/Editor.tsx +700 -0
  221. package/src/components/Embed.tsx +80 -0
  222. package/src/components/FileItem.tsx +391 -0
  223. package/src/components/FileList.tsx +166 -0
  224. package/src/components/FileVersions.tsx +100 -0
  225. package/src/components/Files.tsx +294 -0
  226. package/src/components/Image.tsx +11 -10
  227. package/src/components/Meeting.tsx +1 -2
  228. package/src/components/MeetingCard.tsx +1 -1
  229. package/src/components/Meetings.tsx +13 -5
  230. package/src/components/Message.tsx +14 -19
  231. package/src/components/Messages.tsx +38 -64
  232. package/src/components/NewConversation.tsx +8 -6
  233. package/src/components/PdfViewer.tsx +2 -2
  234. package/src/components/Poll.tsx +45 -0
  235. package/src/components/PollOption.tsx +65 -0
  236. package/src/components/Post.tsx +45 -0
  237. package/src/components/PostEdit.tsx +49 -0
  238. package/src/components/PostList.tsx +95 -0
  239. package/src/components/PostPlaceholder.tsx +32 -0
  240. package/src/components/PostTrashed.tsx +35 -0
  241. package/src/components/PostView.tsx +194 -0
  242. package/src/components/Posts.tsx +59 -0
  243. package/src/components/Preview.tsx +16 -23
  244. package/src/components/PreviewFiles.tsx +336 -0
  245. package/src/components/Reactions.tsx +142 -38
  246. package/src/components/SearchUsers.tsx +77 -37
  247. package/src/components/Typing.tsx +1 -1
  248. package/src/{components/FileBrowser.tsx → contexts/CloudFilesContext.tsx} +46 -30
  249. package/src/contexts/PreviewContext.tsx +102 -85
  250. package/src/contexts/WeavyContext.tsx +10 -6
  251. package/src/hooks/useApps.ts +23 -0
  252. package/src/hooks/useCloudFiles.ts +12 -0
  253. package/src/hooks/useCommentList.ts +30 -0
  254. package/src/hooks/useEmbeds.ts +126 -0
  255. package/src/hooks/useEvents.ts +3 -1
  256. package/src/hooks/useFileList.ts +84 -0
  257. package/src/hooks/useFileUploader.ts +38 -1
  258. package/src/hooks/useFileVersions.ts +20 -0
  259. package/src/hooks/useInfiniteScroll.ts +45 -0
  260. package/src/hooks/useIsFirstRender.ts +15 -0
  261. package/src/hooks/useMembers.ts +3 -3
  262. package/src/hooks/useMutateApps.ts +48 -0
  263. package/src/hooks/useMutateComment.ts +60 -0
  264. package/src/hooks/useMutateConversationName.ts +1 -1
  265. package/src/hooks/useMutateDeleteReaction.ts +17 -4
  266. package/src/hooks/useMutateEditComment.ts +63 -0
  267. package/src/hooks/useMutateEditPost.ts +64 -0
  268. package/src/hooks/useMutateExternalBlobs.ts +5 -9
  269. package/src/hooks/useMutateFile.ts +311 -0
  270. package/src/hooks/useMutateFileRename.ts +51 -0
  271. package/src/hooks/useMutateFileSubscribe.ts +80 -0
  272. package/src/hooks/useMutateFileTrash.ts +115 -0
  273. package/src/hooks/useMutateFileVersion.ts +85 -0
  274. package/src/hooks/useMutateFiles.ts +23 -0
  275. package/src/hooks/useMutateLeaveConversation.ts +38 -0
  276. package/src/hooks/useMutateMessage.ts +23 -62
  277. package/src/hooks/useMutatePost.ts +60 -0
  278. package/src/hooks/useMutateReaction.ts +21 -6
  279. package/src/hooks/useMutateRead.ts +8 -2
  280. package/src/hooks/useMutateRemoveMembers.ts +2 -9
  281. package/src/hooks/useMutateReplaceReaction.ts +59 -0
  282. package/src/hooks/useMutateRestoreComment.ts +37 -0
  283. package/src/hooks/useMutateRestorePost.ts +36 -0
  284. package/src/hooks/useMutateStarred.ts +35 -0
  285. package/src/hooks/useMutateSubscribe.ts +36 -0
  286. package/src/hooks/useMutateTrashComment.ts +37 -0
  287. package/src/hooks/useMutateTrashPost.ts +36 -0
  288. package/src/hooks/useMutateTyping.ts +5 -3
  289. package/src/hooks/useMutateUnsubscribe.ts +36 -0
  290. package/src/hooks/useMutateVote.ts +59 -0
  291. package/src/hooks/usePost.ts +20 -0
  292. package/src/hooks/usePosts.ts +21 -0
  293. package/src/hooks/usePostsList.ts +31 -0
  294. package/src/hooks/useReactionList.ts +21 -0
  295. package/src/hooks/useSearchUsers.ts +2 -2
  296. package/src/hooks/useSessionState.ts +23 -0
  297. package/src/hooks/useUnload.ts +19 -0
  298. package/src/hooks/useUpdateEffect.ts +16 -0
  299. package/src/hooks/useVotes.ts +21 -0
  300. package/src/index.ts +5 -1
  301. package/src/scss/theme/_appbar.scss +8 -4
  302. package/src/scss/theme/_card.scss +2 -0
  303. package/src/scss/theme/_comment-editor-cm.scss +5 -1
  304. package/src/scss/theme/_comments.scss +9 -8
  305. package/src/scss/theme/_conversations.scss +4 -0
  306. package/src/scss/theme/_files.scss +2 -81
  307. package/src/scss/theme/_icons.scss +21 -3
  308. package/src/scss/theme/_input.scss +13 -7
  309. package/src/scss/theme/_item.scss +23 -1
  310. package/src/scss/theme/_message-editor-cm.scss +5 -1
  311. package/src/scss/theme/_pager.scss +1 -1
  312. package/src/scss/theme/_post-editor-cm.scss +2 -2
  313. package/src/scss/theme/_post.scss +3 -10
  314. package/src/scss/theme/_preview-pdf-viewer.scss +996 -0
  315. package/src/scss/theme/_preview-pdf.scss +57 -783
  316. package/src/scss/theme/_sheet.scss +4 -1
  317. package/src/scss/theme/_spinner.scss +10 -1
  318. package/src/scss/theme/_tables.scss +2 -0
  319. package/src/scss/theme/base/_scroll.scss +3 -0
  320. package/src/scss/weavy-chat.scss +3 -1
  321. package/src/scss/weavy-files.scss +31 -0
  322. package/src/scss/weavy-messenger.scss +3 -1
  323. package/src/scss/weavy-posts.scss +35 -0
  324. package/src/scss/weavy.scss +2 -0
  325. package/src/types/ConversationListItem.ts +1 -0
  326. package/src/types/Files.ts +7 -0
  327. package/src/types/Message.ts +2 -2
  328. package/src/types/Posts.ts +4 -0
  329. package/src/types/interfaces.ts +13 -0
  330. package/src/types/types.ts +157 -28
  331. package/src/ui/Button.tsx +6 -5
  332. package/src/ui/Dropdown.tsx +67 -16
  333. package/src/ui/Icon.tsx +112 -15
  334. package/src/ui/Overlay.tsx +6 -2
  335. package/src/ui/Sheet.tsx +87 -0
  336. package/src/ui/Spinner.tsx +7 -4
  337. package/src/utils/cacheUtils.ts +246 -0
  338. package/src/utils/fileUtilities.ts +208 -24
  339. package/src/utils/infinite-scroll.js +103 -0
  340. package/src/utils/mentions.ts +50 -0
  341. package/src/utils/openUrl.ts +41 -0
  342. package/src/utils/{scrollToBottom.js → scroll-position.js} +50 -9
  343. package/src/utils/{scrollbarDetection.js → scrollbar-detection.js} +0 -0
  344. package/src/utils/utils.js +15 -1
  345. package/tsconfig.json +1 -1
  346. package/dist/cjs/components/ConversationForm.d.ts +0 -7
  347. package/dist/cjs/components/File.d.ts +0 -9
  348. package/dist/cjs/components/FileBrowser.d.ts +0 -6
  349. package/dist/cjs/hooks/usePreview.d.ts +0 -4
  350. package/dist/cjs/hooks/useReactions.d.ts +0 -3
  351. package/dist/esm/components/ConversationForm.d.ts +0 -7
  352. package/dist/esm/components/File.d.ts +0 -9
  353. package/dist/esm/components/FileBrowser.d.ts +0 -6
  354. package/dist/esm/hooks/usePreview.d.ts +0 -4
  355. package/dist/esm/hooks/useReactions.d.ts +0 -3
  356. package/src/components/ConversationForm.tsx +0 -210
  357. package/src/components/File.tsx +0 -21
  358. package/src/hooks/usePreview.ts +0 -21
  359. package/src/hooks/useReactions.ts +0 -51
  360. package/src/utils/infiniteScroll.js +0 -184
@@ -0,0 +1,700 @@
1
+ import ReactCodeMirror, { ReactCodeMirrorRef } from '@uiw/react-codemirror';
2
+ import React, { useContext, useState, useRef, useEffect, useCallback } from 'react';
3
+ import { EditorState } from '@codemirror/state';
4
+ import { EditorView, keymap } from '@codemirror/view';
5
+ import { markdown, markdownLanguage } from '@codemirror/lang-markdown';
6
+ import { defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
7
+ import { autocompletion } from '@codemirror/autocomplete';
8
+ import { CompletionResult, Completion, CompletionContext } from '@codemirror/autocomplete';
9
+ import { MentionsCompletion } from '../types/interfaces';
10
+ import { mentions } from '../utils/mentions';
11
+ import { WeavyContext } from '../contexts/WeavyContext';
12
+ import useEmbeds from '../hooks/useEmbeds';
13
+ import Blob from './Blob';
14
+ import Icon from '../ui/Icon';
15
+ import Button from '../ui/Button';
16
+ import Dropdown from '../ui/Dropdown';
17
+ import Embed from './Embed';
18
+ import classNames from 'classnames';
19
+ import useCloudFiles from '../hooks/useCloudFiles';
20
+ import throttle from 'lodash.throttle';
21
+ import useMutateTyping from '../hooks/useMutateTyping';
22
+ import Meetings from './Meetings';
23
+ import Meeting from './Meeting';
24
+ import useUpdateEffect from '../hooks/useUpdateEffect';
25
+ import { FileMutation, useClearMutatingFileUpload, useMutateFileUpload, useMutatingFileUploads, useRemoveMutatingFileUpload } from '../hooks/useMutateFile';
26
+ import FileItem from './FileItem';
27
+ import Dropzone from './Dropzone';
28
+
29
+ type Props = {
30
+ id?: number,
31
+ appId: number,
32
+ parentId?: number,
33
+ placeholder: string,
34
+ text?: string,
35
+ buttonText: string,
36
+ embed?: EmbedType | undefined,
37
+ attachments?: FileType[] | undefined,
38
+ options?: PollOptionType[] | undefined,
39
+ meeting?: MeetingType | undefined,
40
+ showAttachments?: boolean,
41
+ showCloudFiles?: boolean,
42
+ showEmbeds?: boolean,
43
+ showPolls?: boolean,
44
+ showMeetings?: boolean,
45
+ showTyping?: boolean,
46
+ useDraft?: boolean,
47
+ onSubmit: (text: string, blobs: BlobType[], attachments: FileType[], meeting: number | null, embed: number | null, options: PollOptionType[]) => Promise<void>,
48
+ editorType: "posts" | "comments" | "messages",
49
+ editorLocation: "apps" | "posts" | "messages" | "files"
50
+ }
51
+
52
+ let typed = null;
53
+
54
+ const Editor = ({ id, appId, parentId, placeholder, text, buttonText, embed, attachments: initialAttachments, options: initialOptions, meeting: initialMeeting, showAttachments = false, showCloudFiles = false, showEmbeds = false, showPolls = false, showMeetings = false, showTyping = false, useDraft = false, onSubmit, editorType, editorLocation }: Props) => {
55
+
56
+ const { client, options } = useContext(WeavyContext);
57
+ const [files, setFiles] = useState<string>("");
58
+ const [editorError, setEditorError] = useState<boolean>(false);
59
+ const [blobs, setBlobs] = useState<BlobType[]>([]);
60
+ const [attachments, setAttachments] = useState<FileType[]>([]);
61
+ const [meeting, setMeeting] = useState<MeetingType | null>(null);
62
+ const [pollOptions, setPollOptions] = useState<PollOptionType[]>([]);
63
+ const [pollVisible, setPollVisible] = useState<boolean>(false);
64
+ const [embeds, setEmbeds] = useState<EmbedType[]>([]);
65
+ const [disabled, setDisabled] = useState<boolean>(false);
66
+ const [value, setValue] = useState<string>('');
67
+ const { openCloudFiles } = useCloudFiles(handleExternalFileAdded);
68
+ const editorRef = useRef<ReactCodeMirrorRef>(null);
69
+ let fileInput: HTMLInputElement | null;
70
+ const sendTyping = useMutateTyping();
71
+ const cacheKey = [`${editorLocation}-${editorType}-uploads`, appId, id];
72
+ const uploadFileMutation = useMutateFileUpload(cacheKey);
73
+ const { mutations: fileList, progress: progress, status: status } = useMutatingFileUploads(cacheKey);
74
+ const removeMutatingFileUpload = useRemoveMutatingFileUpload(cacheKey);
75
+ const clearMutatingFileUpload = useClearMutatingFileUpload(cacheKey);
76
+
77
+ const throttledTyping = useCallback(throttle(function () { sendTyping.mutate({ id: appId, type: editorType, location: editorLocation }) }, 2000), [appId]);
78
+ const throttledDrafting = useCallback(throttle(function () { saveDraft() }, 500), [appId, blobs, meeting, value, pollOptions]);
79
+
80
+ const extensions: any[] = [
81
+ keymap.of([{
82
+ key: "Ctrl-Enter",
83
+ preventDefault: true,
84
+ run: () => {
85
+ handleCreate();
86
+ return true;
87
+ }
88
+ }]),
89
+ markdown({ base: markdownLanguage }),
90
+ mentions,
91
+ autocompletion({
92
+ override: [autocomplete],
93
+ closeOnBlur: false,
94
+ icons: false,
95
+ addToOptions: [
96
+ {
97
+ render: function (completion: MentionsCompletion, state: EditorState) {
98
+ let div = document.createElement("div");
99
+ div.classList.add("wy-item");
100
+ div.classList.add("wy-item-hover");
101
+
102
+ if (!completion.item?.is_member) {
103
+ div.classList.add("wy-disabled");
104
+ }
105
+
106
+ let img = document.createElement("img");
107
+ img.classList.add("wy-avatar");
108
+ img.src = completion.item?.avatar_url || "";
109
+
110
+ let name = document.createElement("div");
111
+ name.classList.add("wy-item-body");
112
+ name.innerText = (completion.item?.display_name) || "";
113
+
114
+ div.appendChild(img);
115
+ div.appendChild(name);
116
+ return div;
117
+ },
118
+ position: 10
119
+ }
120
+ ]
121
+ }),
122
+ syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
123
+ EditorView.lineWrapping,
124
+ EditorView.domEventHandlers({
125
+ paste(this: any, evt: ClipboardEvent, view: EditorView): boolean | void {
126
+
127
+ let files: any[] = [];
128
+ const items = evt.clipboardData?.items || [];
129
+
130
+ for (let index in items) {
131
+ const item = items[index];
132
+ if (item.kind === 'file') {
133
+ files = [...files, item.getAsFile()];
134
+ }
135
+ }
136
+ if (files.length > 0) {
137
+ for (var i = 0; i < files.length; i++) {
138
+ let file = files[i];
139
+ let fileProps = { file: file }
140
+ uploadFileMutation.mutateAsync(fileProps, {});
141
+ }
142
+ return true;
143
+ }
144
+ }
145
+ })
146
+ ];
147
+
148
+ async function autocomplete(context: CompletionContext): Promise<CompletionResult | null> {
149
+ // match @mention except when preceeded by ](
150
+ // regex lookbehind is unfortunately not supported in safari
151
+ // let before = context.matchBefore(/(?<!\]\()@[^@]+/);
152
+ let before = context.matchBefore(/(?!\]\(@)(^[^@]{0,1}|[^@]{2})@([^@]+)/);
153
+ //let before = context.matchBefore(/(?<!\]\()@[^@]+/);
154
+
155
+ // If completion wasn't explicitly started and there
156
+ // is no word before the cursor, don't open completions.
157
+ if (!context.explicit && !before) return null
158
+
159
+ // if valid, rematch (only when not using regex lookbehind)
160
+ before = context.matchBefore(/@[^@]+/);
161
+
162
+ typed = before?.text.substring(1);
163
+
164
+ const response = await client?.get("/api/users/autocomplete?id=" + appId + "&q=" + typed);
165
+ const result = await response?.json();
166
+
167
+ let completions = [];
168
+
169
+ if (result.data) {
170
+ completions = result.data.filter((item: any) => typeof (item.display_name) !== 'undefined').map((item: any) => {
171
+ return {
172
+ item: item,
173
+ label: item.display_name,
174
+ apply: function (view: EditorView, completion: Completion, from: number, to: number) {
175
+ var toInsert = "[" + item.display_name + "](@u" + item.id.toString() + ")";
176
+ var transaction = view.state.update({ changes: { from: from -1, to: from } });
177
+ view.dispatch(transaction);
178
+ transaction = view.state.update({ changes: { from: from -1, to: to -1, insert: toInsert } });
179
+ view.dispatch(transaction);
180
+ //view.dispatch(pickedCompletion);
181
+ }
182
+ }
183
+ });
184
+ }
185
+
186
+ return {
187
+ from: before ? before.from + 1 : context.pos,
188
+ options: completions,
189
+ filter: false
190
+ }
191
+
192
+ }
193
+
194
+ useEffect(() => {
195
+ if (text != null) {
196
+ setValue(text);
197
+ }
198
+ if (embed != null) {
199
+ setEmbeds([embed]);
200
+ initEmbeds([embed.original_url])
201
+ }
202
+ if (initialAttachments != null) {
203
+ setAttachments(initialAttachments);
204
+ }
205
+
206
+ if (initialOptions != null) {
207
+ setPollOptions([...initialOptions, { id: null, text: "" }]);
208
+ setPollVisible(true);
209
+ }
210
+ if (initialMeeting != null) {
211
+ setMeeting(initialMeeting);
212
+ }
213
+ }, [appId, text, embed, initialAttachments, initialOptions, initialMeeting])
214
+
215
+ useEffect(() => {
216
+ if (useDraft) {
217
+ let key = `draft-${editorType}-${parentId || appId}`;
218
+ let draft = localStorage.getItem(key);
219
+ if (draft) {
220
+ let values = JSON.parse(draft);
221
+
222
+ setValue(values.text);
223
+ setBlobs(values.blobs);
224
+ setEmbeds(values.embeds);
225
+ setMeeting(values.meeting);
226
+ if (values.pollOptions?.length > 0) {
227
+ setPollVisible(true);
228
+ setPollOptions(values.pollOptions);
229
+ }
230
+ }
231
+ }
232
+
233
+ return () => {
234
+ clearMutatingFileUpload();
235
+ }
236
+ }, [])
237
+
238
+
239
+ useUpdateEffect(() => {
240
+ if (useDraft) {
241
+ saveDraft();
242
+ }
243
+ }, [editorRef, fileList, blobs, meeting, embeds, value, pollOptions]);
244
+
245
+ function saveDraft() {
246
+ let key = `draft-${editorType}-${parentId || appId}`;
247
+
248
+ // get editor text
249
+ let text = editorRef.current?.view?.state.doc.toString();
250
+ if (text === undefined) {
251
+ text = value;
252
+ }
253
+
254
+ const blobFiles = fileList.filter((m) => m?.state?.context?.blob != null).map((f) => {
255
+ return f!.state.context!.blob;
256
+ });
257
+ const allBlobs = [...blobFiles, ...blobs];
258
+
259
+ if (!allBlobs.length && !meeting && !embeds.length && !pollOptions.length && text === "") {
260
+ localStorage.removeItem(key);
261
+ } else {
262
+ localStorage.setItem(key, JSON.stringify({ blobs: allBlobs, meeting: meeting, text: text, pollOptions: pollOptions, embeds: embeds }));
263
+ }
264
+
265
+ }
266
+
267
+ // search for embeds
268
+ const handleEmbeds = async (content: string) => {
269
+ await getEmbeds(content)
270
+ }
271
+
272
+ // add resolved embed
273
+ const handleAddEmbed = (data: EmbedType) => {
274
+ // update embeds
275
+ setEmbeds((previous) => [data, ...previous]);
276
+ }
277
+
278
+ // get embeds hook
279
+ const { getEmbeds, initEmbeds, clearEmbeds } = useEmbeds(handleAddEmbed);
280
+
281
+ const handleEmbedRemove = (embedId: number) => {
282
+ setEmbeds((previous) => previous.filter((e: EmbedType) => e.id !== embedId));
283
+ }
284
+
285
+ const handleEmbedSwap = () => {
286
+
287
+ setEmbeds((previous) => {
288
+ let first = previous.shift();
289
+ if (first) {
290
+ return [...previous, first];
291
+ }
292
+
293
+ return previous;
294
+
295
+ });
296
+ }
297
+
298
+ const onChange = (value: string, viewUpdate: any) => {
299
+ //setValue(value);
300
+ if (showEmbeds) {
301
+ handleEmbeds(value);
302
+ }
303
+
304
+ if (showTyping) {
305
+ throttledTyping();
306
+ }
307
+
308
+ if (useDraft) {
309
+ throttledDrafting();
310
+ }
311
+
312
+ };
313
+
314
+ // upload files
315
+ const handleFileUpload = async (e: any) => {
316
+ if (e.target.files) {
317
+ for (var i = 0; i < e.target.files.length; i++) {
318
+ let file = e.target.files[i];
319
+ let fileProps = { file: file }
320
+ uploadFileMutation.mutateAsync(fileProps, {});
321
+ }
322
+ }
323
+ }
324
+
325
+ // open file dialog
326
+ const openFileInput = (e: any) => {
327
+ fileInput?.click();
328
+ }
329
+
330
+ // remove uploaded file
331
+ const handleRemoveFile = (mutation: FileMutation, id: number, e: any) => {
332
+ setFiles("");
333
+ removeMutatingFileUpload(mutation);
334
+ }
335
+
336
+ // remove blob
337
+ const handleRemoveBlob = (id: number, e: any) => {
338
+ setFiles("");
339
+ setBlobs(blobs.filter((b: BlobType) => {
340
+ return b.id !== id
341
+ }));
342
+ }
343
+
344
+ // remove file attachment
345
+ const handleRemoveAttachment = (id: number, e: any) => {
346
+ setAttachments(attachments.filter((a: FileType) => {
347
+ return a.id !== id
348
+ }));
349
+ }
350
+
351
+ // add ecternal file
352
+ function handleExternalFileAdded(externalFiles: BlobType[]) {
353
+ setBlobs([...blobs, ...externalFiles]);
354
+ }
355
+
356
+ const onDrop = useCallback((acceptedFiles: File[]) => {
357
+ // this callback will be called after files get dropped, we will get the acceptedFiles. If you want, you can even access the rejected files too
358
+ console.log(acceptedFiles);
359
+ if (acceptedFiles.length > 0) {
360
+ for (var i = 0; i < acceptedFiles.length; i++) {
361
+ let file = acceptedFiles[i];
362
+ let fileProps = { file: file }
363
+ uploadFileMutation.mutateAsync(fileProps, {});
364
+ }
365
+ return true;
366
+ }
367
+
368
+ }, []);
369
+
370
+ const handlePoll = () => {
371
+ if (!pollVisible) {
372
+ if (pollOptions.length === 0) {
373
+ const option = { id: null, text: "" };
374
+ setPollOptions((prev) => [...prev, option]);
375
+ }
376
+ setPollVisible(true);
377
+ } else {
378
+ setPollVisible(false);
379
+ }
380
+ }
381
+
382
+ const handlePollOptionAdd = (e: React.FocusEvent<HTMLInputElement>, key: number) => {
383
+ if (key === pollOptions.length - 1) {
384
+ const option = { id: null, text: "" };
385
+ setPollOptions((prev) => [...prev, option]);
386
+ }
387
+ }
388
+
389
+ const handlePollOptionChange = (i: number, e: React.ChangeEvent<HTMLInputElement>) => {
390
+ let newValues = [...pollOptions];
391
+ newValues[i].text = e.target.value;
392
+ setPollOptions(newValues);
393
+ }
394
+
395
+ const handleMeetingAdd = (m: any) => {
396
+ setMeeting(m)
397
+ }
398
+
399
+ const handleMeetingDelete = () => {
400
+ setMeeting(null);
401
+ }
402
+
403
+ // create post
404
+ const handleCreate = async () => {
405
+ // get editor text
406
+ const text = (editorRef.current?.view?.state.doc.toString() || "");
407
+
408
+ const blobFiles = fileList.filter((m) => m?.state?.context?.blob != null).map((f) => {
409
+ return f!.state.context!.blob;
410
+ });
411
+ const allBlobs = [...blobFiles, ...blobs];
412
+ // check if not empty
413
+ if (text === "" && allBlobs.length === 0 && attachments.length === 0 && embeds.length === 0 && meeting === null && pollOptions.filter(p => p.text.trim() !== "").length === 0) {
414
+ setEditorError(true);
415
+ return;
416
+ };
417
+
418
+ setDisabled(true);
419
+
420
+ // create post/comment/message
421
+ await onSubmit(text, allBlobs, attachments, meeting?.id || null, embeds.length > 0 ? embeds[0].id : null, pollOptions);
422
+
423
+ // clean up
424
+ editorRef.current?.view?.dispatch({ changes: { from: 0, to: editorRef.current?.view?.state.doc.length, insert: "" } });
425
+ setValue("");
426
+ setFiles("");
427
+ setBlobs([]);
428
+ setAttachments([]);
429
+ setEmbeds([]);
430
+ setPollOptions([]);
431
+ setPollVisible(false);
432
+ clearEmbeds();
433
+ setMeeting(null);
434
+ setDisabled(false);
435
+ setEditorError(false);
436
+ clearMutatingFileUpload();
437
+
438
+ }
439
+
440
+ let editorInputs = (
441
+ <>
442
+ {editorType === "messages" &&
443
+ <div className="wy-message-editor-inputs">
444
+ <Dropdown.UI directionY='up' icon="plus">
445
+
446
+ {showAttachments &&
447
+ <>
448
+ <Dropdown.Item onClick={openFileInput}>
449
+ <Icon.UI name="attachment" /> File from device
450
+ </Dropdown.Item>
451
+ <input type="file" ref={input => fileInput = input} value={files} onChange={handleFileUpload} multiple hidden tabIndex={-1} />
452
+ </>
453
+ }
454
+
455
+ {showCloudFiles && options?.enableCloudFiles &&
456
+ <Dropdown.Item onClick={openCloudFiles}>
457
+ <Icon.UI name="cloud" /> File from cloud
458
+ </Dropdown.Item>
459
+ }
460
+ {/* meetings */}
461
+ {showMeetings &&
462
+ <Meetings onMeetingAdded={handleMeetingAdd} dropdown={true} />
463
+ }
464
+ </Dropdown.UI>
465
+ <div className={classNames("wy-message-editor-text", { "wy-is-invalid": editorError })}>
466
+ <ReactCodeMirror
467
+ ref={editorRef}
468
+ value={value}
469
+ placeholder={placeholder}
470
+ extensions={extensions}
471
+ onChange={onChange}
472
+ basicSetup={{
473
+ defaultKeymap: false,
474
+ lineNumbers: false,
475
+ dropCursor: true,
476
+ highlightActiveLine: false,
477
+ history: true,
478
+ foldGutter: false,
479
+ autocompletion: true,
480
+ drawSelection: false,
481
+ highlightSpecialChars: false,
482
+ syntaxHighlighting: false,
483
+ highlightSelectionMatches: false
484
+ }}
485
+ />
486
+ </div>
487
+ {/* submit */}
488
+ <Button.UI title={buttonText} disabled={disabled} onClick={handleCreate}><Icon.UI name="send" color="primary" /></Button.UI>
489
+ </div>
490
+ }
491
+ {editorType === "comments" &&
492
+ <>
493
+ <div className="wy-comment-editor-inputs">
494
+
495
+ <Dropdown.UI directionY='up' icon="plus">
496
+
497
+ {showAttachments &&
498
+ <>
499
+ <Dropdown.Item onClick={openFileInput}>
500
+ <Icon.UI name="attachment" /> File from device
501
+ </Dropdown.Item>
502
+ <input type="file" ref={input => fileInput = input} value={files} onChange={handleFileUpload} multiple hidden tabIndex={-1} />
503
+ </>
504
+ }
505
+
506
+ {showCloudFiles && options?.enableCloudFiles &&
507
+ <Dropdown.Item onClick={openCloudFiles}>
508
+ <Icon.UI name="cloud" /> File from cloud
509
+ </Dropdown.Item>
510
+ }
511
+ </Dropdown.UI>
512
+ <div className={classNames("wy-comment-editor-text", { "wy-is-invalid": editorError })}>
513
+ <ReactCodeMirror
514
+ ref={editorRef}
515
+ value={value}
516
+ placeholder={placeholder}
517
+ extensions={extensions}
518
+ onChange={onChange}
519
+ basicSetup={{
520
+ defaultKeymap: false,
521
+ lineNumbers: false,
522
+ dropCursor: true,
523
+ highlightActiveLine: false,
524
+ history: true,
525
+ foldGutter: false,
526
+ autocompletion: true,
527
+ drawSelection: false,
528
+ highlightSpecialChars: false,
529
+ syntaxHighlighting: false,
530
+ highlightSelectionMatches: false
531
+ }}
532
+ />
533
+ </div>
534
+ {/* submit */}
535
+ <Button.UI title={buttonText} disabled={disabled} onClick={handleCreate}><Icon.UI name="send" color="primary" /></Button.UI>
536
+ </div>
537
+ </>
538
+ }
539
+
540
+ {editorType === "posts" &&
541
+ <>
542
+ <div className={classNames("wy-post-editor-text", { "wy-is-invalid": editorError })}>
543
+ <ReactCodeMirror
544
+ ref={editorRef}
545
+ value={value}
546
+ placeholder={placeholder}
547
+ extensions={extensions}
548
+ onChange={onChange}
549
+ basicSetup={{
550
+ defaultKeymap: false,
551
+ lineNumbers: false,
552
+ dropCursor: true,
553
+ highlightActiveLine: false,
554
+ history: true,
555
+ foldGutter: false,
556
+ autocompletion: true,
557
+ drawSelection: false,
558
+ highlightSpecialChars: false,
559
+ syntaxHighlighting: false,
560
+ highlightSelectionMatches: false
561
+ }}
562
+ />
563
+ </div>
564
+
565
+ <div className='wy-post-editor-inputs'>
566
+ {/* attachments */}
567
+ {showAttachments &&
568
+ <div>
569
+ <Button.UI title="Add file from device" onClick={openFileInput}><Icon.UI name="attachment" /></Button.UI>
570
+ <input type="file" ref={input => fileInput = input} value={files} onChange={handleFileUpload} multiple hidden tabIndex={-1} />
571
+ </div>
572
+ }
573
+
574
+ {/* cloud files */}
575
+ {showCloudFiles && options?.enableCloudFiles &&
576
+ <Button.UI title="Add file from cloud" onClick={openCloudFiles}>
577
+ <Icon.UI name="cloud"></Icon.UI>
578
+ </Button.UI>
579
+ }
580
+
581
+ {/* meetings */}
582
+ {showMeetings &&
583
+ <Meetings onMeetingAdded={handleMeetingAdd} />
584
+ }
585
+
586
+ {/* polls */}
587
+ {showPolls &&
588
+ <Button.UI title="Add poll" onClick={handlePoll}>
589
+ <Icon.UI name="poll"></Icon.UI>
590
+ </Button.UI>
591
+ }
592
+
593
+ {/* submit */}
594
+ <Button.UI className='wy-button-primary' title={buttonText} disabled={disabled} onClick={handleCreate}>{buttonText}</Button.UI>
595
+
596
+ </div>
597
+ </>
598
+ }
599
+
600
+
601
+ </>
602
+ )
603
+
604
+ let editorLists = (
605
+ <>
606
+ {/* polls */}
607
+ {showPolls && pollVisible && pollOptions.length > 0 &&
608
+ <div className='wy-poll-form'>
609
+ {pollOptions.map((p: PollOptionType, index: number) => {
610
+ return (
611
+ <input key={'option_' + index} value={p.text} onChange={e => handlePollOptionChange(index, e)} className='wy-input' type='text' placeholder='+ add an option' onFocus={(e) => handlePollOptionAdd(e, index)} />
612
+ )
613
+ })}
614
+ </div>
615
+
616
+ }
617
+
618
+ {/* attachments */}
619
+ {(showAttachments || showCloudFiles) &&
620
+ <div>
621
+ {attachments.map((a: FileType) => {
622
+ return (
623
+ <Blob key={a.id} id={a.id} name={a.name} className="wy-item-body">
624
+ <Button.UI onClick={handleRemoveAttachment.bind(Editor, a.id)}><Icon.UI name='close-circle' /></Button.UI>
625
+ </Blob>
626
+ )
627
+ })}
628
+ {/* uploaded files */}
629
+ {fileList && fileList.map((m, index) => {
630
+ let f = m.state.context?.file;
631
+ return (
632
+ <React.Fragment key={'f' + index}>
633
+ {f &&
634
+ <FileItem.Item file={f}>
635
+ <Button.UI onClick={handleRemoveFile.bind(Editor, m, f.id)}><Icon.UI name='close-circle' /></Button.UI>
636
+ </FileItem.Item>
637
+ }
638
+ </React.Fragment>
639
+
640
+ )
641
+ })}
642
+ {/* files from draft */}
643
+ {blobs.map((a: BlobType) => {
644
+ return (
645
+ <Blob key={a.id} id={a.id} name={a.name} className="wy-item-body">
646
+ <Button.UI onClick={handleRemoveBlob.bind(Editor, a.id)}><Icon.UI name='close-circle' /></Button.UI>
647
+ </Blob>
648
+ )
649
+ })}
650
+ </div>
651
+ }
652
+
653
+ {/* meetings */}
654
+ {showMeetings && meeting &&
655
+ <div className="wy-item">
656
+ <Meeting id={meeting.id} title={meeting.provider} className="wy-item-body" />
657
+ <Button.UI onClick={handleMeetingDelete}><Icon.UI name='close-circle' /></Button.UI>
658
+ </div>
659
+ }
660
+
661
+ {/* embeds */}
662
+ {showEmbeds &&
663
+ <div className='wy-embed-preview'>
664
+ <>
665
+ {embeds.map((embed: EmbedType, index: number) => {
666
+ return (
667
+ <Embed key={'embed' + index} embed={embed} onRemove={handleEmbedRemove} onSwap={embeds.length > 1 ? handleEmbedSwap : null} />
668
+ )
669
+ })}
670
+ </>
671
+
672
+ </div>
673
+ }
674
+ </>
675
+ )
676
+
677
+ return (
678
+
679
+ <div className={classNames({ 'wy-post-editor': editorType === 'posts' }, { 'wy-comment-editor': editorType === 'comments' }, { 'wy-message-editor': editorType === 'messages' })}>
680
+ <Dropzone onDrop={onDrop} dragClass={classNames({ 'wy-post-editor-dragging': editorType === 'posts' }, { 'wy-comment-editor-dragging': editorType === 'comments' }, { 'wy-message-editor-dragging': editorType === 'messages' })}>
681
+ {editorType === "messages" &&
682
+ <>
683
+ {editorLists}
684
+ </>
685
+ }
686
+
687
+ {editorInputs}
688
+
689
+ {(editorType === "posts" || editorType === "comments") &&
690
+ <>
691
+ {editorLists}
692
+ </>
693
+ }
694
+ </Dropzone>
695
+ </div>
696
+
697
+ )
698
+ }
699
+
700
+ export default Editor;