@droppii-org/chat-mobile 0.2.58 → 0.2.60

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 (51) hide show
  1. package/lib/module/hooks/message/usePinMessage.js +30 -26
  2. package/lib/module/hooks/message/usePinMessage.js.map +1 -1
  3. package/lib/module/hooks/message/useSearchMessage.js +2 -1
  4. package/lib/module/hooks/message/useSearchMessage.js.map +1 -1
  5. package/lib/module/index.js +1 -0
  6. package/lib/module/index.js.map +1 -1
  7. package/lib/module/screens/ChatInfo/ChatInfoActions.js +1 -1
  8. package/lib/module/screens/ChatInfo/ChatInfoActions.js.map +1 -1
  9. package/lib/module/screens/SearchConversation/index.js +11 -7
  10. package/lib/module/screens/SearchConversation/index.js.map +1 -1
  11. package/lib/module/screens/SearchMessage/SearchMessageResult.js +71 -0
  12. package/lib/module/screens/SearchMessage/SearchMessageResult.js.map +1 -0
  13. package/lib/module/screens/SearchMessage/SearchResultItem.js +94 -0
  14. package/lib/module/screens/SearchMessage/SearchResultItem.js.map +1 -0
  15. package/lib/module/screens/SearchMessage/index.js +63 -0
  16. package/lib/module/screens/SearchMessage/index.js.map +1 -0
  17. package/lib/module/screens/chat-detail/BotMenuSheet.js +4 -4
  18. package/lib/module/screens/chat-detail/BotMenuSheet.js.map +1 -1
  19. package/lib/module/screens/chat-detail/ChatComposer.js +19 -4
  20. package/lib/module/screens/chat-detail/ChatComposer.js.map +1 -1
  21. package/lib/module/screens/chat-detail/ChatDetailHeader.js +2 -2
  22. package/lib/module/screens/chat-detail/ChatDetailHeader.js.map +1 -1
  23. package/lib/typescript/src/hooks/message/usePinMessage.d.ts.map +1 -1
  24. package/lib/typescript/src/hooks/message/useSearchMessage.d.ts.map +1 -1
  25. package/lib/typescript/src/index.d.ts +1 -0
  26. package/lib/typescript/src/index.d.ts.map +1 -1
  27. package/lib/typescript/src/screens/SearchConversation/index.d.ts.map +1 -1
  28. package/lib/typescript/src/screens/SearchMessage/SearchMessageResult.d.ts +9 -0
  29. package/lib/typescript/src/screens/SearchMessage/SearchMessageResult.d.ts.map +1 -0
  30. package/lib/typescript/src/screens/SearchMessage/SearchResultItem.d.ts +8 -0
  31. package/lib/typescript/src/screens/SearchMessage/SearchResultItem.d.ts.map +1 -0
  32. package/lib/typescript/src/screens/SearchMessage/index.d.ts +8 -0
  33. package/lib/typescript/src/screens/SearchMessage/index.d.ts.map +1 -0
  34. package/lib/typescript/src/screens/chat-detail/BotMenuSheet.d.ts.map +1 -1
  35. package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts.map +1 -1
  36. package/lib/typescript/src/screens/chat-detail/ChatDetailHeader.d.ts.map +1 -1
  37. package/lib/typescript/src/screens/chat-detail/types.d.ts +1 -1
  38. package/lib/typescript/src/screens/chat-detail/types.d.ts.map +1 -1
  39. package/package.json +1 -1
  40. package/src/hooks/message/usePinMessage.ts +34 -30
  41. package/src/hooks/message/useSearchMessage.ts +1 -0
  42. package/src/index.tsx +1 -0
  43. package/src/screens/ChatInfo/ChatInfoActions.tsx +1 -1
  44. package/src/screens/SearchConversation/index.tsx +17 -7
  45. package/src/screens/SearchMessage/SearchMessageResult.tsx +69 -0
  46. package/src/screens/SearchMessage/SearchResultItem.tsx +92 -0
  47. package/src/screens/SearchMessage/index.tsx +75 -0
  48. package/src/screens/chat-detail/BotMenuSheet.tsx +2 -3
  49. package/src/screens/chat-detail/ChatComposer.tsx +27 -8
  50. package/src/screens/chat-detail/ChatDetailHeader.tsx +10 -2
  51. package/src/screens/chat-detail/types.ts +1 -1
