@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,28 @@
1
+ import classNames from "classnames";
2
+ import React from "react";
3
+ import Icon from "../ui/Icon";
4
+ import { getExtension, getIcon, getKind } from "../utils/fileUtilities";
5
+ import { toKebabCase } from "../utils/utils";
6
+
7
+ type Props = {
8
+ id: number,
9
+ name: string
10
+ className?: string,
11
+ children?: React.ReactNode
12
+ }
13
+ const Blob = ({ id, name, className, children }: Props) => {
14
+ let ext = getExtension(name);
15
+ let { icon } = getIcon(name);
16
+ let kind = getKind(name)
17
+ return (
18
+ <div className='wy-item'>
19
+ <Icon.UI name={icon} size={1} className={classNames("wy-kind-" + toKebabCase(kind), "wy-ext-" + ext.substring(1))} />
20
+ <div className='wy-item-body'>
21
+ {name}
22
+ </div>
23
+ {children}
24
+ </div>
25
+ )
26
+ }
27
+
28
+ export default Blob;
@@ -0,0 +1,43 @@
1
+ import React, { useState } from 'react';
2
+ import CommentEdit from './CommentEdit';
3
+ import CommentTrashed from './CommentTrashed';
4
+ import CommentView from './CommentView';
5
+
6
+ type Props = {
7
+ appId: number,
8
+ parentId: number,
9
+ id: number,
10
+ text: string,
11
+ html: string,
12
+ created_at: string,
13
+ modified_at?: string,
14
+ created_by: MemberType,
15
+ trashed_at?: string,
16
+ attachments: FileType[],
17
+ reactions: ReactableType[],
18
+ embed: EmbedType | undefined,
19
+ is_trashed: boolean
20
+
21
+ }
22
+
23
+
24
+ const Comment = ({ ...props }: Props) => {
25
+ const [edit, setEdit] = useState<boolean>(false);
26
+
27
+ return (
28
+ <div className='wy-comment'>
29
+ {props.is_trashed &&
30
+ <CommentTrashed {...props} />
31
+ }
32
+ {!props.is_trashed && edit &&
33
+ <CommentEdit {...props} onClose={() => setEdit(prev => !prev)} />
34
+ }
35
+
36
+ {!props.is_trashed && !edit &&
37
+ <CommentView {...props} onEdit={() => setEdit(prev => !prev)} />
38
+ }
39
+ </div>
40
+ )
41
+ }
42
+
43
+ export default Comment;
@@ -0,0 +1,15 @@
1
+ import React from "react";
2
+
3
+ type Props = {
4
+ id: number,
5
+ count: number
6
+ }
7
+
8
+ const CommentCount = ({ id, count }: Props) => {
9
+
10
+ return (
11
+ <>{count} {'comment' + (count !== 1 ? 's': '')}</>
12
+ )
13
+ }
14
+
15
+ export default CommentCount;
@@ -0,0 +1,48 @@
1
+ import React from 'react';
2
+ import Icon from '../ui/Icon';
3
+ import Button from '../ui/Button';
4
+ import Editor from './Editor';
5
+ import useMutateEditComment from '../hooks/useMutateEditComment';
6
+
7
+ type Props = {
8
+ appId: number,
9
+ parentId: number,
10
+ id: number,
11
+ text: string,
12
+ html: string,
13
+ created_at: string,
14
+ created_by: MemberType,
15
+ attachments: FileType[],
16
+ reactions: ReactableType[],
17
+ embed: EmbedType | undefined,
18
+ onClose: (e?: any) => void
19
+ }
20
+
21
+ const CommentEdit = ({ appId, parentId, id, text, embed, attachments, onClose }: Props) => {
22
+ const editCommentMutation = useMutateEditComment();
23
+
24
+ const handleUpdate = async (text: string, blobs: BlobType[], attachments: FileType[], meeting: number | null, embed: number | null, options: PollOptionType[]) => {
25
+ await editCommentMutation.mutateAsync({ id: id, appId: appId, parentId: parentId, text: text, blobs: blobs, attachments: attachments, meeting: meeting, embed: embed });
26
+ onClose();
27
+ }
28
+
29
+ return (
30
+ <>
31
+ <nav className='wy-item'>
32
+ <div className='wy-item-body'>
33
+ <div className='wy-item-title'>Edit comment</div>
34
+ </div>
35
+
36
+ <a className='wy-button wy-button-icon'>
37
+ <Button.UI onClick={onClose}>
38
+ <Icon.UI name="close" />
39
+ </Button.UI>
40
+
41
+ </a>
42
+ </nav>
43
+ <Editor editorType='posts' editorLocation='posts' id={id} appId={appId} placeholder={'Update the comment'} text={text} embed={embed} attachments={attachments} buttonText='Update' onSubmit={handleUpdate} showAttachments={true} showCloudFiles={true} showEmbeds={false} showPolls={false} />
44
+ </>
45
+ )
46
+ }
47
+
48
+ export default CommentEdit;
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import Avatar from './Avatar';
3
+
4
+ type Props = {
5
+ text: string,
6
+ created_at: string,
7
+ created_by: MemberType
8
+ }
9
+
10
+
11
+ const CommentPlaceholder = ({ ...props }: Props) => {
12
+
13
+ return (
14
+ <div className='wy-comment'>
15
+ <div className='wy-item wy-comment-header'>
16
+ <img alt="" className="wy-avatar wy-placeholder" height={32} width={32} src={props.created_by.avatar_url} />
17
+
18
+ <div className='wy-item-body'>
19
+ <div className='wy-item-title'><span className='wy-placeholder'>Placeholder name</span></div>
20
+ <div className='wy-item-text'><time className='wy-placeholder' dateTime='2022-12-31 00:00:00'>2022-12-31 00:00:00</time></div>
21
+ </div>
22
+ </div>
23
+ <div className='wy-comment-body'>
24
+ <div className='wy-comment-content'>
25
+ <div className='wy-content'>
26
+ <span className='wy-placeholder'>Lorem</span> <span className='wy-placeholder'>ipsum</span> <span className='wy-placeholder'>dolor</span> <span className='wy-placeholder'>sit</span> <span className='wy-placeholder'>amet.</span>
27
+ </div>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ )
32
+ }
33
+
34
+ export default CommentPlaceholder;
@@ -0,0 +1,45 @@
1
+ import React from "react";
2
+ import { useQueryClient } from "react-query";
3
+ import useMutateRestoreComment from "../hooks/useMutateRestoreComment";
4
+ import Button from '../ui/Button';
5
+ import { updateCacheItem } from "../utils/cacheUtils";
6
+
7
+ type Props = {
8
+ appId: number,
9
+ parentId: number,
10
+ id: number,
11
+ text: string,
12
+ html: string,
13
+ created_at: string,
14
+ created_by: MemberType,
15
+ attachments: FileType[],
16
+ reactions: ReactableType[],
17
+ embed: EmbedType | undefined
18
+ }
19
+
20
+
21
+ const CommentTrashed = ({id, appId, parentId}: Props) => {
22
+
23
+ const restoreComment = useMutateRestoreComment();
24
+ const queryClient = useQueryClient();
25
+
26
+ const handleUndo = () => {
27
+ restoreComment.mutate({ id: id, appId: appId, parentId: parentId}, {
28
+ onSuccess: () => {
29
+ updateCacheItem(queryClient, ['posts', appId], parentId, (item: MessageType) => {
30
+ item.comment_count = (item.comment_count || 0) + 1;
31
+ });
32
+ }
33
+ });
34
+ }
35
+
36
+ return (
37
+ <div className="wy-item wy-item-lg">
38
+ <div className="wy-item-body">Comment was trashed.</div>
39
+ <Button.UI onClick={handleUndo} className='wy-button-variant'>Undo</Button.UI>
40
+
41
+ </div>
42
+ )
43
+ }
44
+
45
+ export default CommentTrashed;
@@ -0,0 +1,142 @@
1
+ import React, { useContext } from 'react';
2
+ import dayjs from 'dayjs';
3
+ import Dropdown from '../ui/Dropdown';
4
+ import Icon from '../ui/Icon';
5
+ import { ReactionsList, ReactionsMenu } from './Reactions';
6
+ import Image, { ImageGrid } from './Image';
7
+ import Attachment from './Attachment';
8
+ import Avatar from './Avatar';
9
+ import Embed from './Embed';
10
+ import { UserContext } from '../contexts/UserContext';
11
+ import { PreviewContext } from "../contexts/PreviewContext";
12
+ import useMutateTrashComment from '../hooks/useMutateTrashComment';
13
+ import { useQueryClient } from 'react-query';
14
+ import { updateCacheItem } from '../utils/cacheUtils';
15
+
16
+ type Props = {
17
+ appId: number,
18
+ parentId: number,
19
+ id: number,
20
+ text: string,
21
+ html: string,
22
+ created_at: string,
23
+ modified_at?: string,
24
+ created_by: MemberType,
25
+ trashed_at?: string,
26
+ attachments: FileType[],
27
+ reactions: ReactableType[],
28
+ embed: EmbedType | undefined,
29
+ onEdit: (e: any) => void
30
+ }
31
+
32
+ const CommentView = ({ appId, id, parentId, html, created_at, modified_at, created_by, attachments, reactions, embed, onEdit }: Props) => {
33
+ const { user } = useContext(UserContext);
34
+ const queryClient = useQueryClient();
35
+ const { openPreview, setPreviewFiles } = useContext(PreviewContext);
36
+ const date = dayjs.utc(created_at).tz(dayjs.tz.guess());
37
+ const trashComment = useMutateTrashComment();
38
+
39
+ let images = attachments?.filter((a: FileType) => a.kind === "image" && a.thumbnail_url);
40
+ let files = attachments?.filter((a: FileType) => a.kind !== "image" || !a.thumbnail_url);
41
+
42
+ const handlePreviewClick = (e: React.MouseEvent<HTMLInputElement>, attachmentId: number) => {
43
+ e.preventDefault();
44
+ setPreviewFiles(attachments);
45
+ openPreview(attachmentId);
46
+ }
47
+
48
+ const handleDelete = () => {
49
+ trashComment.mutate({ id: id, appId: appId, parentId: parentId }, {
50
+ onSuccess: () => {
51
+ updateCacheItem(queryClient, ['posts', appId], parentId, (item: MessageType) => {
52
+ item.comment_count = (item.comment_count || 1) - 1;
53
+ });
54
+ }
55
+ });
56
+ }
57
+
58
+ return (
59
+ <>
60
+ <div className='wy-item wy-item-sm wy-comment-header'>
61
+ <Avatar src={created_by.avatar_url} size={32} name={created_by.display_name} />
62
+ <div className='wy-item-body'>
63
+ <div className='wy-item-title'>{created_by.display_name}</div>
64
+ <div className='wy-item-text'>
65
+ <time dateTime={created_at} title={date.format('LLLL')}>{date.fromNow()}</time>
66
+ {modified_at &&
67
+ <time dateTime={modified_at}> · edited</time>
68
+ }
69
+ </div>
70
+ </div>
71
+
72
+ <div className='wy-item-actions wy-item-actions-top'>
73
+ <Dropdown.UI directionX='left'>
74
+
75
+ {/* subscribe / unsubscribe */}
76
+
77
+ {/* edit action */}
78
+ {user.id === created_by.id &&
79
+ <Dropdown.Item onClick={onEdit}>
80
+ <Icon.UI name="pencil"></Icon.UI> Edit
81
+ </Dropdown.Item>
82
+ }
83
+
84
+ {/* trash action */}
85
+ {user.id === created_by.id &&
86
+ <Dropdown.Item onClick={handleDelete}>
87
+ <Icon.UI name="trashcan"></Icon.UI> Trash
88
+ </Dropdown.Item>
89
+ }
90
+ </Dropdown.UI>
91
+ </div>
92
+
93
+ </div>
94
+
95
+ <div className='wy-comment-body'>
96
+ <div className='wy-comment-content'>
97
+ {/* image grid */}
98
+ {images && !!images.length && <ImageGrid>
99
+ {images.map((a: FileType) =>
100
+ <React.Fragment key={a.id} >
101
+ {a.download_url &&
102
+ <Image onClick={(e) => handlePreviewClick(e, a.id)} key={a.id} src={a.download_url} previewSrc={a.preview_url} width={a.width} height={a.height} />
103
+ }
104
+ </React.Fragment>
105
+ )}
106
+ </ImageGrid>}
107
+
108
+ {/* embeds */}
109
+ {embed &&
110
+ <Embed embed={embed} />
111
+ }
112
+
113
+ <div className='wy-content' dangerouslySetInnerHTML={{ __html: html }}>
114
+ {/* markdown */}
115
+
116
+ </div>
117
+
118
+ {/* poll */}
119
+
120
+ {/* files */}
121
+ {files && !!files.length && <div className="wy-list wy-list-bordered">
122
+ {files.map((a: FileType) =>
123
+ <Attachment key={a.id} onClick={(e) => handlePreviewClick(e, a.id)} name={a.name} previewFormat={a.kind} provider={a.provider} url={a.download_url} previewUrl={a.provider ? a.external_url : a.preview_url} mediaType={a.media_type} kind={a.kind} size={a.size} />
124
+ )}
125
+ </div>}
126
+
127
+ {/* meeting */}
128
+ </div>
129
+ </div>
130
+
131
+
132
+ <div className='wy-reactions-line'>
133
+ {/* reactions */}
134
+ <ReactionsList id={id} type="comments" parentId={parentId} reactions={reactions} />
135
+ <ReactionsMenu id={id} type="comments" parentId={parentId} reactions={reactions} placement="top-end" />
136
+ </div>
137
+
138
+ </>
139
+ )
140
+ }
141
+
142
+ export default CommentView;
@@ -0,0 +1,78 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { useQueryClient } from 'react-query';
3
+ import useCommentList from '../hooks/useCommentList';
4
+ import useMutateComment from '../hooks/useMutateComment';
5
+ import Spinner from '../ui/Spinner';
6
+ import { updateCacheItem } from '../utils/cacheUtils';
7
+ import Comment from './Comment';
8
+ import CommentPlaceholder from './CommentPlaceholder';
9
+ import Editor from './Editor';
10
+
11
+ type Props = {
12
+ appId: number,
13
+ parentId: number,
14
+ type: "posts" | "files" | "apps"
15
+ }
16
+
17
+ const Comments = ({ appId, parentId, type }: Props) => {
18
+ const queryClient = useQueryClient();
19
+ const addCommentMutation = useMutateComment();
20
+ const { isLoading, isError, data, error, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } = useCommentList(parentId, type, {});
21
+
22
+ const handleCreate = async (text: string, blobs: BlobType[], attachments: FileType[], meeting: number | null, embed: number | null, options: PollOptionType[]) => {
23
+ await addCommentMutation.mutateAsync({ parentId: parentId, type: type, text: text, blobs: blobs, meeting: null, embed: embed }, {
24
+ onSuccess: (data: MessageType) => {
25
+ updateCacheItem(queryClient, [type, appId], parentId, (item: MessageType) => {
26
+ item.comment_count = (item.comment_count || 0) + 1;
27
+ });
28
+ }
29
+ });
30
+ }
31
+
32
+ if (isLoading) {
33
+ return (<div className='wy-buttons'><Spinner.UI /></div>)
34
+ }
35
+ return (
36
+ <div>
37
+ <div className='wy-comments'>
38
+ {!isLoading && data && data.pages && data.pages.map((group, i) => {
39
+ return <React.Fragment key={data.pages.length - i}>
40
+ {
41
+ group.data?.map((comment: MessageType) => {
42
+ return comment.temp ?
43
+ <CommentPlaceholder key={'comment' + comment.id} text={comment.text} created_at={comment.created_at} created_by={comment.created_by} /> :
44
+ <Comment
45
+ key={'comment' + comment.id}
46
+ appId={appId}
47
+ parentId={parentId}
48
+ id={comment.id}
49
+ text={comment.text}
50
+ html={comment.html}
51
+ created_at={comment.created_at}
52
+ modified_at={comment.modified_at}
53
+ created_by={comment.created_by}
54
+ trashed_at={comment.trashed_at}
55
+ attachments={comment.attachments}
56
+ reactions={comment.reactions}
57
+ embed={comment.embed}
58
+ is_trashed={comment.is_trashed}
59
+ />
60
+ })
61
+ }
62
+ </React.Fragment>
63
+ })}
64
+
65
+ </div>
66
+
67
+ {type === "files" ?
68
+ <div className='wy-comment-editor-bottom'>
69
+ <Editor editorType='comments' editorLocation={type} appId={appId} parentId={parentId} placeholder={'Create a comment'} buttonText="Comment" onSubmit={handleCreate} showAttachments={true} showCloudFiles={true} showEmbeds={false} showPolls={false} useDraft={true} />
70
+ </div>
71
+ :
72
+ <Editor editorType='comments' editorLocation={type} appId={appId} parentId={parentId} placeholder={'Create a comment'} buttonText="Comment" onSubmit={handleCreate} showAttachments={true} showCloudFiles={true} showEmbeds={false} showPolls={false} useDraft={true} />
73
+ }
74
+ </div>
75
+ )
76
+ }
77
+
78
+ export default Comments;
@@ -17,6 +17,7 @@ import useMutateRemoveMembers from '../hooks/useMutateRemoveMembers';
17
17
  import Avatar from './Avatar';
