@amityco/react-native-social-uikit 4.1.1-b58e7e9.0 → 4.1.1-bcb7944e.0
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/README.md +7 -0
- package/lib/commonjs/core/assets/icons/post.js +1 -1
- package/lib/commonjs/core/assets/icons/post.js.map +1 -1
- package/lib/commonjs/core/assets/icons/story.js +1 -1
- package/lib/commonjs/core/assets/icons/story.js.map +1 -1
- package/lib/commonjs/core/assets/icons/xml.js +69 -1
- package/lib/commonjs/core/assets/icons/xml.js.map +1 -1
- package/lib/commonjs/core/hooks/usePostByIds.js +38 -0
- package/lib/commonjs/core/hooks/usePostByIds.js.map +1 -0
- package/lib/commonjs/core/legacy/file.js +145 -62
- package/lib/commonjs/core/legacy/file.js.map +1 -1
- package/lib/commonjs/core/stores/slices/feedSlice.js +3 -0
- package/lib/commonjs/core/stores/slices/feedSlice.js.map +1 -1
- package/lib/commonjs/core/stores/slices/globalfeedSlice.js +5 -0
- package/lib/commonjs/core/stores/slices/globalfeedSlice.js.map +1 -1
- package/lib/commonjs/core/stores/slices/localVideoThumbnailSlice.js +46 -0
- package/lib/commonjs/core/stores/slices/localVideoThumbnailSlice.js.map +1 -0
- package/lib/commonjs/core/stores/slices/uiSlice.js +5 -1
- package/lib/commonjs/core/stores/slices/uiSlice.js.map +1 -1
- package/lib/commonjs/core/stores/store/index.js +3 -1
- package/lib/commonjs/core/stores/store/index.js.map +1 -1
- package/lib/commonjs/social/components/LoadingImage/index.js +76 -14
- package/lib/commonjs/social/components/LoadingImage/index.js.map +1 -1
- package/lib/commonjs/social/components/LoadingImage/styles.js +12 -3
- package/lib/commonjs/social/components/LoadingImage/styles.js.map +1 -1
- package/lib/commonjs/social/components/LoadingVideo/index.js +98 -18
- package/lib/commonjs/social/components/LoadingVideo/index.js.map +1 -1
- package/lib/commonjs/social/components/LoadingVideo/styles.js +18 -5
- package/lib/commonjs/social/components/LoadingVideo/styles.js.map +1 -1
- package/lib/commonjs/social/components/MediaViewer/MediaViewer.js +266 -0
- package/lib/commonjs/social/components/MediaViewer/MediaViewer.js.map +1 -0
- package/lib/commonjs/social/components/MediaViewer/index.js +13 -0
- package/lib/commonjs/social/components/MediaViewer/index.js.map +1 -0
- package/lib/commonjs/social/components/MediaViewer/styles.js +126 -0
- package/lib/commonjs/social/components/MediaViewer/styles.js.map +1 -0
- package/lib/commonjs/social/components/PostContent/index.js +80 -146
- package/lib/commonjs/social/components/PostContent/index.js.map +1 -1
- package/lib/commonjs/social/components/SelectedMediaComponent/SelectedMediaComponent.js +239 -0
- package/lib/commonjs/social/components/SelectedMediaComponent/SelectedMediaComponent.js.map +1 -0
- package/lib/commonjs/social/components/SelectedMediaComponent/index.js +13 -0
- package/lib/commonjs/social/components/SelectedMediaComponent/index.js.map +1 -0
- package/lib/commonjs/social/components/SelectedMediaComponent/styles.js +43 -0
- package/lib/commonjs/social/components/SelectedMediaComponent/styles.js.map +1 -0
- package/lib/commonjs/social/components/legacy/LoadingVideo/index.js +17 -6
- package/lib/commonjs/social/components/legacy/LoadingVideo/index.js.map +1 -1
- package/lib/commonjs/social/constants/index.js +11 -0
- package/lib/commonjs/social/constants/index.js.map +1 -0
- package/lib/commonjs/social/elements/PostMediaElement/PostMediaElement.js +342 -0
- package/lib/commonjs/social/elements/PostMediaElement/PostMediaElement.js.map +1 -0
- package/lib/commonjs/social/elements/PostMediaElement/index.js +13 -0
- package/lib/commonjs/social/elements/PostMediaElement/index.js.map +1 -0
- package/lib/commonjs/social/elements/PostMediaElement/styles.js +124 -0
- package/lib/commonjs/social/elements/PostMediaElement/styles.js.map +1 -0
- package/lib/commonjs/social/features/community/PendingRequest/components/PendingPostList/PendingPostList.js +11 -5
- package/lib/commonjs/social/features/community/PendingRequest/components/PendingPostList/PendingPostList.js.map +1 -1
- package/lib/commonjs/social/features/feed/components/NewsFeed/NewsFeed.js +14 -0
- package/lib/commonjs/social/features/feed/components/NewsFeed/NewsFeed.js.map +1 -1
- package/lib/commonjs/social/features/post/Composer/PostComposer.js +273 -154
- package/lib/commonjs/social/features/post/Composer/PostComposer.js.map +1 -1
- package/lib/commonjs/social/features/post/components/DetailedMediaAttachment/DetailedMediaAttachment.js +17 -7
- package/lib/commonjs/social/features/post/components/DetailedMediaAttachment/DetailedMediaAttachment.js.map +1 -1
- package/lib/commonjs/social/features/post/components/MediaAttachment/MediaAttachment.js +17 -7
- package/lib/commonjs/social/features/post/components/MediaAttachment/MediaAttachment.js.map +1 -1
- package/lib/commonjs/social/hooks/index.js +11 -0
- package/lib/commonjs/social/hooks/index.js.map +1 -1
- package/lib/commonjs/social/hooks/useCommunities.js +5 -3
- package/lib/commonjs/social/hooks/useCommunities.js.map +1 -1
- package/lib/commonjs/social/hooks/useCommunityPermission.js +43 -0
- package/lib/commonjs/social/hooks/useCommunityPermission.js.map +1 -0
- package/lib/commonjs/social/hooks/useCustomRankingGlobalFeed.js +10 -1
- package/lib/commonjs/social/hooks/useCustomRankingGlobalFeed.js.map +1 -1
- package/lib/commonjs/social/hooks/useFile.js +11 -0
- package/lib/commonjs/social/hooks/useFile.js.map +1 -1
- package/lib/commonjs/social/screens/CommunityProfile/components/Header/Header.js +18 -7
- package/lib/commonjs/social/screens/CommunityProfile/components/Header/Header.js.map +1 -1
- package/lib/commonjs/social/utils/getFrameRatio.js +52 -0
- package/lib/commonjs/social/utils/getFrameRatio.js.map +1 -0
- package/lib/commonjs/social/utils/getIndicatorConfig.js +59 -0
- package/lib/commonjs/social/utils/getIndicatorConfig.js.map +1 -0
- package/lib/commonjs/social/utils/mediaAttachments.js +150 -0
- package/lib/commonjs/social/utils/mediaAttachments.js.map +1 -0
- package/lib/commonjs/social/utils/postChildren.js +72 -0
- package/lib/commonjs/social/utils/postChildren.js.map +1 -0
- package/lib/module/core/assets/icons/post.js +1 -1
- package/lib/module/core/assets/icons/post.js.map +1 -1
- package/lib/module/core/assets/icons/story.js +1 -1
- package/lib/module/core/assets/icons/story.js.map +1 -1
- package/lib/module/core/assets/icons/xml.js +61 -0
- package/lib/module/core/assets/icons/xml.js.map +1 -1
- package/lib/module/core/hooks/usePostByIds.js +32 -0
- package/lib/module/core/hooks/usePostByIds.js.map +1 -0
- package/lib/module/core/legacy/file.js +145 -62
- package/lib/module/core/legacy/file.js.map +1 -1
- package/lib/module/core/stores/slices/feedSlice.js +3 -0
- package/lib/module/core/stores/slices/feedSlice.js.map +1 -1
- package/lib/module/core/stores/slices/globalfeedSlice.js +5 -0
- package/lib/module/core/stores/slices/globalfeedSlice.js.map +1 -1
- package/lib/module/core/stores/slices/localVideoThumbnailSlice.js +41 -0
- package/lib/module/core/stores/slices/localVideoThumbnailSlice.js.map +1 -0
- package/lib/module/core/stores/slices/uiSlice.js +5 -1
- package/lib/module/core/stores/slices/uiSlice.js.map +1 -1
- package/lib/module/core/stores/store/index.js +3 -1
- package/lib/module/core/stores/store/index.js.map +1 -1
- package/lib/module/social/components/LoadingImage/index.js +77 -16
- package/lib/module/social/components/LoadingImage/index.js.map +1 -1
- package/lib/module/social/components/LoadingImage/styles.js +12 -3
- package/lib/module/social/components/LoadingImage/styles.js.map +1 -1
- package/lib/module/social/components/LoadingVideo/index.js +99 -19
- package/lib/module/social/components/LoadingVideo/index.js.map +1 -1
- package/lib/module/social/components/LoadingVideo/styles.js +18 -5
- package/lib/module/social/components/LoadingVideo/styles.js.map +1 -1
- package/lib/module/social/components/MediaViewer/MediaViewer.js +259 -0
- package/lib/module/social/components/MediaViewer/MediaViewer.js.map +1 -0
- package/lib/module/social/components/MediaViewer/index.js +2 -0
- package/lib/module/social/components/MediaViewer/index.js.map +1 -0
- package/lib/module/social/components/MediaViewer/styles.js +119 -0
- package/lib/module/social/components/MediaViewer/styles.js.map +1 -0
- package/lib/module/social/components/PostContent/index.js +82 -148
- package/lib/module/social/components/PostContent/index.js.map +1 -1
- package/lib/module/social/components/SelectedMediaComponent/SelectedMediaComponent.js +233 -0
- package/lib/module/social/components/SelectedMediaComponent/SelectedMediaComponent.js.map +1 -0
- package/lib/module/social/components/SelectedMediaComponent/index.js +2 -0
- package/lib/module/social/components/SelectedMediaComponent/index.js.map +1 -0
- package/lib/module/social/components/SelectedMediaComponent/styles.js +36 -0
- package/lib/module/social/components/SelectedMediaComponent/styles.js.map +1 -0
- package/lib/module/social/components/legacy/LoadingVideo/index.js +17 -6
- package/lib/module/social/components/legacy/LoadingVideo/index.js.map +1 -1
- package/lib/module/social/constants/index.js +5 -0
- package/lib/module/social/constants/index.js.map +1 -0
- package/lib/module/social/elements/PostMediaElement/PostMediaElement.js +335 -0
- package/lib/module/social/elements/PostMediaElement/PostMediaElement.js.map +1 -0
- package/lib/module/social/elements/PostMediaElement/index.js +2 -0
- package/lib/module/social/elements/PostMediaElement/index.js.map +1 -0
- package/lib/module/social/elements/PostMediaElement/styles.js +117 -0
- package/lib/module/social/elements/PostMediaElement/styles.js.map +1 -0
- package/lib/module/social/features/community/PendingRequest/components/PendingPostList/PendingPostList.js +12 -6
- package/lib/module/social/features/community/PendingRequest/components/PendingPostList/PendingPostList.js.map +1 -1
- package/lib/module/social/features/feed/components/NewsFeed/NewsFeed.js +15 -1
- package/lib/module/social/features/feed/components/NewsFeed/NewsFeed.js.map +1 -1
- package/lib/module/social/features/post/Composer/PostComposer.js +278 -160
- package/lib/module/social/features/post/Composer/PostComposer.js.map +1 -1
- package/lib/module/social/features/post/components/DetailedMediaAttachment/DetailedMediaAttachment.js +17 -7
- package/lib/module/social/features/post/components/DetailedMediaAttachment/DetailedMediaAttachment.js.map +1 -1
- package/lib/module/social/features/post/components/MediaAttachment/MediaAttachment.js +17 -7
- package/lib/module/social/features/post/components/MediaAttachment/MediaAttachment.js.map +1 -1
- package/lib/module/social/hooks/index.js +1 -0
- package/lib/module/social/hooks/index.js.map +1 -1
- package/lib/module/social/hooks/useCommunities.js +5 -3
- package/lib/module/social/hooks/useCommunities.js.map +1 -1
- package/lib/module/social/hooks/useCommunityPermission.js +37 -0
- package/lib/module/social/hooks/useCommunityPermission.js.map +1 -0
- package/lib/module/social/hooks/useCustomRankingGlobalFeed.js +10 -1
- package/lib/module/social/hooks/useCustomRankingGlobalFeed.js.map +1 -1
- package/lib/module/social/hooks/useFile.js +11 -0
- package/lib/module/social/hooks/useFile.js.map +1 -1
- package/lib/module/social/screens/CommunityProfile/components/Header/Header.js +19 -8
- package/lib/module/social/screens/CommunityProfile/components/Header/Header.js.map +1 -1
- package/lib/module/social/utils/getFrameRatio.js +44 -0
- package/lib/module/social/utils/getFrameRatio.js.map +1 -0
- package/lib/module/social/utils/getIndicatorConfig.js +53 -0
- package/lib/module/social/utils/getIndicatorConfig.js.map +1 -0
- package/lib/module/social/utils/mediaAttachments.js +139 -0
- package/lib/module/social/utils/mediaAttachments.js.map +1 -0
- package/lib/module/social/utils/postChildren.js +66 -0
- package/lib/module/social/utils/postChildren.js.map +1 -0
- package/lib/typescript/core/assets/icons/xml.d.ts +8 -0
- package/lib/typescript/core/assets/icons/xml.d.ts.map +1 -1
- package/lib/typescript/core/hooks/usePostByIds.d.ts +8 -0
- package/lib/typescript/core/hooks/usePostByIds.d.ts.map +1 -0
- package/lib/typescript/core/legacy/file.d.ts +32 -0
- package/lib/typescript/core/legacy/file.d.ts.map +1 -1
- package/lib/typescript/core/stores/slices/feedSlice.d.ts.map +1 -1
- package/lib/typescript/core/stores/slices/globalfeedSlice.d.ts.map +1 -1
- package/lib/typescript/core/stores/slices/localVideoThumbnailSlice.d.ts +35 -0
- package/lib/typescript/core/stores/slices/localVideoThumbnailSlice.d.ts.map +1 -0
- package/lib/typescript/core/stores/slices/uiSlice.d.ts +5 -0
- package/lib/typescript/core/stores/slices/uiSlice.d.ts.map +1 -1
- package/lib/typescript/core/stores/store/index.d.ts.map +1 -1
- package/lib/typescript/core/types/mention.d.ts +34 -0
- package/lib/typescript/core/types/mention.d.ts.map +1 -1
- package/lib/typescript/social/components/LoadingImage/index.d.ts +9 -2
- package/lib/typescript/social/components/LoadingImage/index.d.ts.map +1 -1
- package/lib/typescript/social/components/LoadingImage/styles.d.ts +4 -0
- package/lib/typescript/social/components/LoadingImage/styles.d.ts.map +1 -1
- package/lib/typescript/social/components/LoadingVideo/index.d.ts +10 -2
- package/lib/typescript/social/components/LoadingVideo/index.d.ts.map +1 -1
- package/lib/typescript/social/components/LoadingVideo/styles.d.ts +5 -0
- package/lib/typescript/social/components/LoadingVideo/styles.d.ts.map +1 -1
- package/lib/typescript/social/components/MediaViewer/MediaViewer.d.ts +17 -0
- package/lib/typescript/social/components/MediaViewer/MediaViewer.d.ts.map +1 -0
- package/lib/typescript/social/components/MediaViewer/index.d.ts +3 -0
- package/lib/typescript/social/components/MediaViewer/index.d.ts.map +1 -0
- package/lib/typescript/social/components/MediaViewer/styles.d.ts +100 -0
- package/lib/typescript/social/components/MediaViewer/styles.d.ts.map +1 -0
- package/lib/typescript/social/components/PostContent/index.d.ts.map +1 -1
- package/lib/typescript/social/components/SelectedMediaComponent/SelectedMediaComponent.d.ts +12 -0
- package/lib/typescript/social/components/SelectedMediaComponent/SelectedMediaComponent.d.ts.map +1 -0
- package/lib/typescript/social/components/SelectedMediaComponent/index.d.ts +3 -0
- package/lib/typescript/social/components/SelectedMediaComponent/index.d.ts.map +1 -0
- package/lib/typescript/social/components/SelectedMediaComponent/styles.d.ts +25 -0
- package/lib/typescript/social/components/SelectedMediaComponent/styles.d.ts.map +1 -0
- package/lib/typescript/social/components/legacy/LoadingVideo/index.d.ts.map +1 -1
- package/lib/typescript/social/constants/index.d.ts +4 -0
- package/lib/typescript/social/constants/index.d.ts.map +1 -0
- package/lib/typescript/social/elements/PostMediaElement/PostMediaElement.d.ts +15 -0
- package/lib/typescript/social/elements/PostMediaElement/PostMediaElement.d.ts.map +1 -0
- package/lib/typescript/social/elements/PostMediaElement/index.d.ts +3 -0
- package/lib/typescript/social/elements/PostMediaElement/index.d.ts.map +1 -0
- package/lib/typescript/social/elements/PostMediaElement/styles.d.ts +92 -0
- package/lib/typescript/social/elements/PostMediaElement/styles.d.ts.map +1 -0
- package/lib/typescript/social/features/community/PendingRequest/components/PendingPostList/PendingPostList.d.ts.map +1 -1
- package/lib/typescript/social/features/feed/components/NewsFeed/NewsFeed.d.ts.map +1 -1
- package/lib/typescript/social/features/post/Composer/PostComposer.d.ts.map +1 -1
- package/lib/typescript/social/features/post/components/DetailedMediaAttachment/DetailedMediaAttachment.d.ts +3 -0
- package/lib/typescript/social/features/post/components/DetailedMediaAttachment/DetailedMediaAttachment.d.ts.map +1 -1
- package/lib/typescript/social/features/post/components/MediaAttachment/MediaAttachment.d.ts +3 -0
- package/lib/typescript/social/features/post/components/MediaAttachment/MediaAttachment.d.ts.map +1 -1
- package/lib/typescript/social/hooks/index.d.ts +1 -0
- package/lib/typescript/social/hooks/index.d.ts.map +1 -1
- package/lib/typescript/social/hooks/useCommunities.d.ts +2 -1
- package/lib/typescript/social/hooks/useCommunities.d.ts.map +1 -1
- package/lib/typescript/social/hooks/useCommunityPermission.d.ts +14 -0
- package/lib/typescript/social/hooks/useCommunityPermission.d.ts.map +1 -0
- package/lib/typescript/social/hooks/useCustomRankingGlobalFeed.d.ts.map +1 -1
- package/lib/typescript/social/hooks/useFile.d.ts +11 -0
- package/lib/typescript/social/hooks/useFile.d.ts.map +1 -1
- package/lib/typescript/social/screens/CommunityProfile/components/Header/Header.d.ts.map +1 -1
- package/lib/typescript/social/utils/getFrameRatio.d.ts +21 -0
- package/lib/typescript/social/utils/getFrameRatio.d.ts.map +1 -0
- package/lib/typescript/social/utils/getIndicatorConfig.d.ts +11 -0
- package/lib/typescript/social/utils/getIndicatorConfig.d.ts.map +1 -0
- package/lib/typescript/social/utils/mediaAttachments.d.ts +91 -0
- package/lib/typescript/social/utils/mediaAttachments.d.ts.map +1 -0
- package/lib/typescript/social/utils/postChildren.d.ts +38 -0
- package/lib/typescript/social/utils/postChildren.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/core/assets/icons/post.tsx +1 -1
- package/src/core/assets/icons/story.tsx +1 -1
- package/src/core/assets/icons/xml.ts +75 -0
- package/src/core/hooks/usePostByIds.ts +33 -0
- package/src/core/legacy/file.tsx +169 -84
- package/src/core/stores/slices/feedSlice.ts +3 -0
- package/src/core/stores/slices/globalfeedSlice.ts +5 -0
- package/src/core/stores/slices/localVideoThumbnailSlice.ts +58 -0
- package/src/core/stores/slices/uiSlice.ts +8 -0
- package/src/core/stores/store/index.ts +2 -0
- package/src/core/types/mention.ts +34 -0
- package/src/social/components/LoadingImage/index.tsx +93 -14
- package/src/social/components/LoadingImage/styles.ts +12 -3
- package/src/social/components/LoadingVideo/index.tsx +135 -21
- package/src/social/components/LoadingVideo/styles.ts +17 -4
- package/src/social/components/MediaViewer/MediaViewer.tsx +383 -0
- package/src/social/components/MediaViewer/index.tsx +2 -0
- package/src/social/components/MediaViewer/styles.ts +117 -0
- package/src/social/components/PostContent/index.tsx +86 -191
- package/src/social/components/SelectedMediaComponent/SelectedMediaComponent.tsx +292 -0
- package/src/social/components/SelectedMediaComponent/index.ts +2 -0
- package/src/social/components/SelectedMediaComponent/styles.ts +38 -0
- package/src/social/components/legacy/LoadingVideo/index.tsx +26 -15
- package/src/social/constants/index.ts +4 -0
- package/src/social/elements/PostMediaElement/PostMediaElement.tsx +428 -0
- package/src/social/elements/PostMediaElement/index.tsx +5 -0
- package/src/social/elements/PostMediaElement/styles.ts +106 -0
- package/src/social/features/community/PendingRequest/components/PendingPostList/PendingPostList.tsx +11 -6
- package/src/social/features/feed/components/NewsFeed/NewsFeed.tsx +16 -1
- package/src/social/features/post/Composer/PostComposer.tsx +366 -183
- package/src/social/features/post/components/DetailedMediaAttachment/DetailedMediaAttachment.tsx +10 -3
- package/src/social/features/post/components/MediaAttachment/MediaAttachment.tsx +14 -3
- package/src/social/hooks/index.ts +1 -0
- package/src/social/hooks/useCommunities.ts +4 -2
- package/src/social/hooks/useCommunityPermission.ts +40 -0
- package/src/social/hooks/useCustomRankingGlobalFeed.ts +8 -1
- package/src/social/hooks/useFile.ts +11 -0
- package/src/social/screens/CommunityProfile/components/Header/Header.tsx +19 -10
- package/src/social/utils/getFrameRatio.ts +42 -0
- package/src/social/utils/getIndicatorConfig.ts +62 -0
- package/src/social/utils/mediaAttachments.ts +158 -0
- package/src/social/utils/postChildren.ts +85 -0
|
@@ -13,6 +13,7 @@ var _types = require("../../../types");
|
|
|
13
13
|
var _CloseButtonIconElement = _interopRequireDefault(require("../../../elements/CloseButtonIconElement/CloseButtonIconElement"));
|
|
14
14
|
var _native = require("@react-navigation/native");
|
|
15
15
|
var _uiSlice = _interopRequireDefault(require("../../../../core/stores/slices/uiSlice"));
|
|
16
|
+
var _localVideoThumbnailSlice = _interopRequireDefault(require("../../../../core/stores/slices/localVideoThumbnailSlice"));
|
|
16
17
|
var _post = require("../../../../core/utils/post");
|
|
17
18
|
var _useAuth = _interopRequireDefault(require("../../../../core/hooks/useAuth"));
|
|
18
19
|
var _globalfeedSlice = _interopRequireDefault(require("../../../../core/stores/slices/globalfeedSlice"));
|
|
@@ -21,11 +22,11 @@ var _TextKeyElement = _interopRequireDefault(require("../../../elements/TextKeyE
|
|
|
21
22
|
var _MediaAttachment = _interopRequireDefault(require("../components/MediaAttachment"));
|
|
22
23
|
var _DetailedMediaAttachment = _interopRequireDefault(require("../components/DetailedMediaAttachment"));
|
|
23
24
|
var _reactNativeImagePicker = require("react-native-image-picker");
|
|
24
|
-
var
|
|
25
|
-
var _LoadingVideo = _interopRequireDefault(require("../../../components/LoadingVideo"));
|
|
25
|
+
var _SelectedMediaComponent = require("../../../components/SelectedMediaComponent");
|
|
26
26
|
var _tsSdkReactNative = require("@amityco/ts-sdk-react-native");
|
|
27
27
|
var _useMention = _interopRequireDefault(require("../../../hooks/useMention"));
|
|
28
28
|
var _errors = require("../../../utils/errors");
|
|
29
|
+
var _mediaAttachments = require("../../../utils/mediaAttachments");
|
|
29
30
|
var _constants = require("../../../../core/constants");
|
|
30
31
|
var _reactNativeControlledMentions = require("react-native-controlled-mentions");
|
|
31
32
|
var _store = require("../../../../core/stores/store");
|
|
@@ -39,7 +40,7 @@ const AmityPostComposerPage = ({
|
|
|
39
40
|
community,
|
|
40
41
|
post
|
|
41
42
|
}) => {
|
|
42
|
-
var _post$data;
|
|
43
|
+
var _post$data, _post$children;
|
|
43
44
|
(0, _hooks.useRequestPermission)({
|
|
44
45
|
onRequestPermissionFailed: () => {
|
|
45
46
|
_reactNative.Linking.openSettings();
|
|
@@ -58,9 +59,6 @@ const AmityPostComposerPage = ({
|
|
|
58
59
|
pageId
|
|
59
60
|
});
|
|
60
61
|
const styles = (0, _styles.useStyles)(themeStyles);
|
|
61
|
-
const {
|
|
62
|
-
getImage
|
|
63
|
-
} = (0, _hooks.useFile)();
|
|
64
62
|
const isEditMode = mode === _types.AmityPostComposerMode.EDIT;
|
|
65
63
|
const navigation = (0, _native.useNavigation)();
|
|
66
64
|
const {
|
|
@@ -81,6 +79,9 @@ const AmityPostComposerPage = ({
|
|
|
81
79
|
showToastMessage,
|
|
82
80
|
hideToastMessage
|
|
83
81
|
} = _uiSlice.default.actions;
|
|
82
|
+
const {
|
|
83
|
+
setLocalVideoThumbnails
|
|
84
|
+
} = _localVideoThumbnailSlice.default.actions;
|
|
84
85
|
const [inputMessage, setInputMessage] = (0, _react.useState)((post === null || post === void 0 || (_post$data = post.data) === null || _post$data === void 0 ? void 0 : _post$data.text) ?? '');
|
|
85
86
|
const [mentionsPosition, setMentionsPosition] = (0, _react.useState)([]);
|
|
86
87
|
const [chosenMediaType, setChosenMediaType] = (0, _react.useState)(null);
|
|
@@ -89,7 +90,14 @@ const AmityPostComposerPage = ({
|
|
|
89
90
|
const [mentionUsers, setMentionUsers] = (0, _react.useState)([]);
|
|
90
91
|
const [isSwipeup, setIsSwipeup] = (0, _react.useState)(true);
|
|
91
92
|
const [deletedPostIds, setDeletedPostIds] = (0, _react.useState)([]);
|
|
92
|
-
|
|
93
|
+
// Upload progress is tracked per media item, keyed by the item's `source`
|
|
94
|
+
// url — the same shape as `imageErrors`/`videoErrors` below. A
|
|
95
|
+
// single shared boolean was flipped back to false by whichever upload
|
|
96
|
+
// finished first, so Post/Save unlocked while the remaining frames were
|
|
97
|
+
// still in flight. Sources are unique across images and videos, so one set
|
|
98
|
+
// covers both attachment types.
|
|
99
|
+
const [uploadingSources, setUploadingSources] = (0, _react.useState)(new Set());
|
|
100
|
+
const isUploading = uploadingSources.size > 0;
|
|
93
101
|
const [hasChangedAttachment, setHasChangedAttachment] = (0, _react.useState)(false);
|
|
94
102
|
const [imageErrors, setImageErrors] = (0, _react.useState)(new Set());
|
|
95
103
|
const [videoErrors, setVideoErrors] = (0, _react.useState)(new Set());
|
|
@@ -116,7 +124,7 @@ const AmityPostComposerPage = ({
|
|
|
116
124
|
const effectiveCommunity = community ?? fetchedCommunity;
|
|
117
125
|
const privateCommunityId = !(effectiveCommunity !== null && effectiveCommunity !== void 0 && effectiveCommunity.isPublic) && (effectiveCommunity === null || effectiveCommunity === void 0 ? void 0 : effectiveCommunity.communityId);
|
|
118
126
|
const title = isEditMode ? 'Edit Post' : (effectiveCommunity === null || effectiveCommunity === void 0 ? void 0 : effectiveCommunity.displayName) ?? 'My Timeline';
|
|
119
|
-
const isInputValid = !isUploading && imageErrors.size === 0 && videoErrors.size === 0 && inputMessage.trim().length <= _constants.MAXIMUM_POST_CHARACTERS && (inputMessage.trim().length > 0 || displayImages.length > 0 || displayVideos.length > 0) && (displayImages.length <=
|
|
127
|
+
const isInputValid = !isUploading && imageErrors.size === 0 && videoErrors.size === 0 && inputMessage.trim().length <= _constants.MAXIMUM_POST_CHARACTERS && (inputMessage.trim().length > 0 || displayImages.length > 0 || displayVideos.length > 0) && (displayImages.length <= _mediaAttachments.MAX_MEDIA_ATTACHMENTS || displayVideos.length <= _mediaAttachments.MAX_MEDIA_ATTACHMENTS);
|
|
120
128
|
const {
|
|
121
129
|
renderInput,
|
|
122
130
|
renderSuggestions
|
|
@@ -137,8 +145,26 @@ const AmityPostComposerPage = ({
|
|
|
137
145
|
}]);
|
|
138
146
|
}
|
|
139
147
|
});
|
|
148
|
+
|
|
149
|
+
// The edited post carries its own hydrated children: every post payload
|
|
150
|
+
// ingests `postChildren` into the `post` cache (PAYLOAD2MODEL maps it to
|
|
151
|
+
// 'post'), and postLinkedObject reads them straight back out. So the media is
|
|
152
|
+
// known on the first frame, with no fetch — no second source to reconcile.
|
|
153
|
+
const editChildren = (post === null || post === void 0 ? void 0 : post.childrenPosts) ?? [];
|
|
154
|
+
|
|
155
|
+
// `childrenPosts` drops cache misses silently (postLinkedObject filters with
|
|
156
|
+
// isNonNullable), so a short array means we cannot see every child. There is
|
|
157
|
+
// no fallback fetch behind it, so treat that state as read-only: no
|
|
158
|
+
// attachment bar, no Save.
|
|
159
|
+
const editChildrenIncomplete = isEditMode && editChildren.length !== ((post === null || post === void 0 || (_post$children = post.children) === null || _post$children === void 0 ? void 0 : _post$children.length) ?? 0);
|
|
140
160
|
const checkIsEditValid = () => {
|
|
141
161
|
var _post$data2;
|
|
162
|
+
// `type` in onPressPost is derived from displayImages/displayVideos, so
|
|
163
|
+
// saving while a child is missing submits it as removed — `attachments: []`
|
|
164
|
+
// and type 'text' strips the post's media outright. Nothing the user can do
|
|
165
|
+
// in the composer makes an unrendered child safe to save, so key this on
|
|
166
|
+
// completeness alone rather than on hasChangedAttachment.
|
|
167
|
+
if (editChildrenIncomplete) return false;
|
|
142
168
|
return isInputValid && (inputMessage !== (post === null || post === void 0 || (_post$data2 = post.data) === null || _post$data2 === void 0 ? void 0 : _post$data2.text) || hasChangedAttachment);
|
|
143
169
|
};
|
|
144
170
|
const parsePostText = (0, _react.useCallback)((text, mentionUsersArr) => {
|
|
@@ -149,50 +175,82 @@ const AmityPostComposerPage = ({
|
|
|
149
175
|
});
|
|
150
176
|
return parsedText;
|
|
151
177
|
}, []);
|
|
152
|
-
|
|
178
|
+
|
|
179
|
+
// A child post's file is usually already in the SDK cache, where the linked
|
|
180
|
+
// object exposes it synchronously (getImageInfo / getVideoInfo /
|
|
181
|
+
// getVideoThumbnailInfo are `pullFromCache(['file','get', …])` over the very
|
|
182
|
+
// ids we'd otherwise refetch). Use the cached `fileUrl` when it's there and
|
|
183
|
+
// fall back to the round trip on a cache miss. `fileUrlWithSize` is just
|
|
184
|
+
// `?size=`, so both branches produce the same url.
|
|
185
|
+
const resolveFileUrl = (0, _react.useCallback)(async (fileUrl, fileId) => {
|
|
186
|
+
var _file$data;
|
|
187
|
+
if (fileUrl) return _tsSdkReactNative.FileRepository.fileUrlWithSize(fileUrl, _enums.ImageSizeState.full);
|
|
188
|
+
if (!fileId) return undefined;
|
|
189
|
+
|
|
190
|
+
// Resolve the file directly rather than through useFile: that hook
|
|
191
|
+
// answers a miss with the default *avatar* image, which is right for a
|
|
192
|
+
// profile picture and wrong for post media. A video whose thumbnail the
|
|
193
|
+
// server has not produced yet has no file to resolve, and handing back an
|
|
194
|
+
// avatar made the carousel render a person icon behind the play button as
|
|
195
|
+
// though it were the real frame — and, because the url looked valid, it
|
|
196
|
+
// was also stored as the local thumbnail the feed falls back on.
|
|
197
|
+
const file = await _tsSdkReactNative.FileRepository.getFile(fileId);
|
|
198
|
+
const resolved = file === null || file === void 0 || (_file$data = file.data) === null || _file$data === void 0 ? void 0 : _file$data.fileUrl;
|
|
199
|
+
return resolved ? _tsSdkReactNative.FileRepository.fileUrlWithSize(resolved, _enums.ImageSizeState.full) : undefined;
|
|
200
|
+
}, []);
|
|
201
|
+
const getPostInfo = (0, _react.useCallback)(async response => {
|
|
153
202
|
try {
|
|
154
|
-
const response = await Promise.all(postArray.map(async id => {
|
|
155
|
-
const {
|
|
156
|
-
data
|
|
157
|
-
} = await (0, _feed.getPostById)(id);
|
|
158
|
-
return data;
|
|
159
|
-
}));
|
|
160
203
|
const images = [];
|
|
161
204
|
const videos = [];
|
|
162
205
|
for (const item of response) {
|
|
163
206
|
if ((item === null || item === void 0 ? void 0 : item.dataType) === 'image') {
|
|
164
|
-
var _item$
|
|
165
|
-
const fileId = item === null || item === void 0 || (
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
});
|
|
207
|
+
var _data, _item$getImageInfo, _imageInfo$getWidth, _imageInfo$getHeight;
|
|
208
|
+
const fileId = item === null || item === void 0 || (_data = item.data) === null || _data === void 0 ? void 0 : _data.fileId;
|
|
209
|
+
// Dimensions for composer frame-ratio classification (REQ-003d).
|
|
210
|
+
const imageInfo = item === null || item === void 0 || (_item$getImageInfo = item.getImageInfo) === null || _item$getImageInfo === void 0 ? void 0 : _item$getImageInfo.call(item);
|
|
211
|
+
const url = await resolveFileUrl(imageInfo === null || imageInfo === void 0 ? void 0 : imageInfo.fileUrl, fileId);
|
|
170
212
|
images.push({
|
|
171
213
|
url,
|
|
172
214
|
fileId,
|
|
173
215
|
fileName: fileId,
|
|
216
|
+
// A hydrated child has no local pick behind it, so its identity
|
|
217
|
+
// is the file it already is. Unique per child, stable for the
|
|
218
|
+
// whole session, and never equal to a picker file name — so a
|
|
219
|
+
// later pick is de-duplicated against the other staged picks
|
|
220
|
+
// only, which is the most the picker can tell us.
|
|
221
|
+
localId: fileId ?? item.postId,
|
|
174
222
|
isUploaded: true,
|
|
175
|
-
postId: item.postId
|
|
223
|
+
postId: item.postId,
|
|
224
|
+
width: imageInfo === null || imageInfo === void 0 || (_imageInfo$getWidth = imageInfo.getWidth) === null || _imageInfo$getWidth === void 0 ? void 0 : _imageInfo$getWidth.call(imageInfo),
|
|
225
|
+
height: imageInfo === null || imageInfo === void 0 || (_imageInfo$getHeight = imageInfo.getHeight) === null || _imageInfo$getHeight === void 0 ? void 0 : _imageInfo$getHeight.call(imageInfo)
|
|
176
226
|
});
|
|
177
227
|
} else if ((item === null || item === void 0 ? void 0 : item.dataType) === 'video') {
|
|
178
|
-
var _item$
|
|
179
|
-
const
|
|
180
|
-
const
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
228
|
+
var _videoData$videoFileI, _item$getVideoInfo, _item$getVideoThumbna, _videoInfo$getWidth, _videoInfo$getHeight, _videoInfo$getRotatio;
|
|
229
|
+
const videoData = item === null || item === void 0 ? void 0 : item.data;
|
|
230
|
+
const fileId = videoData === null || videoData === void 0 || (_videoData$videoFileI = videoData.videoFileId) === null || _videoData$videoFileI === void 0 ? void 0 : _videoData$videoFileI.original;
|
|
231
|
+
const thumbnailFileId = videoData === null || videoData === void 0 ? void 0 : videoData.thumbnailFileId;
|
|
232
|
+
// STORED dims + rotation; rotation is applied at classify time
|
|
233
|
+
// (SelectedMediaComponent REQ-003d1 / AmityVideo REQ-SDK-002).
|
|
234
|
+
const videoInfo = item === null || item === void 0 || (_item$getVideoInfo = item.getVideoInfo) === null || _item$getVideoInfo === void 0 ? void 0 : _item$getVideoInfo.call(item);
|
|
235
|
+
const thumbnailInfo = item === null || item === void 0 || (_item$getVideoThumbna = item.getVideoThumbnailInfo) === null || _item$getVideoThumbna === void 0 ? void 0 : _item$getVideoThumbna.call(item);
|
|
236
|
+
// Settle the two urls independently: a missing or unreachable
|
|
237
|
+
// thumbnail must not cost us the video itself. `Promise.all` would
|
|
238
|
+
// reject the pair, abort this loop, and leave displayVideos empty
|
|
239
|
+
// — which now also keeps Save disabled (see checkIsEditValid).
|
|
240
|
+
const [urlResult, thumbNailResult] = await Promise.allSettled([resolveFileUrl(videoInfo === null || videoInfo === void 0 ? void 0 : videoInfo.fileUrl, fileId), resolveFileUrl(thumbnailInfo === null || thumbnailInfo === void 0 ? void 0 : thumbnailInfo.fileUrl, thumbnailFileId)]);
|
|
241
|
+
const url = urlResult.status === 'fulfilled' ? urlResult.value : undefined;
|
|
242
|
+
const thumbNail = thumbNailResult.status === 'fulfilled' ? thumbNailResult.value : undefined;
|
|
187
243
|
videos.push({
|
|
188
|
-
|
|
189
|
-
url: (_fileUrls$ = fileUrls[0]) === null || _fileUrls$ === void 0 ? void 0 : _fileUrls$.value,
|
|
244
|
+
url,
|
|
190
245
|
fileId: fileId,
|
|
191
246
|
fileName: fileId,
|
|
247
|
+
localId: fileId ?? item.postId,
|
|
192
248
|
isUploaded: true,
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
249
|
+
thumbNail,
|
|
250
|
+
postId: item.postId,
|
|
251
|
+
width: videoInfo === null || videoInfo === void 0 || (_videoInfo$getWidth = videoInfo.getWidth) === null || _videoInfo$getWidth === void 0 ? void 0 : _videoInfo$getWidth.call(videoInfo),
|
|
252
|
+
height: videoInfo === null || videoInfo === void 0 || (_videoInfo$getHeight = videoInfo.getHeight) === null || _videoInfo$getHeight === void 0 ? void 0 : _videoInfo$getHeight.call(videoInfo),
|
|
253
|
+
rotation: videoInfo === null || videoInfo === void 0 || (_videoInfo$getRotatio = videoInfo.getRotation) === null || _videoInfo$getRotatio === void 0 ? void 0 : _videoInfo$getRotatio.call(videoInfo)
|
|
196
254
|
});
|
|
197
255
|
}
|
|
198
256
|
}
|
|
@@ -205,14 +263,36 @@ const AmityPostComposerPage = ({
|
|
|
205
263
|
} catch (error) {
|
|
206
264
|
console.log('error: ', error);
|
|
207
265
|
}
|
|
208
|
-
}, [
|
|
266
|
+
}, [resolveFileUrl]);
|
|
209
267
|
(0, _react.useEffect)(() => {
|
|
210
268
|
setDeletedPostIds([]);
|
|
211
269
|
return () => setDeletedPostIds([]);
|
|
212
270
|
}, []);
|
|
271
|
+
|
|
272
|
+
// `post` comes from route params, so `editChildren` is reference-stable and
|
|
273
|
+
// this hydrates once. The hasChangedAttachment guard is belt-and-braces:
|
|
274
|
+
// getPostInfo assigns displayImages/displayVideos wholesale, so a re-run must
|
|
275
|
+
// never be able to wipe media the user added.
|
|
213
276
|
(0, _react.useEffect)(() => {
|
|
214
|
-
(
|
|
215
|
-
|
|
277
|
+
if (editChildren.length === 0 || hasChangedAttachment) return;
|
|
278
|
+
getPostInfo(editChildren);
|
|
279
|
+
}, [getPostInfo, post === null || post === void 0 ? void 0 : post.childrenPosts, hasChangedAttachment]);
|
|
280
|
+
|
|
281
|
+
// Media type of the post being edited, read off the children's dataType —
|
|
282
|
+
// the same signal the web UIKit feeds into useMediaAttachmentVisible.
|
|
283
|
+
const editMediaType = (0, _react.useMemo)(() => {
|
|
284
|
+
if (editChildren.some(item => (item === null || item === void 0 ? void 0 : item.dataType) === 'image')) return _enums.mediaAttachment.image;
|
|
285
|
+
if (editChildren.some(item => (item === null || item === void 0 ? void 0 : item.dataType) === 'video')) return _enums.mediaAttachment.video;
|
|
286
|
+
return null;
|
|
287
|
+
}, [post === null || post === void 0 ? void 0 : post.childrenPosts]);
|
|
288
|
+
|
|
289
|
+
// The post's single media type, as every media entry point must see it: the
|
|
290
|
+
// staged attachments when there are any, otherwise the type the edited post
|
|
291
|
+
// already has. Read the display arrays rather than `chosenMediaType`, which
|
|
292
|
+
// is assigned in an effect and so trails them by a render. Once the user has
|
|
293
|
+
// cleared the attachments itself the post has no type again and all three
|
|
294
|
+
// buttons come back, matching web.
|
|
295
|
+
const activeMediaType = displayImages.length > 0 ? _enums.mediaAttachment.image : displayVideos.length > 0 ? _enums.mediaAttachment.video : hasChangedAttachment ? null : editMediaType;
|
|
216
296
|
const getMentionPositions = (0, _react.useCallback)((text, mentioneeIds) => {
|
|
217
297
|
let index = 0;
|
|
218
298
|
let mentions = [];
|
|
@@ -326,6 +406,21 @@ const AmityPostComposerPage = ({
|
|
|
326
406
|
return;
|
|
327
407
|
}
|
|
328
408
|
dispatch(hideToastMessage());
|
|
409
|
+
// The server has no thumbnail for these videos until it finishes
|
|
410
|
+
// transcoding, so hand the feed the frames the composer already decoded
|
|
411
|
+
// to bridge that window (PDT-4904, web parity: LayoutProvider
|
|
412
|
+
// videoThumbnail). Keyed by the uploaded original video's fileId, which
|
|
413
|
+
// is what the created post exposes as `data.videoFileId.original`.
|
|
414
|
+
if (type === 'video' && displayVideos.length > 0) {
|
|
415
|
+
dispatch(setLocalVideoThumbnails({
|
|
416
|
+
postId: response.postId,
|
|
417
|
+
// Only frames that actually decoded: an entry with no thumbnail
|
|
418
|
+
// would still satisfy the feed's lookup and suppress its own
|
|
419
|
+
// pending state, leaving the frame blank instead of showing the
|
|
420
|
+
// play affordance over a plain background.
|
|
421
|
+
videos: (0, _mediaAttachments.toLocalVideoThumbnails)(displayVideos)
|
|
422
|
+
}));
|
|
423
|
+
}
|
|
329
424
|
if (targetType === 'community' && ((effectiveCommunity === null || effectiveCommunity === void 0 ? void 0 : effectiveCommunity.postSetting) === 'ADMIN_REVIEW_POST_REQUIRED' || effectiveCommunity !== null && effectiveCommunity !== void 0 && effectiveCommunity.needApprovalOnPostCreation) && !isCommunityModerator) {
|
|
330
425
|
onPressClose();
|
|
331
426
|
return _reactNative.Alert.alert('Post submitted', 'Your post has been submitted to the pending list. It will be reviewed by community moderator', [{
|
|
@@ -356,7 +451,7 @@ const AmityPostComposerPage = ({
|
|
|
356
451
|
toastMessage: errorMessage
|
|
357
452
|
}));
|
|
358
453
|
}
|
|
359
|
-
}, [addPostToGlobalFeed, chosenMediaType, effectiveCommunity, deletedPostIds, dispatch, displayImages, displayVideos, hideToastMessage, inputMessage, isEditMode, isInputValid, isCommunityModerator, mentionUsers, mentionsPosition, onPressClose, post, showToastMessage, targetId, targetType, updateByPostId]);
|
|
454
|
+
}, [addPostToGlobalFeed, chosenMediaType, effectiveCommunity, deletedPostIds, dispatch, displayImages, displayVideos, hideToastMessage, inputMessage, isEditMode, isInputValid, isCommunityModerator, mentionUsers, mentionsPosition, onPressClose, setLocalVideoThumbnails, post, showToastMessage, targetId, targetType, updateByPostId]);
|
|
360
455
|
let tEvents = [];
|
|
361
456
|
const onSwipe = (0, _react.useCallback)(touchEvent => {
|
|
362
457
|
const swipeUp = touchEvent[0] > touchEvent[touchEvent.length - 1];
|
|
@@ -378,6 +473,14 @@ const AmityPostComposerPage = ({
|
|
|
378
473
|
return {
|
|
379
474
|
url: url,
|
|
380
475
|
fileName: fileName,
|
|
476
|
+
// Camera captures land on a freshly generated temp path, so the path
|
|
477
|
+
// itself is the identity: unique per shot, and stable once the upload
|
|
478
|
+
// rewrites `url` to the remote one. Deliberately no
|
|
479
|
+
// `localFileName` — two shots of the same scene are two distinct
|
|
480
|
+
// attachments and must never de-duplicate against each other, nor
|
|
481
|
+
// against a library pick that happens to share a basename.
|
|
482
|
+
localId: url,
|
|
483
|
+
localUrl: url,
|
|
381
484
|
fileId: '',
|
|
382
485
|
isUploaded: false
|
|
383
486
|
};
|
|
@@ -390,8 +493,8 @@ const AmityPostComposerPage = ({
|
|
|
390
493
|
return setChosenMediaType(null);
|
|
391
494
|
}, [displayImages === null || displayImages === void 0 ? void 0 : displayImages.length, displayVideos === null || displayVideos === void 0 ? void 0 : displayVideos.length]);
|
|
392
495
|
const pickCamera = (0, _react.useCallback)(async mediaType => {
|
|
393
|
-
if (mediaType === 'photo' && displayImages.length
|
|
394
|
-
if (mediaType === 'video' && displayVideos.length
|
|
496
|
+
if (mediaType === 'photo' && displayImages.length >= _mediaAttachments.MAX_MEDIA_ATTACHMENTS) return _reactNative.Alert.alert('Maximum upload limit reached', "You've reached the upload limit of 10 images. Any additional images will not be saved.");
|
|
497
|
+
if (mediaType === 'video' && displayVideos.length >= _mediaAttachments.MAX_MEDIA_ATTACHMENTS) return _reactNative.Alert.alert('Maximum upload limit reached', "You've reached the upload limit of 10 videos. Any additional videos will not be saved.");
|
|
395
498
|
try {
|
|
396
499
|
const result = await (0, _reactNativeImagePicker.launchCamera)({
|
|
397
500
|
mediaType: mediaType,
|
|
@@ -420,8 +523,13 @@ const AmityPostComposerPage = ({
|
|
|
420
523
|
}
|
|
421
524
|
}, [displayImages.length, displayVideos.length, processMedia]);
|
|
422
525
|
const onPressCamera = (0, _react.useCallback)(async () => {
|
|
423
|
-
|
|
424
|
-
|
|
526
|
+
// The camera button is always rendered — unlike photo/video, neither
|
|
527
|
+
// attachment bar hides it on `chosenMediaType` — so this is the one entry
|
|
528
|
+
// point that must decide the capture type itself. Keying it on the staged
|
|
529
|
+
// arrays alone offered both types while an edited post's media was still
|
|
530
|
+
// hydrating, which is how a video could be shot onto an image post.
|
|
531
|
+
if (activeMediaType === _enums.mediaAttachment.image) return pickCamera('photo');
|
|
532
|
+
if (activeMediaType === _enums.mediaAttachment.video) return pickCamera('video');
|
|
425
533
|
if (_reactNative.Platform.OS === 'ios') return pickCamera('mixed');
|
|
426
534
|
_reactNative.Alert.alert('Open Camera', null, [{
|
|
427
535
|
text: 'Photo',
|
|
@@ -430,47 +538,95 @@ const AmityPostComposerPage = ({
|
|
|
430
538
|
text: 'Video',
|
|
431
539
|
onPress: async () => pickCamera('video')
|
|
432
540
|
}]);
|
|
433
|
-
}, [
|
|
434
|
-
|
|
435
|
-
|
|
541
|
+
}, [activeMediaType, pickCamera]);
|
|
542
|
+
|
|
543
|
+
// Open the native OS camera roll (matches the web UIKit's native file
|
|
544
|
+
// picker). Appends the picked media, de-duplicating by uri and capping at 10.
|
|
545
|
+
const pickFromLibrary = (0, _react.useCallback)(async mediaType => {
|
|
546
|
+
var _result$assets;
|
|
547
|
+
const isPhoto = mediaType === 'photo';
|
|
548
|
+
// A post holds one media type. The bar hides the mismatched button, but
|
|
549
|
+
// guard the entry point too so a tap landing before the button updates
|
|
550
|
+
// can't replace the existing attachments with the other type.
|
|
551
|
+
const pickedType = isPhoto ? _enums.mediaAttachment.image : _enums.mediaAttachment.video;
|
|
552
|
+
if (activeMediaType && activeMediaType !== pickedType) return;
|
|
553
|
+
const current = isPhoto ? displayImages.length : displayVideos.length;
|
|
554
|
+
if (current >= _mediaAttachments.MAX_MEDIA_ATTACHMENTS) return _reactNative.Alert.alert('Maximum upload limit reached', `You've reached the upload limit of 10 ${isPhoto ? 'images' : 'videos'}. Any additional ${isPhoto ? 'images' : 'videos'} will not be saved.`);
|
|
436
555
|
const result = await (0, _reactNativeImagePicker.launchImageLibrary)({
|
|
437
|
-
mediaType
|
|
556
|
+
mediaType,
|
|
438
557
|
quality: 1,
|
|
439
|
-
selectionLimit:
|
|
558
|
+
selectionLimit: _mediaAttachments.MAX_MEDIA_ATTACHMENTS - current,
|
|
559
|
+
// Required for `asset.id`, which is what recognises a re-pick of an
|
|
560
|
+
// asset already staged. Without it the iOS picker builds its
|
|
561
|
+
// PHPickerConfiguration without a photo library, so results carry no
|
|
562
|
+
// assetIdentifier and the native side never resolves a PHAsset —
|
|
563
|
+
// leaving `id` undefined and the fallback key, `fileName`, a fresh
|
|
564
|
+
// UUID per pick. Both dedupe keys were therefore unique every time
|
|
565
|
+
// and picking the same photo twice staged it twice. Android was
|
|
566
|
+
// unaffected: its filename is the MediaStore display name, stable
|
|
567
|
+
// across picks.
|
|
568
|
+
includeExtra: true
|
|
440
569
|
});
|
|
441
|
-
if (
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
570
|
+
if (result.didCancel || !((_result$assets = result.assets) !== null && _result$assets !== void 0 && _result$assets.length)) return;
|
|
571
|
+
|
|
572
|
+
// iOS video is the one pick whose dims cannot be trusted: the picker
|
|
573
|
+
// reports the track's stored `naturalSize` with no rotation alongside
|
|
574
|
+
// it, so a portrait iPhone clip arrives as 1920×1080 and would
|
|
575
|
+
// classify the frame 16:9 (PDT-4904). Images on both platforms, and
|
|
576
|
+
// Android video (its extractor swaps w/h on 90°/270°), are already
|
|
577
|
+
// display-oriented and unaffected. With no rotation to correct the iOS
|
|
578
|
+
// value by, carry nothing and let SelectedMediaComponent measure the
|
|
579
|
+
// generated thumbnail, which is a rendered frame.
|
|
580
|
+
const isIosVideoDimsUnusable = !isPhoto && _reactNative.Platform.OS === 'ios';
|
|
581
|
+
const candidates = (result.assets ?? []).flatMap(asset => {
|
|
582
|
+
if (!asset.uri) return [];
|
|
583
|
+
const fileName = asset.fileName ?? asset.uri.substring(asset.uri.lastIndexOf('/') + 1);
|
|
584
|
+
return [{
|
|
585
|
+
url: asset.uri,
|
|
586
|
+
fileName,
|
|
587
|
+
// `asset.id` is the library's own identifier for the asset (PHAsset
|
|
588
|
+
// localIdentifier / MediaStore id) and is the one key that survives
|
|
589
|
+
// the picker copying the pick to a new temp uri every time. It is
|
|
590
|
+
// not populated by every picker configuration, so fall back to the
|
|
591
|
+
// file name and keep the name as a second key either way — that is
|
|
592
|
+
// what catches a re-pick when no id came back.
|
|
593
|
+
localId: asset.id ?? fileName,
|
|
594
|
+
localUrl: asset.uri,
|
|
595
|
+
localFileName: fileName,
|
|
596
|
+
fileId: '',
|
|
597
|
+
isUploaded: false,
|
|
598
|
+
width: isIosVideoDimsUnusable ? undefined : asset.width,
|
|
599
|
+
height: isIosVideoDimsUnusable ? undefined : asset.height
|
|
600
|
+
}];
|
|
460
601
|
});
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
602
|
+
|
|
603
|
+
// Stage the picks and claim their upload slots in one go. Staging alone
|
|
604
|
+
// used to flip `isInputValid` true on the very next render — the frames
|
|
605
|
+
// exist, and `uploadingSources` is still empty because each child only
|
|
606
|
+
// registers from its own mount effect — so Post sat enabled for ~940 ms
|
|
607
|
+
// with nothing uploaded and a quick tap posted media that had no fileId
|
|
608
|
+
// yet. Seeding here makes "staged" and "gated" the same update; children
|
|
609
|
+
// still clear their own entry when they finish, and the unmount cleanup
|
|
610
|
+
// still covers a frame removed mid-flight.
|
|
611
|
+
const staged = isPhoto ? displayImages : displayVideos;
|
|
612
|
+
const accepted = (0, _mediaAttachments.appendWithinCap)(staged, (0, _mediaAttachments.dedupeMediaPicks)(staged, candidates));
|
|
613
|
+
// Only the entries that actually survived dedupe and the cap — seeding a
|
|
614
|
+
// key no child will ever mount for would leave Post disabled forever.
|
|
615
|
+
const newlyStaged = accepted.slice(staged.length);
|
|
616
|
+
const setter = isPhoto ? setDisplayImages : setDisplayVideos;
|
|
617
|
+
setter(accepted);
|
|
618
|
+
setUploadingSources(prev => newlyStaged.reduce((acc, item) => (0, _mediaAttachments.toggleUploadingSource)(acc, item.url, true), prev));
|
|
619
|
+
}, [activeMediaType, displayImages, displayVideos]);
|
|
620
|
+
const onPressImage = (0, _react.useCallback)(() => pickFromLibrary('photo'), [pickFromLibrary]);
|
|
621
|
+
const onPressVideo = (0, _react.useCallback)(() => pickFromLibrary('video'), [pickFromLibrary]);
|
|
622
|
+
|
|
623
|
+
// Children report their own upload start/end keyed by `source`, and a child
|
|
624
|
+
// that unmounts mid-upload (frame removed while still uploading) clears its
|
|
625
|
+
// own entry from its cleanup — otherwise the set would never empty and Post
|
|
626
|
+
// would stay disabled forever.
|
|
627
|
+
const handleUploadingChange = (0, _react.useCallback)((uploading, source) => {
|
|
628
|
+
setUploadingSources(prev => (0, _mediaAttachments.toggleUploadingSource)(prev, source, uploading));
|
|
629
|
+
}, []);
|
|
474
630
|
const handleImageUploadError = (0, _react.useCallback)((hasError, source) => {
|
|
475
631
|
setImageErrors(prev => {
|
|
476
632
|
const newSet = new Set(prev);
|
|
@@ -495,7 +651,7 @@ const AmityPostComposerPage = ({
|
|
|
495
651
|
}, []);
|
|
496
652
|
const handleOnCloseImage = (0, _react.useCallback)((originalPath, _, postId) => {
|
|
497
653
|
setHasChangedAttachment(true);
|
|
498
|
-
setDeletedPostIds(prev => [...prev, postId]);
|
|
654
|
+
if (postId) setDeletedPostIds(prev => [...prev, postId]);
|
|
499
655
|
setImageErrors(prev => {
|
|
500
656
|
const newSet = new Set(prev);
|
|
501
657
|
newSet.delete(originalPath);
|
|
@@ -508,7 +664,7 @@ const AmityPostComposerPage = ({
|
|
|
508
664
|
}, []);
|
|
509
665
|
const handleOnCloseVideo = (0, _react.useCallback)((originalPath, _, postId) => {
|
|
510
666
|
setHasChangedAttachment(true);
|
|
511
|
-
setDeletedPostIds(prev => [...prev, postId]);
|
|
667
|
+
if (postId) setDeletedPostIds(prev => [...prev, postId]);
|
|
512
668
|
setVideoErrors(prev => {
|
|
513
669
|
const newSet = new Set(prev);
|
|
514
670
|
newSet.delete(originalPath);
|
|
@@ -519,54 +675,50 @@ const AmityPostComposerPage = ({
|
|
|
519
675
|
return newData;
|
|
520
676
|
});
|
|
521
677
|
}, []);
|
|
522
|
-
const handleOnFinishImage = (0, _react.useCallback)((fileId, fileUrl, fileName,
|
|
678
|
+
const handleOnFinishImage = (0, _react.useCallback)((fileId, fileUrl, fileName, _index, originalPath) => {
|
|
523
679
|
setHasChangedAttachment(true);
|
|
524
|
-
|
|
680
|
+
setDisplayImages(prevData => (0, _mediaAttachments.applyFinishedUpload)(prevData, originalPath, {
|
|
525
681
|
url: fileUrl,
|
|
526
682
|
fileId: fileId,
|
|
527
683
|
fileName: fileName,
|
|
528
684
|
isUploaded: true
|
|
529
|
-
};
|
|
530
|
-
setDisplayImages(prevData => {
|
|
531
|
-
const newData = [...prevData];
|
|
532
|
-
newData[index] = imageObject;
|
|
533
|
-
return newData;
|
|
534
|
-
});
|
|
685
|
+
}));
|
|
535
686
|
}, []);
|
|
536
|
-
const handleOnFinishVideo = (0, _react.useCallback)((fileId, fileUrl, fileName,
|
|
687
|
+
const handleOnFinishVideo = (0, _react.useCallback)((fileId, fileUrl, fileName, _index, originalPath, thumbnail) => {
|
|
537
688
|
setHasChangedAttachment(true);
|
|
538
|
-
|
|
689
|
+
setDisplayVideos(prevData => (0, _mediaAttachments.applyFinishedUpload)(prevData, originalPath, {
|
|
539
690
|
url: fileUrl,
|
|
540
691
|
fileId: fileId,
|
|
541
692
|
fileName: fileName,
|
|
542
693
|
isUploaded: true,
|
|
543
694
|
thumbNail: thumbnail
|
|
544
|
-
};
|
|
545
|
-
setDisplayVideos(prevData => {
|
|
546
|
-
const newData = [...prevData];
|
|
547
|
-
newData[index] = imageObject;
|
|
548
|
-
return newData;
|
|
549
|
-
});
|
|
695
|
+
}));
|
|
550
696
|
}, []);
|
|
697
|
+
|
|
698
|
+
// PDT-4310 / PDT-4312: at the 10-attachment cap the camera + gallery icons
|
|
699
|
+
// are disabled until the user removes a frame.
|
|
700
|
+
const isMediaCapReached = displayImages.length >= _mediaAttachments.MAX_MEDIA_ATTACHMENTS || displayVideos.length >= _mediaAttachments.MAX_MEDIA_ATTACHMENTS;
|
|
551
701
|
const renderDetailedAttachment = (0, _react.useCallback)(() => {
|
|
552
|
-
if (
|
|
702
|
+
if (editChildrenIncomplete) return null;
|
|
553
703
|
if (shouldShowDetailAttachment) {
|
|
554
704
|
return /*#__PURE__*/React.createElement(_DetailedMediaAttachment.default, {
|
|
555
705
|
onPressCamera: onPressCamera,
|
|
556
706
|
onPressImage: onPressImage,
|
|
557
707
|
onPressVideo: onPressVideo,
|
|
558
|
-
chosenMediaType:
|
|
559
|
-
onHeightChange: setAttachmentBarHeight
|
|
708
|
+
chosenMediaType: activeMediaType,
|
|
709
|
+
onHeightChange: setAttachmentBarHeight,
|
|
710
|
+
disabled: isMediaCapReached
|
|
560
711
|
});
|
|
561
712
|
}
|
|
562
713
|
return /*#__PURE__*/React.createElement(_MediaAttachment.default, {
|
|
563
714
|
onPressCamera: onPressCamera,
|
|
564
715
|
onPressImage: onPressImage,
|
|
565
716
|
onPressVideo: onPressVideo,
|
|
566
|
-
chosenMediaType:
|
|
567
|
-
onHeightChange: setAttachmentBarHeight
|
|
717
|
+
chosenMediaType: activeMediaType,
|
|
718
|
+
onHeightChange: setAttachmentBarHeight,
|
|
719
|
+
disabled: isMediaCapReached
|
|
568
720
|
});
|
|
569
|
-
}, [
|
|
721
|
+
}, [activeMediaType, editChildrenIncomplete, isMediaCapReached, onPressCamera, onPressImage, onPressVideo, shouldShowDetailAttachment]);
|
|
570
722
|
if (isExcluded) return null;
|
|
571
723
|
return /*#__PURE__*/React.createElement(_reactNativeSafeAreaContext.SafeAreaView, {
|
|
572
724
|
testID: accessibilityId,
|
|
@@ -606,55 +758,22 @@ const AmityPostComposerPage = ({
|
|
|
606
758
|
style: styles.input
|
|
607
759
|
}), /*#__PURE__*/React.createElement(_reactNative.View, {
|
|
608
760
|
style: styles.imageContainer
|
|
609
|
-
}, displayImages.length > 0 && /*#__PURE__*/React.createElement(
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
isUploaded: item.isUploaded,
|
|
626
|
-
fileId: item.fileId,
|
|
627
|
-
fileCount: displayImages.length,
|
|
628
|
-
isEditMode: isEditMode,
|
|
629
|
-
postId: item.postId,
|
|
630
|
-
setIsUploading: setIsUploading
|
|
631
|
-
});
|
|
632
|
-
},
|
|
633
|
-
numColumns: 3
|
|
634
|
-
}), displayVideos.length > 0 && /*#__PURE__*/React.createElement(_reactNative.FlatList, {
|
|
635
|
-
data: displayVideos,
|
|
636
|
-
renderItem: ({
|
|
637
|
-
item,
|
|
638
|
-
index
|
|
639
|
-
}) => {
|
|
640
|
-
if (!item) return null;
|
|
641
|
-
return /*#__PURE__*/React.createElement(_LoadingVideo.default, {
|
|
642
|
-
source: item.url,
|
|
643
|
-
onClose: handleOnCloseVideo,
|
|
644
|
-
index: index //TODO: Fix this without index
|
|
645
|
-
,
|
|
646
|
-
onLoadFinish: handleOnFinishVideo,
|
|
647
|
-
onUploadError: handleVideoUploadError,
|
|
648
|
-
isUploaded: item.isUploaded,
|
|
649
|
-
fileId: item.fileId,
|
|
650
|
-
thumbNail: item.thumbNail,
|
|
651
|
-
fileCount: displayVideos.length,
|
|
652
|
-
isEditMode: isEditMode,
|
|
653
|
-
postId: item.postId,
|
|
654
|
-
setIsUploading: setIsUploading
|
|
655
|
-
});
|
|
656
|
-
},
|
|
657
|
-
numColumns: 3
|
|
761
|
+
}, displayImages.length > 0 && /*#__PURE__*/React.createElement(_SelectedMediaComponent.SelectedMediaComponent, {
|
|
762
|
+
mediaType: "image",
|
|
763
|
+
media: displayImages,
|
|
764
|
+
onClose: handleOnCloseImage,
|
|
765
|
+
onLoadFinish: handleOnFinishImage,
|
|
766
|
+
onUploadError: handleImageUploadError,
|
|
767
|
+
isEditMode: isEditMode,
|
|
768
|
+
onUploadingChange: handleUploadingChange
|
|
769
|
+
}), displayVideos.length > 0 && /*#__PURE__*/React.createElement(_SelectedMediaComponent.SelectedMediaComponent, {
|
|
770
|
+
mediaType: "video",
|
|
771
|
+
media: displayVideos,
|
|
772
|
+
onClose: handleOnCloseVideo,
|
|
773
|
+
onLoadFinish: handleOnFinishVideo,
|
|
774
|
+
onUploadError: handleVideoUploadError,
|
|
775
|
+
isEditMode: isEditMode,
|
|
776
|
+
onUploadingChange: handleUploadingChange
|
|
658
777
|
}))), renderSuggestions({
|
|
659
778
|
type: 'post'
|
|
660
779
|
}), /*#__PURE__*/React.createElement(_reactNative.View, {
|