@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,336 @@
1
+ import React, { useContext, useEffect, useState } from "react";
2
+ import Overlay from '../ui/Overlay';
3
+ import Button from '../ui/Button';
4
+ import Icon from '../ui/Icon';
5
+ import Preview from './Preview';
6
+ import { getIcon, getExtension } from "../utils/fileUtilities";
7
+ import { InfiniteData, UseInfiniteQueryResult } from "react-query";
8
+ import Dropdown from "../ui/Dropdown";
9
+ import { FileMenu } from "./FileItem";
10
+ import classNames from "classnames";
11
+ import Comments from "./Comments";
12
+ import FileVersions from "./FileVersions";
13
+ import { WeavyContext } from '../contexts/WeavyContext';
14
+
15
+ function allowedKeyTarget(e: any) {
16
+ var notInputField = !e.target.matches("input, textarea, select") && !e.target.closest('[contenteditable="true"]');
17
+ return notInputField;
18
+ }
19
+
20
+ type Props = {
21
+ appId: number,
22
+ infiniteFiles: UseInfiniteQueryResult<FilesResult, unknown>,
23
+ previewId?: number,
24
+ onClose?: () => void
25
+ }
26
+
27
+ const PreviewFiles = ({ appId, infiniteFiles, previewId, onClose }: Props) => {
28
+ const { client } = useContext(WeavyContext);
29
+
30
+ const [modalPreviewOpen, setModalPreviewOpen] = useState<boolean>(false);
31
+ const [commentsOpen, setCommentsOpen] = useState<boolean>(false);
32
+ const [versionsOpen, setVersionsOpen] = useState<boolean>(false);
33
+ const [sidebarMaximized, setSidebarMaximized] = useState<boolean>(false);
34
+
35
+ const [activeFile, setActiveFile] = useState<FileType>();
36
+ const [versionFile, setVersionFile] = useState<FileType>();
37
+
38
+ const [currentFileId, setCurrentFileId] = useState<number>();
39
+ const [nextFileId, setNextFileId] = useState<number>();
40
+ const [previousFileId, setPreviousFileId] = useState<number>();
41
+
42
+ const { isLoading, data: filesData, dataUpdatedAt, fetchNextPage, hasNextPage, isFetchingNextPage } = infiniteFiles;
43
+
44
+ // sidebar effects
45
+
46
+ useEffect(() => {
47
+ if (!versionsOpen && !commentsOpen) {
48
+ //restore maximize on close
49
+ setSidebarMaximized(false);
50
+ }
51
+
52
+ if (!versionsOpen) {
53
+ setVersionFile(undefined);
54
+ }
55
+ }, [versionsOpen, commentsOpen])
56
+
57
+ useEffect(() => {
58
+ setVersionFile(undefined);
59
+ }, [activeFile])
60
+
61
+ const toggleSidebarTab = (tab?: "comments" | "versions", state?: boolean) => {
62
+ if (tab === "comments") {
63
+ setVersionsOpen(false);
64
+ setCommentsOpen(state !== undefined ? state : !commentsOpen);
65
+ } else if(tab === "versions") {
66
+ setCommentsOpen(false);
67
+ setVersionsOpen(state !== undefined ? state : !versionsOpen);
68
+ } else {
69
+ setCommentsOpen(false);
70
+ setVersionsOpen(false);
71
+ }
72
+ }
73
+
74
+ useEffect(() => {
75
+ if (currentFileId) {
76
+ if (!isLoading) {
77
+ (async () => {
78
+ //console.log("infiniteFIles", infiniteFiles)
79
+ if (filesData && filesData.pages.length > 0) {
80
+ if (currentFileId >= 1) {
81
+ const getIndexFromId = (id:number) => {
82
+ let foundIndex = -1;
83
+ filesData.pages.some((page: any) => {
84
+ let currentFoundIndex = page.data.findIndex((file: FileType) => file.id === id);
85
+ if (currentFoundIndex !== -1) {
86
+ foundIndex = currentFoundIndex + page.start;
87
+ }
88
+ return currentFoundIndex !== -1;
89
+ })
90
+ //console.log("found index", id, foundIndex)
91
+ return foundIndex;
92
+ }
93
+
94
+ const getFileFromIndex = async (index:number) : Promise<FileType | undefined> => {
95
+ if (index > 0 || index <= filesData.pages[0].count) {
96
+ let infiniteFilesData: InfiniteData<FilesResult> | undefined = filesData;
97
+ //console.log("comparing index", index, infiniteFiles.data.pages[infiniteFiles.data.pages.length - 1].end)
98
+ if (index > filesData.pages[filesData.pages.length - 1].end && (hasNextPage || isFetchingNextPage)) {
99
+ //console.log("fetchy fetchy")
100
+ let fetchedInfiniteFiles = await fetchNextPage({ cancelRefetch: false });
101
+ infiniteFilesData = fetchedInfiniteFiles.data;
102
+ console.log("preview nextpage was fetched");
103
+ }
104
+ let foundFile;
105
+ infiniteFilesData?.pages.find((page) => {
106
+ if (index >= page.start && index <= page.end) {
107
+ return foundFile = page.data[index - page.start];
108
+ }
109
+ })
110
+ return foundFile;
111
+ }
112
+ }
113
+ let itemIndex = getIndexFromId(currentFileId);
114
+
115
+ setPreviousFileId((await getFileFromIndex(itemIndex - 1))?.id);
116
+ setNextFileId((await getFileFromIndex(itemIndex + 1))?.id);
117
+ setActiveFile(await getFileFromIndex(itemIndex));
118
+ } else if(currentFileId >= 0 && currentFileId < 1) {
119
+ const getFileFromId = (id:number) => {
120
+ let foundFile: FileType| undefined;
121
+ filesData.pages.some((page: any) => {
122
+ return foundFile = page.data.find((file: FileType) => file.id === id);
123
+ })
124
+ // When file id has changed
125
+ if(!foundFile && activeFile) {
126
+ filesData.pages.some((page: any) => {
127
+ return foundFile = page.data.find((file: FileType) => {
128
+ if (file.name === activeFile.name) {
129
+ if (file.id !== currentFileId) {
130
+ setCurrentFileId(file.id);
131
+ }
132
+ return true;
133
+ }
134
+ });
135
+ })
136
+ }
137
+
138
+ return foundFile;
139
+ }
140
+ setPreviousFileId(undefined);
141
+ setNextFileId(undefined);
142
+ setActiveFile(getFileFromId(currentFileId));
143
+ }
144
+ } else {
145
+ setPreviousFileId(undefined);
146
+ setNextFileId(undefined);
147
+ setActiveFile(undefined);
148
+ }
149
+
150
+ })();
151
+ }
152
+
153
+ }
154
+
155
+ }, [isLoading, filesData, dataUpdatedAt, currentFileId])
156
+
157
+ const openPreview = (id: number) => {
158
+ setCurrentFileId(id);
159
+ setModalPreviewOpen(true);
160
+ }
161
+
162
+ const closePreview = () => {
163
+ setModalPreviewOpen(false);
164
+ if (onClose) {
165
+ onClose();
166
+ }
167
+ }
168
+
169
+ useEffect(() => {
170
+ if (previewId) {
171
+ openPreview(previewId);
172
+ }
173
+ }, [previewId])
174
+
175
+
176
+ const handlePrevious = () => {
177
+ setCurrentFileId(previousFileId);
178
+ }
179
+
180
+ const handleNext = () => {
181
+ setCurrentFileId(nextFileId);
182
+ }
183
+
184
+ const handleVersionFile = (file: FileType) => {
185
+ if (activeFile?.version !== file.version) {
186
+ setVersionFile(file);
187
+ } else {
188
+ setVersionFile(undefined);
189
+ }
190
+ }
191
+
192
+ const previewFile = versionFile || activeFile;
193
+
194
+ // Keyboard handlers
195
+ useEffect(() => {
196
+ if (activeFile) {
197
+ const handleKey = (e: any) => {
198
+ if (modalPreviewOpen) {
199
+ if (e.which === 27) { // ESC
200
+ e.stopImmediatePropagation();
201
+ closePreview();
202
+ } else if (e.which === 37) { // LEFT
203
+ if (allowedKeyTarget(e)) {
204
+ e.stopPropagation();
205
+ setCurrentFileId(previousFileId);
206
+ }
207
+ } else if (e.which === 39) { // RIGHT
208
+ if (allowedKeyTarget(e)) {
209
+ e.stopPropagation();
210
+ setCurrentFileId(nextFileId);
211
+ }
212
+ }
213
+ }
214
+ };
215
+
216
+ document.addEventListener("keyup", handleKey);
217
+
218
+ return () => {
219
+ // cleanup
220
+ document.removeEventListener("keyup", handleKey);
221
+ }
222
+ }
223
+
224
+ }, [activeFile, modalPreviewOpen])
225
+
226
+ let previewExt: string = getExtension(previewFile?.name || '');
227
+ let previewIcon: string = getIcon(previewFile?.name || '').icon;
228
+
229
+ let previewSrc = previewFile?.preview_url || previewFile?.download_url || '';
230
+
231
+ // Let GIF and SVG display raw content
232
+ let animatedImage = previewFile?.preview_format === "image" && (previewExt === ".gif" || previewExt === ".svg");
233
+ if (animatedImage) {
234
+ previewSrc = previewFile?.download_url || '';
235
+ }
236
+
237
+ return (
238
+ <>
239
+ {filesData && <Overlay.UI isOpen={modalPreviewOpen} className="wy-dark" closeOnEsc={false} onClose={() => setModalPreviewOpen(false)} style={{overlay: {zIndex: 10000}}}>
240
+ <header className="wy-appbars">
241
+ <nav className="wy-appbar">
242
+ <Button.UI onClick={closePreview}><Icon.UI name='close' /></Button.UI>
243
+ <div className={classNames("wy-appbar-text", { "wy-appbar-text-trashed": activeFile?.is_trashed })}>
244
+ {activeFile &&
245
+ <span>{activeFile.name}</span>
246
+ }
247
+
248
+ </div>
249
+ <div className="wy-appbar-buttons">
250
+ {activeFile && <>
251
+ {activeFile.id >= 1 &&
252
+ <Button.UI active={commentsOpen} onClick={() => toggleSidebarTab("comments")} title={`Comments`}>
253
+ <Icon.ActiveStack>
254
+ <Icon.UI name="comment-outline" />
255
+ <Icon.UI name="comment" />
256
+ </Icon.ActiveStack>
257
+ </Button.UI>
258
+ }
259
+ <FileMenu file={activeFile}>
260
+ {activeFile.id >= 1 &&
261
+ <Dropdown.Item active={versionsOpen} onClick={() => toggleSidebarTab("versions")}><Icon.UI name="backup-restore"/> Versions</Dropdown.Item>
262
+ }
263
+ </FileMenu>
264
+ </>}
265
+ </div>
266
+
267
+ </nav>
268
+ </header>
269
+
270
+ <div className="wy-main">
271
+ <>
272
+ <aside id="tab-comments" className={classNames("wy-sidebar", { "wy-active": commentsOpen, "wy-maximized": sidebarMaximized })} hidden={!commentsOpen}>
273
+ <nav className="wy-item">
274
+ <div className="wy-item-body">
275
+ <div className="wy-item-title">Comments</div>
276
+ </div>
277
+ <Button.UI onClick={() => toggleSidebarTab("comments", false)}><Icon.UI name='close' /></Button.UI>
278
+ <button onClick={() => setSidebarMaximized(!sidebarMaximized)} className="wy-sidebar-handle" />
279
+ </nav>
280
+ <div className="wy-pane wy-scroll-y">
281
+ {commentsOpen && activeFile && activeFile.id >= 1 && appId &&
282
+ <Comments appId={appId} parentId={activeFile.id} type="files" />
283
+ }
284
+ </div>
285
+ </aside>
286
+ <aside id="tab-versions" className={classNames("wy-sidebar", { "wy-active": versionsOpen, "wy-maximized": sidebarMaximized })} hidden={!versionsOpen}>
287
+ <nav className="wy-item">
288
+ <div className="wy-item-body">
289
+ <div className="wy-item-title">Versions</div>
290
+ </div>
291
+ <Button.UI onClick={() => toggleSidebarTab("versions", false)}><Icon.UI name='close' /></Button.UI>
292
+ <button onClick={() => setSidebarMaximized(!sidebarMaximized)} className="wy-sidebar-handle" />
293
+ </nav>
294
+ <div className="wy-pane wy-scroll-y">
295
+ <div className="wy-pane-body">
296
+ {versionsOpen && activeFile && <FileVersions key={"files-versions" + appId + activeFile.id} filesKey={["files", appId]} file={activeFile} onVersionSelect={handleVersionFile} />}
297
+ </div>
298
+ </div>
299
+ </aside>
300
+ </>
301
+ <div className="wy-preview">
302
+ {previewFile &&
303
+ <>
304
+ {previousFileId &&
305
+ <nav className="wy-nav-prev"><Button.UI onClick={handlePrevious}><Icon.UI name="previous" /></Button.UI></nav>
306
+ }
307
+ {nextFileId &&
308
+ <nav className="wy-nav-next"><Button.UI onClick={handleNext}><Icon.UI name="next" /></Button.UI></nav>
309
+ }
310
+ <div className="wy-preview-area wy-scroll-y wy-scroll-x">
311
+ <Preview
312
+ client={client}
313
+ src={previewSrc}
314
+ link={previewFile.external_url}
315
+ format={previewFile.is_trashed ? "none" : previewFile.preview_format}
316
+ name={previewFile.name}
317
+ icon={previewIcon}
318
+ width={previewFile.width}
319
+ height={previewFile.height}
320
+ mediaType={previewFile.media_type}
321
+ provider={previewFile.provider}
322
+ />
323
+ </div>
324
+ </>
325
+ }
326
+ </div>
327
+ </div>
328
+ </Overlay.UI>}
329
+
330
+ </>
331
+
332
+ )
333
+ };
334
+
335
+ export default PreviewFiles;
336
+
@@ -1,76 +1,95 @@
1
- import React, { useContext, useEffect, useState } from "react";
1
+ import React, { useCallback, useContext, useEffect, useState } from "react";
2
2
  import useMutateReaction from "../hooks/useMutateReaction";
