@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.
- package/.vscode/settings.json +2 -0
- package/changelog.md +10 -0
- package/dist/cjs/client/WeavyClient.d.ts +1 -0
- package/dist/cjs/components/Attachment.d.ts +5 -5
- package/dist/cjs/components/Blob.d.ts +9 -0
- package/dist/cjs/components/Comment.d.ts +18 -0
- package/dist/cjs/components/CommentCount.d.ts +7 -0
- package/dist/cjs/components/CommentEdit.d.ts +16 -0
- package/dist/cjs/components/CommentPlaceholder.d.ts +8 -0
- package/dist/cjs/components/CommentTrashed.d.ts +15 -0
- package/dist/cjs/components/CommentView.d.ts +18 -0
- package/dist/cjs/components/Comments.d.ts +8 -0
- package/dist/cjs/components/ConversationListItem.d.ts +1 -1
- package/dist/cjs/components/Dropzone.d.ts +10 -0
- package/dist/cjs/components/Editor.d.ts +25 -0
- package/dist/cjs/components/Embed.d.ts +8 -0
- package/dist/cjs/components/FileItem.d.ts +41 -0
- package/dist/cjs/components/FileList.d.ts +11 -0
- package/dist/cjs/components/FileVersions.d.ts +9 -0
- package/dist/cjs/components/Files.d.ts +4 -0
- package/dist/cjs/components/Image.d.ts +3 -3
- package/dist/cjs/components/MeetingCard.d.ts +1 -1
- package/dist/cjs/components/Meetings.d.ts +2 -1
- package/dist/cjs/components/Poll.d.ts +8 -0
- package/dist/cjs/components/PollOption.d.ts +10 -0
- package/dist/cjs/components/Post.d.ts +21 -0
- package/dist/cjs/components/PostEdit.d.ts +17 -0
- package/dist/cjs/components/PostList.d.ts +6 -0
- package/dist/cjs/components/PostPlaceholder.d.ts +8 -0
- package/dist/cjs/components/PostTrashed.d.ts +14 -0
- package/dist/cjs/components/PostView.d.ts +21 -0
- package/dist/cjs/components/Posts.d.ts +4 -0
- package/dist/cjs/components/Preview.d.ts +1 -3
- package/dist/cjs/components/PreviewFiles.d.ts +10 -0
- package/dist/cjs/components/Reactions.d.ts +6 -2
- package/dist/cjs/components/SearchUsers.d.ts +2 -1
- package/dist/cjs/contexts/CloudFilesContext.d.ts +9 -0
- package/dist/cjs/hooks/useApps.d.ts +1 -0
- package/dist/cjs/hooks/useCloudFiles.d.ts +3 -0
- package/dist/cjs/hooks/useCommentList.d.ts +1 -0
- package/dist/cjs/hooks/useEmbeds.d.ts +5 -0
- package/dist/cjs/hooks/useFileList.d.ts +1 -0
- package/dist/cjs/hooks/useFileUploader.d.ts +8 -0
- package/dist/cjs/hooks/useFileVersions.d.ts +2 -0
- package/dist/cjs/hooks/useInfiniteScroll.d.ts +4 -0
- package/dist/cjs/hooks/useIsFirstRender.d.ts +2 -0
- package/dist/cjs/hooks/useMutateApps.d.ts +5 -0
- package/dist/cjs/hooks/useMutateComment.d.ts +10 -0
- package/dist/cjs/hooks/useMutateConversationName.d.ts +1 -1
- package/dist/cjs/hooks/useMutateDeleteReaction.d.ts +3 -1
- package/dist/cjs/hooks/useMutateEditComment.d.ts +10 -0
- package/dist/cjs/hooks/useMutateEditPost.d.ts +10 -0
- package/dist/cjs/hooks/useMutateExternalBlobs.d.ts +2 -2
- package/dist/cjs/hooks/useMutateFile.d.ts +26 -0
- package/dist/cjs/hooks/useMutateFileRename.d.ts +5 -0
- package/dist/cjs/hooks/useMutateFileSubscribe.d.ts +7 -0
- package/dist/cjs/hooks/useMutateFileTrash.d.ts +10 -0
- package/dist/cjs/hooks/useMutateFileVersion.d.ts +7 -0
- package/dist/cjs/hooks/useMutateFiles.d.ts +2 -0
- package/dist/cjs/hooks/useMutateLeaveConversation.d.ts +4 -0
- package/dist/cjs/hooks/useMutateMessage.d.ts +2 -2
- package/dist/cjs/hooks/useMutatePost.d.ts +10 -0
- package/dist/cjs/hooks/useMutateReaction.d.ts +3 -1
- package/dist/cjs/hooks/useMutateRead.d.ts +1 -1
- package/dist/cjs/hooks/useMutateReplaceReaction.d.ts +6 -0
- package/dist/cjs/hooks/useMutateRestoreComment.d.ts +5 -0
- package/dist/cjs/hooks/useMutateRestorePost.d.ts +4 -0
- package/dist/cjs/hooks/useMutateStarred.d.ts +4 -0
- package/dist/cjs/hooks/useMutateSubscribe.d.ts +4 -0
- package/dist/cjs/hooks/useMutateTrashComment.d.ts +5 -0
- package/dist/cjs/hooks/useMutateTrashPost.d.ts +4 -0
- package/dist/cjs/hooks/useMutateTyping.d.ts +2 -0
- package/dist/cjs/hooks/useMutateUnsubscribe.d.ts +4 -0
- package/dist/cjs/hooks/useMutateVote.d.ts +5 -0
- package/dist/cjs/hooks/usePost.d.ts +1 -0
- package/dist/cjs/hooks/usePosts.d.ts +1 -0
- package/dist/cjs/hooks/usePostsList.d.ts +1 -0
- package/dist/cjs/hooks/useReactionList.d.ts +1 -0
- package/dist/cjs/hooks/useSessionState.d.ts +2 -0
- package/dist/cjs/hooks/useUnload.d.ts +2 -0
- package/dist/cjs/hooks/useUpdateEffect.d.ts +3 -0
- package/dist/cjs/hooks/useVotes.d.ts +1 -0
- package/dist/cjs/index.d.ts +3 -1
- package/dist/cjs/index.js +28 -6
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/ConversationListItem.d.ts +1 -0
- package/dist/cjs/types/Files.d.ts +7 -0
- package/dist/cjs/types/Message.d.ts +2 -2
- package/dist/cjs/types/Posts.d.ts +4 -0
- package/dist/cjs/types/interfaces.d.ts +9 -0
- package/dist/cjs/types/types.d.ts +138 -22
- package/dist/cjs/ui/Dropdown.d.ts +18 -2
- package/dist/cjs/ui/Icon.d.ts +10 -2
- package/dist/cjs/ui/Overlay.d.ts +3 -1
- package/dist/cjs/ui/Sheet.d.ts +14 -0
- package/dist/cjs/ui/Spinner.d.ts +2 -1
- package/dist/cjs/utils/cacheUtils.d.ts +14 -0
- package/dist/cjs/utils/fileUtilities.d.ts +10 -1
- package/dist/cjs/utils/mentions.d.ts +6 -0
- package/dist/cjs/utils/openUrl.d.ts +1 -0
- package/dist/css/weavy-chat.css +637 -218
- package/dist/css/weavy-files.css +3046 -0
- package/dist/css/weavy-messenger.css +643 -213
- package/dist/css/weavy-posts.css +2773 -0
- package/dist/css/weavy.css +1749 -308
- package/dist/esm/client/WeavyClient.d.ts +1 -0
- package/dist/esm/components/Attachment.d.ts +5 -5
- package/dist/esm/components/Blob.d.ts +9 -0
- package/dist/esm/components/Comment.d.ts +18 -0
- package/dist/esm/components/CommentCount.d.ts +7 -0
- package/dist/esm/components/CommentEdit.d.ts +16 -0
- package/dist/esm/components/CommentPlaceholder.d.ts +8 -0
- package/dist/esm/components/CommentTrashed.d.ts +15 -0
- package/dist/esm/components/CommentView.d.ts +18 -0
- package/dist/esm/components/Comments.d.ts +8 -0
- package/dist/esm/components/ConversationListItem.d.ts +1 -1
- package/dist/esm/components/Dropzone.d.ts +10 -0
- package/dist/esm/components/Editor.d.ts +25 -0
- package/dist/esm/components/Embed.d.ts +8 -0
- package/dist/esm/components/FileItem.d.ts +41 -0
- package/dist/esm/components/FileList.d.ts +11 -0
- package/dist/esm/components/FileVersions.d.ts +9 -0
- package/dist/esm/components/Files.d.ts +4 -0
- package/dist/esm/components/Image.d.ts +3 -3
- package/dist/esm/components/MeetingCard.d.ts +1 -1
- package/dist/esm/components/Meetings.d.ts +2 -1
- package/dist/esm/components/Poll.d.ts +8 -0
- package/dist/esm/components/PollOption.d.ts +10 -0
- package/dist/esm/components/Post.d.ts +21 -0
- package/dist/esm/components/PostEdit.d.ts +17 -0
- package/dist/esm/components/PostList.d.ts +6 -0
- package/dist/esm/components/PostPlaceholder.d.ts +8 -0
- package/dist/esm/components/PostTrashed.d.ts +14 -0
- package/dist/esm/components/PostView.d.ts +21 -0
- package/dist/esm/components/Posts.d.ts +4 -0
- package/dist/esm/components/Preview.d.ts +1 -3
- package/dist/esm/components/PreviewFiles.d.ts +10 -0
- package/dist/esm/components/Reactions.d.ts +6 -2
- package/dist/esm/components/SearchUsers.d.ts +2 -1
- package/dist/esm/contexts/CloudFilesContext.d.ts +9 -0
- package/dist/esm/hooks/useApps.d.ts +1 -0
- package/dist/esm/hooks/useCloudFiles.d.ts +3 -0
- package/dist/esm/hooks/useCommentList.d.ts +1 -0
- package/dist/esm/hooks/useEmbeds.d.ts +5 -0
- package/dist/esm/hooks/useFileList.d.ts +1 -0
- package/dist/esm/hooks/useFileUploader.d.ts +8 -0
- package/dist/esm/hooks/useFileVersions.d.ts +2 -0
- package/dist/esm/hooks/useInfiniteScroll.d.ts +4 -0
- package/dist/esm/hooks/useIsFirstRender.d.ts +2 -0
- package/dist/esm/hooks/useMutateApps.d.ts +5 -0
- package/dist/esm/hooks/useMutateComment.d.ts +10 -0
- package/dist/esm/hooks/useMutateConversationName.d.ts +1 -1
- package/dist/esm/hooks/useMutateDeleteReaction.d.ts +3 -1
- package/dist/esm/hooks/useMutateEditComment.d.ts +10 -0
- package/dist/esm/hooks/useMutateEditPost.d.ts +10 -0
- package/dist/esm/hooks/useMutateExternalBlobs.d.ts +2 -2
- package/dist/esm/hooks/useMutateFile.d.ts +26 -0
- package/dist/esm/hooks/useMutateFileRename.d.ts +5 -0
- package/dist/esm/hooks/useMutateFileSubscribe.d.ts +7 -0
- package/dist/esm/hooks/useMutateFileTrash.d.ts +10 -0
- package/dist/esm/hooks/useMutateFileVersion.d.ts +7 -0
- package/dist/esm/hooks/useMutateFiles.d.ts +2 -0
- package/dist/esm/hooks/useMutateLeaveConversation.d.ts +4 -0
- package/dist/esm/hooks/useMutateMessage.d.ts +2 -2
- package/dist/esm/hooks/useMutatePost.d.ts +10 -0
- package/dist/esm/hooks/useMutateReaction.d.ts +3 -1
- package/dist/esm/hooks/useMutateRead.d.ts +1 -1
- package/dist/esm/hooks/useMutateReplaceReaction.d.ts +6 -0
- package/dist/esm/hooks/useMutateRestoreComment.d.ts +5 -0
- package/dist/esm/hooks/useMutateRestorePost.d.ts +4 -0
- package/dist/esm/hooks/useMutateStarred.d.ts +4 -0
- package/dist/esm/hooks/useMutateSubscribe.d.ts +4 -0
- package/dist/esm/hooks/useMutateTrashComment.d.ts +5 -0
- package/dist/esm/hooks/useMutateTrashPost.d.ts +4 -0
- package/dist/esm/hooks/useMutateTyping.d.ts +2 -0
- package/dist/esm/hooks/useMutateUnsubscribe.d.ts +4 -0
- package/dist/esm/hooks/useMutateVote.d.ts +5 -0
- package/dist/esm/hooks/usePost.d.ts +1 -0
- package/dist/esm/hooks/usePosts.d.ts +1 -0
- package/dist/esm/hooks/usePostsList.d.ts +1 -0
- package/dist/esm/hooks/useReactionList.d.ts +1 -0
- package/dist/esm/hooks/useSessionState.d.ts +2 -0
- package/dist/esm/hooks/useUnload.d.ts +2 -0
- package/dist/esm/hooks/useUpdateEffect.d.ts +3 -0
- package/dist/esm/hooks/useVotes.d.ts +1 -0
- package/dist/esm/index.d.ts +3 -1
- package/dist/esm/index.js +28 -6
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/ConversationListItem.d.ts +1 -0
- package/dist/esm/types/Files.d.ts +7 -0
- package/dist/esm/types/Message.d.ts +2 -2
- package/dist/esm/types/Posts.d.ts +4 -0
- package/dist/esm/types/interfaces.d.ts +9 -0
- package/dist/esm/types/types.d.ts +138 -22
- package/dist/esm/ui/Dropdown.d.ts +18 -2
- package/dist/esm/ui/Icon.d.ts +10 -2
- package/dist/esm/ui/Overlay.d.ts +3 -1
- package/dist/esm/ui/Sheet.d.ts +14 -0
- package/dist/esm/ui/Spinner.d.ts +2 -1
- package/dist/esm/utils/cacheUtils.d.ts +14 -0
- package/dist/esm/utils/fileUtilities.d.ts +10 -1
- package/dist/esm/utils/mentions.d.ts +6 -0
- package/dist/esm/utils/openUrl.d.ts +1 -0
- package/dist/index.d.ts +50 -6
- package/package.json +8 -2
- package/src/client/WeavyClient.ts +35 -1
- package/src/components/Attachment.tsx +20 -13
- package/src/components/Blob.tsx +28 -0
- package/src/components/Comment.tsx +43 -0
- package/src/components/CommentCount.tsx +15 -0
- package/src/components/CommentEdit.tsx +48 -0
- package/src/components/CommentPlaceholder.tsx +34 -0
- package/src/components/CommentTrashed.tsx +45 -0
- package/src/components/CommentView.tsx +142 -0
- package/src/components/Comments.tsx +78 -0
- package/src/components/Conversation.tsx +85 -31
- package/src/components/ConversationList.tsx +12 -41
- package/src/components/ConversationListItem.tsx +125 -74
- package/src/components/Dropzone.tsx +26 -0
- package/src/components/Editor.tsx +700 -0
- package/src/components/Embed.tsx +80 -0
- package/src/components/FileItem.tsx +391 -0
- package/src/components/FileList.tsx +166 -0
- package/src/components/FileVersions.tsx +100 -0
- package/src/components/Files.tsx +294 -0
- package/src/components/Image.tsx +11 -10
- package/src/components/Meeting.tsx +1 -2
- package/src/components/MeetingCard.tsx +1 -1
- package/src/components/Meetings.tsx +13 -5
- package/src/components/Message.tsx +14 -19
- package/src/components/Messages.tsx +38 -64
- package/src/components/NewConversation.tsx +8 -6
- package/src/components/PdfViewer.tsx +2 -2
- package/src/components/Poll.tsx +45 -0
- package/src/components/PollOption.tsx +65 -0
- package/src/components/Post.tsx +45 -0
- package/src/components/PostEdit.tsx +49 -0
- package/src/components/PostList.tsx +95 -0
- package/src/components/PostPlaceholder.tsx +32 -0
- package/src/components/PostTrashed.tsx +35 -0
- package/src/components/PostView.tsx +194 -0
- package/src/components/Posts.tsx +59 -0
- package/src/components/Preview.tsx +16 -23
- package/src/components/PreviewFiles.tsx +336 -0
- package/src/components/Reactions.tsx +142 -38
- package/src/components/SearchUsers.tsx +77 -37
- package/src/components/Typing.tsx +1 -1
- package/src/{components/FileBrowser.tsx → contexts/CloudFilesContext.tsx} +46 -30
- package/src/contexts/PreviewContext.tsx +102 -85
- package/src/contexts/WeavyContext.tsx +10 -6
- package/src/hooks/useApps.ts +23 -0
- package/src/hooks/useCloudFiles.ts +12 -0
- package/src/hooks/useCommentList.ts +30 -0
- package/src/hooks/useEmbeds.ts +126 -0
- package/src/hooks/useEvents.ts +3 -1
- package/src/hooks/useFileList.ts +84 -0
- package/src/hooks/useFileUploader.ts +38 -1
- package/src/hooks/useFileVersions.ts +20 -0
- package/src/hooks/useInfiniteScroll.ts +45 -0
- package/src/hooks/useIsFirstRender.ts +15 -0
- package/src/hooks/useMembers.ts +3 -3
- package/src/hooks/useMutateApps.ts +48 -0
- package/src/hooks/useMutateComment.ts +60 -0
- package/src/hooks/useMutateConversationName.ts +1 -1
- package/src/hooks/useMutateDeleteReaction.ts +17 -4
- package/src/hooks/useMutateEditComment.ts +63 -0
- package/src/hooks/useMutateEditPost.ts +64 -0
- package/src/hooks/useMutateExternalBlobs.ts +5 -9
- package/src/hooks/useMutateFile.ts +311 -0
- package/src/hooks/useMutateFileRename.ts +51 -0
- package/src/hooks/useMutateFileSubscribe.ts +80 -0
- package/src/hooks/useMutateFileTrash.ts +115 -0
- package/src/hooks/useMutateFileVersion.ts +85 -0
- package/src/hooks/useMutateFiles.ts +23 -0
- package/src/hooks/useMutateLeaveConversation.ts +38 -0
- package/src/hooks/useMutateMessage.ts +23 -62
- package/src/hooks/useMutatePost.ts +60 -0
- package/src/hooks/useMutateReaction.ts +21 -6
- package/src/hooks/useMutateRead.ts +8 -2
- package/src/hooks/useMutateRemoveMembers.ts +2 -9
- package/src/hooks/useMutateReplaceReaction.ts +59 -0
- package/src/hooks/useMutateRestoreComment.ts +37 -0
- package/src/hooks/useMutateRestorePost.ts +36 -0
- package/src/hooks/useMutateStarred.ts +35 -0
- package/src/hooks/useMutateSubscribe.ts +36 -0
- package/src/hooks/useMutateTrashComment.ts +37 -0
- package/src/hooks/useMutateTrashPost.ts +36 -0
- package/src/hooks/useMutateTyping.ts +5 -3
- package/src/hooks/useMutateUnsubscribe.ts +36 -0
- package/src/hooks/useMutateVote.ts +59 -0
- package/src/hooks/usePost.ts +20 -0
- package/src/hooks/usePosts.ts +21 -0
- package/src/hooks/usePostsList.ts +31 -0
- package/src/hooks/useReactionList.ts +21 -0
- package/src/hooks/useSearchUsers.ts +2 -2
- package/src/hooks/useSessionState.ts +23 -0
- package/src/hooks/useUnload.ts +19 -0
- package/src/hooks/useUpdateEffect.ts +16 -0
- package/src/hooks/useVotes.ts +21 -0
- package/src/index.ts +5 -1
- package/src/scss/theme/_appbar.scss +8 -4
- package/src/scss/theme/_card.scss +2 -0
- package/src/scss/theme/_comment-editor-cm.scss +5 -1
- package/src/scss/theme/_comments.scss +9 -8
- package/src/scss/theme/_conversations.scss +4 -0
- package/src/scss/theme/_files.scss +2 -81
- package/src/scss/theme/_icons.scss +21 -3
- package/src/scss/theme/_input.scss +13 -7
- package/src/scss/theme/_item.scss +23 -1
- package/src/scss/theme/_message-editor-cm.scss +5 -1
- package/src/scss/theme/_pager.scss +1 -1
- package/src/scss/theme/_post-editor-cm.scss +2 -2
- package/src/scss/theme/_post.scss +3 -10
- package/src/scss/theme/_preview-pdf-viewer.scss +996 -0
- package/src/scss/theme/_preview-pdf.scss +57 -783
- package/src/scss/theme/_sheet.scss +4 -1
- package/src/scss/theme/_spinner.scss +10 -1
- package/src/scss/theme/_tables.scss +2 -0
- package/src/scss/theme/base/_scroll.scss +3 -0
- package/src/scss/weavy-chat.scss +3 -1
- package/src/scss/weavy-files.scss +31 -0
- package/src/scss/weavy-messenger.scss +3 -1
- package/src/scss/weavy-posts.scss +35 -0
- package/src/scss/weavy.scss +2 -0
- package/src/types/ConversationListItem.ts +1 -0
- package/src/types/Files.ts +7 -0
- package/src/types/Message.ts +2 -2
- package/src/types/Posts.ts +4 -0
- package/src/types/interfaces.ts +13 -0
- package/src/types/types.ts +157 -28
- package/src/ui/Button.tsx +6 -5
- package/src/ui/Dropdown.tsx +67 -16
- package/src/ui/Icon.tsx +112 -15
- package/src/ui/Overlay.tsx +6 -2
- package/src/ui/Sheet.tsx +87 -0
- package/src/ui/Spinner.tsx +7 -4
- package/src/utils/cacheUtils.ts +246 -0
- package/src/utils/fileUtilities.ts +208 -24
- package/src/utils/infinite-scroll.js +103 -0
- package/src/utils/mentions.ts +50 -0
- package/src/utils/openUrl.ts +41 -0
- package/src/utils/{scrollToBottom.js → scroll-position.js} +50 -9
- package/src/utils/{scrollbarDetection.js → scrollbar-detection.js} +0 -0
- package/src/utils/utils.js +15 -1
- package/tsconfig.json +1 -1
- package/dist/cjs/components/ConversationForm.d.ts +0 -7
- package/dist/cjs/components/File.d.ts +0 -9
- package/dist/cjs/components/FileBrowser.d.ts +0 -6
- package/dist/cjs/hooks/usePreview.d.ts +0 -4
- package/dist/cjs/hooks/useReactions.d.ts +0 -3
- package/dist/esm/components/ConversationForm.d.ts +0 -7
- package/dist/esm/components/File.d.ts +0 -9
- package/dist/esm/components/FileBrowser.d.ts +0 -6
- package/dist/esm/hooks/usePreview.d.ts +0 -4
- package/dist/esm/hooks/useReactions.d.ts +0 -3
- package/src/components/ConversationForm.tsx +0 -210
- package/src/components/File.tsx +0 -21
- package/src/hooks/usePreview.ts +0 -21
- package/src/hooks/useReactions.ts +0 -51
- package/src/utils/infiniteScroll.js +0 -184
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import React, { useContext, useEffect, useState } from 'react';
|
|
2
|
+
import { triggerDownload } from './FileItem';
|
|
3
|
+
import useFileVersions from '../hooks/useFileVersions';
|
|
4
|
+
import classNames from 'classnames';
|
|
5
|
+
import Icon from '../ui/Icon';
|
|
6
|
+
import { getExtension, getIcon } from '../utils/fileUtilities';
|
|
7
|
+
import Dropdown from '../ui/Dropdown';
|
|
8
|
+
import { useMutateFileVersionDelete, useMutateFileVersionRestore } from '../hooks/useMutateFileVersion';
|
|
9
|
+
import { QueryKey } from 'react-query';
|
|
10
|
+
import { toKebabCase } from '../utils/utils';
|
|
11
|
+
import Spinner from '../ui/Spinner';
|
|
12
|
+
import dayjs from 'dayjs';
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
type Props = {
|
|
16
|
+
filesKey: QueryKey,
|
|
17
|
+
file: FileType,
|
|
18
|
+
onVersionSelect?: (currentVersionFile: FileType) => void
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const FileVersions = ({ filesKey, file, onVersionSelect }: Props) => {
|
|
22
|
+
const fileVersionList = useFileVersions(filesKey, file.id, {});
|
|
23
|
+
const { isLoading, isError, data, error, isFetching } = fileVersionList;
|
|
24
|
+
|
|
25
|
+
const mutateFileVersionRestore = useMutateFileVersionRestore(filesKey);
|
|
26
|
+
const mutateFileVersionDelete = useMutateFileVersionDelete(filesKey);
|
|
27
|
+
|
|
28
|
+
const [activeVersion, setActiveVersion] = useState<FileType>()
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
setActiveVersion(file);
|
|
32
|
+
}, [file, file.version])
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
const handleSelect = (versionFile: FileType) => {
|
|
36
|
+
setActiveVersion(versionFile);
|
|
37
|
+
onVersionSelect && onVersionSelect(versionFile);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const handleSelectWrapper = (versionFile: FileType, e: React.MouseEvent<HTMLTableRowElement>) => {
|
|
41
|
+
if (!e.defaultPrevented) {
|
|
42
|
+
handleSelect(versionFile);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const handleRevert = (versionFile: FileType) => {
|
|
47
|
+
console.log("reverting file version", versionFile.version);
|
|
48
|
+
mutateFileVersionRestore.mutate({versionFile});
|
|
49
|
+
handleSelect(versionFile);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const handleRemove = (versionFile: FileType) => {
|
|
53
|
+
console.log("removing file version", versionFile.version);
|
|
54
|
+
mutateFileVersionDelete.mutate({versionFile});
|
|
55
|
+
if (activeVersion === versionFile) {
|
|
56
|
+
setActiveVersion(file);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (isLoading) {
|
|
61
|
+
return (
|
|
62
|
+
<Spinner.UI spin={true} overlay={true} />
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<div className="wy-list wy-versions" key={"file-versions" + file.id}>
|
|
68
|
+
{data && data.map((versionFile: FileType, index) => {
|
|
69
|
+
let versionIcon = getIcon(versionFile.name || '').icon;
|
|
70
|
+
let num = data.length - index;
|
|
71
|
+
let ext = getExtension(versionFile.name);
|
|
72
|
+
const modifiedAt = dayjs.utc(versionFile.modified_at || versionFile.created_at).tz(dayjs.tz.guess());
|
|
73
|
+
|
|
74
|
+
return <div key={'file-version' + versionFile.version} className={classNames("wy-item wy-item-hover wy-item-lg", {"wy-active": versionFile.version == activeVersion?.version})} onClick={handleSelectWrapper.bind(FileVersions, versionFile)}>
|
|
75
|
+
{
|
|
76
|
+
file.status === "error" ? <Icon.UI name="alert-octagon" color="error" size={48/16/1.5} /> :
|
|
77
|
+
file.status === "conflict" ? <Icon.UI name="alert" color="yellow" size={48/16/1.5} /> :
|
|
78
|
+
file.status === "pending" ? <Spinner.UI spin={!versionFile.progress} progress={versionFile.progress} size={48} /> :
|
|
79
|
+
<Icon.UI name={versionIcon} size={48/16/1.5} className={classNames("wy-kind-" + toKebabCase(versionFile.kind), "wy-ext-" + ext.substring(1))} />
|
|
80
|
+
}
|
|
81
|
+
<div className="wy-item-body">
|
|
82
|
+
<div className="wy-item-title">{num}. {versionFile.name}</div>
|
|
83
|
+
<div className="wy-item-text"><time dateTime={versionFile.modified_at || versionFile.created_at} title={modifiedAt.format('LLLL')}>{modifiedAt.fromNow()}</time> · {versionFile.modified_by?.display_name}</div>
|
|
84
|
+
</div>
|
|
85
|
+
|
|
86
|
+
<Dropdown.UI directionX='left'>
|
|
87
|
+
<Dropdown.Item onClick={() => triggerDownload(versionFile)}><Icon.UI name="download" /> Download</Dropdown.Item>
|
|
88
|
+
{versionFile.version !== file.version && <>
|
|
89
|
+
<Dropdown.Divider/>
|
|
90
|
+
<Dropdown.Item onClick={() => handleRevert(versionFile)}><Icon.UI name='restore' /> Revert</Dropdown.Item>
|
|
91
|
+
<Dropdown.Item onClick={() => handleRemove(versionFile)}><Icon.UI name='delete' /> Remove</Dropdown.Item>
|
|
92
|
+
</>}
|
|
93
|
+
</Dropdown.UI>
|
|
94
|
+
</div>
|
|
95
|
+
})}
|
|
96
|
+
</div>
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export default FileVersions;
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import React, { useState, useContext, useEffect, useCallback } from 'react';
|
|
2
|
+
import { WeavyContext } from '../contexts/WeavyContext';
|
|
3
|
+
import { FilesProps } from '../types/Files';
|
|
4
|
+
import useFiles from '../hooks/useApps';
|
|
5
|
+
import classNames from 'classnames';
|
|
6
|
+
import FileList from './FileList';
|
|
7
|
+
import Dropdown from '../ui/Dropdown';
|
|
8
|
+
import Icon from '../ui/Icon';
|
|
9
|
+
import Button from '../ui/Button';
|
|
10
|
+
import Spinner from '../ui/Spinner';
|
|
11
|
+
import Sheet from '../ui/Sheet';
|
|
12
|
+
import FileItem from './FileItem';
|
|
13
|
+
import useCloudFiles from '../hooks/useCloudFiles';
|
|
14
|
+
import { useMutateFileUpload, useMutateFileCreate, useMutatingFileUploads, useRemoveMutatingFileUpload, CreateFileProps, FileMutation } from '../hooks/useMutateFile';
|
|
15
|
+
import { useMutateFilesCreate } from '../hooks/useMutateFiles';
|
|
16
|
+
import { useSessionState } from '../hooks/useSessionState';
|
|
17
|
+
import { useMutateAppsSubscribe } from '../hooks/useMutateApps';
|
|
18
|
+
import openUrl from '../utils/openUrl';
|
|
19
|
+
import { useDropzone } from 'react-dropzone';
|
|
20
|
+
|
|
21
|
+
const Files = ({
|
|
22
|
+
uid,
|
|
23
|
+
className,
|
|
24
|
+
view: initView = "list",
|
|
25
|
+
order: initOrder = { by: "name", descending: false },
|
|
26
|
+
trashed: initTrashed = false
|
|
27
|
+
}: FilesProps) => {
|
|
28
|
+
|
|
29
|
+
const { client } = useContext(WeavyContext);
|
|
30
|
+
const [appId, setAppId] = useState<number>();
|
|
31
|
+
const [selectedFiles, setSelectedFiles] = useState<string>("");
|
|
32
|
+
|
|
33
|
+
if (!client) {
|
|
34
|
+
throw new Error('Weavy Files component must be used within an WeavyProvider');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// init app
|
|
38
|
+
const { isLoading, data } = useFiles(uid, {});
|
|
39
|
+
const mutateFilesSubscribe = useMutateAppsSubscribe(["apps", uid]);
|
|
40
|
+
|
|
41
|
+
const [showUploadDetails, setShowUploadDetails] = useState<boolean>(false);
|
|
42
|
+
|
|
43
|
+
const createFile = useMutateFilesCreate(appId!);
|
|
44
|
+
const uploadFileMutation = useMutateFileUpload(['files', appId!], createFile);
|
|
45
|
+
const createFileMutation = useMutateFileCreate(['files', appId!], createFile);
|
|
46
|
+
const { mutations, status, progress } = useMutatingFileUploads(['files', appId!]);
|
|
47
|
+
const removeMutatingFileUpload = useRemoveMutatingFileUpload(['files', appId!]);
|
|
48
|
+
|
|
49
|
+
let fileInput: HTMLInputElement | null;
|
|
50
|
+
|
|
51
|
+
const [view, setView] = useSessionState<FileView>(`files-view-${uid}`, initView);
|
|
52
|
+
const [order, setOrder] = useSessionState<FileOrder>(`files-order-${uid}`, initOrder);
|
|
53
|
+
const [showTrashed, setShowTrashed] = useSessionState<boolean>(`files-trashed-${uid}`, initTrashed);
|
|
54
|
+
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (data) {
|
|
57
|
+
setAppId(data.id);
|
|
58
|
+
} else {
|
|
59
|
+
setAppId(undefined);
|
|
60
|
+
}
|
|
61
|
+
}, [data]);
|
|
62
|
+
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
if (status === "error" || status === "conflict") {
|
|
65
|
+
setShowUploadDetails(true);
|
|
66
|
+
}
|
|
67
|
+
if (mutations.length === 0) {
|
|
68
|
+
setShowUploadDetails(false)
|
|
69
|
+
}
|
|
70
|
+
}, [status, mutations.length])
|
|
71
|
+
|
|
72
|
+
// add external file
|
|
73
|
+
const handleExternalFileAdded = (addedBlobs: BlobType[]) => {
|
|
74
|
+
addedBlobs.forEach((blob) => handleCreateFile(blob));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const { openCloudFiles } = useCloudFiles(handleExternalFileAdded);
|
|
78
|
+
|
|
79
|
+
const handleSubscribe = (subscribe: boolean) => {
|
|
80
|
+
if (appId) {
|
|
81
|
+
mutateFilesSubscribe.mutateAsync({appId, subscribe})
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// add uploaded files
|
|
86
|
+
const handleCreateFile = async (blob: BlobType, file?: FileType, replace?: boolean) => {
|
|
87
|
+
let fileProps: CreateFileProps = { blob, file, replace };
|
|
88
|
+
await createFileMutation.mutateAsync(fileProps, {
|
|
89
|
+
onSuccess: (data: FileType) => {
|
|
90
|
+
//console.log("All cloud files added")
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// upload files
|
|
96
|
+
const handleFileUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
97
|
+
if (e.target.files) {
|
|
98
|
+
for (var i = 0; i < e.target.files.length; i++) {
|
|
99
|
+
let file = e.target.files[i];
|
|
100
|
+
let fileProps = { file: file }
|
|
101
|
+
uploadFileMutation.mutateAsync(fileProps, {
|
|
102
|
+
onSuccess: (data: BlobType) => {
|
|
103
|
+
//console.log("All files uploaded")
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
setSelectedFiles("")
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// open file dialog
|
|
112
|
+
const openFileInput = (e: any) => {
|
|
113
|
+
//console.log("click")
|
|
114
|
+
fileInput?.click();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// remove file attachment
|
|
118
|
+
const handleRemoveUpload = (mutation: FileMutation) => {
|
|
119
|
+
removeMutatingFileUpload(mutation);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const handleOverwriteUpload = (mutation: FileMutation) => {
|
|
123
|
+
removeMutatingFileUpload(mutation);
|
|
124
|
+
|
|
125
|
+
let fileBlob = mutation.state.context?.blob;
|
|
126
|
+
if (fileBlob) {
|
|
127
|
+
handleCreateFile(fileBlob, mutation.state.context?.file, true);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Pasted file(s)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
const handleDownloadArchive = () => {
|
|
134
|
+
if (appId && data && data.archive_url) {
|
|
135
|
+
//const archiveUrl = new URL(`/api/apps/${appId}/files.zip`, client.url).toString();
|
|
136
|
+
openUrl(data.archive_url, "_top", `${uid}.zip`, true);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const onDrop = useCallback((acceptedFiles: File[]) => {
|
|
141
|
+
// this callback will be called after files get dropped, we will get the acceptedFiles. If you want, you can even access the rejected files too
|
|
142
|
+
if (acceptedFiles.length > 0) {
|
|
143
|
+
for (var i = 0; i < acceptedFiles.length; i++) {
|
|
144
|
+
let file = acceptedFiles[i];
|
|
145
|
+
let fileProps = { file: file }
|
|
146
|
+
uploadFileMutation.mutateAsync(fileProps, {});
|
|
147
|
+
}
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
}, []);
|
|
152
|
+
|
|
153
|
+
const { getRootProps, rootRef: pasteRef, isDragActive } = useDropzone({
|
|
154
|
+
onDrop,
|
|
155
|
+
noClick: true,
|
|
156
|
+
noKeyboard: true,
|
|
157
|
+
disabled: !appId
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Pasted file(s)
|
|
161
|
+
const handlePaste = (evt: any) => {
|
|
162
|
+
console.debug("File(s) pasted");
|
|
163
|
+
let files: File[] = [];
|
|
164
|
+
const items = (evt.clipboardData || evt.originalEvent.clipboardData).items;
|
|
165
|
+
for (let index in items) {
|
|
166
|
+
const item = items[index];
|
|
167
|
+
if (item.kind === 'file') {
|
|
168
|
+
files = [...files, item.getAsFile()];
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (files.length) {
|
|
172
|
+
for (var i = 0; i < files.length; i++) {
|
|
173
|
+
let file = files[i];
|
|
174
|
+
let fileProps = { file: file }
|
|
175
|
+
uploadFileMutation.mutateAsync(fileProps, {
|
|
176
|
+
onSuccess: (data: BlobType) => {
|
|
177
|
+
//console.log("All files uploaded")
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const delegateHandlePaste = (evt: any) => {
|
|
185
|
+
if (pasteRef.current) {
|
|
186
|
+
var targ = evt.target;
|
|
187
|
+
do {
|
|
188
|
+
if (pasteRef.current === targ) {
|
|
189
|
+
handlePaste(evt);
|
|
190
|
+
}
|
|
191
|
+
} while ((targ = targ.parentNode) && targ !== evt.currentTarget);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
useEffect(() => {
|
|
196
|
+
if (appId) {
|
|
197
|
+
document.addEventListener("paste", delegateHandlePaste);
|
|
198
|
+
return () => {
|
|
199
|
+
document.removeEventListener("paste", delegateHandlePaste);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}, [appId])
|
|
203
|
+
|
|
204
|
+
return (!isLoading && !data &&
|
|
205
|
+
<div>No files app with the contextual id <strong>{uid}</strong> was found.</div>
|
|
206
|
+
|| appId &&
|
|
207
|
+
|
|
208
|
+
<div className={classNames("wy-files", className, { "wy-files-dragging": isDragActive })} {...getRootProps()}>
|
|
209
|
+
<header className="wy-appbars">
|
|
210
|
+
<nav className="wy-toolbar">
|
|
211
|
+
|
|
212
|
+
<div className="wy-toolbar-buttons">
|
|
213
|
+
<Dropdown.UI title="Add files" disabled={!appId} buttonContent={
|
|
214
|
+
<><span>Add files</span><Icon.UI name="plus"/></>
|
|
215
|
+
}>
|
|
216
|
+
<>
|
|
217
|
+
<Dropdown.Item onClick={openFileInput}><Icon.UI name="attachment"/> From device</Dropdown.Item>
|
|
218
|
+
<input type="file" value={selectedFiles} ref={input => fileInput = input} onChange={handleFileUpload} multiple hidden tabIndex={-1} />
|
|
219
|
+
</>
|
|
220
|
+
<Dropdown.Item onClick={openCloudFiles}><Icon.UI name="cloud"/> From cloud</Dropdown.Item>
|
|
221
|
+
</Dropdown.UI>
|
|
222
|
+
</div>
|
|
223
|
+
|
|
224
|
+
<div className="wy-toolbar-buttons wy-toolbar-buttons-last">
|
|
225
|
+
{mutations.length > 0 && <Button.UI onClick={() => setShowUploadDetails(!showUploadDetails)}>
|
|
226
|
+
{
|
|
227
|
+
status === "conflict" ? <Icon.UI name="alert" color="yellow" title="File conflict" /> :
|
|
228
|
+
status === "error" ? <Icon.UI name="alert-octagon" color="error" title="Upload error" /> :
|
|
229
|
+
status === "pending" ? <Spinner.UI spin={progress === undefined} progress={progress} />:
|
|
230
|
+
<Icon.UI name="check" title='All uploads finished' />
|
|
231
|
+
}
|
|
232
|
+
</Button.UI>}
|
|
233
|
+
<Sheet.UI title={"Uploads"} isOpen={showUploadDetails} onClose={() => setShowUploadDetails(false)}>
|
|
234
|
+
{mutations.map((mutation) => {
|
|
235
|
+
let file = mutation.state.context?.file;
|
|
236
|
+
if (file) {
|
|
237
|
+
return (
|
|
238
|
+
<FileItem.Item key={"file-mutation" + mutation.mutationId} file={file} statusText={file.status === "conflict" ? "Replace existing file?" : ''} title={file.name + (file.statusText ? `: ${file.statusText}` : '')}>
|
|
239
|
+
<div className='wy-item-actions'>
|
|
240
|
+
{file.status === "conflict" && <>
|
|
241
|
+
<Button.UI onClick={handleOverwriteUpload.bind(Files, mutation) } title="Replace"><Icon.UI name='check' /></Button.UI>
|
|
242
|
+
</>}
|
|
243
|
+
<Button.UI onClick={handleRemoveUpload.bind(Files, mutation)} title="Discard"><Icon.UI name='close' /></Button.UI>
|
|
244
|
+
</div>
|
|
245
|
+
</FileItem.Item>
|
|
246
|
+
)
|
|
247
|
+
}
|
|
248
|
+
return undefined;
|
|
249
|
+
})}
|
|
250
|
+
</Sheet.UI>
|
|
251
|
+
|
|
252
|
+
<Dropdown.UI icon="sort" title="Sort items by" directionX='left'>
|
|
253
|
+
<Dropdown.Item className={classNames("wy-option", { "wy-selected": order.by === "name" })} onClick={(e: any) => setOrder({...order, by: "name" })}><Icon.UI name="check"/> Name</Dropdown.Item>
|
|
254
|
+
<Dropdown.Item className={classNames("wy-option", { "wy-selected": order.by === "modified_at" })} onClick={(e: any) => setOrder({...order, by: "modified_at" })}><Icon.UI name="check"/> Modified</Dropdown.Item>
|
|
255
|
+
<Dropdown.Item className={classNames("wy-option", { "wy-selected": order.by === "size" })} onClick={(e: any) => setOrder({...order, by: "size" })}><Icon.UI name="check"/> Size</Dropdown.Item>
|
|
256
|
+
<Dropdown.Divider/>
|
|
257
|
+
<Dropdown.Item className={classNames("wy-option", { "wy-selected": !order.descending })} onClick={(e: any) => setOrder({...order, descending: false })}><Icon.UI name="check"/> Ascending</Dropdown.Item>
|
|
258
|
+
<Dropdown.Item className={classNames("wy-option", { "wy-selected": order.descending })} onClick={(e: any) => setOrder({...order, descending: true })}><Icon.UI name="check"/> Descending</Dropdown.Item>
|
|
259
|
+
</Dropdown.UI>
|
|
260
|
+
|
|
261
|
+
<Dropdown.UI icon={view === "grid" ? "view-module-outline" :"view-list-outline"} title="View options" directionX='left'>
|
|
262
|
+
<Dropdown.Item className={classNames("wy-option", { "wy-selected": view === "list" })} onClick={(e: any) => setView("list")}><Icon.UI name="check"/> List view</Dropdown.Item>
|
|
263
|
+
<Dropdown.Item className={classNames("wy-option", { "wy-selected": view === "grid" })} onClick={(e: any) => setView("grid")}><Icon.UI name="check"/> Grid view</Dropdown.Item>
|
|
264
|
+
<Dropdown.Divider/>
|
|
265
|
+
<Dropdown.Item className={classNames("wy-option", { "wy-selected": !showTrashed })} onClick={(e: any) => setShowTrashed(false)}><Icon.UI name="check" /> Hide trashed</Dropdown.Item>
|
|
266
|
+
<Dropdown.Item className={classNames("wy-option", { "wy-selected": showTrashed })} onClick={(e: any) => setShowTrashed(true)}><Icon.UI name="check" /> Show trashed</Dropdown.Item>
|
|
267
|
+
</Dropdown.UI>
|
|
268
|
+
|
|
269
|
+
<Dropdown.UI directionX='left' disabled={isLoading || !data}>
|
|
270
|
+
{data && <>
|
|
271
|
+
{data.is_subscribed ?
|
|
272
|
+
<Dropdown.Item onClick={() => handleSubscribe(false)}><Icon.UI name="bell-off" size={1} /> Unsubscribe</Dropdown.Item>
|
|
273
|
+
:
|
|
274
|
+
<Dropdown.Item onClick={() => handleSubscribe(true)}><Icon.UI name="bell" size={1} /> Subscribe</Dropdown.Item>
|
|
275
|
+
}
|
|
276
|
+
{data.archive_url &&
|
|
277
|
+
<Dropdown.Item onClick={() => openUrl(data.archive_url, "_top", `${uid}.zip`, true)}><Icon.UI name="download"/> Download files</Dropdown.Item>
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
</>}
|
|
281
|
+
</Dropdown.UI>
|
|
282
|
+
|
|
283
|
+
</div>
|
|
284
|
+
|
|
285
|
+
</nav>
|
|
286
|
+
</header>
|
|
287
|
+
|
|
288
|
+
<FileList appId={appId} view={view} order={order} trashed={showTrashed} onSorting={(sortOrder) => setOrder(sortOrder)} onHandleError={(errorFile) => setShowUploadDetails(true)} />
|
|
289
|
+
</div>
|
|
290
|
+
|
|
291
|
+
)
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export default Files;
|
package/src/components/Image.tsx
CHANGED
|
@@ -2,9 +2,9 @@ import React, { useCallback } from "react";
|
|
|
2
2
|
|
|
3
3
|
type ImageProps = {
|
|
4
4
|
src: string,
|
|
5
|
-
previewSrc
|
|
6
|
-
width
|
|
7
|
-
height
|
|
5
|
+
previewSrc?: string,
|
|
6
|
+
width?: number
|
|
7
|
+
height?: number,
|
|
8
8
|
more?: number,
|
|
9
9
|
onClick: (e: any) => void
|
|
10
10
|
}
|
|
@@ -13,18 +13,18 @@ export function checkImageLoad(img: HTMLImageElement) {
|
|
|
13
13
|
var isLoaded = img.complete && img.naturalHeight !== 0;
|
|
14
14
|
if (isLoaded) {
|
|
15
15
|
if (!img.classList.contains("wy-loading")) {
|
|
16
|
-
console.debug("image is instantly loaded")
|
|
16
|
+
//console.debug("image is instantly loaded")
|
|
17
17
|
img.classList.add("wy-loading", "wy-loaded");
|
|
18
18
|
} else {
|
|
19
19
|
img.decode().then(() => {
|
|
20
|
-
console.debug("image is loaded after delay")
|
|
20
|
+
//console.debug("image is loaded after delay")
|
|
21
21
|
img.classList.add("wy-loaded");
|
|
22
22
|
})
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
} else {
|
|
27
|
-
console.debug("image is loading")
|
|
27
|
+
//console.debug("image is loading")
|
|
28
28
|
img.classList.add("wy-loading");
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -32,19 +32,20 @@ export function checkImageLoad(img: HTMLImageElement) {
|
|
|
32
32
|
export function imageLoaded(event: any) {
|
|
33
33
|
var img = event.target;
|
|
34
34
|
if (img.tagName === 'IMG' && img.classList.contains("wy-loading") && !img.classList.contains("wy-loaded")) {
|
|
35
|
-
console.debug("load event");
|
|
36
|
-
|
|
35
|
+
//console.debug("load event");
|
|
36
|
+
img.classList.add("wy-loaded")
|
|
37
|
+
}
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
export const Image = ({src, previewSrc, width, height, more, onClick}: ImageProps) => {
|
|
40
|
-
let ratio = width / height;
|
|
41
|
+
let ratio = width! / height! || 1;
|
|
41
42
|
let baseSize = 64;
|
|
42
43
|
let maxScale = 2;
|
|
43
44
|
let flexRatio = ratio.toPrecision(5);
|
|
44
45
|
let flexBasis = (ratio * baseSize).toPrecision(5) + "px";
|
|
45
46
|
let padding = (100 / ratio).toPrecision(5) + "%"
|
|
46
47
|
let intrinsicWidth = width + "px"
|
|
47
|
-
let maxWidth = (maxScale * width) + "px";
|
|
48
|
+
let maxWidth = width! > 0 ? (maxScale * width!) + "px" : "none";
|
|
48
49
|
|
|
49
50
|
const imageRef = useCallback((element: HTMLImageElement) => {
|
|
50
51
|
if (element) {
|
|
@@ -12,8 +12,7 @@ const Meeting = ({ id, title, className }: Props) => {
|
|
|
12
12
|
<>
|
|
13
13
|
{/* <div className={className}>{title}</div> */}
|
|
14
14
|
<Icon.UI name="zoom" />
|
|
15
|
-
<div className={className}>Zoom meeting</div>
|
|
16
|
-
<input type="hidden" value={id} name="meeting"/>
|
|
15
|
+
<div className={className}>Zoom meeting</div>
|
|
17
16
|
</>
|
|
18
17
|
)
|
|
19
18
|
}
|
|
@@ -4,12 +4,14 @@ import { WeavyContext } from "../contexts/WeavyContext";
|
|
|
4
4
|
import useMutateMeeting from "../hooks/useMutateMeeting";
|
|
5
5
|
import Button from '../ui/Button';
|
|
6
6
|
import Icon from '../ui/Icon';
|
|
7
|
+
import Dropdown from '../ui/Dropdown';
|
|
7
8
|
|
|
8
9
|
type Props = {
|
|
9
|
-
onMeetingAdded: Function
|
|
10
|
+
onMeetingAdded: Function,
|
|
11
|
+
dropdown?: boolean
|
|
10
12
|
}
|
|
11
13
|
|
|
12
|
-
const Meetings = ({ onMeetingAdded }: Props) => {
|
|
14
|
+
const Meetings = ({ onMeetingAdded, dropdown = false }: Props) => {
|
|
13
15
|
|
|
14
16
|
const { options } = useContext(WeavyContext);
|
|
15
17
|
const { user } = useContext(UserContext);
|
|
@@ -28,7 +30,7 @@ const Meetings = ({ onMeetingAdded }: Props) => {
|
|
|
28
30
|
|
|
29
31
|
switch (e.data.name) {
|
|
30
32
|
case "zoom-signed-in":
|
|
31
|
-
var meeting = await addMeeting.mutateAsync({ provider: "zoom" });
|
|
33
|
+
var meeting = await addMeeting.mutateAsync({ provider: "zoom" });
|
|
32
34
|
onMeetingAdded(meeting)
|
|
33
35
|
break;
|
|
34
36
|
|
|
@@ -47,8 +49,14 @@ const Meetings = ({ onMeetingAdded }: Props) => {
|
|
|
47
49
|
|
|
48
50
|
return (
|
|
49
51
|
<>
|
|
50
|
-
{options?.zoomAuthenticationUrl &&
|
|
51
|
-
<
|
|
52
|
+
{options?.zoomAuthenticationUrl && dropdown &&
|
|
53
|
+
<Dropdown.Item onClick={handleZoom}>
|
|
54
|
+
<Icon.UI name="zoom" /> Zoom meeting
|
|
55
|
+
</Dropdown.Item>
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
{options?.zoomAuthenticationUrl && !dropdown &&
|
|
59
|
+
<Button.UI onClick={handleZoom} title="Zoom meeting"><Icon.UI name="zoom" /></Button.UI>
|
|
52
60
|
}
|
|
53
61
|
</>
|
|
54
62
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { FC } from 'react';
|
|
1
|
+
import React, { FC, useContext } from 'react';
|
|
2
2
|
import dayjs from 'dayjs';
|
|
3
3
|
import { MessageProps } from "../types/Message"
|
|
4
4
|
import Attachment from './Attachment';
|
|
@@ -7,21 +7,22 @@ import { Image, ImageGrid } from "./Image"
|
|
|
7
7
|
import SeenBy from './SeenBy';
|
|
8
8
|
import Avatar from "./Avatar";
|
|
9
9
|
import MeetingCard from './MeetingCard';
|
|
10
|
-
import
|
|
10
|
+
import { PreviewContext } from "../contexts/PreviewContext";
|
|
11
11
|
import classNames from 'classnames';
|
|
12
12
|
|
|
13
13
|
const Message: FC<MessageProps> = ({ id, html, temp, me, avatar, name, created_at, created_by, attachments, meeting, parentId, reactions, seenBy, chatRoom }) => {
|
|
14
14
|
|
|
15
|
-
const {
|
|
15
|
+
const { openPreview, setPreviewFiles } = useContext(PreviewContext);
|
|
16
16
|
|
|
17
|
-
let images = attachments?.filter((a:
|
|
18
|
-
let files = attachments?.filter((a:
|
|
17
|
+
let images = attachments?.filter((a: FileType) => a.kind === "image" && a.thumbnail_url);
|
|
18
|
+
let files = attachments?.filter((a: FileType) => a.kind !== "image" || !a.thumbnail_url);
|
|
19
19
|
|
|
20
20
|
const date = dayjs.utc(created_at).tz(dayjs.tz.guess());
|
|
21
21
|
|
|
22
22
|
const handlePreviewClick = (e: React.MouseEvent<HTMLInputElement>, attachmentId: number) => {
|
|
23
23
|
e.preventDefault();
|
|
24
|
-
|
|
24
|
+
setPreviewFiles(attachments);
|
|
25
|
+
openPreview(attachmentId);
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
return (
|
|
@@ -47,8 +48,9 @@ const Message: FC<MessageProps> = ({ id, html, temp, me, avatar, name, created_a
|
|
|
47
48
|
{!temp &&
|
|
48
49
|
<>
|
|
49
50
|
{images && !!images.length && <ImageGrid>
|
|
50
|
-
{images.map((a:
|
|
51
|
-
|
|
51
|
+
{images.map((a: FileType) =>
|
|
52
|
+
a.download_url &&
|
|
53
|
+
<Image onClick={(e) => handlePreviewClick(e, a.id)} key={a.id} src={a.download_url} previewSrc={a.preview_url} width={a.width} height={a.height} /> || null
|
|
52
54
|
)}
|
|
53
55
|
</ImageGrid>}
|
|
54
56
|
|
|
@@ -58,26 +60,19 @@ const Message: FC<MessageProps> = ({ id, html, temp, me, avatar, name, created_a
|
|
|
58
60
|
<MeetingCard meeting={meeting} />
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
{files && !!files.length && <div className="wy-list
|
|
62
|
-
{files.map((a:
|
|
63
|
+
{files && !!files.length && <div className="wy-list wy-list-bordered">
|
|
64
|
+
{files.map((a: FileType) =>
|
|
63
65
|
<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} />
|
|
64
66
|
)}
|
|
65
67
|
</div>}
|
|
66
68
|
<div className="wy-reactions-line">
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
</div>
|
|
70
|
-
{!temp && <ReactionsMenu id={id} reactions={reactions} />}
|
|
69
|
+
<ReactionsList id={id} type="messages" parentId={parentId} reactions={reactions} />
|
|
70
|
+
{!temp && <ReactionsMenu parentId={parentId}id={id} type="messages" reactions={reactions} placement={ me ? "top-end" : "top-start"} />}
|
|
71
71
|
</div>
|
|
72
72
|
</>
|
|
73
73
|
}
|
|
74
74
|
</div>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
75
|
</div>
|
|
79
|
-
|
|
80
|
-
|
|
81
76
|
</div>
|
|
82
77
|
<SeenBy id={id} parentId={parentId} seenBy={seenBy} createdAt={created_at} />
|
|
83
78
|
</>
|