@droppii-org/chat-mobile 0.2.80 → 0.2.81
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/lib/module/config/api-endpoints.js +2 -1
- package/lib/module/config/api-endpoints.js.map +1 -1
- package/lib/module/hooks/contacts/useSearchContacts.js +50 -0
- package/lib/module/hooks/contacts/useSearchContacts.js.map +1 -0
- package/lib/module/hooks/query-keys.js +4 -0
- package/lib/module/hooks/query-keys.js.map +1 -1
- package/lib/module/screens/SearchConversation/ContactResultItem.js +119 -0
- package/lib/module/screens/SearchConversation/ContactResultItem.js.map +1 -0
- package/lib/module/screens/SearchConversation/SearchAllResult.js +26 -20
- package/lib/module/screens/SearchConversation/SearchAllResult.js.map +1 -1
- package/lib/module/screens/SearchConversation/SearchCommunityResult.js +79 -0
- package/lib/module/screens/SearchConversation/SearchCommunityResult.js.map +1 -0
- package/lib/module/screens/SearchConversation/SearchContactsResult.js +117 -0
- package/lib/module/screens/SearchConversation/SearchContactsResult.js.map +1 -0
- package/lib/module/screens/SearchConversation/SearchEmpty.js +2 -0
- package/lib/module/screens/SearchConversation/SearchEmpty.js.map +1 -1
- package/lib/module/screens/SearchConversation/SearchMessagesResult.js +1 -8
- package/lib/module/screens/SearchConversation/SearchMessagesResult.js.map +1 -1
- package/lib/module/screens/SearchConversation/SearchResultItem.js +2 -0
- package/lib/module/screens/SearchConversation/SearchResultItem.js.map +1 -1
- package/lib/module/screens/SearchConversation/TabResult.js +24 -7
- package/lib/module/screens/SearchConversation/TabResult.js.map +1 -1
- package/lib/module/screens/SearchConversation/index.js +6 -2
- package/lib/module/screens/SearchConversation/index.js.map +1 -1
- package/lib/module/screens/SearchConversation/types.js +1 -0
- package/lib/module/screens/SearchConversation/types.js.map +1 -1
- package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxWrapper.js +11 -1
- package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxWrapper.js.map +1 -1
- package/lib/module/services/endpoints.js +2 -1
- package/lib/module/services/endpoints.js.map +1 -1
- package/lib/module/translation/resources/i18n.js +6 -0
- package/lib/module/translation/resources/i18n.js.map +1 -1
- package/lib/module/types/chat.js +8 -0
- package/lib/module/types/chat.js.map +1 -1
- package/lib/module/utils/dateTimeUtils.js +10 -0
- package/lib/module/utils/dateTimeUtils.js.map +1 -1
- package/lib/module/utils/highlightSearch.js +6 -2
- package/lib/module/utils/highlightSearch.js.map +1 -1
- package/lib/module/utils/messageUtils.js +10 -2
- package/lib/module/utils/messageUtils.js.map +1 -1
- package/lib/typescript/src/config/api-endpoints.d.ts +1 -0
- package/lib/typescript/src/config/api-endpoints.d.ts.map +1 -1
- package/lib/typescript/src/hooks/contacts/useSearchContacts.d.ts +221 -0
- package/lib/typescript/src/hooks/contacts/useSearchContacts.d.ts.map +1 -0
- package/lib/typescript/src/hooks/query-keys.d.ts +4 -0
- package/lib/typescript/src/hooks/query-keys.d.ts.map +1 -1
- package/lib/typescript/src/screens/SearchConversation/ContactResultItem.d.ts +9 -0
- package/lib/typescript/src/screens/SearchConversation/ContactResultItem.d.ts.map +1 -0
- package/lib/typescript/src/screens/SearchConversation/SearchAllResult.d.ts +3 -2
- package/lib/typescript/src/screens/SearchConversation/SearchAllResult.d.ts.map +1 -1
- package/lib/typescript/src/screens/SearchConversation/SearchCommunityResult.d.ts +7 -0
- package/lib/typescript/src/screens/SearchConversation/SearchCommunityResult.d.ts.map +1 -0
- package/lib/typescript/src/screens/SearchConversation/SearchContactsResult.d.ts +8 -0
- package/lib/typescript/src/screens/SearchConversation/SearchContactsResult.d.ts.map +1 -0
- package/lib/typescript/src/screens/SearchConversation/SearchEmpty.d.ts.map +1 -1
- package/lib/typescript/src/screens/SearchConversation/SearchMessagesResult.d.ts.map +1 -1
- package/lib/typescript/src/screens/SearchConversation/SearchResultItem.d.ts.map +1 -1
- package/lib/typescript/src/screens/SearchConversation/TabResult.d.ts +4 -2
- package/lib/typescript/src/screens/SearchConversation/TabResult.d.ts.map +1 -1
- package/lib/typescript/src/screens/SearchConversation/index.d.ts +4 -2
- package/lib/typescript/src/screens/SearchConversation/index.d.ts.map +1 -1
- package/lib/typescript/src/screens/SearchConversation/types.d.ts +2 -1
- package/lib/typescript/src/screens/SearchConversation/types.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxWrapper.d.ts.map +1 -1
- package/lib/typescript/src/services/endpoints.d.ts +1 -0
- package/lib/typescript/src/services/endpoints.d.ts.map +1 -1
- package/lib/typescript/src/translation/resources/i18n.d.ts.map +1 -1
- package/lib/typescript/src/types/chat.d.ts +27 -0
- package/lib/typescript/src/types/chat.d.ts.map +1 -1
- package/lib/typescript/src/utils/dateTimeUtils.d.ts +2 -0
- package/lib/typescript/src/utils/dateTimeUtils.d.ts.map +1 -1
- package/lib/typescript/src/utils/highlightSearch.d.ts.map +1 -1
- package/lib/typescript/src/utils/messageUtils.d.ts.map +1 -1
- package/package.json +3 -1
- package/src/build-ignore.d.ts +2 -0
- package/src/config/api-endpoints.ts +2 -0
- package/src/hooks/contacts/useSearchContacts.ts +66 -0
- package/src/hooks/query-keys.ts +6 -0
- package/src/screens/SearchConversation/ContactResultItem.tsx +128 -0
- package/src/screens/SearchConversation/SearchAllResult.tsx +38 -24
- package/src/screens/SearchConversation/SearchCommunityResult.tsx +96 -0
- package/src/screens/SearchConversation/SearchContactsResult.tsx +155 -0
- package/src/screens/SearchConversation/SearchEmpty.tsx +2 -0
- package/src/screens/SearchConversation/SearchMessagesResult.tsx +1 -6
- package/src/screens/SearchConversation/SearchResultItem.tsx +6 -1
- package/src/screens/SearchConversation/TabResult.tsx +40 -5
- package/src/screens/SearchConversation/index.tsx +10 -2
- package/src/screens/SearchConversation/types.tsx +1 -0
- package/src/screens/chat-detail/messageToolbox/MessageToolboxWrapper.tsx +22 -4
- package/src/services/endpoints.ts +1 -0
- package/src/translation/resources/i18n.ts +6 -0
- package/src/types/chat.ts +30 -0
- package/src/utils/dateTimeUtils.ts +15 -0
- package/src/utils/highlightSearch.ts +12 -2
- package/src/utils/messageUtils.ts +15 -9
|
@@ -12,19 +12,30 @@ import { SearchConversationTabResultType } from './types';
|
|
|
12
12
|
import { trans } from '../../translation';
|
|
13
13
|
import SearchMessagesResult from './SearchMessagesResult';
|
|
14
14
|
import SearchAllResult from './SearchAllResult';
|
|
15
|
-
import
|
|
15
|
+
import SearchContactsResult from './SearchContactsResult';
|
|
16
|
+
import SearchCommunityResult from './SearchCommunityResult';
|
|
17
|
+
import type { IContactSearchItem, ISearchMessageItem } from '../../types/chat';
|
|
16
18
|
|
|
17
19
|
type TabRoute = { key: string; title: string };
|
|
18
20
|
|
|
19
21
|
interface ISearchConversationTabResultProps {
|
|
20
22
|
searchTerm: string;
|
|
21
23
|
onPressItem?: (item: ISearchMessageItem) => void;
|
|
24
|
+
onPressSearchContact?: (item: IContactSearchItem) => void;
|
|
25
|
+
onPressGroup?: (groupId: string) => void;
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
const TabRoutes: TabRoute[] = [
|
|
25
29
|
{ key: SearchConversationTabResultType.All, title: trans('all') },
|
|
26
|
-
|
|
30
|
+
{
|
|
31
|
+
key: SearchConversationTabResultType.Conversations,
|
|
32
|
+
title: trans('contacts'),
|
|
33
|
+
},
|
|
27
34
|
{ key: SearchConversationTabResultType.Messages, title: trans('messages') },
|
|
35
|
+
{
|
|
36
|
+
key: SearchConversationTabResultType.Community,
|
|
37
|
+
title: trans('community'),
|
|
38
|
+
},
|
|
28
39
|
];
|
|
29
40
|
|
|
30
41
|
interface CustomTabBarProps {
|
|
@@ -58,7 +69,12 @@ const CustomTabBar = memo(({ routes, index, onPress }: CustomTabBarProps) => (
|
|
|
58
69
|
));
|
|
59
70
|
|
|
60
71
|
const SearchConversationTabResult = memo(
|
|
61
|
-
({
|
|
72
|
+
({
|
|
73
|
+
searchTerm,
|
|
74
|
+
onPressItem,
|
|
75
|
+
onPressSearchContact,
|
|
76
|
+
onPressGroup,
|
|
77
|
+
}: ISearchConversationTabResultProps) => {
|
|
62
78
|
const [index, setIndex] = useState(0);
|
|
63
79
|
const [routes] = useState<TabRoute[]>(TabRoutes);
|
|
64
80
|
|
|
@@ -78,10 +94,16 @@ const SearchConversationTabResult = memo(
|
|
|
78
94
|
searchTerm={searchTerm}
|
|
79
95
|
handleChangeTab={handleChangeTab}
|
|
80
96
|
onPressItem={onPressItem}
|
|
97
|
+
onPressSearchContact={onPressSearchContact}
|
|
81
98
|
/>
|
|
82
99
|
);
|
|
83
100
|
case SearchConversationTabResultType.Conversations:
|
|
84
|
-
return
|
|
101
|
+
return (
|
|
102
|
+
<SearchContactsResult
|
|
103
|
+
searchTerm={searchTerm}
|
|
104
|
+
onPressSearchContact={onPressSearchContact}
|
|
105
|
+
/>
|
|
106
|
+
);
|
|
85
107
|
case SearchConversationTabResultType.Messages:
|
|
86
108
|
return (
|
|
87
109
|
<SearchMessagesResult
|
|
@@ -89,11 +111,24 @@ const SearchConversationTabResult = memo(
|
|
|
89
111
|
onPressItem={onPressItem}
|
|
90
112
|
/>
|
|
91
113
|
);
|
|
114
|
+
case SearchConversationTabResultType.Community:
|
|
115
|
+
return (
|
|
116
|
+
<SearchCommunityResult
|
|
117
|
+
searchTerm={searchTerm}
|
|
118
|
+
onPressGroup={onPressGroup}
|
|
119
|
+
/>
|
|
120
|
+
);
|
|
92
121
|
default:
|
|
93
122
|
return null;
|
|
94
123
|
}
|
|
95
124
|
},
|
|
96
|
-
[
|
|
125
|
+
[
|
|
126
|
+
searchTerm,
|
|
127
|
+
handleChangeTab,
|
|
128
|
+
onPressItem,
|
|
129
|
+
onPressSearchContact,
|
|
130
|
+
onPressGroup,
|
|
131
|
+
]
|
|
97
132
|
);
|
|
98
133
|
|
|
99
134
|
const renderTabBar = useCallback(
|
|
@@ -5,13 +5,19 @@ import { trans } from '../../translation';
|
|
|
5
5
|
import debounce from 'lodash/debounce';
|
|
6
6
|
import type { TextInput } from 'react-native';
|
|
7
7
|
import SearchConversationTabResult from './TabResult';
|
|
8
|
-
import type { ISearchMessageItem } from '../../types/chat';
|
|
8
|
+
import type { IContactSearchItem, ISearchMessageItem } from '../../types/chat';
|
|
9
9
|
|
|
10
10
|
interface SearchConversationScreenProps {
|
|
11
11
|
onPressItem?: (item: ISearchMessageItem) => void;
|
|
12
|
+
onPressSearchContact?: (item: IContactSearchItem) => void;
|
|
13
|
+
onPressGroup?: (groupId: string) => void;
|
|
12
14
|
}
|
|
13
15
|
const SearchConversationScreen = memo(
|
|
14
|
-
({
|
|
16
|
+
({
|
|
17
|
+
onPressItem,
|
|
18
|
+
onPressSearchContact,
|
|
19
|
+
onPressGroup,
|
|
20
|
+
}: SearchConversationScreenProps) => {
|
|
15
21
|
const nav = useNavigation();
|
|
16
22
|
const [inputValue, setInputValue] = useState('');
|
|
17
23
|
const [searchTerm, setSearchTerm] = useState('');
|
|
@@ -62,6 +68,8 @@ const SearchConversationScreen = memo(
|
|
|
62
68
|
<SearchConversationTabResult
|
|
63
69
|
searchTerm={searchTerm}
|
|
64
70
|
onPressItem={onPressItem}
|
|
71
|
+
onPressSearchContact={onPressSearchContact}
|
|
72
|
+
onPressGroup={onPressGroup}
|
|
65
73
|
/>
|
|
66
74
|
</KContainer.Page>
|
|
67
75
|
);
|
|
@@ -35,11 +35,19 @@ export const MessageToolboxWrapper = memo(
|
|
|
35
35
|
toolbox,
|
|
36
36
|
}: MessageToolboxWrapperProps) => {
|
|
37
37
|
const insets = useSafeAreaInsets();
|
|
38
|
+
const messageHeight = useSharedValue(0);
|
|
38
39
|
const reactionHeight = useSharedValue(0);
|
|
39
40
|
const toolboxHeight = useSharedValue(0);
|
|
40
41
|
const topOffset = Platform.OS === 'android' ? insets.top : 0;
|
|
41
42
|
const { height: windowHeight } = useWindowDimensions();
|
|
42
43
|
|
|
44
|
+
const onMessageCloneLayout = useCallback(
|
|
45
|
+
({ nativeEvent }: LayoutChangeEvent) => {
|
|
46
|
+
messageHeight.value = nativeEvent.layout.height;
|
|
47
|
+
},
|
|
48
|
+
[messageHeight]
|
|
49
|
+
);
|
|
50
|
+
|
|
43
51
|
const onToolboxLayout = useCallback(
|
|
44
52
|
({ nativeEvent }: LayoutChangeEvent) => {
|
|
45
53
|
toolboxHeight.value = nativeEvent.layout.height;
|
|
@@ -62,7 +70,7 @@ export const MessageToolboxWrapper = memo(
|
|
|
62
70
|
const overflowBottom =
|
|
63
71
|
Math.max(rect.y, insets.top) +
|
|
64
72
|
topOffset +
|
|
65
|
-
|
|
73
|
+
messageHeight.value +
|
|
66
74
|
toolboxHeight.value +
|
|
67
75
|
(insets.bottom || 32) +
|
|
68
76
|
menuGap -
|
|
@@ -89,9 +97,19 @@ export const MessageToolboxWrapper = memo(
|
|
|
89
97
|
containerStyles,
|
|
90
98
|
]}
|
|
91
99
|
>
|
|
92
|
-
<View
|
|
93
|
-
|
|
94
|
-
|
|
100
|
+
<View
|
|
101
|
+
pointerEvents="none"
|
|
102
|
+
collapsable={false}
|
|
103
|
+
onLayout={onMessageCloneLayout}
|
|
104
|
+
>
|
|
105
|
+
{message}
|
|
106
|
+
</View>
|
|
107
|
+
<View collapsable={false} onLayout={onReactionLayout}>
|
|
108
|
+
{reaction}
|
|
109
|
+
</View>
|
|
110
|
+
<View collapsable={false} onLayout={onToolboxLayout}>
|
|
111
|
+
{toolbox}
|
|
112
|
+
</View>
|
|
95
113
|
</Animated.View>
|
|
96
114
|
);
|
|
97
115
|
}
|
|
@@ -39,6 +39,7 @@ export const ENDPOINTS = {
|
|
|
39
39
|
`${getApiEndpoint('stickersByCategory')}/${id}/stickers`,
|
|
40
40
|
stickerHistory: () => getApiEndpoint('stickerHistory'),
|
|
41
41
|
searchMessages: () => `${getApiEndpoint('messages')}/search`,
|
|
42
|
+
searchContacts: () => `${getApiEndpoint('contacts')}/search`,
|
|
42
43
|
},
|
|
43
44
|
uploaderService: {
|
|
44
45
|
get uploadImage() {
|
|
@@ -188,7 +188,13 @@ const i18nKey: Record<string, string> = {
|
|
|
188
188
|
'Bạn có thể tìm kiếm theo liên hệ hoặc nội dung tin nhắn',
|
|
189
189
|
'search_message:empty_hint': 'Bạn có thể tìm kiếm theo nội dung tin nhắn',
|
|
190
190
|
'search_conversation:empty_hint': 'Bạn có thể tìm kiếm theo liên hệ',
|
|
191
|
+
'search_community:empty_hint': 'Bạn có thể tìm kiếm theo tên nhóm cộng đồng',
|
|
191
192
|
'view_all': 'Xem tất cả',
|
|
193
|
+
'contact_type:customer': 'Khách hàng',
|
|
194
|
+
'contact_type:pdp': 'PDP',
|
|
195
|
+
'contact_type:group': 'Nhóm',
|
|
196
|
+
'contact_type:seller': 'Người bán',
|
|
197
|
+
'group:no_description': 'Chưa có mô tả nhóm',
|
|
192
198
|
'search_message:revoked_message': 'Tin nhắn đã được thu hồi',
|
|
193
199
|
'chat:no_permission': 'Bạn không có quyền này',
|
|
194
200
|
'chat:no_send_permission': 'Bạn không có quyền gửi tin nhắn',
|
package/src/types/chat.ts
CHANGED
|
@@ -341,3 +341,33 @@ export interface ISearchMessageItem {
|
|
|
341
341
|
chatLog: MessageItem;
|
|
342
342
|
conversation: ConversationItem;
|
|
343
343
|
}
|
|
344
|
+
|
|
345
|
+
export enum ContactCategory {
|
|
346
|
+
Customer = 'CUSTOMER',
|
|
347
|
+
Pdp = 'PDP_BOT',
|
|
348
|
+
Group = 'GROUP',
|
|
349
|
+
Seller = 'USER',
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
export type IContactSearchRequest = {
|
|
353
|
+
applicationType: DChatApplicationType;
|
|
354
|
+
searchTerm: string;
|
|
355
|
+
page: number;
|
|
356
|
+
pageSize: number;
|
|
357
|
+
type?: ContactCategory;
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
export interface IContactSearchItem {
|
|
361
|
+
id: string;
|
|
362
|
+
type: ContactCategory;
|
|
363
|
+
targetUserId?: string;
|
|
364
|
+
targetCustomerId?: string;
|
|
365
|
+
targetGroupId?: string;
|
|
366
|
+
targetBotId?: string;
|
|
367
|
+
targetName: string;
|
|
368
|
+
targetAvatar?: string;
|
|
369
|
+
applicationType: DChatApplicationType;
|
|
370
|
+
lastOnlineTime?: string;
|
|
371
|
+
memberCount?: number;
|
|
372
|
+
description?: string;
|
|
373
|
+
}
|
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
* Date and time formatting utilities
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import dayjs from 'dayjs';
|
|
6
|
+
import relativeTime from 'dayjs/plugin/relativeTime';
|
|
7
|
+
import 'dayjs/locale/vi';
|
|
8
|
+
|
|
9
|
+
dayjs.extend(relativeTime);
|
|
10
|
+
|
|
5
11
|
export const formatDuration = (durationMs: number): string => {
|
|
6
12
|
// Convert milliseconds to seconds
|
|
7
13
|
const totalSeconds = Math.floor(durationMs / 1000);
|
|
@@ -46,3 +52,12 @@ export const formatTimestamp = (ts: number | string | null): string => {
|
|
|
46
52
|
return '';
|
|
47
53
|
}
|
|
48
54
|
};
|
|
55
|
+
|
|
56
|
+
export const formatLastOnlineTime = (ts: number | string | null): string => {
|
|
57
|
+
if (!ts) return '';
|
|
58
|
+
|
|
59
|
+
const date = dayjs(ts).locale('vi');
|
|
60
|
+
if (!date.isValid()) return '';
|
|
61
|
+
|
|
62
|
+
return date.fromNow();
|
|
63
|
+
};
|
|
@@ -4,6 +4,16 @@ export interface HighlightResult {
|
|
|
4
4
|
after: string;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
// Strips Vietnamese diacritics one base-character-at-a-time (NFD decomposition +
|
|
8
|
+
// combining-mark removal, plus đ/Đ which NFD doesn't decompose) so the result stays
|
|
9
|
+
// the same length and index-aligned with the input
|
|
10
|
+
const stripDiacritics = (input: string): string =>
|
|
11
|
+
input
|
|
12
|
+
.normalize('NFD')
|
|
13
|
+
.replace(/[\u0300-\u036f]/g, '')
|
|
14
|
+
.replace(/đ/g, 'd')
|
|
15
|
+
.replace(/Đ/g, 'D');
|
|
16
|
+
|
|
7
17
|
export const highlightSearch = (
|
|
8
18
|
text: string,
|
|
9
19
|
keyword: string,
|
|
@@ -11,8 +21,8 @@ export const highlightSearch = (
|
|
|
11
21
|
): HighlightResult | null => {
|
|
12
22
|
if (!keyword) return null;
|
|
13
23
|
|
|
14
|
-
const lowerText = text.toLowerCase();
|
|
15
|
-
const lowerKeyword = keyword.toLowerCase();
|
|
24
|
+
const lowerText = stripDiacritics(text.toLowerCase());
|
|
25
|
+
const lowerKeyword = stripDiacritics(keyword.toLowerCase());
|
|
16
26
|
const index = lowerText.indexOf(lowerKeyword);
|
|
17
27
|
|
|
18
28
|
if (index === -1) return null;
|
|
@@ -442,15 +442,21 @@ export const getSenderName = (
|
|
|
442
442
|
currentUserId?: string,
|
|
443
443
|
conversation?: ConversationItem
|
|
444
444
|
): string => {
|
|
445
|
-
const
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
445
|
+
const isCurrentUser = currentUserId && message.sendID === currentUserId;
|
|
446
|
+
|
|
447
|
+
if (isCurrentUser) return 'Bạn';
|
|
448
|
+
|
|
449
|
+
switch (conversation?.peerType) {
|
|
450
|
+
case PeerType.Bot:
|
|
451
|
+
case PeerType.Customer:
|
|
452
|
+
case PeerType.User:
|
|
453
|
+
return '';
|
|
454
|
+
|
|
455
|
+
default:
|
|
456
|
+
return (
|
|
457
|
+
message?.senderNickname || getNotificationOpUserNickname(message) || ''
|
|
458
|
+
);
|
|
459
|
+
}
|
|
454
460
|
};
|
|
455
461
|
|
|
456
462
|
export interface GetLastMessageTextParams {
|