@droppii-org/chat-mobile 0.2.52 → 0.2.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/lib/module/components/Avatar/Avatar.utils.js +4 -2
  2. package/lib/module/components/Avatar/Avatar.utils.js.map +1 -1
  3. package/lib/module/components/Avatar/SingleAvatar.js +2 -0
  4. package/lib/module/components/Avatar/SingleAvatar.js.map +1 -1
  5. package/lib/module/components/ThreadCard/MuteThread.js +4 -61
  6. package/lib/module/components/ThreadCard/MuteThread.js.map +1 -1
  7. package/lib/module/context/ChatDetailContext.js +2 -1
  8. package/lib/module/context/ChatDetailContext.js.map +1 -1
  9. package/lib/module/hooks/flows/useFlow.js +10 -0
  10. package/lib/module/hooks/flows/useFlow.js.map +1 -1
  11. package/lib/module/hooks/query-keys.js +1 -0
  12. package/lib/module/hooks/query-keys.js.map +1 -1
  13. package/lib/module/hooks/useMuteConversation.js +66 -1
  14. package/lib/module/hooks/useMuteConversation.js.map +1 -1
  15. package/lib/module/index.js +1 -0
  16. package/lib/module/index.js.map +1 -1
  17. package/lib/module/screens/ChatInfo/ChatInfo.js +75 -0
  18. package/lib/module/screens/ChatInfo/ChatInfo.js.map +1 -0
  19. package/lib/module/screens/ChatInfo/ChatInfoActions.js +141 -0
  20. package/lib/module/screens/ChatInfo/ChatInfoActions.js.map +1 -0
  21. package/lib/module/screens/ChatInfo/ChatInfoMediaRow.js +58 -0
  22. package/lib/module/screens/ChatInfo/ChatInfoMediaRow.js.map +1 -0
  23. package/lib/module/screens/ChatInfo/ChatInfoProfile.js +134 -0
  24. package/lib/module/screens/ChatInfo/ChatInfoProfile.js.map +1 -0
  25. package/lib/module/screens/ChatInfo/index.js +4 -0
  26. package/lib/module/screens/ChatInfo/index.js.map +1 -0
  27. package/lib/module/screens/ChatInfo/types.js +4 -0
  28. package/lib/module/screens/ChatInfo/types.js.map +1 -0
  29. package/lib/module/screens/chat-detail/BotMenuSheet.js +73 -0
  30. package/lib/module/screens/chat-detail/BotMenuSheet.js.map +1 -0
  31. package/lib/module/screens/chat-detail/ChatComposer.js +78 -3
  32. package/lib/module/screens/chat-detail/ChatComposer.js.map +1 -1
  33. package/lib/module/screens/chat-detail/components/ChatMessageInput.js +11 -6
  34. package/lib/module/screens/chat-detail/components/ChatMessageInput.js.map +1 -1
  35. package/lib/module/services/endpoints.js +1 -0
  36. package/lib/module/services/endpoints.js.map +1 -1
  37. package/lib/module/translation/resources/i18n.js +18 -1
  38. package/lib/module/translation/resources/i18n.js.map +1 -1
  39. package/lib/module/types/chat.js.map +1 -1
  40. package/lib/typescript/src/components/Avatar/Avatar.types.d.ts +1 -1
  41. package/lib/typescript/src/components/Avatar/Avatar.types.d.ts.map +1 -1
  42. package/lib/typescript/src/components/Avatar/Avatar.utils.d.ts +2 -0
  43. package/lib/typescript/src/components/Avatar/Avatar.utils.d.ts.map +1 -1
  44. package/lib/typescript/src/components/Avatar/SingleAvatar.d.ts.map +1 -1
  45. package/lib/typescript/src/components/ThreadCard/MuteThread.d.ts.map +1 -1
  46. package/lib/typescript/src/context/ChatDetailContext.d.ts.map +1 -1
  47. package/lib/typescript/src/hooks/flows/useFlow.d.ts +1 -0
  48. package/lib/typescript/src/hooks/flows/useFlow.d.ts.map +1 -1
  49. package/lib/typescript/src/hooks/query-keys.d.ts +1 -0
  50. package/lib/typescript/src/hooks/query-keys.d.ts.map +1 -1
  51. package/lib/typescript/src/hooks/useMuteConversation.d.ts.map +1 -1
  52. package/lib/typescript/src/index.d.ts +2 -0
  53. package/lib/typescript/src/index.d.ts.map +1 -1
  54. package/lib/typescript/src/screens/ChatInfo/ChatInfo.d.ts +4 -0
  55. package/lib/typescript/src/screens/ChatInfo/ChatInfo.d.ts.map +1 -0
  56. package/lib/typescript/src/screens/ChatInfo/ChatInfoActions.d.ts +11 -0
  57. package/lib/typescript/src/screens/ChatInfo/ChatInfoActions.d.ts.map +1 -0
  58. package/lib/typescript/src/screens/ChatInfo/ChatInfoMediaRow.d.ts +7 -0
  59. package/lib/typescript/src/screens/ChatInfo/ChatInfoMediaRow.d.ts.map +1 -0
  60. package/lib/typescript/src/screens/ChatInfo/ChatInfoProfile.d.ts +9 -0
  61. package/lib/typescript/src/screens/ChatInfo/ChatInfoProfile.d.ts.map +1 -0
  62. package/lib/typescript/src/screens/ChatInfo/index.d.ts +3 -0
  63. package/lib/typescript/src/screens/ChatInfo/index.d.ts.map +1 -0
  64. package/lib/typescript/src/screens/ChatInfo/types.d.ts +14 -0
  65. package/lib/typescript/src/screens/ChatInfo/types.d.ts.map +1 -0
  66. package/lib/typescript/src/screens/chat-detail/BotMenuSheet.d.ts +7 -0
  67. package/lib/typescript/src/screens/chat-detail/BotMenuSheet.d.ts.map +1 -0
  68. package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts.map +1 -1
  69. package/lib/typescript/src/screens/chat-detail/components/ChatMessageInput.d.ts +2 -1
  70. package/lib/typescript/src/screens/chat-detail/components/ChatMessageInput.d.ts.map +1 -1
  71. package/lib/typescript/src/services/endpoints.d.ts +1 -0
  72. package/lib/typescript/src/services/endpoints.d.ts.map +1 -1
  73. package/lib/typescript/src/translation/resources/i18n.d.ts.map +1 -1
  74. package/lib/typescript/src/types/chat.d.ts +2 -1
  75. package/lib/typescript/src/types/chat.d.ts.map +1 -1
  76. package/package.json +1 -1
  77. package/src/build-ignore.d.ts +1 -0
  78. package/src/components/Avatar/Avatar.types.ts +1 -1
  79. package/src/components/Avatar/Avatar.utils.ts +2 -0
  80. package/src/components/Avatar/SingleAvatar.tsx +2 -0
  81. package/src/components/ThreadCard/MuteThread.tsx +4 -61
  82. package/src/context/ChatDetailContext.tsx +1 -0
  83. package/src/hooks/flows/useFlow.ts +14 -0
  84. package/src/hooks/query-keys.ts +4 -0
  85. package/src/hooks/useMuteConversation.tsx +124 -0
  86. package/src/index.tsx +2 -0
  87. package/src/screens/ChatInfo/ChatInfo.tsx +75 -0
  88. package/src/screens/ChatInfo/ChatInfoActions.tsx +168 -0
  89. package/src/screens/ChatInfo/ChatInfoMediaRow.tsx +73 -0
  90. package/src/screens/ChatInfo/ChatInfoProfile.tsx +147 -0
  91. package/src/screens/ChatInfo/index.ts +2 -0
  92. package/src/screens/ChatInfo/types.ts +14 -0
  93. package/src/screens/chat-detail/BotMenuSheet.tsx +94 -0
  94. package/src/screens/chat-detail/ChatComposer.tsx +100 -3
  95. package/src/screens/chat-detail/components/ChatMessageInput.tsx +11 -7
  96. package/src/services/endpoints.ts +2 -0
  97. package/src/translation/resources/i18n.ts +18 -0
  98. package/src/types/chat.ts +2 -0
  99. package/src/hooks/useMuteConversation.ts +0 -59
