@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,80 @@
1
+ import Icon from '../ui/Icon';
2
+ import Button from '../ui/Button';
3
+ import React from 'react';
4
+
5
+ type Props = {
6
+ embed: EmbedType,
7
+ onRemove?: Function,
8
+ onSwap?: Function | null
9
+ }
10
+
11
+ const Embed = ({ embed, onRemove, onSwap }: Props) => {
12
+
13
+ const giphy = embed.type === "photo" && embed.provider_name.toLocaleLowerCase() === "giphy";
14
+ const caption = !embed.html && !giphy;
15
+
16
+ return (
17
+ <div className='wy-embed'>
18
+ <div className='wy-embed-actions'>
19
+ {onSwap &&
20
+ <Button.UI title='Switch' onClick={onSwap}>
21
+ <Icon.UI name="swap-horizontal" />
22
+ </Button.UI>
23
+ }
24
+
25
+ {!onSwap &&
26
+ <Button.UI className='wy-embed-cycle'></Button.UI>
27
+ }
28
+
29
+ {onRemove &&
30
+ <Button.UI title='Remove' onClick={() => onRemove(embed.id)}>
31
+ <Icon.UI name="close-circle" />
32
+ </Button.UI>
33
+ }
34
+
35
+ </div >
36
+
37
+ {embed.type === "audio" &&
38
+ <div className='wy-embed-audio'></div>
39
+ }
40
+ {embed.type === "video" && embed.html &&
41
+ <div className='wy-embed-video'>
42
+ <div dangerouslySetInnerHTML={{ __html: embed.html }}></div>
43
+ </div>
44
+ }
45
+ {embed.type === "rich" &&
46
+ <div className='wy-embed-rich'></div>
47
+ }
48
+ {embed.type === "photo" && embed.thumbnail_url &&
49
+ <div className={'wy-embed-photo' + ((embed.thumbnail_width || 0) < 250 ? 'wy-embed-photo-sm' : '')}>
50
+ <a href={embed.original_url} target="_blank">
51
+ <img src={embed.thumbnail_url} width={embed.thumbnail_width} height={embed.thumbnail_height} alt='' />
52
+ </a>
53
+ </div>
54
+ }
55
+ {embed.type !== "audio" && embed.type !== "video" && embed.type !== "rich" && embed.type !== "photo" && embed.thumbnail_url &&
56
+ <div className={'wy-embed-photo' + ((embed.thumbnail_width || 0) < 250 ? 'wy-embed-photo-sm' : '')}>
57
+ <a href={embed.original_url} target="_blank">
58
+ <img src={embed.thumbnail_url} width={embed.thumbnail_width} height={embed.thumbnail_height} alt='' />
59
+ </a>
60
+ </div>
61
+ }
62
+
63
+ {caption &&
64
+ <div className='wy-embed-caption'>
65
+ <a className='wy-embed-link' href={embed.original_url} target='_blank'>{embed.host}</a>
66
+ {embed.title &&
67
+ <div className='wy-embed-title'>{embed.title}</div>
68
+ }
69
+ {embed.description &&
70
+ <div className='wy-embed-description'>{embed.description}</div>
71
+ }
72
+ </div>
73
+ }
74
+
75
+ </div >
76
+ )
77
+
78
+ }
79
+
80
+ export default Embed;
@@ -0,0 +1,391 @@
1
+ import React, { ReactNode, useEffect, useState } from "react";
2
+ import Icon from "../ui/Icon";
3
+ import Dropdown from "../ui/Dropdown";
4
+ import classNames from "classnames";
5
+ import dayjs from 'dayjs';
6
+ import { fileSizeAsString, getExtension, getIcon, isOfficeDocument } from "../utils/fileUtilities";
7
+ import { toKebabCase } from "../utils/utils";
8
+ import Spinner from "../ui/Spinner";
9
+ import openUrl from "../utils/openUrl";
10
+
11
+ type FileProps = {
12
+ file: FileType,
13
+ className?: string,
14
+ onClick?: (e: any) => void
15
+ onRename?: (name: string, file: FileType) => void,
16
+ isRenaming?: boolean,
17
+ onSubscribe?: (file: FileType) => void,
18
+ onUnsubscribe?: (file: FileType) => void,
19
+ onTrash?: (file: FileType) => void,
20
+ onRestore?: (file: FileType) => void,
21
+ onDeleteForever?: (file: FileType) => void,
22
+ onHandleError?: (file: FileType) => void,
23
+ statusText?: string,
24
+ title?: string,
25
+ children?: React.ReactNode
26
+ }
27
+
28
+ export const triggerDownload = (file: FileType) => {
29
+ openUrl(file.download_url, "_top", file.name, true);
30
+ }
31
+
32
+ export const triggerExternal = (file: FileType) => {
33
+ openUrl(file?.external_url, "_blank", file.name);
34
+ }
35
+
36
+ export const triggerApplication = (file: FileType) => {
37
+ // TODO: Change to webdav-url
38
+ openUrl(file?.application_url, "_top", file.name);
39
+ }
40
+
41
+ type FileMenuProps = {
42
+ file: FileType,
43
+ className?: string,
44
+ onRename?: (e: any) => void,
45
+ onSubscribe?: (e: any) => void,
46
+ onUnsubscribe?: (e: any) => void,
47
+ onTrash?: (e: any) => void,
48
+ onRestore?: (e: any) => void,
49
+ onDeleteForever?: (e: any) => void,
50
+ children?: ReactNode,
51
+ noWrapper?: boolean,
52
+ props?: React.HTMLAttributes<HTMLSpanElement>
53
+ }
54
+
55
+ export const FileMenu = ({ file, className, onRename, onSubscribe, onUnsubscribe, onTrash, onRestore, onDeleteForever, children, noWrapper, ...props }: FileMenuProps) => {
56
+ let { icon } = getIcon(file.name);
57
+
58
+ let isNotTemp = file.id >= 1;
59
+
60
+ return (
61
+ <Dropdown.UI directionX='left' className={className} disabled={file.status && file.status !== "ok"} noWrapper={noWrapper} {...props}>
62
+ {isNotTemp && file.is_trashed && <>
63
+ {onRestore && <Dropdown.Item onClick={onRestore}><Icon.UI name="delete-restore"/>Restore</Dropdown.Item>}
64
+ {onRestore && onDeleteForever && <Dropdown.Divider/>}
65
+ {onDeleteForever && <Dropdown.Item onClick={onDeleteForever}><Icon.UI name="delete-forever"/>Delete</Dropdown.Item>}
66
+ </>}
67
+ {!file.is_trashed && <>
68
+ {file.external_url ?
69
+ <Dropdown.Item onClick={() => triggerExternal(file)}><Icon.UI name={icon} /> {`Open in ${file.provider}`}</Dropdown.Item>
70
+ : <>
71
+ { file.application_url &&
72
+ <Dropdown.Item onClick={() => triggerApplication(file)}><Icon.UI name={file.provider ? toKebabCase(file.provider) : icon } /> {`Open in ${file.provider || 'app'}`}</Dropdown.Item>
73
+ }
74
+ <Dropdown.Item onClick={() => triggerDownload(file)}><Icon.UI name="download" size={1} /> Download</Dropdown.Item>
75
+ </>}
76
+ {isNotTemp && <>
77
+ {onRename && <Dropdown.Item onClick={onRename}><Icon.UI name="textbox" size={1} /> Rename</Dropdown.Item>}
78
+ {!file.is_subscribed && onSubscribe && <Dropdown.Item onClick={onSubscribe}><Icon.UI name="bell" size={1} /> Subscribe</Dropdown.Item>}
79
+ {file.is_subscribed && onUnsubscribe && <Dropdown.Item onClick={onUnsubscribe}><Icon.UI name="bell-off" size={1} /> Unsubscribe</Dropdown.Item>}
80
+ {onTrash && <>
81
+ <Dropdown.Divider/>
82
+ <Dropdown.Item onClick={onTrash}><Icon.UI name="delete" size={1} /> Trash</Dropdown.Item>
83
+ </>}
84
+ </>}
85
+ </>}
86
+ {children}
87
+ </Dropdown.UI>
88
+ );
89
+ }
90
+
91
+ /* Blocks click for a while */
92
+ const clickBlock = (callback: React.EventHandler<React.SyntheticEvent>) => {
93
+ return (e: React.SyntheticEvent) => {
94
+ e.preventDefault();
95
+
96
+ const onClickBlock = (e: Event) => {
97
+ console.log("Blocked event", e.type);
98
+ e.preventDefault();
99
+ e.stopImmediatePropagation();
100
+ }
101
+
102
+ // Disable any click for a short while
103
+ document.addEventListener("click", onClickBlock, { once: true, capture: true})
104
+
105
+ setTimeout(() => {
106
+ document.removeEventListener("click", onClickBlock, { capture: true})
107
+ }, 500);
108
+
109
+ return callback(e);
110
+ }
111
+ }
112
+
113
+ const FileRow = ({ file, className, onClick, onRename, isRenaming, onSubscribe, onUnsubscribe, onTrash, onRestore, onDeleteForever, onHandleError, statusText, title, children }: FileProps) => {
114
+ const [renaming, setRenaming] = useState<boolean>(false);
115
+
116
+ useEffect(() => {
117
+ if (isRenaming !== undefined) {
118
+ setRenaming(isRenaming);
119
+ }
120
+ }, [isRenaming]);
121
+
122
+ let fileSize = file.size && file.size > 0 ? fileSizeAsString(file.size) : null;
123
+ const fileChangedAt = file.modified_at || file.created_at;
124
+ const fileDate = dayjs.utc(fileChangedAt).tz(dayjs.tz.guess());
125
+
126
+ let { icon } = getIcon(file.name);
127
+ let ext = getExtension(file.name);
128
+
129
+ const onClickWrapper = (e: React.MouseEvent) => {
130
+ if (!e.defaultPrevented) {
131
+ if (onHandleError && (file.status === "conflict" || file.status === "error")) {
132
+ onHandleError(file);
133
+ } else if (onClick) {
134
+ onClick(e);
135
+ }
136
+ }
137
+ }
138
+
139
+ const handleRename = (e: React.SyntheticEvent) => {
140
+ let renameTarget = e.target as HTMLInputElement;
141
+ if (renameTarget.value && renameTarget.value !== file.name) {
142
+ onRename!(renameTarget.value, file);
143
+ }
144
+ setRenaming(false);
145
+ };
146
+
147
+ const handleRenameKey = (e: any) => {
148
+ if (e.key === "Escape") {
149
+ e.preventDefault();
150
+ e.target.value = file.name;
151
+ e.target.blur();
152
+ } else if(e.key === "Enter") {
153
+ e.preventDefault();
154
+ handleRename(e);
155
+ }
156
+ };
157
+
158
+
159
+ return (
160
+ <tr className={classNames({ "wy-table-trashed": file.is_trashed }, className)} onClick={onClickWrapper} title={title}>
161
+ <td className="wy-table-cell-icon">{
162
+ file.status === "error" ? <Icon.UI name="alert-octagon" color="error" size={1} title={file.statusText || statusText} /> :
163
+ file.status === "conflict" ? <Icon.UI name="alert" color="yellow" size={1} title={file.statusText || statusText} /> :
164
+ file.status === "pending" ? <Spinner.UI spin={!file.progress} progress={file.progress} /> :
165
+ <Icon.UI name={icon} size={1} className={classNames("wy-kind-" + toKebabCase(file.kind), "wy-ext-" + ext.substring(1))} />
166
+ }</td>
167
+ <td>{renaming && onRename ? <>
168
+ <input
169
+ type="text"
170
+ maxLength={256}
171
+ className="wy-input"
172
+ defaultValue={file.name}
173
+ onBlur={clickBlock(handleRename)}
174
+ onKeyUp={handleRenameKey}
175
+ onClick={(e: any) => e.preventDefault()}
176
+ onFocus={(e: any) => {
177
+ const i = e.target.value.lastIndexOf(".");
178
+ if (i === -1) {
179
+ e.target.select();
180
+ } else {
181
+ e.target.setSelectionRange(0, i);
182
+ }
183
+ }}
184
+ autoFocus />
185
+ </>
186
+ :
187
+ <>
188
+ <span title={file.name + ((statusText || file.statusText) ? `: ${statusText || file.statusText}` : '')}>{file.name}{(statusText || file.statusText) && <>: <em>{statusText || file.statusText}</em></>}</span>
189
+ </>
190
+ }</td>
191
+ <td><time dateTime={fileChangedAt} title={fileDate.format('LLLL')}>{fileDate.format('l')}</time></td>
192
+ <td><span>{file.kind}</span></td>
193
+ <td><span>{fileSize}</span></td>
194
+ <td className="wy-table-cell-icon">
195
+ {children || <>
196
+ <FileMenu
197
+ file={file}
198
+ onRename={onRename ? () => setRenaming(true) : undefined}
199
+ onSubscribe={onSubscribe?.bind(FileRow, file)}
200
+ onUnsubscribe={onUnsubscribe?.bind(FileRow, file)}
201
+ onTrash={onTrash?.bind(FileRow, file)}
202
+ onRestore={onRestore?.bind(FileRow, file)}
203
+ onDeleteForever={onDeleteForever?.bind(FileRow, file)}
204
+ noWrapper={true}
205
+ />
206
+ </>}
207
+ </td>
208
+ </tr>
209
+ )
210
+ }
211
+
212
+ const FileCard = ({ file, className, onClick, onRename, isRenaming, onSubscribe, onUnsubscribe, onTrash, onRestore, onDeleteForever, onHandleError, statusText, title, children }: FileProps) => {
213
+ const [renaming, setRenaming] = useState<boolean>(false);
214
+
215
+ useEffect(() => {
216
+ if (isRenaming !== undefined) {
217
+ setRenaming(isRenaming);
218
+ }
219
+ }, [isRenaming]);
220
+
221
+ let { icon } = getIcon(file.name);
222
+ let ext = getExtension(file.name);
223
+
224
+ const onClickWrapper = (e: React.MouseEvent) => {
225
+ if (!e.defaultPrevented && !renaming) {
226
+ if (onHandleError && (file.status === "conflict" || file.status === "error")) {
227
+ onHandleError(file);
228
+ } else if (onClick) {
229
+ onClick(e);
230
+ }
231
+ }
232
+ }
233
+
234
+ const handleRename = (e: React.SyntheticEvent) => {
235
+ let renameTarget = e.target as HTMLInputElement;
236
+ if (renameTarget.value && renameTarget.value !== file.name) {
237
+ onRename!(renameTarget.value, file);
238
+ }
239
+ setRenaming(false);
240
+ };
241
+
242
+ const handleRenameKey = (e: any) => {
243
+ if (e.key === "Escape") {
244
+ e.preventDefault();
245
+ e.target.value = file.name;
246
+ e.target.blur();
247
+ } else if(e.key === "Enter") {
248
+ e.preventDefault();
249
+ handleRename(e);
250
+ }
251
+ };
252
+
253
+ return (
254
+ <div className={classNames("wy-card", { "wy-card-trashed": file.is_trashed, "wy-card-hover": onClick && !file.is_trashed && !renaming }, className)} onClick={onClickWrapper} title={title}>
255
+ <div className="wy-card-actions">
256
+ {
257
+ file.status === "error" && <Icon.UI name="alert-octagon" color="error" size={1} title={file.statusText || statusText} /> ||
258
+ file.status === "conflict" && <Icon.UI name="alert" color="yellow" size={1} title={file.statusText || statusText} /> ||
259
+ file.status === "pending" && <Spinner.UI spin={!file.progress} progress={file.progress} />
260
+ }
261
+ {children || <>
262
+ <FileMenu
263
+ file={file}
264
+ onRename={onRename ? () => setRenaming(true) : undefined}
265
+ onSubscribe={onSubscribe?.bind(FileRow, file)}
266
+ onUnsubscribe={onUnsubscribe?.bind(FileRow, file)}
267
+ onTrash={onTrash?.bind(FileRow, file)}
268
+ onRestore={onRestore?.bind(FileRow, file)}
269
+ onDeleteForever={onDeleteForever?.bind(FileRow, file)}
270
+ />
271
+ </>}
272
+ </div>
273
+ {!file.is_trashed && file.thumbnail_url &&
274
+ <img className={classNames("wy-card-top wy-card-content", {"wy-card-top-image": file.kind === "image"})} src={file.thumbnail_url} loading="lazy" />
275
+ ||
276
+ <div className="wy-content-icon wy-card-top wy-card-content">
277
+ <Icon.UI name={icon} size={4/1.5} className={classNames("wy-kind-" + toKebabCase(file.kind), "wy-ext-" + ext.substring(1))} />
278
+ </div>
279
+ }
280
+ <div className="wy-card-label wy-card-content wy-filename">
281
+ {renaming && onRename ? <>
282
+ <input
283
+ type="text"
284
+ maxLength={256}
285
+ className="wy-input"
286
+ defaultValue={file.name}
287
+ onBlur={clickBlock(handleRename)}
288
+ onKeyUp={handleRenameKey}
289
+ onClick={(e: any) => e.preventDefault()}
290
+ onFocus={(e: any) => {
291
+ const i = e.target.value.lastIndexOf(".");
292
+ if (i === -1) {
293
+ e.target.select();
294
+ } else {
295
+ e.target.setSelectionRange(0, i);
296
+ }
297
+ }}
298
+ autoFocus />
299
+ </> : <span title={file.name + ((statusText || file.statusText) ? `: ${statusText || file.statusText}` : '')}>{file.name}{(statusText || file.statusText) && <>: <em>{statusText || file.statusText}</em></>}</span>}
300
+ </div>
301
+ </div>
302
+
303
+ )
304
+ }
305
+
306
+ const FileItem = ({ file, className, onClick, onRename, isRenaming, onSubscribe, onUnsubscribe, onTrash, onRestore, onDeleteForever, onHandleError, statusText, title, children }: FileProps) => {
307
+ const [renaming, setRenaming] = useState<boolean>(false);
308
+
309
+ useEffect(() => {
310
+ if (isRenaming !== undefined) {
311
+ setRenaming(isRenaming);
312
+ }
313
+ }, [isRenaming]);
314
+
315
+ let { icon } = getIcon(file.name);
316
+ let ext = getExtension(file.name);
317
+
318
+ const onClickWrapper = (e: React.MouseEvent) => {
319
+ if (!e.defaultPrevented && !renaming) {
320
+ if (onHandleError && (file.status === "conflict" || file.status === "error")) {
321
+ onHandleError(file);
322
+ } else if (onClick) {
323
+ onClick(e);
324
+ }
325
+ }
326
+ }
327
+
328
+ const handleRename = (e: React.SyntheticEvent) => {
329
+ let renameTarget = e.target as HTMLInputElement;
330
+ if (renameTarget.value && renameTarget.value !== file.name) {
331
+ onRename!(renameTarget.value, file);
332
+ }
333
+ setRenaming(false);
334
+ };
335
+
336
+ const handleRenameKey = (e: any) => {
337
+ if (e.key === "Escape") {
338
+ e.preventDefault();
339
+ e.target.value = file.name;
340
+ e.target.blur();
341
+ } else if(e.key === "Enter") {
342
+ e.preventDefault();
343
+ handleRename(e);
344
+ }
345
+ };
346
+
347
+ return (
348
+ <div className={classNames("wy-item", { "wy-item-trashed": file.is_trashed, "wy-item-hover": onClick && !file.is_trashed && !renaming }, className)} onClick={onClickWrapper} title={title}>
349
+ {
350
+ file.status === "error" ? <Icon.UI name="alert-octagon" color="error" size={1} title={file.statusText || statusText} /> :
351
+ file.status === "conflict" ? <Icon.UI name="alert" color="yellow" size={1} title={file.statusText || statusText} /> :
352
+ file.status === "pending" ? <Spinner.UI spin={!file.progress} progress={file.progress} /> :
353
+ <Icon.UI name={icon} size={1} className={classNames("wy-kind-" + toKebabCase(file.kind), "wy-ext-" + ext.substring(1))} />
354
+ }
355
+ <div className="wy-item-body">
356
+ {renaming && onRename ? <>
357
+ <input
358
+ type="text"
359
+ maxLength={256}
360
+ className="wy-input"
361
+ defaultValue={file.name}
362
+ onBlur={clickBlock(handleRename)}
363
+ onKeyUp={handleRenameKey}
364
+ onClick={(e: any) => e.preventDefault()}
365
+ onFocus={(e: any) => {
366
+ const i = e.target.value.lastIndexOf(".");
367
+ if (i === -1) {
368
+ e.target.select();
369
+ } else {
370
+ e.target.setSelectionRange(0, i);
371
+ }
372
+ }}
373
+ autoFocus />
374
+ </> : <span title={file.name + ((statusText || file.statusText) ? `: ${statusText || file.statusText}` : '')}>{file.name}{(statusText || file.statusText) && <>: <em>{statusText || file.statusText}</em></>}</span> }
375
+ </div>
376
+ {children || <>
377
+ <FileMenu
378
+ file={file}
379
+ onRename={onRename ? () => setRenaming(true) : undefined}
380
+ onSubscribe={onSubscribe?.bind(FileRow, file)}
381
+ onUnsubscribe={onUnsubscribe?.bind(FileRow, file)}
382
+ onTrash={onTrash?.bind(FileRow, file)}
383
+ onRestore={onRestore?.bind(FileRow, file)}
384
+ onDeleteForever={onDeleteForever?.bind(FileRow, file)}
385
+ />
386
+ </>}
387
+ </div>
388
+ )
389
+ }
390
+
391
+ export default { Row: FileRow, Card: FileCard, Item: FileItem, Menu: FileMenu };
@@ -0,0 +1,166 @@
1
+ import React, { useContext, useEffect, useState } from 'react';
2
+ import useFileList from '../hooks/useFileList';
3
+ import useInfiniteScroll from '../hooks/useInfiniteScroll';
4
+ import FileItem from './FileItem';
5
+ import Button from '../ui/Button';
6
+ import useMutateFileRename from '../hooks/useMutateFileRename';
7
+ import { useMutateFileDeleteForever, useMutateFileRestore, useMutateFileTrash } from '../hooks/useMutateFileTrash';
8
+ import { useMutateFileSubscribe, useMutateFileUnsubscribe } from '../hooks/useMutateFileSubscribe';
9
+ import Spinner from '../ui/Spinner';
10
+ import Icon from '../ui/Icon';
11
+ import PreviewFiles from './PreviewFiles';
12
+
13
+ type Props = {
14
+ appId: number,
15
+ view?: FileView,
16
+ order?: FileOrder,
17
+ trashed?: boolean,
18
+ onSorting?: (order: FileOrder) => void,
19
+ onHandleError?: (file: FileType) => void
20
+ }
21
+
22
+ const FileList = ({ appId, view = "list", order, trashed = false, onSorting, onHandleError }: Props) => {
23
+
24
+ const infiniteFiles = useFileList(appId, { meta: { order: order, trashed: trashed }});
25
+ const { isLoading, data, fetchNextPage, hasNextPage, isFetchingNextPage, remove: resetInfiniteFiles } = infiniteFiles;
26
+
27
+ const [currentPreview, setCurrentPreview] = useState<number>();
28
+
29
+ const openPreview = (previewId: number) => {
30
+ setCurrentPreview(previewId);
31
+ }
32
+
33
+ const onClosePreview = () => {
34
+ setCurrentPreview(undefined);
35
+ }
36
+
37
+ // Reset query when unmounted
38
+ useEffect(() => () => resetInfiniteFiles(), []);
39
+
40
+ const loadMoreRef = useInfiniteScroll(infiniteFiles, [view])
41
+
42
+ const mutateFileRename = useMutateFileRename(["files", appId]);
43
+ const mutateFileTrash = useMutateFileTrash(["files", appId]);
44
+ const mutateFileDeleteForever = useMutateFileDeleteForever(["files", appId]);
45
+ const mutateFileRestore = useMutateFileRestore(["files", appId]);
46
+ const mutateFileSubscribe = useMutateFileSubscribe(["files", appId])
47
+ const mutateFileUnsubscribe = useMutateFileUnsubscribe(["files", appId])
48
+
49
+ if (isLoading) {
50
+ return (
51
+ <Spinner.UI spin={true} overlay={true} />
52
+ )
53
+ }
54
+
55
+ let loadMoreButton = <Button.UI onClick={() => fetchNextPage()} disabled={!hasNextPage || isFetchingNextPage} className="wy-message-readmore">Load more</Button.UI>;
56
+
57
+ if (view == "grid") {
58
+ return (
59
+ <>
60
+
61
+ <div className="wy-grid wy-pane-group">
62
+ {data && data.pages && data.pages.map((group: any, i: number) => {
63
+ return <React.Fragment key={i}>
64
+ {
65
+ group.data?.map((file: FileType) => {
66
+
67
+ return <FileItem.Card
68
+ key={'file-card' + file.id}
69
+ file={file}
70
+ onClick={(e: any) => !file.is_trashed && openPreview(file.id)}
71
+ onRename={(name: string) => mutateFileRename.mutateAsync({ file: file, name: name})}
72
+ onSubscribe={(file: FileType) => mutateFileSubscribe.mutateAsync({ file: file })}
73
+ onUnsubscribe={(file: FileType) => mutateFileUnsubscribe.mutateAsync({ file: file })}
74
+ onTrash={(file: FileType) => mutateFileTrash.mutateAsync({ file: file })}
75
+ onRestore={(file: FileType) => mutateFileRestore.mutateAsync({ file: file })}
76
+ onDeleteForever={(file: FileType) => mutateFileDeleteForever.mutateAsync({ file: file })}
77
+ onHandleError={onHandleError}
78
+ />
79
+ })
80
+ }
81
+ </React.Fragment>
82
+ })}
83
+
84
+ <div className="wy-pager" ref={loadMoreRef}>
85
+ {isFetchingNextPage
86
+ ? 'Loading more...'
87
+ : hasNextPage
88
+ ? loadMoreButton
89
+ : ""}
90
+ </div>
91
+ </div>
92
+ <PreviewFiles appId={appId} infiniteFiles={infiniteFiles} previewId={currentPreview} onClose={onClosePreview} />
93
+ </>
94
+ );
95
+ }
96
+
97
+ const headers: ({ by: FileOrderBy | undefined, title: string })[] = [
98
+ { by: "name", title: "Name" },
99
+ { by: "modified_at", title: "Modified" },
100
+ { by: undefined, title: "Kind" },
101
+ { by: "size", title: "Size" }
102
+ ]
103
+
104
+ return (
105
+ <>
106
+ <table className="wy-table wy-table-hover wy-table-files">
107
+ <thead>
108
+ <tr>
109
+ <th className="wy-table-cell-icon"></th>
110
+ {headers.map((header) => {
111
+ let active = header.by === order?.by;
112
+ let onHeaderClick = (e: any) => {
113
+ e.preventDefault();
114
+ header.by && onSorting && onSorting({ by: header.by, descending: active && !order?.descending });
115
+ }
116
+ return <th key={"files-header" + header.title}>{header.by ?
117
+ <div className={"wy-table-sort-link"} onClick={onHeaderClick}>{header.title} {active && <Icon.UI name={order?.descending ? "menu-down" : "menu-up"} />}</div>
118
+ :
119
+ <>{header.title}</>
120
+ }</th>
121
+ })}
122
+ <th className="wy-table-cell-icon"></th>
123
+ </tr>
124
+ </thead>
125
+ <tbody>
126
+ {data && data.pages && data.pages.map((group: any, i: number) => {
127
+ return <React.Fragment key={i}>
128
+ {
129
+ group.data?.map((file: FileType) => {
130
+
131
+ return <FileItem.Row
132
+ key={'file-row' + file.id}
133
+ file={file}
134
+ onClick={(e: any) => !file.is_trashed && openPreview(file.id)}
135
+ onRename={(name: string) => mutateFileRename.mutateAsync({ file: file, name: name})}
136
+ onSubscribe={(file: FileType) => mutateFileSubscribe.mutateAsync({ file: file })}
137
+ onUnsubscribe={(file: FileType) => mutateFileUnsubscribe.mutateAsync({ file: file })}
138
+ onTrash={(file: FileType) => mutateFileTrash.mutateAsync({ file: file })}
139
+ onRestore={(file: FileType) => mutateFileRestore.mutateAsync({ file: file })}
140
+ onDeleteForever={(file: FileType) => mutateFileDeleteForever.mutateAsync({ file: file })}
141
+ onHandleError={onHandleError}
142
+ />
143
+ })
144
+ }
145
+ </React.Fragment>
146
+ })}
147
+
148
+
149
+ <tr className="wy-pager" ref={loadMoreRef}>
150
+ <td colSpan={6}>
151
+ {isFetchingNextPage
152
+ ? 'Loading more...'
153
+ : hasNextPage
154
+ ? loadMoreButton
155
+ : ""}
156
+ </td>
157
+ </tr>
158
+
159
+ </tbody>
160
+ </table>
161
+ <PreviewFiles appId={appId} infiniteFiles={infiniteFiles} previewId={currentPreview} onClose={onClosePreview} />
162
+ </>
163
+ )
164
+ }
165
+
166
+ export default FileList;