rn-erxes-sdk 0.1.23 → 0.1.25

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 (248) hide show
  1. package/README.md +322 -24
  2. package/lib/commonjs/App.js +7 -6
  3. package/lib/commonjs/App.js.map +1 -1
  4. package/lib/commonjs/Widget.js +154 -29
  5. package/lib/commonjs/Widget.js.map +1 -1
  6. package/lib/commonjs/assets/images/index.js +1 -1
  7. package/lib/commonjs/assets/images/index.js.map +1 -1
  8. package/lib/commonjs/assets/images/x.png +0 -0
  9. package/lib/commonjs/components/Avatar.js +24 -27
  10. package/lib/commonjs/components/Avatar.js.map +1 -1
  11. package/lib/commonjs/components/AvatarWithStatus.js +56 -0
  12. package/lib/commonjs/components/AvatarWithStatus.js.map +1 -0
  13. package/lib/commonjs/components/ConversationItem.js +161 -0
  14. package/lib/commonjs/components/ConversationItem.js.map +1 -0
  15. package/lib/commonjs/components/Icons.js +558 -0
  16. package/lib/commonjs/components/Icons.js.map +1 -0
  17. package/lib/commonjs/components/InputTools.js +329 -38
  18. package/lib/commonjs/components/InputTools.js.map +1 -1
  19. package/lib/commonjs/components/MessengerShell.js +64 -0
  20. package/lib/commonjs/components/MessengerShell.js.map +1 -0
  21. package/lib/commonjs/components/conversation/DateSeparator.js +47 -0
  22. package/lib/commonjs/components/conversation/DateSeparator.js.map +1 -0
  23. package/lib/commonjs/components/conversation/EmojiPicker.js +62 -0
  24. package/lib/commonjs/components/conversation/EmojiPicker.js.map +1 -0
  25. package/lib/commonjs/components/conversation/PersistentMenu.js +64 -0
  26. package/lib/commonjs/components/conversation/PersistentMenu.js.map +1 -0
  27. package/lib/commonjs/components/conversation/TypingStatus.js +122 -0
  28. package/lib/commonjs/components/conversation/TypingStatus.js.map +1 -0
  29. package/lib/commonjs/components/conversation/WelcomeMessage.js +85 -0
  30. package/lib/commonjs/components/conversation/WelcomeMessage.js.map +1 -0
  31. package/lib/commonjs/components/nav/Navigation.js +130 -0
  32. package/lib/commonjs/components/nav/Navigation.js.map +1 -0
  33. package/lib/commonjs/components/nav/constants.js +23 -0
  34. package/lib/commonjs/components/nav/constants.js.map +1 -0
  35. package/lib/commonjs/graphql/ApolloContainer.js +1 -2
  36. package/lib/commonjs/graphql/ApolloContainer.js.map +1 -1
  37. package/lib/commonjs/graphql/mutation.js +58 -23
  38. package/lib/commonjs/graphql/mutation.js.map +1 -1
  39. package/lib/commonjs/graphql/query.js +85 -55
  40. package/lib/commonjs/graphql/query.js.map +1 -1
  41. package/lib/commonjs/graphql/subscription.js +32 -28
  42. package/lib/commonjs/graphql/subscription.js.map +1 -1
  43. package/lib/commonjs/screen/conversation/Attachment.js +77 -12
  44. package/lib/commonjs/screen/conversation/Attachment.js.map +1 -1
  45. package/lib/commonjs/screen/conversation/ConversationDetail.js +305 -137
  46. package/lib/commonjs/screen/conversation/ConversationDetail.js.map +1 -1
  47. package/lib/commonjs/screen/conversation/Message.js +145 -82
  48. package/lib/commonjs/screen/conversation/Message.js.map +1 -1
  49. package/lib/commonjs/screen/faq/Faq.js +373 -0
  50. package/lib/commonjs/screen/faq/Faq.js.map +1 -0
  51. package/lib/commonjs/screen/greetings/Social.js +19 -9
  52. package/lib/commonjs/screen/greetings/Social.js.map +1 -1
  53. package/lib/commonjs/screen/greetings/Supporters.js +49 -46
  54. package/lib/commonjs/screen/greetings/Supporters.js.map +1 -1
  55. package/lib/commonjs/screen/home/Home.js +303 -0
  56. package/lib/commonjs/screen/home/Home.js.map +1 -0
  57. package/lib/commonjs/screen/messages/Messages.js +312 -0
  58. package/lib/commonjs/screen/messages/Messages.js.map +1 -0
  59. package/lib/commonjs/theme.js +132 -0
  60. package/lib/commonjs/theme.js.map +1 -0
  61. package/lib/commonjs/utils/messages.js +93 -0
  62. package/lib/commonjs/utils/messages.js.map +1 -0
  63. package/lib/commonjs/utils/objectId.js +61 -0
  64. package/lib/commonjs/utils/objectId.js.map +1 -0
  65. package/lib/commonjs/utils/onlineHours.js +127 -0
  66. package/lib/commonjs/utils/onlineHours.js.map +1 -0
  67. package/lib/commonjs/utils/upload.js +245 -0
  68. package/lib/commonjs/utils/upload.js.map +1 -0
  69. package/lib/module/App.js +7 -6
  70. package/lib/module/App.js.map +1 -1
  71. package/lib/module/Widget.js +157 -32
  72. package/lib/module/Widget.js.map +1 -1
  73. package/lib/module/assets/images/index.js +1 -1
  74. package/lib/module/assets/images/index.js.map +1 -1
  75. package/lib/module/assets/images/x.png +0 -0
  76. package/lib/module/components/Avatar.js +25 -28
  77. package/lib/module/components/Avatar.js.map +1 -1
  78. package/lib/module/components/AvatarWithStatus.js +47 -0
  79. package/lib/module/components/AvatarWithStatus.js.map +1 -0
  80. package/lib/module/components/ConversationItem.js +153 -0
  81. package/lib/module/components/ConversationItem.js.map +1 -0
  82. package/lib/module/components/Icons.js +537 -0
  83. package/lib/module/components/Icons.js.map +1 -0
  84. package/lib/module/components/InputTools.js +331 -39
  85. package/lib/module/components/InputTools.js.map +1 -1
  86. package/lib/module/components/MessengerShell.js +55 -0
  87. package/lib/module/components/MessengerShell.js.map +1 -0
  88. package/lib/module/components/conversation/DateSeparator.js +40 -0
  89. package/lib/module/components/conversation/DateSeparator.js.map +1 -0
  90. package/lib/module/components/conversation/EmojiPicker.js +55 -0
  91. package/lib/module/components/conversation/EmojiPicker.js.map +1 -0
  92. package/lib/module/components/conversation/PersistentMenu.js +57 -0
  93. package/lib/module/components/conversation/PersistentMenu.js.map +1 -0
  94. package/lib/module/components/conversation/TypingStatus.js +113 -0
  95. package/lib/module/components/conversation/TypingStatus.js.map +1 -0
  96. package/lib/module/components/conversation/WelcomeMessage.js +76 -0
  97. package/lib/module/components/conversation/WelcomeMessage.js.map +1 -0
  98. package/lib/module/components/nav/Navigation.js +121 -0
  99. package/lib/module/components/nav/Navigation.js.map +1 -0
  100. package/lib/module/components/nav/constants.js +16 -0
  101. package/lib/module/components/nav/constants.js.map +1 -0
  102. package/lib/module/graphql/ApolloContainer.js +1 -2
  103. package/lib/module/graphql/ApolloContainer.js.map +1 -1
  104. package/lib/module/graphql/mutation.js +57 -23
  105. package/lib/module/graphql/mutation.js.map +1 -1
  106. package/lib/module/graphql/query.js +83 -52
  107. package/lib/module/graphql/query.js.map +1 -1
  108. package/lib/module/graphql/subscription.js +31 -28
  109. package/lib/module/graphql/subscription.js.map +1 -1
  110. package/lib/module/screen/conversation/Attachment.js +79 -14
  111. package/lib/module/screen/conversation/Attachment.js.map +1 -1
  112. package/lib/module/screen/conversation/ConversationDetail.js +309 -140
  113. package/lib/module/screen/conversation/ConversationDetail.js.map +1 -1
  114. package/lib/module/screen/conversation/Message.js +145 -82
  115. package/lib/module/screen/conversation/Message.js.map +1 -1
  116. package/lib/module/screen/faq/Faq.js +363 -0
  117. package/lib/module/screen/faq/Faq.js.map +1 -0
  118. package/lib/module/screen/greetings/Social.js +19 -9
  119. package/lib/module/screen/greetings/Social.js.map +1 -1
  120. package/lib/module/screen/greetings/Supporters.js +50 -46
  121. package/lib/module/screen/greetings/Supporters.js.map +1 -1
  122. package/lib/module/screen/home/Home.js +293 -0
  123. package/lib/module/screen/home/Home.js.map +1 -0
  124. package/lib/module/screen/messages/Messages.js +303 -0
  125. package/lib/module/screen/messages/Messages.js.map +1 -0
  126. package/lib/module/theme.js +122 -0
  127. package/lib/module/theme.js.map +1 -0
  128. package/lib/module/utils/messages.js +81 -0
  129. package/lib/module/utils/messages.js.map +1 -0
  130. package/lib/module/utils/objectId.js +53 -0
  131. package/lib/module/utils/objectId.js.map +1 -0
  132. package/lib/module/utils/onlineHours.js +118 -0
  133. package/lib/module/utils/onlineHours.js.map +1 -0
  134. package/lib/module/utils/upload.js +233 -0
  135. package/lib/module/utils/upload.js.map +1 -0
  136. package/lib/typescript/App.d.ts +2 -1
  137. package/lib/typescript/App.d.ts.map +1 -1
  138. package/lib/typescript/Widget.d.ts.map +1 -1
  139. package/lib/typescript/components/Avatar.d.ts +7 -1
  140. package/lib/typescript/components/Avatar.d.ts.map +1 -1
  141. package/lib/typescript/components/AvatarWithStatus.d.ts +11 -0
  142. package/lib/typescript/components/AvatarWithStatus.d.ts.map +1 -0
  143. package/lib/typescript/components/ConversationItem.d.ts +9 -0
  144. package/lib/typescript/components/ConversationItem.d.ts.map +1 -0
  145. package/lib/typescript/components/Icons.d.ts +33 -0
  146. package/lib/typescript/components/Icons.d.ts.map +1 -0
  147. package/lib/typescript/components/InputTools.d.ts.map +1 -1
  148. package/lib/typescript/components/MessengerShell.d.ts +4 -0
  149. package/lib/typescript/components/MessengerShell.d.ts.map +1 -0
  150. package/lib/typescript/components/conversation/DateSeparator.d.ts +6 -0
  151. package/lib/typescript/components/conversation/DateSeparator.d.ts.map +1 -0
  152. package/lib/typescript/components/conversation/EmojiPicker.d.ts +7 -0
  153. package/lib/typescript/components/conversation/EmojiPicker.d.ts.map +1 -0
  154. package/lib/typescript/components/conversation/PersistentMenu.d.ts +13 -0
  155. package/lib/typescript/components/conversation/PersistentMenu.d.ts.map +1 -0
  156. package/lib/typescript/components/conversation/TypingStatus.d.ts +4 -0
  157. package/lib/typescript/components/conversation/TypingStatus.d.ts.map +1 -0
  158. package/lib/typescript/components/conversation/WelcomeMessage.d.ts +6 -0
  159. package/lib/typescript/components/conversation/WelcomeMessage.d.ts.map +1 -0
  160. package/lib/typescript/components/nav/Navigation.d.ts +12 -0
  161. package/lib/typescript/components/nav/Navigation.d.ts.map +1 -0
  162. package/lib/typescript/components/nav/constants.d.ts +7 -0
  163. package/lib/typescript/components/nav/constants.d.ts.map +1 -0
  164. package/lib/typescript/graphql/ApolloContainer.d.ts.map +1 -1
  165. package/lib/typescript/graphql/mutation.d.ts +2 -1
  166. package/lib/typescript/graphql/mutation.d.ts.map +1 -1
  167. package/lib/typescript/graphql/query.d.ts +2 -3
  168. package/lib/typescript/graphql/query.d.ts.map +1 -1
  169. package/lib/typescript/graphql/subscription.d.ts +2 -1
  170. package/lib/typescript/graphql/subscription.d.ts.map +1 -1
  171. package/lib/typescript/screen/conversation/Attachment.d.ts.map +1 -1
  172. package/lib/typescript/screen/conversation/ConversationDetail.d.ts.map +1 -1
  173. package/lib/typescript/screen/conversation/Message.d.ts.map +1 -1
  174. package/lib/typescript/screen/faq/Faq.d.ts +4 -0
  175. package/lib/typescript/screen/faq/Faq.d.ts.map +1 -0
  176. package/lib/typescript/screen/greetings/Social.d.ts +1 -1
  177. package/lib/typescript/screen/greetings/Social.d.ts.map +1 -1
  178. package/lib/typescript/screen/greetings/Supporters.d.ts.map +1 -1
  179. package/lib/typescript/screen/home/Home.d.ts +4 -0
  180. package/lib/typescript/screen/home/Home.d.ts.map +1 -0
  181. package/lib/typescript/screen/messages/Messages.d.ts +4 -0
  182. package/lib/typescript/screen/messages/Messages.d.ts.map +1 -0
  183. package/lib/typescript/theme.d.ts +93 -0
  184. package/lib/typescript/theme.d.ts.map +1 -0
  185. package/lib/typescript/utils/messages.d.ts +27 -0
  186. package/lib/typescript/utils/messages.d.ts.map +1 -0
  187. package/lib/typescript/utils/objectId.d.ts +3 -0
  188. package/lib/typescript/utils/objectId.d.ts.map +1 -0
  189. package/lib/typescript/utils/onlineHours.d.ts +19 -0
  190. package/lib/typescript/utils/onlineHours.d.ts.map +1 -0
  191. package/lib/typescript/utils/upload.d.ts +32 -0
  192. package/lib/typescript/utils/upload.d.ts.map +1 -0
  193. package/package.json +29 -23
  194. package/src/App.tsx +10 -7
  195. package/src/Widget.tsx +211 -39
  196. package/src/assets/images/index.ts +1 -1
  197. package/src/assets/images/x.png +0 -0
  198. package/src/components/Avatar.tsx +30 -30
  199. package/src/components/AvatarWithStatus.tsx +63 -0
  200. package/src/components/ConversationItem.tsx +199 -0
  201. package/src/components/Icons.tsx +532 -0
  202. package/src/components/InputTools.tsx +388 -49
  203. package/src/components/MessengerShell.tsx +58 -0
  204. package/src/components/conversation/DateSeparator.tsx +36 -0
  205. package/src/components/conversation/EmojiPicker.tsx +111 -0
  206. package/src/components/conversation/PersistentMenu.tsx +74 -0
  207. package/src/components/conversation/TypingStatus.tsx +112 -0
  208. package/src/components/conversation/WelcomeMessage.tsx +70 -0
  209. package/src/components/nav/Navigation.tsx +137 -0
  210. package/src/components/nav/constants.ts +16 -0
  211. package/src/graphql/ApolloContainer.tsx +0 -1
  212. package/src/graphql/mutation.ts +58 -22
  213. package/src/graphql/query.ts +83 -55
  214. package/src/graphql/subscription.ts +31 -27
  215. package/src/screen/conversation/Attachment.tsx +123 -33
  216. package/src/screen/conversation/ConversationDetail.tsx +365 -135
  217. package/src/screen/conversation/Message.tsx +160 -98
  218. package/src/screen/faq/Faq.tsx +425 -0
  219. package/src/screen/greetings/Social.tsx +18 -4
  220. package/src/screen/greetings/Supporters.tsx +56 -41
  221. package/src/screen/home/Home.tsx +347 -0
  222. package/src/screen/messages/Messages.tsx +331 -0
  223. package/src/theme.ts +104 -0
  224. package/src/utils/messages.ts +105 -0
  225. package/src/utils/objectId.ts +59 -0
  226. package/src/utils/onlineHours.ts +167 -0
  227. package/src/utils/upload.ts +326 -0
  228. package/lib/commonjs/components/FAB.js +0 -51
  229. package/lib/commonjs/components/FAB.js.map +0 -1
  230. package/lib/commonjs/screen/conversation/Conversations.js +0 -160
  231. package/lib/commonjs/screen/conversation/Conversations.js.map +0 -1
  232. package/lib/commonjs/screen/greetings/Greetings.js +0 -96
  233. package/lib/commonjs/screen/greetings/Greetings.js.map +0 -1
  234. package/lib/module/components/FAB.js +0 -42
  235. package/lib/module/components/FAB.js.map +0 -1
  236. package/lib/module/screen/conversation/Conversations.js +0 -149
  237. package/lib/module/screen/conversation/Conversations.js.map +0 -1
  238. package/lib/module/screen/greetings/Greetings.js +0 -85
  239. package/lib/module/screen/greetings/Greetings.js.map +0 -1
  240. package/lib/typescript/components/FAB.d.ts +0 -16
  241. package/lib/typescript/components/FAB.d.ts.map +0 -1
  242. package/lib/typescript/screen/conversation/Conversations.d.ts +0 -4
  243. package/lib/typescript/screen/conversation/Conversations.d.ts.map +0 -1
  244. package/lib/typescript/screen/greetings/Greetings.d.ts +0 -4
  245. package/lib/typescript/screen/greetings/Greetings.d.ts.map +0 -1
  246. package/src/components/FAB.tsx +0 -69
  247. package/src/screen/conversation/Conversations.tsx +0 -150
  248. package/src/screen/greetings/Greetings.tsx +0 -98