@@ -0,0 +1,124 @@
1
+ import { useCallback } from 'react';
2
+ import OpenIMSDK, {
3
+ MessageReceiveOptType,
4
+ } from '@droppii/openim-rn-client-sdk';
5
+ import type { ConversationItem } from '@droppii/openim-rn-client-sdk';
6
+ import { UIUtils } from '../utils/UIUtils';
7
+ import { trans } from '../translation';
8
+ import { KContainer, KLabel } from '@droppii/libs';
9
+ import { Image, StyleSheet } from 'react-native';
10
+ import Images from '../assets/images';
11
+
12
+ export function useMuteConversation() {
13
+ const openMutePopup = useCallback(() => {
14
+ return new Promise((resolve, reject) => {
15
+ UIUtils.popup.open({
16
+ header: {
17
+ title: { text: trans('chat:mute_confirm_title') },
18
+ alignment: 'center',
19
+ },
20
+ body: {
21
+ renderContent: () => {
22
+ return (
23
+ <KContainer.View padding={'1rem'} justifyContent alignItems>
24
+ <KContainer.View paddingV={'1rem'}>
25
+ <Image
26
+ source={Images.NOTIFICATION_WARNING}
27
+ style={styles.notificationWarning}
28
+ />
29
+ </KContainer.View>
30
+ <KLabel.RichText
31
+ typo="TextMdNormal"
32
+ richTextOptions={{
33
+ i18nKey: trans('chat:mute_confirm_desc'),
34
+ components: {
35
+ b: <KLabel.Text typo="TextMdBold" />,
36
+ },
37
+ }}
38
+ />
39
+ </KContainer.View>
40
+ );
41
+ },
42
+ },
43
+ actions: {
44
+ buttons: [
45
+ {
46
+ label: trans('chat:mute_confirm_secondary'),
47
+ kind: 'light',
48
+ onPress: reject,
49
+ },
50
+ {
51
+ label: trans('chat:mute_confirm_primary'),
52
+ kind: 'primary',
53
+ onPress: resolve,
54
+ },
55
+ ],
56
+ type: 'horizontal-button',
57
+ },
58
+ });
59
+ });
60
+ }, []);
61
+
62
+ const muteConversation = useCallback(
63
+ async (conversation?: ConversationItem) => {
64
+ if (conversation == null) return;
65
+
66
+ try {
67
+ await openMutePopup();
68
+ } catch {
69
+ return;
70
+ }
71
+
72
+ try {
73
+ await OpenIMSDK.setConversationRecvMessageOpt({
74
+ conversationID: conversation.conversationID,
75
+ opt: MessageReceiveOptType.NotNotify,
76
+ });
77
+ UIUtils.toast.open({
78
+ title: trans('chat:mute_toast_success'),
79
+ theme: 'light',
80
+ });
81
+ } catch (error) {
82
+ console.error('muteConversation failed', error);
83
+ UIUtils.toast.open({
84
+ title: trans('chat:generic_error'),
85
+ theme: 'error',
86
+ });
87
+ }
88
+ },
89
+ [openMutePopup]
90
+ );
91
+
92
+ const unmuteConversation = useCallback(
93
+ async (conversation?: ConversationItem) => {
94
+ if (conversation == null) return;
95
+
96
+ try {
97
+ await OpenIMSDK.setConversationRecvMessageOpt({
98
+ conversationID: conversation.conversationID,
99
+ opt: MessageReceiveOptType.Normal,
100
+ });
101
+ UIUtils.toast.open({
102
+ title: trans('chat:unmute_toast_success'),
103
+ theme: 'light',
104
+ });
105
+ } catch (error) {
106
+ console.error('unmuteConversation failed', error);
107
+ UIUtils.toast.open({
108
+ title: trans('chat:generic_error'),
109
+ theme: 'error',
110
+ });
111
+ }
112
+ },
113
+ []
114
+ );
115
+
116
+ return { muteConversation, unmuteConversation };
117
+ }
118
+
119
+ const styles = StyleSheet.create({
120
+ notificationWarning: {
121
+ width: 120,
122
+ height: 144,
123
+ },
124
+ });
package/src/index.tsx CHANGED
@@ -31,6 +31,7 @@ export { default as MediaViewerScreen } from './screens/MediaView';
31
31
  export { default as ResourceCenterScreen } from './screens/ResourceCenter';