@@ -0,0 +1,75 @@
1
+ import { KColors, KContainer, KNavigation } from '@droppii/libs';
2
+ import { useCallback, useEffect, useRef, useState } from 'react';
3
+ import type { TextInput } from 'react-native';
4
+ import { useNavigation } from '@react-navigation/native';
5
+ import debounce from 'lodash/debounce';
6
+ import { trans } from '../../translation';
7
+ import type { ISearchMessageItem } from '../../types/chat';
8
+ import SearchMessagesResult from './SearchMessageResult';
9
+
10
+ interface SearchMessageScreenProps {
11
+ onPressItem?: (item: ISearchMessageItem) => void;
12
+ targetConversationId: string;
13
+ }
14
+
15
+ const SearchMessageScreen = ({
16
+ onPressItem,
17
+ targetConversationId,
18
+ }: SearchMessageScreenProps) => {
19
+ const nav = useNavigation();
20
+ const [inputValue, setInputValue] = useState('');
21
+ const [searchTerm, setSearchTerm] = useState('');
22
+ const searchInputRef = useRef<TextInput>(null);
23
+
24
+ const debouncedSearch = useRef(
25
+ debounce((text: string) => setSearchTerm(text), 500, {
26
+ leading: false,
27
+ trailing: true,
28
+ })
29
+ ).current;
30
+
31
+ useEffect(() => () => debouncedSearch.cancel(), [debouncedSearch]);
32
+
33
+ const handleChangeText = useCallback(
34
+ (text: string) => {
35
+ setInputValue(text);
36
+ debouncedSearch(text);
37
+ },
38
+ [debouncedSearch]
39
+ );
40
+
41
+ return (
42
+ <KContainer.Page flex background={KColors.white} edges={['bottom']}>
43
+ <KNavigation.HeaderV2Body
44
+ theme="light"
45
+ size="large"
46
+ isNested
47
+ leftButton={{
48
+ id: 'back',
49
+ icon: { vectorName: 'arrow-left-o' },
50
+ onPress: nav.goBack,
51
+ }}
52
+ searchProps={{
53
+ position: 'center',
54
+ placeholder: trans('search'),
55
+ onChangeText: handleChangeText,
56
+ ref: searchInputRef as any,
57
+ returnKeyType: 'search',
58
+ value: inputValue,
59
+ autoFocus: true,
60
+ background: KColors.palette.gray.w25,
61
+ br: '2x',
62
+ searchIconLeftColor: KColors.gray.normal,
63
+ marginL: undefined,
64
+ }}
65
+ />
66
+ <SearchMessagesResult
67
+ searchTerm={searchTerm}
68
+ conversationId={targetConversationId}
69
+ onPressItem={onPressItem}
70
+ />
71
+ </KContainer.Page>
72
+ );
73
+ };
74
+
75
+ export default SearchMessageScreen;
@@ -31,9 +31,8 @@ const BotMenuSheetContent = memo(
31
31
  return (
32
32
  <KContainer.View paddingH="0.75rem" paddingV="0.25rem">
33
33
  {options?.map((item, index) => (
34
- <>
34
+ <KContainer.View key={item.id}>
35
35
  <KContainer.Touchable
36
- key={item.id}
37
36
  row
38
37
  alignItems
39
38
  justifyContent="space-between"
@@ -54,7 +53,7 @@ const BotMenuSheetContent = memo(
54
53
  <KContainer.VisibleView visible={index !== options?.length - 1}>
55
54
  <KDivider size="hairline" />
56
55
  </KContainer.VisibleView>
57
- </>
56
+ </KContainer.View>
58
57
  ))}
59
58
  </KContainer.View>
60
59
  );
@@ -48,9 +48,13 @@ import { useChatComposerState } from './hooks/useChatComposerState';
48
48
  import { useChatComposerAnimation } from './hooks/useChatComposerAnimation';
49
49
  import { useChatDetailContext } from '../../context/ChatDetailContext';
50
50
  import { trans } from '../../translation';
51
- import { useCloseSupportSession, useRunFlow } from '../../hooks/flows/useFlow';
51
+ import {
52
+ useCloseSupportSession,
53
+ useResetFlow,
54
+ useRunFlow,
55
+ } from '../../hooks/flows/useFlow';
52
56
  import { ReactFlowsNodeTypes, type InputButtonItem } from '../../types/flows';
53
- import { isContextButton } from '../../utils/flows';
57
+ import { DEFAULT_BUTTON_ID, isContextButton } from '../../utils/flows';
54
58
  import { DFlowState } from '../../types/chat';
55
59
  import { useAttachmentMapping } from './hooks/useAttachmentMapping';
56
60
  import type { AttachmentType } from '../../types/attachment';
@@ -87,6 +91,7 @@ export const ChatComposer = memo(
87
91
  flowState,
88
92
  } = useChatDetailContext();
89
93
  const { mutate: runFlow, isPending } = useRunFlow();
94
+ const { mutate: resetFlow } = useResetFlow();
90
95
  const { mutateAsync: closeSupportSession } = useCloseSupportSession();
91
96
  const { sendMessage } = useSendMessage();
92
97
  const compose = useChatCompose();
@@ -215,18 +220,32 @@ export const ChatComposer = memo(
215
220
  });
216
221
  }, [runFlow, conversationFlow]);