18
18
  import { UserContext } from '../contexts/UserContext';
19
19
  import Messages from './Messages';
20
+ import useMutateLeaveConversation from '../hooks/useMutateLeaveConversation';
20
21
 
21
22
  const Conversation = ({ id, showBackButton }: ConversationProps) => {
22
23
 
@@ -41,7 +42,7 @@ const Conversation = ({ id, showBackButton }: ConversationProps) => {
41
42
  enabled: selectedConversationId != null
42
43
  });
43
44
 
44
- const { isLoading: isLoadingMembers, data: dataMembers } = useMembers(selectedConversationId, {
45
+ const { isLoading: isLoadingMembers, data: dataMembers, refetch: refetchMembers } = useMembers(selectedConversationId, {
45
46
  // The query will not execute until the activeConversation exists
46
47
  enabled: selectedConversationId != null
47
48
  });
@@ -51,14 +52,14 @@ const Conversation = ({ id, showBackButton }: ConversationProps) => {
51
52
  const addMembersMutation = useMutateMembers();
52
53
  const updateNameMutation = useMutateConversationName();
53
54
  const removeMembers = useMutateRemoveMembers();
55
+ const leaveConversation = useMutateLeaveConversation();
54
56
 
55
- const handleRealtimeAppUpdated = useCallback((realtimeEvent: RealtimeApp) => {
57
+ const handleRealtimeAppUpdated = useCallback((realtimeEvent: RealtimeApp) => {
56
58
  if (realtimeEvent.app.id !== selectedConversationId) return;
57
59
  queryClient.invalidateQueries(['conversation', selectedConversationId]);
58
60
  }, [selectedConversationId]);
59
61
 
60
- const handleAdd = async (selected: UserType[]) => {
61
-
62
+ const handleAdd = async (selected: MemberType[]) => {
62
63
  const membersList = selected.map((m) => m.id);
63
64
  await addMembersMutation.mutateAsync({ id: selectedConversationId, members: membersList });
64
65
  setModalAddOpen(false);
@@ -74,11 +75,29 @@ const Conversation = ({ id, showBackButton }: ConversationProps) => {
74
75
 
75
76
  const handleUpdateTitle = (e: any) => {
76
77
  setTitle(e.target.value);
77
- updateNameMutation.mutate({ id: selectedConversationId, name: e.target.value });
78
+ }
79
+
80
+ const handleSaveTitle = () => {
81
+ updateNameMutation.mutate({ id: selectedConversationId, name: title || null });
78
82
  }
79
83
 
80
84
  const handleLeaveConversation = () => {
81
- removeMembers.mutate({ id: selectedConversationId, members: [user.id] });
85
+ leaveConversation.mutate({ id: selectedConversationId, members: [user.id] });
86
+ setModalDetailsOpen(false);
87
+ setModalAddOpen(false);
88
+ }
89
+
90
+ const handleAddMembers = () => {
91
+ setModalDetailsOpen(false);
92
+ setModalAddOpen(true);
93
+ }
94
+
95
+ const handleRemoveMember = (id: number) => {
96
+ removeMembers.mutate({ id: selectedConversationId, members: [id] }, {
97
+ onSuccess: () => {
98
+ refetchMembers();
99
+ }
100
+ });
82
101
  }
83
102
 
84
103
  const handleBack = () => {
@@ -111,11 +130,11 @@ const Conversation = ({ id, showBackButton }: ConversationProps) => {
111
130
  if (dataConversation && dataConversation.type === ChatRoom) {
112
131
  setTitle(dataConversation?.display_name);
113
132
  }
114
- if(dataConversation && (dataConversation.type === ChatRoom || dataConversation.type === Chat)){
133
+ if (dataConversation && (dataConversation.type === ChatRoom || dataConversation.type === Chat)) {
115
134
  setIsRoomOrChat(true)
116
135
  }
117
136
  }, [dataConversation]);
118
-
137
+
119
138
  return (
120
139
  <>
121
140
  <header className="wy-appbars" data-adjust-scrollbar-top>
@@ -134,12 +153,21 @@ const Conversation = ({ id, showBackButton }: ConversationProps) => {
134
153
  </div>
135
154
  <Dropdown.UI directionX='left'>
136
155
 
137
- <Dropdown.Item onClick={() => toggleDetailsModal(true)}>Details</Dropdown.Item>
156
+ <Dropdown.Item onClick={() => toggleDetailsModal(true)}>
157
+ <Icon.UI name="information"></Icon.UI>
158
+ Details
159
+ </Dropdown.Item>
138
160
 
139
161
  {dataConversation.type === ChatRoom &&
140
162
  <>
141
- <Dropdown.Item onClick={() => toggleAddModal(true)}>Add people</Dropdown.Item>
142
- <Dropdown.Item onClick={handleLeaveConversation}>Leave conversation</Dropdown.Item>
163
+ <Dropdown.Item onClick={() => toggleAddModal(true)}>
164
+ <Icon.UI name="account-plus"></Icon.UI>
165
+ Add members
166
+ </Dropdown.Item>
167
+ <Dropdown.Item onClick={handleLeaveConversation}>
168
+ <Icon.UI name="account-minus"></Icon.UI>
169
+ Leave conversation
170
+ </Dropdown.Item>
143
171
  </>
144
172
  }
145
173
 
@@ -157,52 +185,78 @@ const Conversation = ({ id, showBackButton }: ConversationProps) => {
157
185
  </div>
158
186
  }
159
187
  {selectedConversationId && dataMembers && dataConversation &&
160
- <Messages id={selectedConversationId} chatRoom={isRoomOrChat} members={dataMembers} displayName={dataConversation?.display_name} avatarUrl={dataConversation?.avatar_url} lastMessageId={dataConversation?.last_message?.id}/>
188
+ <Messages id={selectedConversationId} chatRoom={isRoomOrChat} members={dataMembers} displayName={dataConversation?.display_name} avatarUrl={dataConversation?.avatar_url} lastMessageId={dataConversation?.last_message?.id} />
161
189
  }
162
190
 
163
191
  <Overlay.UI isOpen={modalAddOpen} className="wy-modal">
164
192
  <header className="wy-appbars" data-adjust-scrollbar-top>
165
193
  <nav className="wy-appbar">
166
194
  <Button.UI onClick={() => toggleAddModal(false)}><Icon.UI name='close' /></Button.UI>
167
- <div className="wy-appbar-text">Add people</div>
195
+ <div className="wy-appbar-text">Add members</div>
168
196
  </nav>
169
197
  </header>
170
- <SearchUsers handleSubmit={handleAdd} buttonTitle="Add selected" />
198
+ {dataMembers &&
199
+ <SearchUsers existingMembers={dataMembers.data} handleSubmit={handleAdd} buttonTitle="Save" />
200
+ }
201
+
171
202
  </Overlay.UI>
172
203
 
173
204
  <Overlay.UI isOpen={modalDetailsOpen} className="wy-modal">
174
205
  <header className="wy-appbars">
175
206
  <nav className="wy-appbar">
176
207
  <Button.UI onClick={() => toggleDetailsModal(false)}><Icon.UI name='close' /></Button.UI>
177
- <div className="wy-appbar-text">Conversation details</div>
208
+ <div className="wy-appbar-text">Details</div>
178
209
  </nav>
179
210
  </header>
180
211
  <div className='wy-scroll-y'>
181
- {dataConversation && <div className="wy-avatar-header">
212
+ {dataConversation && <div className="wy-avatar-header">
182
213
  <Avatar src={dataConversation?.avatar_url} name={title} size={128} />
183
- {dataConversation?.type !== ChatRoom &&
184
- <h3 className="wy-headline">{dataConversation?.display_name}</h3>
214
+ {dataConversation?.type !== ChatRoom &&
215
+ <h3 className="wy-headline">{dataConversation?.display_name}</h3>
185
216
  }
186
217
  </div>}
187
218
 
188
219
  {dataConversation?.type === ChatRoom && (
189
220
  <>
190
221
  <div className="wy-pane-group">
191
- <input className="wy-input" value={title} onChange={(e) => handleUpdateTitle(e)} />
222
+ <label className="wy-input-label">Conversation name</label>
223
+ <div className="wy-input-group">
224
+
225
+ <input className="wy-input" value={title} onChange={(e) => handleUpdateTitle(e)} />
226
+ <Button.UI onClick={handleSaveTitle} className="wy-button-icon">
227
+ <Icon.Raw name="content-save" />
228
+ </Button.UI>
229
+ </div>
230
+ <div className="wy-description">Changing the name of a group chat changes it for everyone.</div>
231
+
192
232
  </div>
193
233
  <div className="wy-pane-group">
194
- <table className="wy-table wy-search-result-table">
195
- <tbody>
196
- {dataMembers && dataMembers.data && dataMembers.data.map((m: MemberType) => {
197
- return (
198
- <tr key={m.id}>
199
- <td className="wy-table-cell-icon wy-search-result-table-icon"><Avatar src={m.avatar_url} name={m.display_name} id={m.id} size={24} presence={m.presence} /></td>
200
- <td className='wy-table-cell-text'>{m.display_name}</td>
201
- </tr>
202
- )
203
- })}
204
- </tbody>
205
- </table>
234
+ <label className="wy-input-label">Members</label>
235
+
236
+ {dataConversation && dataMembers && dataMembers.data && dataMembers.data.map((m: MemberType) => {
237
+ return (
238
+ <div className='wy-item' key={m.id}>
239
+ <Avatar src={m.avatar_url} name={m.display_name} id={m.id} size={32} presence={m.presence} />
240
+ <div className="wy-item-body">
241
+ {m.display_name}
242
+ </div>
243
+ {dataConversation.created_by_id === user.id && m.id !== user.id &&
244
+ <Button.UI onClick={() => handleRemoveMember(m.id)} className="wy-button-icon" title="Remove member">
245
+ <Icon.Raw name="account-minus" />
246
+ </Button.UI>
247
+ }
248
+ {m.id === user.id &&
249
+ <Button.UI onClick={() => handleLeaveConversation()} className="wy-button-icon" title="Leave conversation">
250
+ <Icon.Raw name="account-minus" />
251
+ </Button.UI>
252
+ }
253
+ </div>
254
+ )
255
+ })}
256
+ <Button.UI onClick={handleAddMembers} title="Add members">
257
+ <Icon.UI name="account-plus"/>
258
+ <div className="wy-item-body">Add members</div>
259
+ </Button.UI>
206
260
  </div>
207
261
  </>
208
262
  )}