3
3
  import Icon from "../ui/Icon";
4
4
  import Button from "../ui/Button";
5
- import { MessengerContext } from "../contexts/MessengerContext";
6
5
  import classNames from "classnames";
6
+ import useEvents from "../hooks/useEvents";
7
7
 
8
- import useReactions from "../hooks/useReactions";
9
8
  import useMutateDeleteReaction from "../hooks/useMutateDeleteReaction";
10
9
  import { WeavyContext } from "../contexts/WeavyContext";
10
+ import Sheet from "../ui/Sheet";
11
+ import Avatar from "./Avatar";
12
+ import Spinner from "../ui/Spinner";
13
+ import useReactionList from "../hooks/useReactionList";
14
+ import { UserContext } from "../contexts/UserContext";
15
+ import useMutateReplaceReaction from "../hooks/useMutateReplaceReaction";
16
+
17
+ import { usePopper } from 'react-popper';
11
18
 
12
19
  type ReactionMenuProps = {
13
20
  id: number,
21
+ parentId: number | null,
22
+ type: "messages" | "posts" | "comments",
23
+ placement?: "top" | "top-start" | "top-end",
14
24
  reactions: ReactableType[]
15
25
  }
16
26
 
17
27
  type ReactionsProps = {
18
28
  id: number,
29
+ type: "messages" | "posts" | "comments",
19
30
  parentId: number | null,
20
31
  reactions: ReactableType[]
21
32
  }