217
222
 
218
- const botMenuOptions = useMemo(
219
- () =>
223
+ const botMenuOptions = useMemo(() => {
224
+ const apiOptions =
220
225
  conversationFlowMainMenu?.filter(
221
226
  (item) => !isContextButton(item.label)
222
- ) || [],
223
- [conversationFlowMainMenu]
224
- );
227
+ ) || [];
228
+
229
+ const hasDefaultButton = apiOptions.some(
230
+ (item) => item.id === DEFAULT_BUTTON_ID
231
+ );
232
+
233
+ if (hasDefaultButton) return apiOptions;
234
+
235
+ return [
236
+ ...apiOptions,
237
+ { id: DEFAULT_BUTTON_ID, label: trans('restart') },
238
+ ];
239
+ }, [conversationFlowMainMenu]);
225
240
 
226
241
  const hasBotMenuOptions = isBotConversation && botMenuOptions.length > 0;
227
242
 
228
243
  const runBotMenuOption = useCallback(
229
244
  (item: InputButtonItem) => {
245
+ if (item.id === DEFAULT_BUTTON_ID) {
246
+ resetFlow();
247
+ return;
248
+ }
230
249
  runFlow({
231
250
  actionId: item.id,
232
251
  groupId: '',
@@ -234,7 +253,7 @@ export const ChatComposer = memo(
234
253
  plainText: item.label,
235
254
  });
236
255
  },
237
- [runFlow]
256
+ [runFlow, resetFlow]
238
257
  );
239
258
 
240
259
  const handleSelectBotMenuOption = useCallback(
@@ -47,7 +47,9 @@ const ChatDetailHeader = memo(
47
47
  icon: {
48
48
  vectorName: 'search-o',
49
49
  },
50
- onPress: onPressSearch,
50
+ onPress: conversationId
51
+ ? () => onPressSearch?.(conversationId)
52
+ : undefined,
51
53
  },
52
54
  {
53
55
  id: 'menu',
@@ -71,7 +73,13 @@ const ChatDetailHeader = memo(
71
73
  }
72
74
 
73
75
  return buttons;
74
- }, [onPressSearch, onPressAddMember, onPressMenu, showAddMember]);
76
+ }, [
77
+ onPressSearch,
78
+ onPressAddMember,
79
+ onPressMenu,
80
+ showAddMember,
81
+ conversationId,
82
+ ]);
75
83
 
76
84
  const leftNode = useMemo(
77
85
  () => (
@@ -40,7 +40,7 @@ export interface DChatPannelAction extends DChatActionItem {
40
40
  export interface ChatDetailHeaderProps {
41
41
  showAddMember?: boolean;
42
42
  onBack?: () => void;
43
- onPressSearch?: () => void;
43
+ onPressSearch?: (conversationId: string) => void;
44
44
  onPressAddMember?: () => void;
45
45
  onPressMenu?: (conversationId?: string) => void;
46
46
  onPressAvatar?: () => void;