@@ -0,0 +1,425 @@
1
+ /* eslint-disable react-native/no-inline-styles */
2
+ import {
3
+ View,
4
+ Text,
5
+ StyleSheet,
6
+ ScrollView,
7
+ TouchableOpacity,
8
+ ActivityIndicator,
9
+ SafeAreaView,
10
+ Platform,
11
+ StatusBar,
12
+ useWindowDimensions,
13
+ } from 'react-native';
14
+ import React, { useContext, useMemo, useState } from 'react';
15
+ import { useQuery } from '@apollo/client';
16
+ import HTML from 'react-native-render-html';
17
+ import dayjs from 'dayjs';
18
+ import AppContext from '../../context/Context';
19
+ import { knowledgeBaseTopicDetail } from '../../graphql/query';
20
+ import { messengerTheme } from '../../theme';
21
+ import { BackIcon, ChevronRightIcon, HelpIcon } from '../../components/Icons';
22
+
23
+ // FAQ / Knowledge base — RN port of the web messenger KnowledgeBaseView /
24
+ // CategoryView / ArticleView. Uses the same `knowledgeBaseTopicDetail` query
25
+ // (same backend) and an in-screen topic → category → article stack.
26
+ const Faq = () => {
27
+ const value = useContext(AppContext);
28
+ const { greetings, bgColor, textColor } = value;
29
+ const { width } = useWindowDimensions();
30
+
31
+ const topicId = greetings?.knowledgeBaseTopicId;
32
+
33
+ const { data, loading, error } = useQuery(knowledgeBaseTopicDetail, {
34
+ variables: { _id: topicId },
35
+ skip: !topicId,
36
+ });
37
+
38
+ const detail = data?.knowledgeBaseTopicDetail;
39
+
40
+ const [stack, setStack] = useState<string[]>([]);
41
+ const [articleId, setArticleId] = useState<string | null>(null);
42
+
43
+ const view: 'topic' | 'category' | 'article' = articleId
44
+ ? 'article'
45
+ : stack.length > 0
46
+ ? 'category'
47
+ : 'topic';
48
+
49
+ const allCategories = useMemo(
50
+ () => [...(detail?.parentCategories || []), ...(detail?.categories || [])],
51
+ [detail]
52
+ );
53
+
54
+ const allArticles = useMemo(
55
+ () => [
56
+ ...(detail?.parentCategories?.flatMap((c: any) => c.articles || []) ??
57
+ []),
58
+ ...(detail?.categories?.flatMap((c: any) => c.articles || []) ?? []),
59
+ ],
60
+ [detail]
61
+ );
62
+
63
+ const topLevelCategories =
64
+ detail?.parentCategories?.length > 0
65
+ ? detail.parentCategories
66
+ : (detail?.categories || []).filter((c: any) => !c.parentCategoryId);
67
+
68
+ const currentCategoryId = stack[stack.length - 1];
69
+ const currentCategory = allCategories.find(
70
+ (c: any) => c._id === currentCategoryId
71
+ );
72
+ const subCategories = (detail?.categories || []).filter(
73
+ (c: any) => c.parentCategoryId === currentCategoryId
74
+ );
75
+ const article = allArticles.find((a: any) => a._id === articleId);
76
+
77
+ const goBack = () => {
78
+ if (articleId) {
79
+ setArticleId(null);
80
+ } else {
81
+ setStack((prev) => prev.slice(0, -1));
82
+ }
83
+ };
84
+
85
+ const headerTitle =
86
+ view === 'article'
87
+ ? currentCategory?.title || 'Article'
88
+ : view === 'category'
89
+ ? currentCategory?.title || 'Help'
90
+ : detail?.title || 'Help';
91
+
92
+ const headerSubtitle =
93
+ view === 'topic'
94
+ ? 'Browse our help articles'
95
+ : currentCategory?.description;
96
+
97
+ const androidTop =
98
+ Platform.OS === 'android' ? StatusBar.currentHeight || 0 : 0;
99
+
100
+ const articleCount = (n?: number) =>
101
+ n === 1 ? '1 article' : `${n || 0} articles`;
102
+
103
+ const renderCategoryCard = (cat: any, onPress: () => void) => (
104
+ <TouchableOpacity
105
+ key={cat._id}
106
+ activeOpacity={0.85}
107
+ style={styles.card}
108
+ onPress={onPress}
109
+ >
110
+ <View style={[styles.cardIcon, { backgroundColor: bgColor + '1A' }]}>
111
+ <HelpIcon color={bgColor} size={20} />
112
+ </View>
113
+ <View style={styles.cardBody}>
114
+ <Text style={styles.cardTitle} numberOfLines={1}>
115
+ {cat.title}
116
+ </Text>
117
+ {cat.description ? (
118
+ <Text style={styles.cardDesc} numberOfLines={2}>
119
+ {cat.description}
120
+ </Text>
121
+ ) : null}
122
+ <Text style={styles.cardMeta}>
123
+ {articleCount(cat.numOfArticles)}
124
+ {cat.childrens?.length ? ` · ${cat.childrens.length} sections` : ''}
125
+ </Text>
126
+ </View>
127
+ <ChevronRightIcon color={messengerTheme.colors.subtleText} size={18} />
128
+ </TouchableOpacity>
129
+ );
130
+
131
+ const renderArticleCard = (a: any) => (
132
+ <TouchableOpacity
133
+ key={a._id}
134
+ activeOpacity={0.85}
135
+ style={styles.card}
136
+ onPress={() => setArticleId(a._id)}
137
+ >
138
+ <View style={[styles.cardIcon, styles.cardIconMuted]}>
139
+ <HelpIcon color={messengerTheme.colors.mutedText} size={18} />
140
+ </View>
141
+ <View style={styles.cardBody}>
142
+ <Text style={styles.cardTitle} numberOfLines={1}>
143
+ {a.title}
144
+ </Text>
145
+ {a.modifiedDate ? (
146
+ <Text style={styles.cardMeta}>
147
+ Updated {dayjs(a.modifiedDate).format('MMM YYYY')}
148
+ </Text>
149
+ ) : null}
150
+ </View>
151
+ <ChevronRightIcon color={messengerTheme.colors.subtleText} size={18} />
152
+ </TouchableOpacity>
153
+ );
154
+
155
+ const renderBody = () => {
156
+ if (loading) {
157
+ return (
158
+ <View style={styles.stateWrap}>
159
+ <ActivityIndicator color={bgColor} />
160
+ </View>
161
+ );
162
+ }
163
+ if (error || !topicId) {
164
+ return (
165
+ <View style={styles.stateWrap}>
166
+ <Text style={styles.stateTitle}>Help center unavailable</Text>
167
+ <Text style={styles.stateSubtitle}>
168
+ We couldn't load the help articles right now.
169
+ </Text>
170
+ </View>
171
+ );
172
+ }
173
+
174
+ if (view === 'article' && article) {
175
+ return (
176
+ <View style={styles.articleWrap}>
177
+ <Text style={styles.articleTitle}>{article.title}</Text>
178
+ {article.modifiedDate ? (
179
+ <Text style={styles.articleDate}>
180
+ Updated {dayjs(article.modifiedDate).format('MMM YYYY')}
181
+ </Text>
182
+ ) : null}
183
+ <View style={styles.articleDivider} />
184
+ <HTML
185
+ contentWidth={width - 2 * messengerTheme.spacing.lg}
186
+ source={{ html: article.content || '' }}
187
+ baseStyle={{
188
+ color: messengerTheme.colors.text,
189
+ fontSize: 14,
190
+ lineHeight: 21,
191
+ }}
192
+ tagsStyles={{
193
+ a: { color: bgColor },
194
+ h1: { fontSize: 18, fontWeight: '700' },
195
+ h2: { fontSize: 16, fontWeight: '600' },
196
+ li: { color: messengerTheme.colors.text },
197
+ }}
198
+ ignoredDomTags={['meta', 'script', 'font', 'title']}
199
+ />
200
+ </View>
201
+ );
202
+ }
203
+
204
+ if (view === 'category') {
205
+ const articles = currentCategory?.articles || [];
206
+ if (subCategories.length === 0 && articles.length === 0) {
207
+ return (
208
+ <View style={styles.stateWrap}>
209
+ <Text style={styles.stateSubtitle}>
210
+ No articles in this category yet.
211
+ </Text>
212
+ </View>
213
+ );
214
+ }
215
+ return (
216
+ <View style={styles.list}>
217
+ {subCategories.map((sub: any) =>
218
+ renderCategoryCard(sub, () => setStack((p) => [...p, sub._id]))
219
+ )}
220
+ {articles.length > 0 ? (
221
+ <>
222
+ {subCategories.length > 0 ? (
223
+ <Text style={styles.sectionLabel}>ARTICLES</Text>
224
+ ) : null}
225
+ {articles.map((a: any) => renderArticleCard(a))}
226
+ </>
227
+ ) : null}
228
+ </View>
229
+ );
230
+ }
231
+
232
+ // topic view
233
+ if (!topLevelCategories?.length) {
234
+ return (
235
+ <View style={styles.stateWrap}>
236
+ <Text style={styles.stateSubtitle}>No help articles yet.</Text>
237
+ </View>
238
+ );
239
+ }
240
+ return (
241
+ <View style={styles.list}>
242
+ {topLevelCategories.map((cat: any) =>
243
+ renderCategoryCard(cat, () => setStack((p) => [...p, cat._id]))
244
+ )}
245
+ </View>
246
+ );
247
+ };
248
+
249
+ return (
250
+ <View style={styles.root}>
251
+ <SafeAreaView style={{ backgroundColor: bgColor }}>
252
+ <View style={[styles.header, { paddingTop: androidTop + 12 }]}>
253
+ <View style={styles.headerRow}>
254
+ {view !== 'topic' ? (
255
+ <TouchableOpacity
256
+ onPress={goBack}
257
+ style={styles.backButton}
258
+ hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
259
+ >
260
+ <BackIcon
261
+ color={messengerTheme.colors.primaryForeground}
262
+ size={18}
263
+ />
264
+ </TouchableOpacity>
265
+ ) : null}
266
+ <Text
267
+ numberOfLines={1}
268
+ style={[
269
+ styles.headerTitle,
270
+ { color: textColor },
271
+ view !== 'topic' && { marginLeft: messengerTheme.spacing.sm },
272
+ ]}
273
+ >
274
+ {headerTitle}
275
+ </Text>
276
+ </View>
277
+ {headerSubtitle ? (
278
+ <Text
279
+ numberOfLines={1}
280
+ style={[styles.headerSubtitle, { color: textColor }]}
281
+ >
282
+ {headerSubtitle}
283
+ </Text>
284
+ ) : null}
285
+ </View>
286
+ </SafeAreaView>
287
+
288
+ <ScrollView
289
+ showsVerticalScrollIndicator={false}
290
+ contentContainerStyle={styles.scrollContent}
291
+ >
292
+ {renderBody()}
293
+ </ScrollView>
294
+ </View>
295
+ );
296
+ };
297
+
298
+ export default Faq;
299
+
300
+ const styles = StyleSheet.create({
301
+ root: {
302
+ flex: 1,
303
+ backgroundColor: messengerTheme.colors.background,
304
+ },
305
+ header: {
306
+ paddingHorizontal: messengerTheme.spacing.xl,
307
+ paddingBottom: messengerTheme.spacing.lg,
308
+ },
309
+ headerRow: {
310
+ flexDirection: 'row',
311
+ alignItems: 'center',
312
+ },
313
+ backButton: {
314
+ width: 36,
315
+ height: 36,
316
+ borderRadius: 18,
317
+ justifyContent: 'center',
318
+ alignItems: 'center',
319
+ backgroundColor: 'rgba(255,255,255,0.16)',
320
+ },
321
+ headerTitle: {
322
+ flex: 1,
323
+ fontSize: 22,
324
+ fontWeight: '700',
325
+ },
326
+ headerSubtitle: {
327
+ marginTop: 4,
328
+ fontSize: 13,
329
+ opacity: 0.7,
330
+ },
331
+ scrollContent: {
332
+ paddingBottom: messengerTheme.spacing.xl,
333
+ },
334
+ list: {
335
+ paddingHorizontal: messengerTheme.spacing.md,
336
+ paddingTop: messengerTheme.spacing.md,
337
+ gap: messengerTheme.spacing.sm,
338
+ },
339
+ sectionLabel: {
340
+ fontSize: 11,
341
+ letterSpacing: 1,
342
+ fontWeight: '700',
343
+ color: messengerTheme.colors.subtleText,
344
+ marginTop: messengerTheme.spacing.sm,
345
+ marginLeft: 4,
346
+ },
347
+ card: {
348
+ flexDirection: 'row',
349
+ alignItems: 'center',
350
+ backgroundColor: messengerTheme.colors.surface,
351
+ borderRadius: messengerTheme.radius.lg,
352
+ padding: 14,
353
+ ...messengerTheme.shadow.card,
354
+ },
355
+ cardIcon: {
356
+ width: 38,
357
+ height: 38,
358
+ borderRadius: messengerTheme.radius.md,
359
+ alignItems: 'center',
360
+ justifyContent: 'center',
361
+ marginRight: messengerTheme.spacing.md,
362
+ },
363
+ cardIconMuted: {
364
+ backgroundColor: messengerTheme.colors.background,
365
+ },
366
+ cardBody: {
367
+ flex: 1,
368
+ marginRight: messengerTheme.spacing.sm,
369
+ },
370
+ cardTitle: {
371
+ fontSize: 15,
372
+ fontWeight: '600',
373
+ color: messengerTheme.colors.text,
374
+ },
375
+ cardDesc: {
376
+ marginTop: 2,
377
+ fontSize: 12,
378
+ lineHeight: 16,
379
+ color: messengerTheme.colors.mutedText,
380
+ },
381
+ cardMeta: {
382
+ marginTop: 3,
383
+ fontSize: 11,
384
+ color: messengerTheme.colors.subtleText,
385
+ fontWeight: '500',
386
+ },
387
+ articleWrap: {
388
+ paddingHorizontal: messengerTheme.spacing.lg,
389
+ paddingTop: messengerTheme.spacing.lg,
390
+ },
391
+ articleTitle: {
392
+ fontSize: 20,
393
+ fontWeight: '700',
394
+ color: messengerTheme.colors.text,
395
+ lineHeight: 26,
396
+ },
397
+ articleDate: {
398
+ marginTop: 6,
399
+ fontSize: 12,
400
+ color: messengerTheme.colors.mutedText,
401
+ },
402
+ articleDivider: {
403
+ height: 1,
404
+ backgroundColor: messengerTheme.colors.border,
405
+ marginVertical: messengerTheme.spacing.md,
406
+ },
407
+ stateWrap: {
408
+ alignItems: 'center',
409
+ justifyContent: 'center',
410
+ paddingTop: 64,
411
+ paddingHorizontal: messengerTheme.spacing.xxl,
412
+ },
413
+ stateTitle: {
414
+ fontWeight: '600',
415
+ fontSize: 16,
416
+ color: messengerTheme.colors.text,
417
+ },
418
+ stateSubtitle: {
419
+ marginTop: 6,
420
+ color: messengerTheme.colors.mutedText,
421
+ fontSize: 13,
422
+ lineHeight: 18,
423
+ textAlign: 'center',
424
+ },
425
+ });
@@ -15,22 +15,28 @@ const Social = (props: any) => {
15
15
  const renderSocial = (link: any, imageUrl: any, index: number) => {
16
16
  return (
17
17
  <TouchableOpacity
18
- style={{ marginLeft: index !== 0 ? 10 : 0 }}
18
+ key={index}
19
+ activeOpacity={0.7}
20
+ style={[styles.button, index !== 0 && { marginLeft: 8 }]}
19
21
  onPress={() => {
20
22
  Linking.openURL(link);
21
23
  }}
22
24
  >
23
- <Image source={imageUrl} style={styles.image} />
25
+ <Image source={imageUrl} style={styles.image} resizeMode="cover" />
24
26
  </TouchableOpacity>
25
27
  );
26
28
  };
27
29
 
30
+ if (!links) {
31
+ return null;
32
+ }
33
+
28
34
  return (
29
35
  <View style={styles.container}>
30
36
  {links?.facebook
31
37
  ? renderSocial(links.facebook, images.facebook, 0)
32
38
  : null}
33
- {links.twitter ? renderSocial(links.twitter, images.twitter, 1) : null}
39
+ {links?.twitter ? renderSocial(links.twitter, images.twitter, 1) : null}
34
40
  {links?.youtube ? renderSocial(links.youtube, images.youtube, 2) : null}
35
41
  </View>
36
42
  );
@@ -41,6 +47,14 @@ export default Social;
41
47
  const styles = StyleSheet.create({
42
48
  container: {
43
49
  flexDirection: 'row',
50
+ alignItems: 'center',
51
+ },
52
+ button: {
53
+ opacity: 0.95,
54
+ },
55
+ image: {
56
+ width: 28,
57
+ height: 28,
58
+ borderRadius: 14,
44
59
  },
45
- image: { width: 30, height: 30, borderRadius: 90 },
46
60
  });
@@ -1,17 +1,21 @@
1
- /* eslint-disable react-native/no-inline-styles */
2
- import { View, Image, StyleSheet } from 'react-native';
1
+ import { View, Text, StyleSheet } from 'react-native';
3
2
  import React, { useContext } from 'react';
4
3
  import { useQuery } from '@apollo/client';
5
4
  import { widgetsMessengerSupporters } from '../../graphql/query';
6
5
  import AppContext from '../../context/Context';
7
6
  import { getAttachmentUrl } from '../../utils/utils';
7
+ import AvatarWithStatus from '../../components/AvatarWithStatus';
8
+
9
+ const MAX_VISIBLE = 3;
8
10
 
9
11
  const Supporters = (props: any) => {
10
- const { integrationId } = props;
12
+ const { integrationId, compact } = props;
13
+
14
+ const AVATAR_SIZE = compact ? 28 : 36;
11
15
 
12
16
  const value = useContext(AppContext);
13
17
 
14
- const { subDomain } = value;
18
+ const { subDomain, textColor } = value;
15
19
 
16
20
  const { data, loading } = useQuery(widgetsMessengerSupporters, {
17
21
  variables: {
@@ -23,38 +27,45 @@ const Supporters = (props: any) => {
23
27
  return null;
24
28
  }
25
29
 
26
- const supporters = data?.widgetsMessengerSupporters?.supporters;
30
+ const supporters = (
31
+ data?.widgetsMessengerSupporters?.supporters || []
32
+ ).filter((supporter: any) => supporter?.isActive);
33
+
34
+ if (supporters.length === 0) {
35
+ return null;
36
+ }
37
+
38
+ const visible = supporters.slice(0, MAX_VISIBLE);
39
+ const anyOnline = supporters.some((supporter: any) => supporter?.isOnline);
27
40
 
28
- const renderSupporter = (supporter: any, index: number) => {
29
- const color = supporter?.isOnline ? '#3ccc38' : 'white';
30
- let source;
41
+ const getSource = (supporter: any) => {
31
42
  if (supporter?.details?.avatar) {
32
- source = {
33
- uri: getAttachmentUrl(supporter?.details?.avatar, subDomain),
34
- };
35
- } else {
36
- source = require('../../assets/images/avatar.png');
43
+ return { uri: getAttachmentUrl(supporter.details.avatar, subDomain) };
37
44
  }
38
- return (
39
- <View
40
- key={index}
41
- style={{
42
- marginLeft: index === 0 ? 0 : 10,
43
- }}
44
- >
45
- <Image source={source} style={styles.image} resizeMode="center" />
46
- <View style={[{ backgroundColor: color }, styles.activeStatus]} />
47
- </View>
48
- );
45
+ return require('../../assets/images/avatar.png');
49
46
  };
50
47
 
51
48
  return (
52
- <View style={{ marginTop: 10, flexDirection: 'row' }}>
53
- {supporters
54
- ?.filter((supporter: any) => supporter?.isActive)
55
- ?.map((supporter: any, index: number) => {
56
- return renderSupporter(supporter, index);
57
- })}
49
+ <View style={styles.container}>
50
+ <View style={styles.avatars}>
51
+ {visible.map((supporter: any, index: number) => (
52
+ <AvatarWithStatus
53
+ key={index}
54
+ source={getSource(supporter)}
55
+ size={AVATAR_SIZE}
56
+ online={supporter?.isOnline}
57
+ style={[
58
+ index === 0 ? null : styles.overlap,
59
+ { zIndex: visible.length - index },
60
+ ]}
61
+ />
62
+ ))}
63
+ </View>
64
+ {compact ? null : (
65
+ <Text style={[styles.label, { color: textColor }]}>
66
+ {anyOnline ? 'Online support' : 'Support team'}
67
+ </Text>
68
+ )}
58
69
  </View>
59
70
  );
60
71
  };
@@ -62,17 +73,21 @@ const Supporters = (props: any) => {
62
73
  export default Supporters;
63
74
 
64
75
  const styles = StyleSheet.create({
65
- image: {
66
- width: 50,
67
- height: 50,
68
- borderRadius: 90,
76
+ container: {
77
+ flexDirection: 'row',
78
+ alignItems: 'center',
79
+ },
80
+ avatars: {
81
+ flexDirection: 'row',
82
+ alignItems: 'center',
83
+ },
84
+ overlap: {
85
+ marginLeft: -10,
69
86
  },
70
- activeStatus: {
71
- width: 13,
72
- height: 13,
73
- borderRadius: 90,
74
- position: 'absolute',
75
- bottom: 0,
76
- left: 35,
87
+ label: {
88
+ marginLeft: 10,
89
+ fontSize: 13,
90
+ fontWeight: '500',
91
+ opacity: 0.95,
77
92
  },
78
93
  });