32
32
  export type { ResourceCenterScreenProps } from './screens/ResourceCenter/types';
33
33
  export * from './screens/chat-detail';
34
+ export * from './screens/ChatInfo';
34
35
 
35
36
  export type {
36
37
  PeerType,
@@ -52,6 +53,7 @@ export type {
52
53
  ChatQuickActionsRenderParams,
53
54
  ChatPanelProps,
54
55
  } from './screens/chat-detail';
56
+ export type * from './screens/ChatInfo';
55
57
 
56
58
  export { registerUIUtils, UIUtils } from './utils/UIUtils';
57
59
 
@@ -0,0 +1,75 @@
1
+ import { memo } from 'react';
2
+ import { KContainer, KNavigation } from '@droppii/libs';
3
+ import { useNavigation } from '@react-navigation/native';
4
+ import {
5
+ useGetConversationDetail,
6
+ useGetConversationTarget,
7
+ } from '../../hooks/conversation/useGetConversationDetail';
8
+ import { useConversation } from '../../store';
9
+ import ChatInfoProfile from './ChatInfoProfile';
10
+ import ChatInfoMediaRow from './ChatInfoMediaRow';
11
+ import ChatInfoActions from './ChatInfoActions';
12
+ import type { ChatInfoProps } from './types';
13
+ import { trans } from '../../translation';
14
+
15
+ const ChatInfo = memo(
16
+ ({
17
+ targetConversationId = '',
18
+ targetUserId = '',
19
+ targetGroupId = '',
20
+ targetBotId = '',
21
+ onBack,
22
+ onPressSearch,
23
+ onPressMedia,
24
+ onPressOrders,
25
+ onPressCreateGroup,
26
+ onPressAddToGroup,
27
+ }: ChatInfoProps) => {
28
+ const navigation = useNavigation();
29
+
30
+ const { conversationId } = useGetConversationDetail({
31
+ targetConversationId,
32
+ targetUserId,
33
+ targetGroupId,
34
+ targetBotId,
35
+ });
36
+
37
+ const conversation = useConversation(conversationId);
38
+ const { data: target } = useGetConversationTarget(conversationId);
39
+ const isTargetActive = target ? target.isActive : true;
40
+
41
+ return (
42
+ <KContainer.Page flex edges={['bottom']} background="#EBEDF2">
43
+ <KNavigation.Header
44
+ theme="light"
45
+ alignment="left"
46
+ size="small"
47
+ leftButton={{
48
+ id: 'ChatInfoBackButton',
49
+ icon: { vectorName: 'arrow-left-o' },
50
+ onPress: onBack ?? navigation.goBack,
51
+ }}
52
+ title={trans('chat:info_title')}
53
+ shadow={false}
54
+ />
55
+ <KContainer.ScrollView showsVerticalScrollIndicator={false}>
56
+ <ChatInfoProfile
57
+ conversation={conversation}
58
+ targetUserId={targetUserId}
59
+ onPressSearch={onPressSearch}
60
+ />
61
+ <ChatInfoMediaRow onPressMedia={onPressMedia} />
62
+ <ChatInfoActions
63
+ conversation={conversation}
64
+ isTargetActive={isTargetActive}
65
+ onPressOrders={onPressOrders}
66
+ onPressCreateGroup={onPressCreateGroup}
67
+ onPressAddToGroup={onPressAddToGroup}
68
+ />
69
+ </KContainer.ScrollView>
70
+ </KContainer.Page>
71
+ );
72
+ }
73
+ );
74
+
75
+ export default ChatInfo;
@@ -0,0 +1,168 @@
1
+ import { memo, useCallback, useMemo } from 'react';
2
+ import {
3
+ KContainer,
4
+ KListItem,
5
+ KColors,
6
+ type KListItemBaseItemProps,
7
+ KLabel,
8
+ } from '@droppii/libs';
9
+ import type { ConversationItem } from '@droppii/openim-rn-client-sdk';
10
+ import { usePinConversation } from '../../hooks/usePinConversation';
11
+ import { trans } from '../../translation';
12
+
13
+ interface ChatInfoActionsProps {
14
+ conversation?: ConversationItem;
15
+ isTargetActive: boolean;
16
+ onPressOrders?: () => void;
17
+ onPressCreateGroup?: () => void;
18
+ onPressAddToGroup?: () => void;
19
+ }
20
+
21
+ const ChatInfoActions = memo(
22
+ ({
23
+ conversation,
24
+ isTargetActive,
25
+ onPressOrders,
26
+ onPressCreateGroup,
27
+ onPressAddToGroup,
28
+ }: ChatInfoActionsProps) => {
29
+ const { pinConversation, unpinConversation } = usePinConversation();
30
+ const isPinned = Boolean(conversation?.isPinned);
31
+ const showName = conversation?.showName || '';
32
+
33
+ const handlePinPress = useCallback(() => {
34
+ if (isPinned) {
35
+ unpinConversation(conversation);
36
+ } else {
37
+ pinConversation(conversation);
38
+ }
39
+ }, [isPinned, conversation, pinConversation, unpinConversation]);
40
+
41
+ const handleDeleteHistory = useCallback(() => {}, []);
42
+
43
+ const primaryData = useMemo(() => {
44
+ const items: KListItemBaseItemProps[] = [
45
+ {
46
+ leftNode: { icon: { vectorName: 'receipt-o' } },
47
+ onPress: onPressOrders,
48
+ paddingH: '0.75rem',
49
+ paddingV: '0.75rem',
50
+ customLabel: (
51
+ <KLabel.Text typo="TextMdMedium" numberOfLines={1}>
52
+ {trans('chat:info_orders', { name: showName })}
53
+ </KLabel.Text>
54
+ ),
55
+ },
56
+ ];
57
+
58
+ if (isTargetActive) {
59
+ items.push(
60
+ {
61
+ leftNode: { icon: { vectorName: 'user-two-o' } },
62
+ onPress: onPressCreateGroup,
63
+ paddingH: '0.75rem',
64
+ paddingV: '0.75rem',
65
+ customLabel: (
66
+ <KLabel.Text typo="TextMdMedium" numberOfLines={1}>
67
+ {trans('chat:info_create_group', { name: showName })}
68
+ </KLabel.Text>
69
+ ),
70
+ },
71
+ {
72
+ leftNode: { icon: { vectorName: 'user-add-o' } },
73
+ onPress: onPressAddToGroup,
74
+ paddingH: '0.75rem',
75
+ paddingV: '0.75rem',
76
+ customLabel: (
77
+ <KLabel.Text typo="TextMdMedium" numberOfLines={1}>
78
+ {trans('chat:info_add_to_group')}
79
+ </KLabel.Text>
80
+ ),
81
+ }
82
+ );
83
+ }
84
+
85
+ items.push({
86
+ leftNode: {
87
+ icon: { vectorName: isPinned ? 'thumbtack-off-o' : 'thumbtack-o' },
88
+ },
89
+ onPress: handlePinPress,
90
+ showChevron: false,
91
+ paddingH: '0.75rem',
92
+ paddingV: '0.75rem',
93
+ customLabel: (
94
+ <KLabel.Text typo="TextMdMedium" numberOfLines={1}>
95
+ {isPinned
96
+ ? trans('chat:info_unpin_message')
97
+ : trans('chat:info_pin_message')}
98
+ </KLabel.Text>
99
+ ),
100
+ });
101
+
102
+ return items;
103
+ }, [
104
+ showName,
105
+ isTargetActive,
106
+ isPinned,
107
+ onPressOrders,
108
+ onPressCreateGroup,
109
+ onPressAddToGroup,
110
+ handlePinPress,
111
+ ]);
112
+
113
+ const deleteData: KListItemBaseItemProps[] = useMemo(
114
+ () => [
115
+ {
116
+ label: trans('chat:info_delete_history'),
117
+ leftNode: {
118
+ icon: {
119
+ vectorName: 'trash-alt-o',
120
+ tintColor: KColors.danger.normal,
121
+ },
122
+ },
123
+ tintColor: KColors.danger.normal,
124
+ onPress: handleDeleteHistory,
125
+ showChevron: false,
126
+ paddingH: '0.75rem',
127
+ paddingV: '0.75rem',
128
+ customLabel: (
129
+ <KLabel.Text
130
+ typo="TextMdMedium"
131
+ color={KColors.danger.normal}
132
+ numberOfLines={1}
133
+ >
134
+ {trans('chat:info_delete_history')}
135
+ </KLabel.Text>
136
+ ),
137
+ },
138
+ ],
139
+ [handleDeleteHistory]
140
+ );
141
+
142
+ return (
143
+ <>
144
+ <KContainer.View
145
+ background={KColors.white}
146
+ br={'3x'}
147
+ marginH="0.75rem"
148
+ marginT="0.75rem"
149
+ hiddenOverflow
150
+ >
151
+ <KListItem.Base data={primaryData} />
152
+ </KContainer.View>
153
+
154
+ <KContainer.View
155
+ background={KColors.white}
156
+ br={'3x'}
157
+ marginH="0.75rem"
158
+ marginT="0.75rem"
159
+ hiddenOverflow
160
+ >
161
+ <KListItem.Base data={deleteData} />
162
+ </KContainer.View>
163
+ </>
164
+ );
165
+ }
166
+ );
167
+
168
+ export default ChatInfoActions;
@@ -0,0 +1,73 @@
1
+ import { memo } from 'react';
2
+ import { KContainer, KImage, KLabel, KColors } from '@droppii/libs';
3
+ import { trans } from '../../translation';
4
+ import { DThreadResourceContentType } from '../../types/chat';
5
+
6
+ const MEDIA_TABS: Array<{
7
+ tab: DThreadResourceContentType;
8
+ iconName: string;
9
+ labelKey: string;
10
+ }> = [
11
+ {
12
+ tab: DThreadResourceContentType.IMAGE,
13
+ iconName: 'image-o',
14
+ labelKey: 'chat:info_media_photo',
15
+ },
16
+ {
17
+ tab: DThreadResourceContentType.VIDEO,
18
+ iconName: 'video-o',
19
+ labelKey: 'chat:info_media_video',
20
+ },
21
+ {
22
+ tab: DThreadResourceContentType.FILE,
23
+ iconName: 'paperclip-o',
24
+ labelKey: 'chat:info_media_file',
25
+ },
26
+ {
27
+ tab: DThreadResourceContentType.URL_TEXT,
28
+ iconName: 'link-alt-o',
29
+ labelKey: 'chat:info_media_link',
30
+ },
31
+ ];
32
+
33
+ interface ChatInfoMediaRowProps {
34
+ onPressMedia?: (tab: DThreadResourceContentType) => void;
35
+ }
36
+
37
+ const ChatInfoMediaRow = memo(({ onPressMedia }: ChatInfoMediaRowProps) => {
38
+ return (
39
+ <KContainer.View
40
+ row
41
+ background={KColors.white}
42
+ br={'3x'}
43
+ marginH="0.75rem"
44
+ marginT="0.75rem"
45
+ >
46
+ {MEDIA_TABS.map(({ tab, iconName, labelKey }) => (
47
+ <KContainer.Touchable
48
+ key={tab}
49
+ flex
50
+ alignItems
51
+ justifyContent
52
+ paddingV="0.75rem"
53
+ onPress={() => onPressMedia?.(tab)}
54
+ >
55
+ <KImage.VectorIcons
56
+ name={iconName}
57
+ size={24}
58
+ color={KColors.gray.dark}
59
+ />
60
+ <KLabel.Text
61
+ typo="TextXsNormal"
62
+ color={KColors.gray.dark}
63
+ marginT="0.25rem"
64
+ >
65
+ {trans(labelKey)}
66
+ </KLabel.Text>
67
+ </KContainer.Touchable>
68
+ ))}
69
+ </KContainer.View>
70
+ );
71
+ });
72
+
73
+ export default ChatInfoMediaRow;
@@ -0,0 +1,147 @@
1
+ import { memo, useCallback, useMemo } from 'react';
2
+ import { KContainer, KImage, KLabel, KColors } from '@droppii/libs';
3
+ import {
4
+ MessageReceiveOptType,
5
+ PeerType,
6
+ type ConversationItem,
7
+ } from '@droppii/openim-rn-client-sdk';
8
+ import { Avatar } from '../../components/Avatar';
9
+ import { useGetUsersInfo } from '../../hooks/users/useGetUsersInfo';
10
+ import { useMuteConversation } from '../../hooks/useMuteConversation';
11
+ import { trans } from '../../translation';
12
+ import { StyleSheet } from 'react-native';
13
+ import { NamePrefixIcon } from '../../components/ThreadCard';
14
+
15
+ interface QuickActionProps {
16
+ iconName: string;
17
+ label: string;
18
+ onPress?: () => void;
19
+ }
20
+
21
+ const QuickAction = memo(({ iconName, label, onPress }: QuickActionProps) => (
22
+ <KContainer.View alignItems paddingH="0.75rem" paddingV="0.5rem">
23
+ <KContainer.Touchable
24
+ height={40}
25
+ width={40}
26
+ br={'round'}
27
+ background={KColors.palette.gray.w25}
28
+ center
29
+ onPress={onPress}
30
+ >
31
+ <KImage.VectorIcons name={iconName} size={18} color={KColors.gray.dark} />
32
+ </KContainer.Touchable>
33
+ <KLabel.Text
34
+ typo="TextSmMedium"
35
+ color={KColors.gray.dark}
36
+ marginT="0.25rem"
37
+ textAlign="center"
38
+ >
39
+ {label}
40
+ </KLabel.Text>
41
+ </KContainer.View>
42
+ ));
43
+
44
+ interface ChatInfoProfileProps {
45
+ conversation?: ConversationItem;
46
+ targetUserId?: string;
47
+ onPressSearch?: () => void;
48
+ }
49
+
50
+ const ChatInfoProfile = memo(
51
+ ({ conversation, targetUserId, onPressSearch }: ChatInfoProfileProps) => {
52
+ const { data: usersInfo } = useGetUsersInfo(
53
+ targetUserId ? [targetUserId] : []
54
+ );
55
+
56
+ const { faceURL, showName } = useMemo(() => {
57
+ const userInfo = usersInfo?.[0];
58
+ return {
59
+ faceURL: conversation?.faceURL || userInfo?.faceURL,
60
+ showName: conversation?.showName || userInfo?.nickname,
61
+ };
62
+ }, [conversation, usersInfo]);
63
+
64
+ const isMuted =
65
+ conversation != null &&
66
+ conversation.recvMsgOpt !== MessageReceiveOptType.Normal;
67
+
68
+ const { muteConversation, unmuteConversation } = useMuteConversation();
69
+
70
+ const handleNotificationPress = useCallback(() => {
71
+ if (isMuted) {
72
+ unmuteConversation(conversation);
73
+ } else {
74
+ muteConversation(conversation);
75
+ }
76
+ }, [isMuted, conversation, muteConversation, unmuteConversation]);
77
+
78
+ const badge = useMemo(() => {
79
+ switch (conversation?.peerType) {
80
+ case PeerType.Bot:
81
+ return { variant: 'bot' } as const;
82
+
83
+ case PeerType.Customer:
84
+ return { variant: 'mall' } as const;
85
+ default:
86
+ return;
87
+ }
88
+ }, [conversation?.peerType]);
89
+
90
+ return (
91
+ <KContainer.View
92
+ background={KColors.white}
93
+ brBL={'4x'}
94
+ brBR={'4x'}
95
+ paddingV="0.5rem"
96
+ >
97
+ <KContainer.View alignItems>
98
+ <Avatar
99
+ source={faceURL}
100
+ size="4xlg"
101
+ fullName={showName || ''}
102
+ badge={badge}
103
+ />
104
+ <KContainer.View row alignItems marginT="0.5rem">
105
+ <NamePrefixIcon peerType={conversation?.peerType} />
106
+ <KLabel.Text
107
+ typo="TextLgBold"
108
+ color={KColors.black}
109
+ numberOfLines={1}
110
+ >
111
+ {showName || ''}
112
+ </KLabel.Text>
113
+ </KContainer.View>
114
+ </KContainer.View>
115
+
116
+ <KContainer.View
117
+ row
118
+ justifyContent="center"
119
+ alignItems
120
+ style={styles.quickActionContainer}
121
+ marginT="0.5rem"
122
+ >
123
+ <QuickAction
124
+ iconName="search-o"
125
+ label={trans('chat:info_search_action')}
126
+ onPress={onPressSearch}
127
+ />
128
+ <QuickAction
129
+ iconName={isMuted ? 'bell-o' : 'bell-off-o'}
130
+ label={
131
+ isMuted ? trans('chat:unmute_action') : trans('chat:mute_action')
132
+ }
133
+ onPress={handleNotificationPress}
134
+ />
135
+ </KContainer.View>
136
+ </KContainer.View>
137
+ );
138
+ }
139
+ );
140
+
141
+ export default ChatInfoProfile;
142
+
143
+ const styles = StyleSheet.create({
144
+ quickActionContainer: {
145
+ gap: 8,
146
+ },
147
+ });
@@ -0,0 +1,2 @@
1
+ export { default as ChatInfo } from './ChatInfo';
2
+ export type * from './types';
@@ -0,0 +1,14 @@
1
+ import type { DThreadResourceContentType } from '../../types/chat';
2
+
3
+ export interface ChatInfoProps {
4
+ targetConversationId?: string;
5
+ targetUserId?: string;
6
+ targetGroupId?: string;
7
+ targetBotId?: string;
8
+ onBack?: () => void;
9
+ onPressSearch?: () => void;
10
+ onPressMedia?: (tab: DThreadResourceContentType) => void;
11
+ onPressOrders?: () => void;
12
+ onPressCreateGroup?: () => void;
13
+ onPressAddToGroup?: () => void;
14
+ }