@sendbird/uikit-react-native 3.5.4 → 3.7.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 +11 -27
- package/lib/commonjs/components/ChannelInput/SendInput.js +23 -6
- package/lib/commonjs/components/ChannelInput/SendInput.js.map +1 -1
- package/lib/commonjs/components/ChannelInput/index.js.map +1 -1
- package/lib/commonjs/components/ChannelMessageList/index.js +22 -4
- package/lib/commonjs/components/ChannelMessageList/index.js.map +1 -1
- package/lib/commonjs/components/ChannelThreadMessageList/index.js +349 -0
- package/lib/commonjs/components/ChannelThreadMessageList/index.js.map +1 -0
- package/lib/commonjs/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.js +2 -2
- package/lib/commonjs/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.js.map +1 -1
- package/lib/commonjs/components/GroupChannelMessageRenderer/GroupChannelMessageReplyInfo.js +100 -0
- package/lib/commonjs/components/GroupChannelMessageRenderer/GroupChannelMessageReplyInfo.js.map +1 -0
- package/lib/commonjs/components/GroupChannelMessageRenderer/index.js +24 -6
- package/lib/commonjs/components/GroupChannelMessageRenderer/index.js.map +1 -1
- package/lib/commonjs/components/ReactionAddons/MessageReactionAddon.js +23 -6
- package/lib/commonjs/components/ReactionAddons/MessageReactionAddon.js.map +1 -1
- package/lib/commonjs/components/ThreadChatFlatList/index.js +76 -0
- package/lib/commonjs/components/ThreadChatFlatList/index.js.map +1 -0
- package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.file.image.js +41 -0
- package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.file.image.js.map +1 -0
- package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.file.js +74 -0
- package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.file.js.map +1 -0
- package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.file.video.js +42 -0
- package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.file.video.js.map +1 -0
- package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.file.voice.js +94 -0
- package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.file.voice.js.map +1 -0
- package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.user.js +61 -0
- package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.user.js.map +1 -0
- package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.user.og.js +127 -0
- package/lib/commonjs/components/ThreadParentMessageRenderer/ThreadParentMessage.user.og.js.map +1 -0
- package/lib/commonjs/components/ThreadParentMessageRenderer/index.js +206 -0
- package/lib/commonjs/components/ThreadParentMessageRenderer/index.js.map +1 -0
- package/lib/commonjs/containers/SendbirdUIKitContainer.js +12 -11
- package/lib/commonjs/containers/SendbirdUIKitContainer.js.map +1 -1
- package/lib/commonjs/contexts/SendbirdChatCtx.js +7 -0
- package/lib/commonjs/contexts/SendbirdChatCtx.js.map +1 -1
- package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js +28 -5
- package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
- package/lib/commonjs/domain/groupChannel/module/moduleContext.js +14 -4
- package/lib/commonjs/domain/groupChannel/module/moduleContext.js.map +1 -1
- package/lib/commonjs/domain/groupChannel/types.js.map +1 -1
- package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadHeader.js +82 -0
- package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadHeader.js.map +1 -0
- package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadInput.js +44 -0
- package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadInput.js.map +1 -0
- package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadMessageList.js +127 -0
- package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadMessageList.js.map +1 -0
- package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadParentMessageInfo.js +315 -0
- package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadParentMessageInfo.js.map +1 -0
- package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadStatusEmpty.js +27 -0
- package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadStatusEmpty.js.map +1 -0
- package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadStatusLoading.js +27 -0
- package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadStatusLoading.js.map +1 -0
- package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadSuggestedMentionList.js +195 -0
- package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadSuggestedMentionList.js.map +1 -0
- package/lib/commonjs/domain/groupChannelThread/index.js +69 -0
- package/lib/commonjs/domain/groupChannelThread/index.js.map +1 -0
- package/lib/commonjs/domain/groupChannelThread/module/createGroupChannelThreadModule.js +42 -0
- package/lib/commonjs/domain/groupChannelThread/module/createGroupChannelThreadModule.js.map +1 -0
- package/lib/commonjs/domain/groupChannelThread/module/moduleContext.js +148 -0
- package/lib/commonjs/domain/groupChannelThread/module/moduleContext.js.map +1 -0
- package/lib/commonjs/domain/groupChannelThread/types.js +6 -0
- package/lib/commonjs/domain/groupChannelThread/types.js.map +1 -0
- package/lib/commonjs/fragments/createGroupChannelFragment.js +30 -5
- package/lib/commonjs/fragments/createGroupChannelFragment.js.map +1 -1
- package/lib/commonjs/fragments/createGroupChannelThreadFragment.js +267 -0
- package/lib/commonjs/fragments/createGroupChannelThreadFragment.js.map +1 -0
- package/lib/commonjs/hooks/useMentionSuggestion.js +5 -2
- package/lib/commonjs/hooks/useMentionSuggestion.js.map +1 -1
- package/lib/commonjs/index.js +72 -40
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/libs/EmojiManager.js.map +1 -1
- package/lib/commonjs/libs/InternalLocalCacheStorage.js +65 -19
- package/lib/commonjs/libs/InternalLocalCacheStorage.js.map +1 -1
- package/lib/commonjs/libs/VoiceMessageStatusManager.js +66 -0
- package/lib/commonjs/libs/VoiceMessageStatusManager.js.map +1 -0
- package/lib/commonjs/localization/StringSet.type.js.map +1 -1
- package/lib/commonjs/localization/createBaseStringSet.js +25 -3
- package/lib/commonjs/localization/createBaseStringSet.js.map +1 -1
- package/lib/commonjs/platform/createMediaService.native.js.map +1 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/version.js +1 -1
- package/lib/commonjs/version.js.map +1 -1
- package/lib/module/components/ChannelInput/SendInput.js +23 -6
- package/lib/module/components/ChannelInput/SendInput.js.map +1 -1
- package/lib/module/components/ChannelInput/index.js.map +1 -1
- package/lib/module/components/ChannelMessageList/index.js +22 -4
- package/lib/module/components/ChannelMessageList/index.js.map +1 -1
- package/lib/module/components/ChannelThreadMessageList/index.js +341 -0
- package/lib/module/components/ChannelThreadMessageList/index.js.map +1 -0
- package/lib/module/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.js +2 -2
- package/lib/module/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.js.map +1 -1
- package/lib/module/components/GroupChannelMessageRenderer/GroupChannelMessageReplyInfo.js +92 -0
- package/lib/module/components/GroupChannelMessageRenderer/GroupChannelMessageReplyInfo.js.map +1 -0
- package/lib/module/components/GroupChannelMessageRenderer/index.js +24 -6
- package/lib/module/components/GroupChannelMessageRenderer/index.js.map +1 -1
- package/lib/module/components/ReactionAddons/MessageReactionAddon.js +23 -6
- package/lib/module/components/ReactionAddons/MessageReactionAddon.js.map +1 -1
- package/lib/module/components/ThreadChatFlatList/index.js +66 -0
- package/lib/module/components/ThreadChatFlatList/index.js.map +1 -0
- package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.file.image.js +34 -0
- package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.file.image.js.map +1 -0
- package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.file.js +67 -0
- package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.file.js.map +1 -0
- package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.file.video.js +34 -0
- package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.file.video.js.map +1 -0
- package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.file.voice.js +87 -0
- package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.file.voice.js.map +1 -0
- package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.user.js +54 -0
- package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.user.js.map +1 -0
- package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.user.og.js +119 -0
- package/lib/module/components/ThreadParentMessageRenderer/ThreadParentMessage.user.og.js.map +1 -0
- package/lib/module/components/ThreadParentMessageRenderer/index.js +196 -0
- package/lib/module/components/ThreadParentMessageRenderer/index.js.map +1 -0
- package/lib/module/containers/SendbirdUIKitContainer.js +13 -12
- package/lib/module/containers/SendbirdUIKitContainer.js.map +1 -1
- package/lib/module/contexts/SendbirdChatCtx.js +6 -0
- package/lib/module/contexts/SendbirdChatCtx.js.map +1 -1
- package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js +30 -6
- package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
- package/lib/module/domain/groupChannel/module/moduleContext.js +14 -4
- package/lib/module/domain/groupChannel/module/moduleContext.js.map +1 -1
- package/lib/module/domain/groupChannel/types.js.map +1 -1
- package/lib/module/domain/groupChannelThread/component/GroupChannelThreadHeader.js +73 -0
- package/lib/module/domain/groupChannelThread/component/GroupChannelThreadHeader.js.map +1 -0
- package/lib/module/domain/groupChannelThread/component/GroupChannelThreadInput.js +34 -0
- package/lib/module/domain/groupChannelThread/component/GroupChannelThreadInput.js.map +1 -0
- package/lib/module/domain/groupChannelThread/component/GroupChannelThreadMessageList.js +117 -0
- package/lib/module/domain/groupChannelThread/component/GroupChannelThreadMessageList.js.map +1 -0
- package/lib/module/domain/groupChannelThread/component/GroupChannelThreadParentMessageInfo.js +305 -0
- package/lib/module/domain/groupChannelThread/component/GroupChannelThreadParentMessageInfo.js.map +1 -0
- package/lib/module/domain/groupChannelThread/component/GroupChannelThreadStatusEmpty.js +19 -0
- package/lib/module/domain/groupChannelThread/component/GroupChannelThreadStatusEmpty.js.map +1 -0
- package/lib/module/domain/groupChannelThread/component/GroupChannelThreadStatusLoading.js +19 -0
- package/lib/module/domain/groupChannelThread/component/GroupChannelThreadStatusLoading.js.map +1 -0
- package/lib/module/domain/groupChannelThread/component/GroupChannelThreadSuggestedMentionList.js +185 -0
- package/lib/module/domain/groupChannelThread/component/GroupChannelThreadSuggestedMentionList.js.map +1 -0
- package/lib/module/domain/groupChannelThread/index.js +9 -0
- package/lib/module/domain/groupChannelThread/index.js.map +1 -0
- package/lib/module/domain/groupChannelThread/module/createGroupChannelThreadModule.js +34 -0
- package/lib/module/domain/groupChannelThread/module/createGroupChannelThreadModule.js.map +1 -0
- package/lib/module/domain/groupChannelThread/module/moduleContext.js +137 -0
- package/lib/module/domain/groupChannelThread/module/moduleContext.js.map +1 -0
- package/lib/module/domain/groupChannelThread/types.js +2 -0
- package/lib/module/domain/groupChannelThread/types.js.map +1 -0
- package/lib/module/fragments/createGroupChannelFragment.js +33 -7
- package/lib/module/fragments/createGroupChannelFragment.js.map +1 -1
- package/lib/module/fragments/createGroupChannelThreadFragment.js +257 -0
- package/lib/module/fragments/createGroupChannelThreadFragment.js.map +1 -0
- package/lib/module/hooks/useMentionSuggestion.js +5 -2
- package/lib/module/hooks/useMentionSuggestion.js.map +1 -1
- package/lib/module/index.js +3 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/libs/EmojiManager.js.map +1 -1
- package/lib/module/libs/InternalLocalCacheStorage.js +65 -19
- package/lib/module/libs/InternalLocalCacheStorage.js.map +1 -1
- package/lib/module/libs/VoiceMessageStatusManager.js +59 -0
- package/lib/module/libs/VoiceMessageStatusManager.js.map +1 -0
- package/lib/module/localization/StringSet.type.js.map +1 -1
- package/lib/module/localization/createBaseStringSet.js +27 -4
- package/lib/module/localization/createBaseStringSet.js.map +1 -1
- package/lib/module/platform/createMediaService.native.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/module/version.js +1 -1
- package/lib/module/version.js.map +1 -1
- package/lib/typescript/src/components/ChannelInput/index.d.ts +1 -0
- package/lib/typescript/src/components/ChannelMessageList/index.d.ts +5 -2
- package/lib/typescript/src/components/ChannelThreadMessageList/index.d.ts +55 -0
- package/lib/typescript/src/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.d.ts +1 -1
- package/lib/typescript/src/components/GroupChannelMessageRenderer/GroupChannelMessageReplyInfo.d.ts +9 -0
- package/lib/typescript/src/components/GroupChannelMessageRenderer/index.d.ts +3 -1
- package/lib/typescript/src/components/OpenChannelMessageRenderer/index.d.ts +3 -1
- package/lib/typescript/src/components/ReactionAddons/MessageReactionAddon.d.ts +3 -1
- package/lib/typescript/src/components/ReactionAddons/index.d.ts +2 -1
- package/lib/typescript/src/components/ThreadChatFlatList/index.d.ts +9 -0
- package/lib/typescript/src/components/ThreadParentMessageRenderer/ThreadParentMessage.file.d.ts +4 -0
- package/lib/typescript/src/components/ThreadParentMessageRenderer/ThreadParentMessage.file.image.d.ts +4 -0
- package/lib/typescript/src/components/ThreadParentMessageRenderer/ThreadParentMessage.file.video.d.ts +9 -0
- package/lib/typescript/src/components/ThreadParentMessageRenderer/ThreadParentMessage.file.voice.d.ts +13 -0
- package/lib/typescript/src/components/ThreadParentMessageRenderer/ThreadParentMessage.user.d.ts +10 -0
- package/lib/typescript/src/components/ThreadParentMessageRenderer/ThreadParentMessage.user.og.d.ts +10 -0
- package/lib/typescript/src/components/ThreadParentMessageRenderer/index.d.ts +20 -0
- package/lib/typescript/src/containers/SendbirdUIKitContainer.d.ts +8 -10
- package/lib/typescript/src/contexts/SendbirdChatCtx.d.ts +15 -1
- package/lib/typescript/src/domain/groupChannel/types.d.ts +4 -1
- package/lib/typescript/src/domain/groupChannelThread/component/GroupChannelThreadHeader.d.ts +4 -0
- package/lib/typescript/src/domain/groupChannelThread/component/GroupChannelThreadInput.d.ts +3 -0
- package/lib/typescript/src/domain/groupChannelThread/component/GroupChannelThreadMessageList.d.ts +7 -0
- package/lib/typescript/src/domain/groupChannelThread/component/GroupChannelThreadParentMessageInfo.d.ts +8 -0
- package/lib/typescript/src/domain/groupChannelThread/component/GroupChannelThreadStatusEmpty.d.ts +3 -0
- package/lib/typescript/src/domain/groupChannelThread/component/GroupChannelThreadStatusLoading.d.ts +3 -0
- package/lib/typescript/src/domain/groupChannelThread/component/GroupChannelThreadSuggestedMentionList.d.ts +4 -0
- package/lib/typescript/src/domain/groupChannelThread/index.d.ts +8 -0
- package/lib/typescript/src/domain/groupChannelThread/module/createGroupChannelThreadModule.d.ts +3 -0
- package/lib/typescript/src/domain/groupChannelThread/module/moduleContext.d.ts +3 -0
- package/lib/typescript/src/domain/groupChannelThread/types.d.ts +136 -0
- package/lib/typescript/src/domain/openChannel/component/OpenChannelHeader.d.ts +1 -1
- package/lib/typescript/src/fragments/createGroupChannelThreadFragment.d.ts +5 -0
- package/lib/typescript/src/hooks/useChannelInputItems.d.ts +1 -1
- package/lib/typescript/src/index.d.ts +3 -0
- package/lib/typescript/src/libs/InternalLocalCacheStorage.d.ts +5 -4
- package/lib/typescript/src/libs/VoiceMessageStatusManager.d.ts +11 -0
- package/lib/typescript/src/localization/StringSet.type.d.ts +23 -0
- package/lib/typescript/src/localization/createBaseStringSet.d.ts +1 -1
- package/lib/typescript/src/types.d.ts +4 -1
- package/lib/typescript/src/version.d.ts +1 -1
- package/package.json +27 -22
- package/src/components/ChannelInput/SendInput.tsx +24 -5
- package/src/components/ChannelInput/index.tsx +1 -0
- package/src/components/ChannelMessageList/index.tsx +27 -5
- package/src/components/ChannelThreadMessageList/index.tsx +406 -0
- package/src/components/GroupChannelMessageRenderer/GroupChannelMessageParentMessage.tsx +3 -3
- package/src/components/GroupChannelMessageRenderer/GroupChannelMessageReplyInfo.tsx +96 -0
- package/src/components/GroupChannelMessageRenderer/index.tsx +21 -5
- package/src/components/ReactionAddons/MessageReactionAddon.tsx +38 -5
- package/src/components/ThreadChatFlatList/index.tsx +63 -0
- package/src/components/ThreadParentMessageRenderer/ThreadParentMessage.file.image.tsx +36 -0
- package/src/components/ThreadParentMessageRenderer/ThreadParentMessage.file.tsx +61 -0
- package/src/components/ThreadParentMessageRenderer/ThreadParentMessage.file.video.tsx +45 -0
- package/src/components/ThreadParentMessageRenderer/ThreadParentMessage.file.voice.tsx +107 -0
- package/src/components/ThreadParentMessageRenderer/ThreadParentMessage.user.og.tsx +133 -0
- package/src/components/ThreadParentMessageRenderer/ThreadParentMessage.user.tsx +65 -0
- package/src/components/ThreadParentMessageRenderer/index.tsx +194 -0
- package/src/containers/SendbirdUIKitContainer.tsx +28 -17
- package/src/contexts/SendbirdChatCtx.tsx +20 -0
- package/src/domain/groupChannel/component/GroupChannelMessageList.tsx +37 -8
- package/src/domain/groupChannel/module/moduleContext.tsx +12 -2
- package/src/domain/groupChannel/types.ts +5 -0
- package/src/domain/groupChannelThread/component/GroupChannelThreadHeader.tsx +63 -0
- package/src/domain/groupChannelThread/component/GroupChannelThreadInput.tsx +38 -0
- package/src/domain/groupChannelThread/component/GroupChannelThreadMessageList.tsx +105 -0
- package/src/domain/groupChannelThread/component/GroupChannelThreadParentMessageInfo.tsx +326 -0
- package/src/domain/groupChannelThread/component/GroupChannelThreadStatusEmpty.tsx +18 -0
- package/src/domain/groupChannelThread/component/GroupChannelThreadStatusLoading.tsx +18 -0
- package/src/domain/groupChannelThread/component/GroupChannelThreadSuggestedMentionList.tsx +174 -0
- package/src/domain/groupChannelThread/index.ts +8 -0
- package/src/domain/groupChannelThread/module/createGroupChannelThreadModule.tsx +35 -0
- package/src/domain/groupChannelThread/module/moduleContext.tsx +165 -0
- package/src/domain/groupChannelThread/types.ts +184 -0
- package/src/fragments/createGroupChannelFragment.tsx +38 -8
- package/src/fragments/createGroupChannelThreadFragment.tsx +280 -0
- package/src/hooks/useMentionSuggestion.ts +13 -9
- package/src/index.ts +4 -0
- package/src/libs/EmojiManager.ts +2 -2
- package/src/libs/InternalLocalCacheStorage.ts +70 -21
- package/src/libs/VoiceMessageStatusManager.ts +56 -0
- package/src/localization/StringSet.type.ts +27 -0
- package/src/localization/createBaseStringSet.ts +33 -4
- package/src/platform/createMediaService.native.tsx +9 -1
- package/src/types.ts +6 -1
- package/src/version.ts +1 -1
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import React, { useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
import { RegexTextPattern, Text, useUIKitTheme } from '@sendbird/uikit-react-native-foundation';
|
|
4
|
+
import {
|
|
5
|
+
SendbirdFileMessage,
|
|
6
|
+
type SendbirdUser,
|
|
7
|
+
SendbirdUserMessage,
|
|
8
|
+
getMessageType,
|
|
9
|
+
isMyMessage,
|
|
10
|
+
isVoiceMessage,
|
|
11
|
+
} from '@sendbird/uikit-utils';
|
|
12
|
+
|
|
13
|
+
import { VOICE_MESSAGE_META_ARRAY_DURATION_KEY } from '../../constants';
|
|
14
|
+
import SBUUtils from '../../libs/SBUUtils';
|
|
15
|
+
import { usePlatformService, useSendbirdChat } from './../../hooks/useContext';
|
|
16
|
+
import ThreadParentMessageFile from './ThreadParentMessage.file';
|
|
17
|
+
import ThreadParentMessageFileImage from './ThreadParentMessage.file.image';
|
|
18
|
+
import ThreadParentMessageFileVideo from './ThreadParentMessage.file.video';
|
|
19
|
+
import ThreadParentMessageFileVoice, { VoiceFileMessageState } from './ThreadParentMessage.file.voice';
|
|
20
|
+
import ThreadParentMessageUser from './ThreadParentMessage.user';
|
|
21
|
+
import ThreadParentMessageUserOg from './ThreadParentMessage.user.og';
|
|
22
|
+
|
|
23
|
+
export type ThreadParentMessageRendererProps<AdditionalProps = unknown> = {
|
|
24
|
+
parentMessage: SendbirdUserMessage | SendbirdFileMessage;
|
|
25
|
+
onPress?: () => void;
|
|
26
|
+
onLongPress?: () => void;
|
|
27
|
+
onPressURL?: (url: string) => void;
|
|
28
|
+
onPressMentionedUser?: (mentionedUser?: SendbirdUser) => void;
|
|
29
|
+
onToggleVoiceMessage?: (
|
|
30
|
+
state: VoiceFileMessageState,
|
|
31
|
+
setState: React.Dispatch<React.SetStateAction<VoiceFileMessageState>>,
|
|
32
|
+
) => Promise<void>;
|
|
33
|
+
} & AdditionalProps;
|
|
34
|
+
|
|
35
|
+
const ThreadParentMessageRenderer = (props: ThreadParentMessageRendererProps) => {
|
|
36
|
+
const playerUnsubscribes = useRef<(() => void)[]>([]);
|
|
37
|
+
const { sbOptions, currentUser, mentionManager } = useSendbirdChat();
|
|
38
|
+
const { palette } = useUIKitTheme();
|
|
39
|
+
const { mediaService, playerService } = usePlatformService();
|
|
40
|
+
const parentMessage = props.parentMessage;
|
|
41
|
+
|
|
42
|
+
const resetPlayer = async () => {
|
|
43
|
+
playerUnsubscribes.current.forEach((unsubscribe) => {
|
|
44
|
+
try {
|
|
45
|
+
unsubscribe();
|
|
46
|
+
} catch {}
|
|
47
|
+
});
|
|
48
|
+
playerUnsubscribes.current.length = 0;
|
|
49
|
+
await playerService.reset();
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const messageProps: ThreadParentMessageRendererProps = {
|
|
53
|
+
onPressURL: (url) => SBUUtils.openURL(url),
|
|
54
|
+
onToggleVoiceMessage: async (state, setState) => {
|
|
55
|
+
if (isVoiceMessage(parentMessage) && parentMessage.sendingStatus === 'succeeded') {
|
|
56
|
+
if (playerService.uri === parentMessage.url) {
|
|
57
|
+
if (playerService.state === 'playing') {
|
|
58
|
+
await playerService.pause();
|
|
59
|
+
} else {
|
|
60
|
+
await playerService.play(parentMessage.url);
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
if (playerService.state !== 'idle') {
|
|
64
|
+
await resetPlayer();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const shouldSeekToTime = state.duration > state.currentTime && state.currentTime > 0;
|
|
68
|
+
let seekFinished = !shouldSeekToTime;
|
|
69
|
+
|
|
70
|
+
const forPlayback = playerService.addPlaybackListener(({ stopped, currentTime, duration }) => {
|
|
71
|
+
if (seekFinished) {
|
|
72
|
+
setState((prevState) => ({ ...prevState, currentTime: stopped ? 0 : currentTime, duration }));
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
const forState = playerService.addStateListener((state) => {
|
|
76
|
+
switch (state) {
|
|
77
|
+
case 'preparing':
|
|
78
|
+
setState((prevState) => ({ ...prevState, status: 'preparing' }));
|
|
79
|
+
break;
|
|
80
|
+
case 'playing':
|
|
81
|
+
setState((prevState) => ({ ...prevState, status: 'playing' }));
|
|
82
|
+
break;
|
|
83
|
+
case 'idle':
|
|
84
|
+
case 'paused': {
|
|
85
|
+
setState((prevState) => ({ ...prevState, status: 'paused' }));
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case 'stopped':
|
|
89
|
+
setState((prevState) => ({ ...prevState, status: 'paused' }));
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
playerUnsubscribes.current.push(forPlayback, forState);
|
|
94
|
+
|
|
95
|
+
await playerService.play(parentMessage.url);
|
|
96
|
+
if (shouldSeekToTime) {
|
|
97
|
+
await playerService.seek(state.currentTime);
|
|
98
|
+
seekFinished = true;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
...props,
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const userMessageProps: {
|
|
107
|
+
renderRegexTextChildren: (message: SendbirdUserMessage) => string;
|
|
108
|
+
regexTextPatterns: RegexTextPattern[];
|
|
109
|
+
} = {
|
|
110
|
+
renderRegexTextChildren: (message) => {
|
|
111
|
+
if (
|
|
112
|
+
mentionManager.shouldUseMentionedMessageTemplate(message, sbOptions.uikit.groupChannel.channel.enableMention)
|
|
113
|
+
) {
|
|
114
|
+
return message.mentionedMessageTemplate;
|
|
115
|
+
} else {
|
|
116
|
+
return message.message;
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
regexTextPatterns: [
|
|
120
|
+
{
|
|
121
|
+
regex: mentionManager.templateRegex,
|
|
122
|
+
replacer({ match, groups, parentProps, index, keyPrefix }) {
|
|
123
|
+
const user = parentMessage.mentionedUsers?.find((it) => it.userId === groups[2]);
|
|
124
|
+
if (user) {
|
|
125
|
+
const mentionColor =
|
|
126
|
+
!isMyMessage(parentMessage, currentUser?.userId) && user.userId === currentUser?.userId
|
|
127
|
+
? palette.onBackgroundLight01
|
|
128
|
+
: parentProps?.color;
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<Text
|
|
132
|
+
{...parentProps}
|
|
133
|
+
key={`${keyPrefix}-${index}`}
|
|
134
|
+
color={mentionColor}
|
|
135
|
+
onPress={() => messageProps.onPressMentionedUser?.(user)}
|
|
136
|
+
onLongPress={messageProps.onLongPress}
|
|
137
|
+
style={[
|
|
138
|
+
parentProps?.style,
|
|
139
|
+
{ fontWeight: '700' },
|
|
140
|
+
user.userId === currentUser?.userId && { backgroundColor: palette.highlight },
|
|
141
|
+
]}
|
|
142
|
+
>
|
|
143
|
+
{`${mentionManager.asMentionedMessageText(user)}`}
|
|
144
|
+
</Text>
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
return match;
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
switch (getMessageType(props.parentMessage)) {
|
|
154
|
+
case 'user': {
|
|
155
|
+
return <ThreadParentMessageUser {...userMessageProps} {...messageProps} />;
|
|
156
|
+
}
|
|
157
|
+
case 'user.opengraph': {
|
|
158
|
+
return <ThreadParentMessageUserOg {...userMessageProps} {...messageProps} />;
|
|
159
|
+
}
|
|
160
|
+
case 'file':
|
|
161
|
+
case 'file.audio': {
|
|
162
|
+
return <ThreadParentMessageFile {...messageProps} />;
|
|
163
|
+
}
|
|
164
|
+
case 'file.video': {
|
|
165
|
+
return (
|
|
166
|
+
<ThreadParentMessageFileVideo
|
|
167
|
+
fetchThumbnailFromVideoSource={(uri) => mediaService.getVideoThumbnail({ url: uri, timeMills: 1000 })}
|
|
168
|
+
{...messageProps}
|
|
169
|
+
/>
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
case 'file.image': {
|
|
173
|
+
return <ThreadParentMessageFileImage {...messageProps} />;
|
|
174
|
+
}
|
|
175
|
+
case 'file.voice': {
|
|
176
|
+
return (
|
|
177
|
+
<ThreadParentMessageFileVoice
|
|
178
|
+
durationMetaArrayKey={VOICE_MESSAGE_META_ARRAY_DURATION_KEY}
|
|
179
|
+
onUnmount={() => {
|
|
180
|
+
if (isVoiceMessage(parentMessage) && playerService.uri === parentMessage.url) {
|
|
181
|
+
resetPlayer();
|
|
182
|
+
}
|
|
183
|
+
}}
|
|
184
|
+
{...messageProps}
|
|
185
|
+
/>
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
default: {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
export default React.memo(ThreadParentMessageRenderer);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import type { AsyncStorageStatic } from '@react-native-async-storage/async-storage';
|
|
1
2
|
import React, { useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
2
3
|
import { Platform } from 'react-native';
|
|
4
|
+
import type { MMKV } from 'react-native-mmkv';
|
|
3
5
|
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
4
6
|
|
|
5
7
|
import SendbirdChat, { DeviceOsPlatform, SendbirdChatParams, SendbirdPlatform, SendbirdProduct } from '@sendbird/chat';
|
|
@@ -15,15 +17,17 @@ import {
|
|
|
15
17
|
UIKitThemeProvider,
|
|
16
18
|
} from '@sendbird/uikit-react-native-foundation';
|
|
17
19
|
import { SBUConfig, UIKitConfigProvider } from '@sendbird/uikit-tools';
|
|
18
|
-
import
|
|
20
|
+
import {
|
|
21
|
+
Logger,
|
|
22
|
+
NOOP,
|
|
19
23
|
PartialDeep,
|
|
20
24
|
SendbirdChatSDK,
|
|
21
25
|
SendbirdGroupChannel,
|
|
22
26
|
SendbirdGroupChannelCreateParams,
|
|
23
27
|
SendbirdMember,
|
|
24
28
|
SendbirdUser,
|
|
29
|
+
useIsFirstMount,
|
|
25
30
|
} from '@sendbird/uikit-utils';
|
|
26
|
-
import { NOOP, useIsFirstMount } from '@sendbird/uikit-utils';
|
|
27
31
|
|
|
28
32
|
import { LocalizationContext, LocalizationProvider } from '../contexts/LocalizationCtx';
|
|
29
33
|
import { PlatformServiceProvider } from '../contexts/PlatformServiceCtx';
|
|
@@ -38,6 +42,7 @@ import InternalLocalCacheStorage from '../libs/InternalLocalCacheStorage';
|
|
|
38
42
|
import MentionConfig, { MentionConfigInterface } from '../libs/MentionConfig';
|
|
39
43
|
import MentionManager from '../libs/MentionManager';
|
|
40
44
|
import VoiceMessageConfig, { VoiceMessageConfigInterface } from '../libs/VoiceMessageConfig';
|
|
45
|
+
import VoiceMessageStatusManager from '../libs/VoiceMessageStatusManager';
|
|
41
46
|
import StringSetEn from '../localization/StringSet.en';
|
|
42
47
|
import type { StringSet } from '../localization/StringSet.type';
|
|
43
48
|
import SBUDynamicModule from '../platform/dynamicModule';
|
|
@@ -49,7 +54,7 @@ import type {
|
|
|
49
54
|
PlayerServiceInterface,
|
|
50
55
|
RecorderServiceInterface,
|
|
51
56
|
} from '../platform/types';
|
|
52
|
-
import
|
|
57
|
+
import { ErrorBoundaryProps, LocalCacheStorage } from '../types';
|
|
53
58
|
import VERSION from '../version';
|
|
54
59
|
import InternalErrorBoundaryContainer from './InternalErrorBoundaryContainer';
|
|
55
60
|
|
|
@@ -64,7 +69,6 @@ export const SendbirdUIKit = Object.freeze({
|
|
|
64
69
|
},
|
|
65
70
|
});
|
|
66
71
|
|
|
67
|
-
type UnimplementedFeatures = 'threadReplySelectType' | 'replyType' | 'enableReactionsSupergroup';
|
|
68
72
|
export type ChatOmittedInitParams = Omit<
|
|
69
73
|
SendbirdChatParams<[GroupChannelModule, OpenChannelModule]>,
|
|
70
74
|
(typeof chatOmitKeys)[number]
|
|
@@ -78,13 +82,13 @@ const chatOmitKeys = [
|
|
|
78
82
|
'appVersion',
|
|
79
83
|
'localCacheEnabled',
|
|
80
84
|
'useAsyncStorageStore',
|
|
85
|
+
'useMMKVStorageStore',
|
|
81
86
|
] as const;
|
|
82
87
|
function sanitizeChatOptions<T extends Record<string, unknown>>(chatOptions: T): T {
|
|
83
88
|
const opts = { ...chatOptions };
|
|
84
89
|
chatOmitKeys.forEach((key) => delete opts[key]);
|
|
85
90
|
return opts;
|
|
86
91
|
}
|
|
87
|
-
|
|
88
92
|
export type SendbirdUIKitContainerProps = React.PropsWithChildren<{
|
|
89
93
|
appId: string;
|
|
90
94
|
platformServices: {
|
|
@@ -95,15 +99,14 @@ export type SendbirdUIKitContainerProps = React.PropsWithChildren<{
|
|
|
95
99
|
player: PlayerServiceInterface;
|
|
96
100
|
recorder: RecorderServiceInterface;
|
|
97
101
|
};
|
|
98
|
-
chatOptions:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
chatOptions: Partial<ChatOmittedInitParams> &
|
|
103
|
+
Partial<ChatRelatedFeaturesInUIKit> & {
|
|
104
|
+
onInitialized?: (sdkInstance: SendbirdChatSDK) => SendbirdChatSDK;
|
|
105
|
+
localCacheStorage: LocalCacheStorage;
|
|
106
|
+
};
|
|
103
107
|
uikitOptions?: PartialDeep<{
|
|
104
108
|
common: SBUConfig['common'];
|
|
105
|
-
groupChannel: Omit<SBUConfig['groupChannel']['channel'],
|
|
106
|
-
replyType: Extract<SBUConfig['groupChannel']['channel']['replyType'], 'none' | 'quote_reply'>;
|
|
109
|
+
groupChannel: Omit<SBUConfig['groupChannel']['channel'], 'enableReactionsSupergroup'> & {
|
|
107
110
|
/**
|
|
108
111
|
* @deprecated Currently, this feature is turned off by default. If you wish to use this feature, contact us: {@link https://dashboard.sendbird.com/settings/contact_us?category=feedback_and_feature_requests&product=UIKit}
|
|
109
112
|
*/
|
|
@@ -163,6 +166,10 @@ const SendbirdUIKitContainer = (props: SendbirdUIKitContainerProps) => {
|
|
|
163
166
|
|
|
164
167
|
if (!chatOptions.localCacheStorage) {
|
|
165
168
|
throw new Error('SendbirdUIKitContainer: chatOptions.localCacheStorage is required');
|
|
169
|
+
} else if ('getItem' in chatOptions.localCacheStorage) {
|
|
170
|
+
Logger.warn(
|
|
171
|
+
'SendbirdUIKitContainer: localCacheStorage for `AsyncStorage` is deprecated. Please use `MMKV` instead.',
|
|
172
|
+
);
|
|
166
173
|
}
|
|
167
174
|
|
|
168
175
|
const defaultStringSet = localization?.stringSet ?? StringSetEn;
|
|
@@ -172,7 +179,7 @@ const SendbirdUIKitContainer = (props: SendbirdUIKitContainerProps) => {
|
|
|
172
179
|
|
|
173
180
|
const [internalStorage] = useState(() => new InternalLocalCacheStorage(chatOptions.localCacheStorage));
|
|
174
181
|
const [sdkInstance, setSdkInstance] = useState<SendbirdChatSDK>(() => {
|
|
175
|
-
const sendbird = initializeSendbird(appId,
|
|
182
|
+
const sendbird = initializeSendbird(appId, sanitizeChatOptions(chatOptions));
|
|
176
183
|
unsubscribes.current = sendbird.unsubscribes;
|
|
177
184
|
return sendbird.chatSDK;
|
|
178
185
|
});
|
|
@@ -180,10 +187,11 @@ const SendbirdUIKitContainer = (props: SendbirdUIKitContainerProps) => {
|
|
|
180
187
|
const { imageCompressionConfig, voiceMessageConfig, mentionConfig } = useConfigInstance(props);
|
|
181
188
|
const emojiManager = useMemo(() => new EmojiManager(internalStorage), [internalStorage]);
|
|
182
189
|
const mentionManager = useMemo(() => new MentionManager(mentionConfig), [mentionConfig]);
|
|
190
|
+
const voiceMessageStatusManager = useMemo(() => new VoiceMessageStatusManager(), []);
|
|
183
191
|
|
|
184
192
|
useLayoutEffect(() => {
|
|
185
193
|
if (!isFirstMount) {
|
|
186
|
-
const sendbird = initializeSendbird(appId,
|
|
194
|
+
const sendbird = initializeSendbird(appId, sanitizeChatOptions(chatOptions));
|
|
187
195
|
setSdkInstance(sendbird.chatSDK);
|
|
188
196
|
unsubscribes.current = sendbird.unsubscribes;
|
|
189
197
|
}
|
|
@@ -227,6 +235,7 @@ const SendbirdUIKitContainer = (props: SendbirdUIKitContainerProps) => {
|
|
|
227
235
|
mentionManager={mentionManager}
|
|
228
236
|
imageCompressionConfig={imageCompressionConfig}
|
|
229
237
|
voiceMessageConfig={voiceMessageConfig}
|
|
238
|
+
voiceMessageStatusManager={voiceMessageStatusManager}
|
|
230
239
|
enableAutoPushTokenRegistration={
|
|
231
240
|
chatOptions.enableAutoPushTokenRegistration ?? SendbirdUIKit.DEFAULT.AUTO_PUSH_TOKEN_REGISTRATION
|
|
232
241
|
}
|
|
@@ -287,21 +296,23 @@ const SendbirdUIKitContainer = (props: SendbirdUIKitContainerProps) => {
|
|
|
287
296
|
};
|
|
288
297
|
|
|
289
298
|
interface InitOptions extends ChatOmittedInitParams {
|
|
290
|
-
|
|
299
|
+
localCacheStorage: LocalCacheStorage;
|
|
291
300
|
onInitialized?: (sdk: SendbirdChatSDK) => SendbirdChatSDK;
|
|
292
301
|
}
|
|
293
302
|
const initializeSendbird = (appId: string, options: InitOptions) => {
|
|
294
303
|
let chatSDK: SendbirdChatSDK;
|
|
295
304
|
const unsubscribes: Array<() => void> = [];
|
|
296
|
-
const {
|
|
305
|
+
const { localCacheStorage, onInitialized, ...chatInitParams } = options;
|
|
297
306
|
|
|
307
|
+
const isMMKVStorage = 'getString' in localCacheStorage;
|
|
298
308
|
chatSDK = SendbirdChat.init({
|
|
299
309
|
...chatInitParams,
|
|
300
310
|
appId,
|
|
301
311
|
newInstance: true,
|
|
302
312
|
modules: [new GroupChannelModule(), new OpenChannelModule()],
|
|
303
313
|
localCacheEnabled: true,
|
|
304
|
-
|
|
314
|
+
useMMKVStorageStore: isMMKVStorage ? (localCacheStorage as MMKV) : undefined,
|
|
315
|
+
useAsyncStorageStore: !isMMKVStorage ? (localCacheStorage as AsyncStorageStatic) : undefined,
|
|
305
316
|
});
|
|
306
317
|
|
|
307
318
|
if (onInitialized) {
|
|
@@ -14,7 +14,9 @@ import type EmojiManager from '../libs/EmojiManager';
|
|
|
14
14
|
import type ImageCompressionConfig from '../libs/ImageCompressionConfig';
|
|
15
15
|
import type MentionManager from '../libs/MentionManager';
|
|
16
16
|
import type VoiceMessageConfig from '../libs/VoiceMessageConfig';
|
|
17
|
+
import VoiceMessageStatusManager from '../libs/VoiceMessageStatusManager';
|
|
17
18
|
import type { FileType } from '../platform/types';
|
|
19
|
+
import pubsub, { type PubSub } from '../utils/pubsub';
|
|
18
20
|
|
|
19
21
|
export interface ChatRelatedFeaturesInUIKit {
|
|
20
22
|
enableAutoPushTokenRegistration: boolean;
|
|
@@ -27,10 +29,18 @@ interface Props extends ChatRelatedFeaturesInUIKit, React.PropsWithChildren {
|
|
|
27
29
|
|
|
28
30
|
emojiManager: EmojiManager;
|
|
29
31
|
mentionManager: MentionManager;
|
|
32
|
+
voiceMessageStatusManager: VoiceMessageStatusManager;
|
|
30
33
|
imageCompressionConfig: ImageCompressionConfig;
|
|
31
34
|
voiceMessageConfig: VoiceMessageConfig;
|
|
32
35
|
}
|
|
33
36
|
|
|
37
|
+
export type GroupChannelFragmentOptionsPubSubContextPayload = {
|
|
38
|
+
type: 'OVERRIDE_SEARCH_ITEM_STARTING_POINT';
|
|
39
|
+
data: {
|
|
40
|
+
startingPoint: number;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
|
|
34
44
|
export type SendbirdChatContextType = {
|
|
35
45
|
sdk: SendbirdChatSDK;
|
|
36
46
|
currentUser?: SendbirdUser;
|
|
@@ -39,6 +49,7 @@ export type SendbirdChatContextType = {
|
|
|
39
49
|
// feature related instances
|
|
40
50
|
emojiManager: EmojiManager;
|
|
41
51
|
mentionManager: MentionManager;
|
|
52
|
+
voiceMessageStatusManager: VoiceMessageStatusManager;
|
|
42
53
|
imageCompressionConfig: ImageCompressionConfig;
|
|
43
54
|
voiceMessageConfig: VoiceMessageConfig;
|
|
44
55
|
|
|
@@ -46,6 +57,9 @@ export type SendbirdChatContextType = {
|
|
|
46
57
|
updateCurrentUserInfo: (nickname?: string, profile?: string | FileType) => Promise<SendbirdUser>;
|
|
47
58
|
markAsDeliveredWithChannel: (channel: SendbirdGroupChannel) => void;
|
|
48
59
|
|
|
60
|
+
groupChannelFragmentOptions: {
|
|
61
|
+
pubsub: PubSub<GroupChannelFragmentOptionsPubSubContextPayload>;
|
|
62
|
+
};
|
|
49
63
|
sbOptions: {
|
|
50
64
|
// UIKit options
|
|
51
65
|
uikit: SBUConfig;
|
|
@@ -80,6 +94,7 @@ export type SendbirdChatContextType = {
|
|
|
80
94
|
broadcastChannelEnabled: boolean;
|
|
81
95
|
superGroupChannelEnabled: boolean;
|
|
82
96
|
reactionEnabled: boolean;
|
|
97
|
+
uploadSizeLimit: number | undefined;
|
|
83
98
|
};
|
|
84
99
|
};
|
|
85
100
|
};
|
|
@@ -90,6 +105,7 @@ export const SendbirdChatProvider = ({
|
|
|
90
105
|
sdkInstance,
|
|
91
106
|
emojiManager,
|
|
92
107
|
mentionManager,
|
|
108
|
+
voiceMessageStatusManager,
|
|
93
109
|
imageCompressionConfig,
|
|
94
110
|
voiceMessageConfig,
|
|
95
111
|
enableAutoPushTokenRegistration,
|
|
@@ -164,11 +180,15 @@ export const SendbirdChatProvider = ({
|
|
|
164
180
|
mentionManager,
|
|
165
181
|
imageCompressionConfig,
|
|
166
182
|
voiceMessageConfig,
|
|
183
|
+
voiceMessageStatusManager,
|
|
167
184
|
currentUser,
|
|
168
185
|
setCurrentUser,
|
|
169
186
|
|
|
170
187
|
updateCurrentUserInfo,
|
|
171
188
|
markAsDeliveredWithChannel,
|
|
189
|
+
groupChannelFragmentOptions: {
|
|
190
|
+
pubsub: pubsub<GroupChannelFragmentOptionsPubSubContextPayload>(),
|
|
191
|
+
},
|
|
172
192
|
|
|
173
193
|
// TODO: Options should be moved to the common area at the higher level to be passed to the context of each product.
|
|
174
194
|
// For example, common -> chat context, common -> calls context
|
|
@@ -2,11 +2,12 @@ import React, { useContext, useEffect } from 'react';
|
|
|
2
2
|
|
|
3
3
|
import { useChannelHandler } from '@sendbird/uikit-chat-hooks';
|
|
4
4
|
import { useToast } from '@sendbird/uikit-react-native-foundation';
|
|
5
|
-
import
|
|
6
|
-
import { isDifferentChannel, useFreshCallback,
|
|
5
|
+
import { SendbirdMessage, SendbirdSendableMessage, useIsFirstMount } from '@sendbird/uikit-utils';
|
|
6
|
+
import { isDifferentChannel, useFreshCallback, useUniqHandlerId } from '@sendbird/uikit-utils';
|
|
7
7
|
|
|
8
8
|
import ChannelMessageList from '../../../components/ChannelMessageList';
|
|
9
9
|
import { MESSAGE_FOCUS_ANIMATION_DELAY, MESSAGE_SEARCH_SAFE_SCROLL_DELAY } from '../../../constants';
|
|
10
|
+
import { GroupChannelFragmentOptionsPubSubContextPayload } from '../../../contexts/SendbirdChatCtx';
|
|
10
11
|
import { useLocalization, useSendbirdChat } from '../../../hooks/useContext';
|
|
11
12
|
import { GroupChannelContexts } from '../module/moduleContext';
|
|
12
13
|
import type { GroupChannelProps } from '../types';
|
|
@@ -14,10 +15,12 @@ import type { GroupChannelProps } from '../types';
|
|
|
14
15
|
const GroupChannelMessageList = (props: GroupChannelProps['MessageList']) => {
|
|
15
16
|
const toast = useToast();
|
|
16
17
|
const { STRINGS } = useLocalization();
|
|
17
|
-
const { sdk } = useSendbirdChat();
|
|
18
|
+
const { sdk, sbOptions, groupChannelFragmentOptions } = useSendbirdChat();
|
|
18
19
|
const { setMessageToEdit, setMessageToReply } = useContext(GroupChannelContexts.Fragment);
|
|
19
20
|
const { subscribe } = useContext(GroupChannelContexts.PubSub);
|
|
20
|
-
const { flatListRef, lazyScrollToBottom, lazyScrollToIndex } = useContext(
|
|
21
|
+
const { flatListRef, lazyScrollToBottom, lazyScrollToIndex, onPressReplyMessageInThread } = useContext(
|
|
22
|
+
GroupChannelContexts.MessageList,
|
|
23
|
+
);
|
|
21
24
|
|
|
22
25
|
const id = useUniqHandlerId('GroupChannelMessageList');
|
|
23
26
|
const isFirstMount = useIsFirstMount();
|
|
@@ -90,6 +93,17 @@ const GroupChannelMessageList = (props: GroupChannelProps['MessageList']) => {
|
|
|
90
93
|
});
|
|
91
94
|
}, [props.scrolledAwayFromBottom]);
|
|
92
95
|
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
return groupChannelFragmentOptions.pubsub.subscribe((payload: GroupChannelFragmentOptionsPubSubContextPayload) => {
|
|
98
|
+
switch (payload.type) {
|
|
99
|
+
case 'OVERRIDE_SEARCH_ITEM_STARTING_POINT': {
|
|
100
|
+
scrollToMessageWithCreatedAt(payload.data.startingPoint, false, MESSAGE_SEARCH_SAFE_SCROLL_DELAY);
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}, []);
|
|
106
|
+
|
|
93
107
|
useEffect(() => {
|
|
94
108
|
// Only trigger once when message list mount with initial props.searchItem
|
|
95
109
|
// - Search screen + searchItem > mount message list
|
|
@@ -99,16 +113,31 @@ const GroupChannelMessageList = (props: GroupChannelProps['MessageList']) => {
|
|
|
99
113
|
}
|
|
100
114
|
}, [isFirstMount]);
|
|
101
115
|
|
|
102
|
-
const onPressParentMessage = useFreshCallback(
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
116
|
+
const onPressParentMessage = useFreshCallback(
|
|
117
|
+
(parentMessage: SendbirdMessage, childMessage: SendbirdSendableMessage) => {
|
|
118
|
+
if (
|
|
119
|
+
onPressReplyMessageInThread &&
|
|
120
|
+
sbOptions.uikit.groupChannel.channel.replyType === 'thread' &&
|
|
121
|
+
sbOptions.uikit.groupChannel.channel.threadReplySelectType === 'thread'
|
|
122
|
+
) {
|
|
123
|
+
if (parentMessage.createdAt >= props.channel.messageOffsetTimestamp) {
|
|
124
|
+
onPressReplyMessageInThread(parentMessage as SendbirdSendableMessage, childMessage.createdAt);
|
|
125
|
+
} else {
|
|
126
|
+
toast.show(STRINGS.TOAST.FIND_PARENT_MSG_ERROR, 'error');
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
const canScrollToParent = scrollToMessageWithCreatedAt(parentMessage.createdAt, true, 0);
|
|
130
|
+
if (!canScrollToParent) toast.show(STRINGS.TOAST.FIND_PARENT_MSG_ERROR, 'error');
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
);
|
|
106
134
|
|
|
107
135
|
return (
|
|
108
136
|
<ChannelMessageList
|
|
109
137
|
{...props}
|
|
110
138
|
ref={flatListRef}
|
|
111
139
|
onReplyMessage={setMessageToReply}
|
|
140
|
+
onReplyInThreadMessage={setMessageToReply}
|
|
112
141
|
onEditMessage={setMessageToEdit}
|
|
113
142
|
onPressParentMessage={onPressParentMessage}
|
|
114
143
|
onPressNewMessagesButton={scrollToBottom}
|
|
@@ -58,12 +58,13 @@ export const GroupChannelContextsProvider: GroupChannelModule['Provider'] = ({
|
|
|
58
58
|
groupChannelPubSub,
|
|
59
59
|
messages,
|
|
60
60
|
onUpdateSearchItem,
|
|
61
|
+
onPressReplyMessageInThread,
|
|
61
62
|
}) => {
|
|
62
63
|
if (!channel) throw new Error('GroupChannel is not provided to GroupChannelModule');
|
|
63
64
|
|
|
64
65
|
const handlerId = useUniqHandlerId('GroupChannelContextsProvider');
|
|
65
66
|
const { STRINGS } = useLocalization();
|
|
66
|
-
const { currentUser, sdk } = useSendbirdChat();
|
|
67
|
+
const { currentUser, sdk, sbOptions } = useSendbirdChat();
|
|
67
68
|
|
|
68
69
|
const [typingUsers, setTypingUsers] = useState<SendbirdUser[]>([]);
|
|
69
70
|
const [messageToEdit, setMessageToEdit] = useState<SendbirdUserMessage | SendbirdFileMessage>();
|
|
@@ -90,6 +91,14 @@ export const GroupChannelContextsProvider: GroupChannelModule['Provider'] = ({
|
|
|
90
91
|
}
|
|
91
92
|
};
|
|
92
93
|
|
|
94
|
+
const onPressMessageToReply = (parentMessage?: SendbirdUserMessage | SendbirdFileMessage) => {
|
|
95
|
+
if (sbOptions.uikit.groupChannel.channel.replyType === 'thread' && parentMessage) {
|
|
96
|
+
onPressReplyMessageInThread?.(parentMessage, Number.MAX_SAFE_INTEGER);
|
|
97
|
+
} else if (sbOptions.uikit.groupChannel.channel.replyType === 'quote_reply') {
|
|
98
|
+
updateInputMode('reply', parentMessage);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
93
102
|
useChannelHandler(sdk, handlerId, {
|
|
94
103
|
onMessageDeleted(_, messageId) {
|
|
95
104
|
if (messageToReply?.messageId === messageId) {
|
|
@@ -125,7 +134,7 @@ export const GroupChannelContextsProvider: GroupChannelModule['Provider'] = ({
|
|
|
125
134
|
messageToEdit,
|
|
126
135
|
setMessageToEdit: useCallback((message) => updateInputMode('edit', message), []),
|
|
127
136
|
messageToReply,
|
|
128
|
-
setMessageToReply: useCallback((message) =>
|
|
137
|
+
setMessageToReply: useCallback((message) => onPressMessageToReply(message), []),
|
|
129
138
|
}}
|
|
130
139
|
>
|
|
131
140
|
<GroupChannelContexts.PubSub.Provider value={groupChannelPubSub}>
|
|
@@ -136,6 +145,7 @@ export const GroupChannelContextsProvider: GroupChannelModule['Provider'] = ({
|
|
|
136
145
|
scrollToMessage,
|
|
137
146
|
lazyScrollToIndex,
|
|
138
147
|
lazyScrollToBottom,
|
|
148
|
+
onPressReplyMessageInThread,
|
|
139
149
|
}}
|
|
140
150
|
>
|
|
141
151
|
{children}
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
SendbirdFileMessageUpdateParams,
|
|
12
12
|
SendbirdGroupChannel,
|
|
13
13
|
SendbirdMessage,
|
|
14
|
+
SendbirdSendableMessage,
|
|
14
15
|
SendbirdUser,
|
|
15
16
|
SendbirdUserMessage,
|
|
16
17
|
SendbirdUserMessageCreateParams,
|
|
@@ -30,6 +31,7 @@ export interface GroupChannelProps {
|
|
|
30
31
|
onPressHeaderLeft: GroupChannelProps['Header']['onPressHeaderLeft'];
|
|
31
32
|
onPressHeaderRight: GroupChannelProps['Header']['onPressHeaderRight'];
|
|
32
33
|
onPressMediaMessage?: GroupChannelProps['MessageList']['onPressMediaMessage'];
|
|
34
|
+
onPressReplyMessageInThread?: GroupChannelProps['Provider']['onPressReplyMessageInThread'];
|
|
33
35
|
|
|
34
36
|
onBeforeSendUserMessage?: OnBeforeHandler<SendbirdUserMessageCreateParams>;
|
|
35
37
|
onBeforeSendFileMessage?: OnBeforeHandler<SendbirdFileMessageCreateParams>;
|
|
@@ -114,6 +116,7 @@ export interface GroupChannelProps {
|
|
|
114
116
|
messages: SendbirdMessage[];
|
|
115
117
|
// Changing the search item will trigger the focus animation on messages.
|
|
116
118
|
onUpdateSearchItem: (searchItem?: GroupChannelProps['MessageList']['searchItem']) => void;
|
|
119
|
+
onPressReplyMessageInThread: (parentMessage: SendbirdSendableMessage, startingPoint?: number) => void;
|
|
117
120
|
};
|
|
118
121
|
}
|
|
119
122
|
|
|
@@ -171,6 +174,8 @@ export interface GroupChannelContextsType {
|
|
|
171
174
|
timeout?: number;
|
|
172
175
|
viewPosition?: number;
|
|
173
176
|
}) => void;
|
|
177
|
+
|
|
178
|
+
onPressReplyMessageInThread?: (parentMessage: SendbirdSendableMessage, startingPoint?: number) => void;
|
|
174
179
|
}>;
|
|
175
180
|
}
|
|
176
181
|
export interface GroupChannelModule {
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React, { useContext } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { Icon, Text, createStyleSheet, useHeaderStyle, useUIKitTheme } from '@sendbird/uikit-react-native-foundation';
|
|
5
|
+
|
|
6
|
+
import { useLocalization, useSendbirdChat } from '../../../hooks/useContext';
|
|
7
|
+
import { GroupChannelThreadContexts } from '../module/moduleContext';
|
|
8
|
+
import type { GroupChannelThreadProps } from '../types';
|
|
9
|
+
|
|
10
|
+
const GroupChannelThreadHeader = ({ onPressLeft, onPressSubtitle }: GroupChannelThreadProps['Header']) => {
|
|
11
|
+
const { headerTitle, channel } = useContext(GroupChannelThreadContexts.Fragment);
|
|
12
|
+
const { HeaderComponent } = useHeaderStyle();
|
|
13
|
+
const { STRINGS } = useLocalization();
|
|
14
|
+
const { select, colors, palette } = useUIKitTheme();
|
|
15
|
+
const { currentUser } = useSendbirdChat();
|
|
16
|
+
|
|
17
|
+
const renderSubtitle = () => {
|
|
18
|
+
if (!currentUser) return null;
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<Text
|
|
22
|
+
onPress={onPressSubtitle}
|
|
23
|
+
caption2
|
|
24
|
+
style={styles.subtitle}
|
|
25
|
+
color={select({ light: palette.primary300, dark: palette.primary200 })}
|
|
26
|
+
numberOfLines={1}
|
|
27
|
+
>
|
|
28
|
+
{STRINGS.GROUP_CHANNEL_THREAD.HEADER_SUBTITLE(currentUser.userId, channel)}
|
|
29
|
+
</Text>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<HeaderComponent
|
|
35
|
+
clearTitleMargin
|
|
36
|
+
title={
|
|
37
|
+
<View style={styles.titleContainer}>
|
|
38
|
+
<View style={{ flexShrink: 1 }}>
|
|
39
|
+
<Text h2 color={colors.onBackground01} numberOfLines={1}>
|
|
40
|
+
{headerTitle}
|
|
41
|
+
</Text>
|
|
42
|
+
{renderSubtitle()}
|
|
43
|
+
</View>
|
|
44
|
+
</View>
|
|
45
|
+
}
|
|
46
|
+
left={<Icon icon={'arrow-left'} size={24} />}
|
|
47
|
+
onPressLeft={onPressLeft}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const styles = createStyleSheet({
|
|
53
|
+
titleContainer: {
|
|
54
|
+
maxWidth: '100%',
|
|
55
|
+
flexDirection: 'row',
|
|
56
|
+
width: '100%',
|
|
57
|
+
},
|
|
58
|
+
subtitle: {
|
|
59
|
+
marginTop: 2,
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
export default GroupChannelThreadHeader;
|