@droppii-org/chat-mobile 0.2.11 → 0.2.13
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/components/ThreadCard/AvatarSection.js +2 -3
- package/lib/module/components/ThreadCard/AvatarSection.js.map +1 -1
- package/lib/module/components/flows/inputButtons/index.js +77 -0
- package/lib/module/components/flows/inputButtons/index.js.map +1 -0
- package/lib/module/components/messages/linkMessage/index.js +35 -7
- package/lib/module/components/messages/linkMessage/index.js.map +1 -1
- package/lib/module/config/api-endpoints.js +1 -0
- package/lib/module/config/api-endpoints.js.map +1 -1
- package/lib/module/context/ChatDetailContext.js +57 -0
- package/lib/module/context/ChatDetailContext.js.map +1 -0
- package/lib/module/hooks/flows/useCurrentConversationFlow.js +9 -0
- package/lib/module/hooks/flows/useCurrentConversationFlow.js.map +1 -0
- package/lib/module/hooks/flows/useFlow.js +57 -0
- package/lib/module/hooks/flows/useFlow.js.map +1 -0
- package/lib/module/hooks/message/useSendMessage.js +4 -2
- package/lib/module/hooks/message/useSendMessage.js.map +1 -1
- package/lib/module/hooks/query-keys.js +4 -1
- package/lib/module/hooks/query-keys.js.map +1 -1
- package/lib/module/hooks/useConversationList.js +1 -1
- package/lib/module/hooks/useConversationList.js.map +1 -1
- package/lib/module/hooks/useLinkPreview/useFetchUrlMetadata.js +6 -4
- package/lib/module/hooks/useLinkPreview/useFetchUrlMetadata.js.map +1 -1
- package/lib/module/hooks/useLinkPreview/useLinkPreview.js +2 -2
- package/lib/module/hooks/useLinkPreview/useLinkPreview.js.map +1 -1
- package/lib/module/screens/chat-detail/ChatComposer.js +41 -3
- package/lib/module/screens/chat-detail/ChatComposer.js.map +1 -1
- package/lib/module/screens/chat-detail/ChatDetail.js +65 -60
- package/lib/module/screens/chat-detail/ChatDetail.js.map +1 -1
- package/lib/module/screens/chat-detail/ChatListLegend.js +45 -10
- package/lib/module/screens/chat-detail/ChatListLegend.js.map +1 -1
- package/lib/module/screens/chat-detail/ChatQuickActions.js +12 -3
- package/lib/module/screens/chat-detail/ChatQuickActions.js.map +1 -1
- package/lib/module/screens/chat-detail/conversationHeader.utils.js +1 -1
- package/lib/module/screens/chat-detail/conversationHeader.utils.js.map +1 -1
- package/lib/module/screens/chat-detail/legend/LegendChatMessage.js +6 -1
- package/lib/module/screens/chat-detail/legend/LegendChatMessage.js.map +1 -1
- package/lib/module/screens/inbox/Inbox.js +1 -3
- package/lib/module/screens/inbox/Inbox.js.map +1 -1
- package/lib/module/screens/inbox/MessagesTab.js +2 -1
- package/lib/module/screens/inbox/MessagesTab.js.map +1 -1
- package/lib/module/services/endpoints.js +4 -1
- package/lib/module/services/endpoints.js.map +1 -1
- package/lib/module/translation/resources/i18n.js +3 -1
- package/lib/module/translation/resources/i18n.js.map +1 -1
- package/lib/module/types/chat.js.map +1 -1
- package/lib/module/types/flows.js +17 -0
- package/lib/module/types/flows.js.map +1 -0
- package/lib/module/utils/flows.js +11 -0
- package/lib/module/utils/flows.js.map +1 -0
- package/lib/module/utils/url.js +12 -1
- package/lib/module/utils/url.js.map +1 -1
- package/lib/typescript/src/components/ThreadCard/AvatarSection.d.ts +1 -1
- package/lib/typescript/src/components/ThreadCard/AvatarSection.d.ts.map +1 -1
- package/lib/typescript/src/components/flows/inputButtons/index.d.ts +9 -0
- package/lib/typescript/src/components/flows/inputButtons/index.d.ts.map +1 -0
- package/lib/typescript/src/components/messages/linkMessage/index.d.ts +2 -1
- package/lib/typescript/src/components/messages/linkMessage/index.d.ts.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/context/ChatDetailContext.d.ts +5 -0
- package/lib/typescript/src/context/ChatDetailContext.d.ts.map +1 -0
- package/lib/typescript/src/hooks/flows/useCurrentConversationFlow.d.ts +3 -0
- package/lib/typescript/src/hooks/flows/useCurrentConversationFlow.d.ts.map +1 -0
- package/lib/typescript/src/hooks/flows/useFlow.d.ts +4 -0
- package/lib/typescript/src/hooks/flows/useFlow.d.ts.map +1 -0
- package/lib/typescript/src/hooks/message/useSendMessage.d.ts +3 -1
- package/lib/typescript/src/hooks/message/useSendMessage.d.ts.map +1 -1
- package/lib/typescript/src/hooks/query-keys.d.ts +3 -0
- package/lib/typescript/src/hooks/query-keys.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useConversationList.d.ts +2 -2
- package/lib/typescript/src/hooks/useConversationList.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useLinkPreview/useFetchUrlMetadata.d.ts +6 -2
- package/lib/typescript/src/hooks/useLinkPreview/useFetchUrlMetadata.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useLinkPreview/useLinkPreview.d.ts +6 -1
- package/lib/typescript/src/hooks/useLinkPreview/useLinkPreview.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatQuickActions.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/conversationHeader.utils.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts +2 -1
- package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/types.d.ts +5 -10
- package/lib/typescript/src/screens/chat-detail/types.d.ts.map +1 -1
- package/lib/typescript/src/screens/inbox/Inbox.d.ts +1 -2
- package/lib/typescript/src/screens/inbox/Inbox.d.ts.map +1 -1
- package/lib/typescript/src/screens/inbox/MessagesTab.d.ts +1 -2
- package/lib/typescript/src/screens/inbox/MessagesTab.d.ts.map +1 -1
- package/lib/typescript/src/services/endpoints.d.ts +3 -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 +11 -1
- package/lib/typescript/src/types/chat.d.ts.map +1 -1
- package/lib/typescript/src/types/flows.d.ts +82 -0
- package/lib/typescript/src/types/flows.d.ts.map +1 -0
- package/lib/typescript/src/utils/flows.d.ts +4 -0
- package/lib/typescript/src/utils/flows.d.ts.map +1 -0
- package/lib/typescript/src/utils/url.d.ts.map +1 -1
- package/package.json +6 -4
- package/src/components/ThreadCard/AvatarSection.tsx +2 -2
- package/src/components/flows/inputButtons/index.tsx +105 -0
- package/src/components/messages/linkMessage/index.tsx +48 -8
- package/src/config/api-endpoints.ts +2 -0
- package/src/context/ChatDetailContext.tsx +85 -0
- package/src/hooks/flows/useCurrentConversationFlow.ts +11 -0
- package/src/hooks/flows/useFlow.ts +63 -0
- package/src/hooks/message/useSendMessage.ts +4 -0
- package/src/hooks/query-keys.ts +6 -0
- package/src/hooks/useConversationList.ts +15 -7
- package/src/hooks/useLinkPreview/useFetchUrlMetadata.ts +7 -3
- package/src/hooks/useLinkPreview/useLinkPreview.ts +2 -2
- package/src/index.tsx +1 -0
- package/src/screens/chat-detail/ChatComposer.tsx +41 -2
- package/src/screens/chat-detail/ChatDetail.tsx +81 -74
- package/src/screens/chat-detail/ChatListLegend.tsx +57 -3
- package/src/screens/chat-detail/ChatQuickActions.tsx +10 -3
- package/src/screens/chat-detail/conversationHeader.utils.ts +1 -4
- package/src/screens/chat-detail/legend/LegendChatMessage.tsx +7 -0
- package/src/screens/chat-detail/types.ts +9 -10
- package/src/screens/inbox/Inbox.tsx +3 -15
- package/src/screens/inbox/MessagesTab.tsx +48 -49
- package/src/services/endpoints.ts +6 -0
- package/src/translation/resources/i18n.ts +2 -0
- package/src/types/chat.ts +16 -1
- package/src/types/flows.ts +102 -0
- package/src/utils/flows.ts +18 -0
- package/src/utils/url.ts +30 -1
|
@@ -15,6 +15,7 @@ interface LegendChatMessageProps {
|
|
|
15
15
|
isOutgoing: boolean;
|
|
16
16
|
createdAtTime: number;
|
|
17
17
|
onMediaPress?: (items: MediaItem[], index?: number) => void;
|
|
18
|
+
onPressUrl?: (url: string) => void;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
// OpenIM message types (not all exposed as MessageType enum)
|
|
@@ -41,6 +42,7 @@ export const LegendChatMessage = memo(
|
|
|
41
42
|
isOutgoing,
|
|
42
43
|
createdAtTime,
|
|
43
44
|
onMediaPress,
|
|
45
|
+
onPressUrl,
|
|
44
46
|
}: LegendChatMessageProps) => {
|
|
45
47
|
const MessageComponent =
|
|
46
48
|
messageComponentMap[message?.contentType] ?? TextMessage;
|
|
@@ -53,6 +55,8 @@ export const LegendChatMessage = memo(
|
|
|
53
55
|
];
|
|
54
56
|
const hasMediaPress =
|
|
55
57
|
mediaTypes.includes(message?.contentType) && onMediaPress;
|
|
58
|
+
const hasUrlPress =
|
|
59
|
+
onPressUrl && message?.contentType === MessageType.UrlTextMessage;
|
|
56
60
|
|
|
57
61
|
const props: any = {
|
|
58
62
|
message,
|
|
@@ -63,6 +67,9 @@ export const LegendChatMessage = memo(
|
|
|
63
67
|
if (hasMediaPress) {
|
|
64
68
|
props.onMediaPress = onMediaPress;
|
|
65
69
|
}
|
|
70
|
+
if (hasUrlPress) {
|
|
71
|
+
props.onPressUrl = onPressUrl;
|
|
72
|
+
}
|
|
66
73
|
|
|
67
74
|
return <MessageComponent {...props} />;
|
|
68
75
|
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
|
|
3
3
|
import type { MediaItem } from '../../hooks/useMediaViewer';
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
DChatApplicationType,
|
|
6
|
+
DConversationItem,
|
|
7
|
+
DMessageItem,
|
|
8
|
+
} from '../../types/chat';
|
|
5
9
|
import type { IUrlMetadata } from '../../types/common';
|
|
6
10
|
import type { PeerType } from '@droppii/openim-rn-client-sdk';
|
|
7
11
|
|
|
@@ -75,6 +79,7 @@ export interface ChatComposerProps {
|
|
|
75
79
|
renderQuickActions?: ChatQuickActionsProps['renderQuickActions'];
|
|
76
80
|
renderAttachmentAction?: ChatAttachmentPanelProps['renderAction'];
|
|
77
81
|
attachmentColumns?: number;
|
|
82
|
+
isEmptyMessage: boolean;
|
|
78
83
|
}
|
|
79
84
|
|
|
80
85
|
export interface ChatListProps {
|
|
@@ -89,6 +94,7 @@ export interface ChatListProps {
|
|
|
89
94
|
isLoadingNewer?: boolean;
|
|
90
95
|
hasMoreNewer?: boolean;
|
|
91
96
|
onMediaPress?: (items: MediaItem[], index?: number) => void;
|
|
97
|
+
onPressUrl?: (url: string) => void;
|
|
92
98
|
}
|
|
93
99
|
|
|
94
100
|
export interface ChatDetailProps extends Omit<
|
|
@@ -108,25 +114,17 @@ export interface ChatDetailProps extends Omit<
|
|
|
108
114
|
avatarUri?: string | null;
|
|
109
115
|
avatarFullName?: string;
|
|
110
116
|
peerType?: PeerType;
|
|
111
|
-
applicationType?:
|
|
117
|
+
applicationType?: DChatApplicationType;
|
|
112
118
|
showAddMember?: boolean;
|
|
113
119
|
getSubtitle?: (conversation: DConversationItem) => string | undefined;
|
|
114
120
|
renderChat?: (item: DMessageItem) => ReactNode;
|
|
115
121
|
showQuickActions?: boolean;
|
|
116
122
|
showAttachmentActions?: boolean;
|
|
117
|
-
onLoadEarlier?: () => void;
|
|
118
|
-
isLoading?: boolean;
|
|
119
|
-
isLoadingEarlier?: boolean;
|
|
120
|
-
hasMoreEarlier?: boolean;
|
|
121
|
-
onLoadNewer?: () => void;
|
|
122
|
-
isLoadingNewer?: boolean;
|
|
123
|
-
hasMoreNewer?: boolean;
|
|
124
123
|
quickActions?: DChatQuickAction[];
|
|
125
124
|
getQuickActions?: (
|
|
126
125
|
conversation: DConversationItem
|
|
127
126
|
) => DChatQuickAction[] | undefined;
|
|
128
127
|
attachmentActions?: DChatAttachmentAction[];
|
|
129
|
-
inputValue?: string;
|
|
130
128
|
inputPlaceholder?: string;
|
|
131
129
|
onChangeInput?: (text: string) => void;
|
|
132
130
|
onSend?: () => void;
|
|
@@ -138,4 +136,5 @@ export interface ChatDetailProps extends Omit<
|
|
|
138
136
|
renderQuickActions?: ChatQuickActionsProps['renderQuickActions'];
|
|
139
137
|
renderAttachmentAction?: ChatAttachmentPanelProps['renderAction'];
|
|
140
138
|
attachmentColumns?: number;
|
|
139
|
+
onPressUrl?: (url: string) => void;
|
|
141
140
|
}
|
|
@@ -5,7 +5,6 @@ import { KContainer, KImage, KLabel, KColors } from '@droppii/libs';
|
|
|
5
5
|
import { MessagesTab } from './MessagesTab';
|
|
6
6
|
|
|
7
7
|
interface InboxProps {
|
|
8
|
-
applicationType: string;
|
|
9
8
|
onPressThread?: (item: string) => void;
|
|
10
9
|
onPressSearch?: () => void;
|
|
11
10
|
onPressEdit?: () => void;
|
|
@@ -15,13 +14,7 @@ interface InboxProps {
|
|
|
15
14
|
type TabRoute = { key: string; title: string };
|
|
16
15
|
|
|
17
16
|
const Inbox = memo(
|
|
18
|
-
({
|
|
19
|
-
applicationType,
|
|
20
|
-
onPressThread,
|
|
21
|
-
onPressSearch,
|
|
22
|
-
onPressEdit,
|
|
23
|
-
onPressGroup,
|
|
24
|
-
}: InboxProps) => {
|
|
17
|
+
({ onPressThread, onPressSearch, onPressEdit, onPressGroup }: InboxProps) => {
|
|
25
18
|
const [index, setIndex] = useState(0);
|
|
26
19
|
const [routes] = useState<TabRoute[]>([
|
|
27
20
|
{ key: 'messages', title: 'Tin nhắn' },
|
|
@@ -30,16 +23,11 @@ const Inbox = memo(
|
|
|
30
23
|
const renderScene = useCallback(
|
|
31
24
|
({ route }: { route: TabRoute }) => {
|
|
32
25
|
if (route.key === 'messages') {
|
|
33
|
-
return
|
|
34
|
-
<MessagesTab
|
|
35
|
-
applicationType={applicationType}
|
|
36
|
-
onPressThread={onPressThread}
|
|
37
|
-
/>
|
|
38
|
-
);
|
|
26
|
+
return <MessagesTab onPressThread={onPressThread} />;
|
|
39
27
|
}
|
|
40
28
|
return null;
|
|
41
29
|
},
|
|
42
|
-
[
|
|
30
|
+
[onPressThread]
|
|
43
31
|
);
|
|
44
32
|
|
|
45
33
|
const renderTabBar = useCallback(
|
|
@@ -4,69 +4,68 @@ import { KContainer, KDivider, KLabel, KColors } from '@droppii/libs';
|
|
|
4
4
|
import { useConversationList } from '../../hooks/useConversationList';
|
|
5
5
|
import { ThreadCard } from '../../components/ThreadCard';
|
|
6
6
|
import { useConversationStore } from '../../store';
|
|
7
|
+
import { useChatContext } from '../../context';
|
|
7
8
|
|
|
8
9
|
interface MessagesTabProps {
|
|
9
|
-
applicationType: string;
|
|
10
10
|
onPressThread?: (item: string) => void;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
const Separator = () => <KDivider type="line" size="hairline" />;
|
|
14
14
|
const keyExtractor = (item: string) => item;
|
|
15
15
|
|
|
16
|
-
export const MessagesTab = memo(
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
export const MessagesTab = memo(({ onPressThread }: MessagesTabProps) => {
|
|
17
|
+
const data = useConversationStore((state) => state.list);
|
|
18
|
+
const applicationType = useChatContext().applicationType;
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
const { isLoading, refetch, isRefetching } = useConversationList({
|
|
21
|
+
applicationType,
|
|
22
|
+
page: 1,
|
|
23
|
+
});
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
const handleThreadPress = useCallback(
|
|
26
|
+
(params: { item: string; event: GestureResponderEvent }) => {
|
|
27
|
+
onPressThread?.(params.item);
|
|
28
|
+
},
|
|
29
|
+
[onPressThread]
|
|
30
|
+
);
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
const renderItem = useCallback(
|
|
33
|
+
({ item }: { item: string }) => (
|
|
34
|
+
<ThreadCard item={item} onPress={handleThreadPress} />
|
|
35
|
+
),
|
|
36
|
+
[handleThreadPress]
|
|
37
|
+
);
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
const LoadingComponent = (
|
|
40
|
+
<KContainer.View center flex paddingV="3rem">
|
|
41
|
+
<ActivityIndicator size="large" color={KColors.palette.primary.w400} />
|
|
42
|
+
</KContainer.View>
|
|
43
|
+
);
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
const EmptyComponent = isLoading ? null : (
|
|
46
|
+
<KContainer.View center flex paddingV="3rem">
|
|
47
|
+
<KLabel.Text typo="TextSmNormal" color={KColors.palette.gray.w400}>
|
|
48
|
+
Không có tin nhắn nào
|
|
49
|
+
</KLabel.Text>
|
|
50
|
+
</KContainer.View>
|
|
51
|
+
);
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return (
|
|
58
|
-
<KContainer.FlatList
|
|
59
|
-
data={data}
|
|
60
|
-
renderItem={renderItem}
|
|
61
|
-
keyExtractor={keyExtractor}
|
|
62
|
-
ItemSeparatorComponent={Separator}
|
|
63
|
-
ListEmptyComponent={EmptyComponent}
|
|
64
|
-
refreshing={isRefetching}
|
|
65
|
-
onRefresh={refetch}
|
|
66
|
-
showsVerticalScrollIndicator={false}
|
|
67
|
-
/>
|
|
68
|
-
);
|
|
53
|
+
if (isLoading && data.length === 0) {
|
|
54
|
+
return LoadingComponent;
|
|
69
55
|
}
|
|
70
|
-
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<KContainer.FlatList
|
|
59
|
+
data={data}
|
|
60
|
+
renderItem={renderItem}
|
|
61
|
+
keyExtractor={keyExtractor}
|
|
62
|
+
ItemSeparatorComponent={Separator}
|
|
63
|
+
ListEmptyComponent={EmptyComponent}
|
|
64
|
+
refreshing={isRefetching}
|
|
65
|
+
onRefresh={refetch}
|
|
66
|
+
showsVerticalScrollIndicator={false}
|
|
67
|
+
/>
|
|
68
|
+
);
|
|
69
|
+
});
|
|
71
70
|
|
|
72
71
|
MessagesTab.displayName = 'MessagesTab';
|
|
@@ -16,6 +16,12 @@ export const ENDPOINTS = {
|
|
|
16
16
|
get urlMetadata() {
|
|
17
17
|
return getApiEndpoint('urlMetadata');
|
|
18
18
|
},
|
|
19
|
+
conversationFlow: (id: string) =>
|
|
20
|
+
`${getApiEndpoint('conversationFlow')}/${id}`,
|
|
21
|
+
resetConversationFlow: (id: string) =>
|
|
22
|
+
`${getApiEndpoint('conversationFlow')}/${id}/bot-flows/reset`,
|
|
23
|
+
runConversationFlow: (id: string) =>
|
|
24
|
+
`${getApiEndpoint('conversationFlow')}/${id}/bot-flows/run`,
|
|
19
25
|
},
|
|
20
26
|
uploaderService: {
|
|
21
27
|
get uploadImage() {
|
package/src/types/chat.ts
CHANGED
|
@@ -5,6 +5,11 @@ import {
|
|
|
5
5
|
} from '@droppii/openim-rn-client-sdk';
|
|
6
6
|
import type { PropsWithChildren } from 'react';
|
|
7
7
|
import type { IUrlMetadata } from './common';
|
|
8
|
+
import type {
|
|
9
|
+
IConversationFlow,
|
|
10
|
+
IConversationFlowStep,
|
|
11
|
+
IRunConversationFlowPayload,
|
|
12
|
+
} from './flows';
|
|
8
13
|
|
|
9
14
|
export const EventProvider = {
|
|
10
15
|
ga: 'ga',
|
|
@@ -66,7 +71,7 @@ export interface DConversationItem extends ConversationItem {
|
|
|
66
71
|
conversationId: string;
|
|
67
72
|
chatCategory: DChatCategory;
|
|
68
73
|
chatType: PeerType;
|
|
69
|
-
applicationType:
|
|
74
|
+
applicationType: DChatApplicationType;
|
|
70
75
|
memberRole: DMemberRole;
|
|
71
76
|
pinnedAt: string | null;
|
|
72
77
|
isMuted: boolean;
|
|
@@ -123,6 +128,7 @@ export interface IMessageItemEx {
|
|
|
123
128
|
content: string;
|
|
124
129
|
};
|
|
125
130
|
urlMetadata?: IUrlMetadata;
|
|
131
|
+
flow?: IRunConversationFlowPayload;
|
|
126
132
|
}
|
|
127
133
|
|
|
128
134
|
export interface MessageStore {
|
|
@@ -135,3 +141,12 @@ export interface MessageStore {
|
|
|
135
141
|
deleteOneMessage: (clientMsgID: string) => void;
|
|
136
142
|
reset: () => void;
|
|
137
143
|
}
|
|
144
|
+
|
|
145
|
+
export interface ChatDetailContextType {
|
|
146
|
+
conversationFlow?: IConversationFlow;
|
|
147
|
+
refetchConversationFlow: () => void;
|
|
148
|
+
isBotConversation: boolean;
|
|
149
|
+
setConverationFlowStep: (step: IConversationFlowStep) => void;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export interface ChatDetailProviderProps extends PropsWithChildren {}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { PeerType } from '@droppii/openim-rn-client-sdk';
|
|
2
|
+
import type { DChatApplicationType, DChatCategory } from './chat';
|
|
3
|
+
|
|
4
|
+
/** START NODE TYPE */
|
|
5
|
+
export const NodeTypes = {
|
|
6
|
+
BubbleText: 'bubble-text',
|
|
7
|
+
BubbleImage: 'bubble-image',
|
|
8
|
+
InputText: 'input-text',
|
|
9
|
+
InputButtons: 'input-buttons',
|
|
10
|
+
LogicCsTeam: 'logic-cs-team',
|
|
11
|
+
} as const;
|
|
12
|
+
|
|
13
|
+
export type NodeTypes = (typeof NodeTypes)[keyof typeof NodeTypes];
|
|
14
|
+
|
|
15
|
+
export const ReactFlowsNodeTypes = {
|
|
16
|
+
Group: 'group',
|
|
17
|
+
Start: 'start',
|
|
18
|
+
} as const;
|
|
19
|
+
|
|
20
|
+
export type ReactFlowsNodeTypes =
|
|
21
|
+
(typeof ReactFlowsNodeTypes)[keyof typeof ReactFlowsNodeTypes];
|
|
22
|
+
|
|
23
|
+
export interface BaseNodeData {
|
|
24
|
+
id: string;
|
|
25
|
+
type: NodeTypes;
|
|
26
|
+
parentId: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface BubbleTextNodeData {
|
|
30
|
+
content?: string;
|
|
31
|
+
plainText?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface BubbleImageNodeData {
|
|
35
|
+
sourceType: 'link' | 'upload' | 'giphy' | 'unsplash' | 'icon';
|
|
36
|
+
url?: string;
|
|
37
|
+
onClickLink?: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface InputButtonItem {
|
|
41
|
+
id: string;
|
|
42
|
+
label: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface LogicCsTeamNodeData {
|
|
46
|
+
csTeamId?: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface InputButtonsNodeData {
|
|
50
|
+
buttons?: InputButtonItem[];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface InputTextNodeData {
|
|
54
|
+
longText?: boolean;
|
|
55
|
+
placeholder?: string;
|
|
56
|
+
buttonLabel?: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export type NodeDataMap = {
|
|
60
|
+
[NodeTypes.BubbleText]: BubbleTextNodeData;
|
|
61
|
+
[NodeTypes.BubbleImage]: BubbleImageNodeData;
|
|
62
|
+
[NodeTypes.InputText]: InputTextNodeData;
|
|
63
|
+
[NodeTypes.InputButtons]: InputButtonsNodeData;
|
|
64
|
+
[NodeTypes.LogicCsTeam]: LogicCsTeamNodeData;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export type GroupChild<T extends NodeTypes = NodeTypes> = {
|
|
68
|
+
data: NodeDataMap[T];
|
|
69
|
+
} & BaseNodeData;
|
|
70
|
+
|
|
71
|
+
export interface GroupNodeData {
|
|
72
|
+
label: string;
|
|
73
|
+
children: GroupChild[];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** END NODE TYPE */
|
|
77
|
+
|
|
78
|
+
export interface IConversationFlowStep {
|
|
79
|
+
id: string;
|
|
80
|
+
type: ReactFlowsNodeTypes;
|
|
81
|
+
data: GroupNodeData;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface IConversationFlow {
|
|
85
|
+
conversationId: string;
|
|
86
|
+
chatCategory: DChatCategory;
|
|
87
|
+
chatType: PeerType;
|
|
88
|
+
applicationType: DChatApplicationType;
|
|
89
|
+
flowCurrentStep: IConversationFlowStep | null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface IRunConversationFlowResponse {
|
|
93
|
+
flowNextStep: IConversationFlowStep | null;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface IRunConversationFlowPayload {
|
|
97
|
+
groupId: string;
|
|
98
|
+
childId: string | null;
|
|
99
|
+
actionId: string | null;
|
|
100
|
+
//for send msg
|
|
101
|
+
plainText?: string;
|
|
102
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
NodeTypes,
|
|
3
|
+
type GroupChild,
|
|
4
|
+
type IConversationFlowStep,
|
|
5
|
+
} from '../types/flows';
|
|
6
|
+
|
|
7
|
+
export const getFlowInputButtonsNode = (
|
|
8
|
+
step?: IConversationFlowStep | null
|
|
9
|
+
) => {
|
|
10
|
+
if (!step) return null;
|
|
11
|
+
const childrenNode = step?.data?.children || [];
|
|
12
|
+
const inputButtonsNode = childrenNode?.find(
|
|
13
|
+
(f) => f.type === NodeTypes.InputButtons
|
|
14
|
+
) as GroupChild<'input-buttons'>;
|
|
15
|
+
return inputButtonsNode;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const DEFAULT_BUTTON_ID = 'default-item-button';
|
package/src/utils/url.ts
CHANGED
|
@@ -1,4 +1,33 @@
|
|
|
1
|
-
|
|
1
|
+
// Generic TLDs
|
|
2
|
+
const GENERIC_TLDS =
|
|
3
|
+
'com|net|org|edu|gov|mil|int|biz|info|name|pro|mobi|travel|jobs|museum|coop|aero';
|
|
4
|
+
|
|
5
|
+
// New gTLDs (popular tech/startup)
|
|
6
|
+
const NEW_TLDS =
|
|
7
|
+
'io|app|dev|ai|co|me|tv|cc|gg|ly|fm|im|link|click|page|live|site|web|xyz|' +
|
|
8
|
+
'tech|digital|online|store|shop|cloud|media|news|blog|studio|agency|' +
|
|
9
|
+
'design|finance|health|legal|academy|solutions|ventures|capital|group';
|
|
10
|
+
|
|
11
|
+
// Country codes (Vietnam + Southeast Asia + popular worldwide)
|
|
12
|
+
const CC_TLDS =
|
|
13
|
+
'vn|jp|kr|cn|sg|th|ph|id|my|tw|hk|' +
|
|
14
|
+
'uk|us|ca|au|de|fr|it|es|nl|ru|br|in|' +
|
|
15
|
+
'ac|ad|ae|am|at|az|ba|be|bg|bh|bn|by|bz|' +
|
|
16
|
+
'ch|cl|cz|dk|dz|ec|ee|eg|es|eu|fi|ga|ge|' +
|
|
17
|
+
'gr|gt|hr|hu|ie|il|iq|ir|is|jo|ke|kh|kw|' +
|
|
18
|
+
'kz|la|lb|li|lk|lt|lu|lv|ma|mc|md|mk|mm|' +
|
|
19
|
+
'mn|mo|mt|mx|mz|na|ng|no|np|nz|om|pa|pe|' +
|
|
20
|
+
'pk|pl|pt|qa|ro|rs|sa|se|sk|sl|sr|sv|sy|' +
|
|
21
|
+
'tn|to|tr|tt|ua|ug|uy|uz|va|vc|ve|vu|ws|za|zm|zw';
|
|
22
|
+
|
|
23
|
+
const TLD_LIST = `${GENERIC_TLDS}|${NEW_TLDS}|${CC_TLDS}`;
|
|
24
|
+
|
|
25
|
+
// Matches: https://... | http://... | www.... | bare domain with known TLD (t.me, droppii.com)
|
|
26
|
+
const URL_REGEX = new RegExp(
|
|
27
|
+
`\\b(?:https?:\\/\\/|www\\.)[^\\s<>"']*[^\\s<>"',.!?()[\\]{}]` +
|
|
28
|
+
`|\\b[a-zA-Z0-9][\\w-]*(?:\\.[a-zA-Z0-9][\\w-]*)*\\.(?:${TLD_LIST})(?:[/?#][^\\s<>"']*[^\\s<>"',.!?()[\\]{}])?(?=\\s|$|[,!?()\\[\\]{}"'])`,
|
|
29
|
+
'g'
|
|
30
|
+
);
|
|
2
31
|
|
|
3
32
|
export function extractUrls(text: string): string[] {
|
|
4
33
|
return text.match(URL_REGEX) ?? [];
|