22
33
 
23
- export const ReactionsMenu = ({ id, reactions }: ReactionMenuProps) => {
24
- const { reactionsList } = useReactions(id, reactions);
25
- const reactionMutation = useMutateReaction();
26
- const reactionDeleteMutation = useMutateDeleteReaction();
27
- const [visible, setVisible] = useState<boolean>(false);
34
+ export const ReactionsMenu = ({ id, parentId, type, placement = "top", reactions }: ReactionMenuProps) => {
35
+ const { user } = useContext(UserContext);
28
36
  const { options } = useContext(WeavyContext);
37
+
38
+ const [visible, setVisible] = useState<boolean>(false);
29
39
  const [reactedEmoji, setReactedEmoji] = useState<string>('');
30
-
31
40
  const emojis = options?.reactions;
41
+ const react = useMutateReaction();
42
+ const unreact = useMutateDeleteReaction();
43
+ const replaceReact = useMutateReplaceReaction();
32
44
 
33
- useEffect(() => {
34
- var filtered = reactionsList.find((e) => e.has_reacted);
35
- setReactedEmoji(filtered ? filtered.content : '')
36
- }, [reactionsList]);
45
+ const [referenceElement, setReferenceElement] = useState<HTMLButtonElement|null>(null);
46
+ const [popperElement, setPopperElement] = useState<HTMLDivElement|null>(null);
47
+ const { styles, attributes, update } = usePopper(referenceElement, popperElement, { placement: placement });
37
48
 
38
49
  useEffect(() => {
50
+ update?.();
51
+
39
52
  if (visible) {
40
53
  document.addEventListener("click", () => { setVisible(false) });
41
54
  } else {
42
55
  document.removeEventListener("click", () => { setVisible(false) });
43
56
  }
44
-
45
57
  }, [visible]);
46
58
 
59
+ useEffect(() => {
60
+ var filtered = reactions?.find((e) => e.created_by_id === user.id);
61
+ setReactedEmoji(filtered ? filtered.content : '')
62
+ }, [reactions]);
63
+
47
64
  const toggleReactionMenu = (e: any) => {
48
65
  e.stopPropagation();
49
66
  setVisible(!visible);
50
67
  }
51
68
 
52
69
  const handleReaction = async (e: any) => {
53
- // check if the reaction already exists for the user
54
- const existing = reactionsList.find((r) => r.has_reacted)
55
70
  const emoji = e.target.dataset.emoji;
71
+ const existing = reactions?.find((r) => r.created_by_id === user.id)
56
72
 
57
- if (existing) {
58
- // delete existing reaction
59
- await reactionDeleteMutation.mutateAsync({ id: id, reaction: emoji });
60
- }
61
73
 
62
- // add if not same reaction as before
63
- if (!existing || existing.content !== emoji) {
64
- await reactionMutation.mutateAsync({ id: id, reaction: emoji });
74
+ if (existing && existing.content !== emoji) {
75
+ // replace
76
+ await replaceReact.mutateAsync({ parentId: parentId, id: id, type: type, reaction: emoji })
77
+ } else if (existing) {
78
+ // remove
79
+ await unreact.mutateAsync({ parentId: parentId, id: id, type: type, reaction: emoji });
80
+ } else {
81
+ // add
82
+ await react.mutateAsync({ parentId: parentId, id: id, type: type, reaction: emoji });
65
83
  }
66
-
84
+
85
+
67
86
  setVisible(false);
68
87
  }
69
88
 
70
89
  return (
71
90
  <div className={classNames({ "wy-active": visible })} style={{ position: 'relative' }}>
72
- <Button.UI className="wy-reaction-menu-button" onClick={toggleReactionMenu}><Icon.UI name="emoticon-plus" size={1.25/1.5} /></Button.UI>
73
- <div className="wy-reaction-menu wy-dropdown-menu" style={{ display: visible ? 'block' : 'none', position: 'absolute', top: '-3.25rem' }}>
91
+ <Button.UI ref={setReferenceElement} className="wy-reaction-menu-button" onClick={toggleReactionMenu}><Icon.UI name="emoticon-plus" size={1.25 / 1.5} /></Button.UI>
92
+ <div ref={setPopperElement} className="wy-reaction-menu wy-dropdown-menu" hidden={!visible} style={styles.popper} {...attributes.popper}>
74
93
  <div className="wy-reaction-picker">
75
94
  {emojis?.map((r: string, i: number) => {
76
95
  return <Button.UI key={i} onClick={handleReaction} className={classNames("wy-button-icon wy-reaction-button", { "wy-active": reactedEmoji === r })} data-emoji={r}>{r}</Button.UI> //reactedEmoji
@@ -79,23 +98,108 @@ export const ReactionsMenu = ({ id, reactions }: ReactionMenuProps) => {
79
98
  </div>
80
99
  </div>
81
100
  )
82
-
83
101
  }
84
102
 
85
- export const ReactionsList = ({ id, reactions }: ReactionsProps) => {
86
- const { reactionsList } = useReactions(id, reactions);
87
-
88
- let reactionCount = reactionsList.reduce(
89
- (previousValue, currentItem) => previousValue + currentItem.count,
90
- 0,
91
- );
103
+ export const ReactionsList = ({ id, type, reactions }: ReactionsProps) => {
104
+ const { user } = useContext(UserContext);
105
+ const [reactionsList, setReactionsList] = useState<ReactableType[]>();
106
+ const [list, setList] = useState<ReactionGroup[]>([]);
107
+ const [count, setCount] = useState<number>(0)
108
+ const { data, isLoading, refetch } = useReactionList(id, type, { enabled: false });
109
+ const { on, off } = useEvents();
110
+
111
+ const [isOpen, setIsOpen] = useState(false);
92
112
 
113
+ useEffect(() => {
114
+ on('reaction_added_' + id, handleRealtimeReactionInserted);
115
+ on('reaction_deleted_' + id, handleRealtimeReactionDeleted);
116
+
117
+ return () => {
118
+ off('reaction_added_' + id, handleRealtimeReactionInserted);
119
+ off('reaction_deleted_' + id, handleRealtimeReactionDeleted);
120
+ }
121
+ }, [id]);
122
+
123
+ useEffect(() => {
124
+ setReactionsList(reactions);
125
+ }, [reactions])
126
+
127
+ useEffect(() => {
128
+
129
+ if (reactionsList) {
130
+ let group = [...new Map<string, ReactableType>(reactionsList?.map((item: ReactableType) => [item.content, item])).values()];
131
+
132
+ let list = group.map((item: ReactableType): ReactionGroup => {
133
+ return {
134
+ content: item.content,
135
+ count: reactionsList.filter((r) => r.content === item.content).length,
136
+ has_reacted: reactionsList.filter((r) => r.content === item.content && r.created_by_id === user.id).length > 0
137
+ }
138
+ });
139
+
140
+ let reactionCount = list.reduce(
141
+ (previousValue, currentItem) => previousValue + currentItem.count,
142
+ 0,
143
+ );
144
+ setList(list);
145
+ setCount(reactionCount);
146
+
147
+ if(isOpen){
148
+ setTimeout(() => refetch(), 200) ;
149
+ }
150
+ }
151
+
152
+ }, [reactionsList, id, type]);
153
+
154
+ const handleRealtimeReactionInserted = useCallback((reaction: RealtimeReaction) => {
155
+ if (reaction.entity.id === id && reaction.actor.id !== user.id) {
156
+ setReactionsList((oldList) => {
157
+ return [...oldList || [], { content: reaction.reaction, created_by_id: reaction.actor.id }];
158
+ });
159
+ }
160
+ }, [id, reactionsList]);
161
+
162
+ const handleRealtimeReactionDeleted = useCallback((reaction: RealtimeReaction) => {
163
+ if (reaction.entity.id === id && reaction.actor.id !== user.id) {
164
+ setReactionsList(oldList => oldList?.filter(item => item.created_by_id !== reaction.actor.id));
165
+ }
166
+ }, [id, reactionsList]);
167
+
168
+
169
+ const handleOpen = () => {
170
+ refetch();
171
+ setIsOpen(true);
172
+ }
173
+
174
+
93
175
  return (
94
176
  <>
95
- {!!reactionsList && reactionsList.map((r: ReactionGroup, i: number) => {
96
- return <span key={i} className="wy-reaction" title={r.count.toString()}>{r.content}</span> //r.has_reacted
97
- })}
98
- {reactionCount > 1 && <span className="wy-reaction-count">{reactionCount}</span>}
177
+ {count > 0 && <>
178
+ <Button.UI className="wy-reactions wy-button-icon" onClick={handleOpen}>
179
+ {!!list && list.map((r: ReactionGroup, i: number) => {
180
+ return <span key={i} className="wy-reaction" title={r.count.toString()}>{r.content}</span>
181
+ })}
182
+ {count > 1 && <span className="wy-reaction-count">{count}</span>}
183
+ </Button.UI>
184
+
185
+ {<Sheet.UI title="Reactions" isOpen={isOpen} onClose={() => {setIsOpen(false);}}>
186
+ {isOpen && <>
187
+ {isLoading &&
188
+ <Spinner.UI overlay={true}/>
189
+ }
190
+ {!isLoading && data && data.data?.map((reaction: ReactionType, index: number) => {
191
+ return (
192
+ <div className="wy-item" key={'r' + index}>
193
+ <Avatar size={32} src={reaction.created_by.avatar_url} name={reaction.created_by.display_name} />
194
+ <div className="wy-item-body">{reaction.created_by.display_name}</div>
195
+ <div>{reaction.content}</div>
196
+ </div>
197
+ )
198
+ })}
199
+ </>}
200
+ </Sheet.UI>}
201
+ </>}
202
+
99
203
  </>
100
204
  )
101
205
  }