turbodesk-livechat-react-native 0.1.0-alpha.3 → 0.1.0-alpha.30

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 (64) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/dist/api/conversation-api.d.ts +9 -0
  3. package/dist/api/conversation-api.d.ts.map +1 -1
  4. package/dist/api/conversation-api.js +15 -1
  5. package/dist/api/conversation-api.js.map +1 -1
  6. package/dist/hooks/use-live-chat.d.ts +1 -0
  7. package/dist/hooks/use-live-chat.d.ts.map +1 -1
  8. package/dist/hooks/use-live-chat.js +2 -0
  9. package/dist/hooks/use-live-chat.js.map +1 -1
  10. package/dist/hooks/use-send-message.d.ts +1 -0
  11. package/dist/hooks/use-send-message.d.ts.map +1 -1
  12. package/dist/hooks/use-send-message.js +20 -14
  13. package/dist/hooks/use-send-message.js.map +1 -1
  14. package/dist/index.d.ts +2 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +4 -2
  17. package/dist/index.js.map +1 -1
  18. package/dist/navigation/LiveChatPanel.d.ts.map +1 -1
  19. package/dist/navigation/LiveChatPanel.js +20 -1
  20. package/dist/navigation/LiveChatPanel.js.map +1 -1
  21. package/dist/provider/LiveChatContext.d.ts.map +1 -1
  22. package/dist/provider/LiveChatContext.js +2 -0
  23. package/dist/provider/LiveChatContext.js.map +1 -1
  24. package/dist/provider/LiveChatProvider.d.ts +1 -1
  25. package/dist/provider/LiveChatProvider.d.ts.map +1 -1
  26. package/dist/provider/LiveChatProvider.js +17 -2
  27. package/dist/provider/LiveChatProvider.js.map +1 -1
  28. package/dist/provider/types.d.ts +4 -0
  29. package/dist/provider/types.d.ts.map +1 -1
  30. package/dist/ui/components/ConversationHeader.d.ts.map +1 -1
  31. package/dist/ui/components/ConversationHeader.js +7 -4
  32. package/dist/ui/components/ConversationHeader.js.map +1 -1
  33. package/dist/ui/components/ConversationListScreen.d.ts.map +1 -1
  34. package/dist/ui/components/ConversationListScreen.js +11 -2
  35. package/dist/ui/components/ConversationListScreen.js.map +1 -1
  36. package/dist/ui/components/ConversationScreen.d.ts.map +1 -1
  37. package/dist/ui/components/ConversationScreen.js +13 -3
  38. package/dist/ui/components/ConversationScreen.js.map +1 -1
  39. package/dist/ui/components/HomeScreen.d.ts.map +1 -1
  40. package/dist/ui/components/HomeScreen.js +14 -4
  41. package/dist/ui/components/HomeScreen.js.map +1 -1
  42. package/dist/ui/components/MessageComposer.d.ts +1 -0
  43. package/dist/ui/components/MessageComposer.d.ts.map +1 -1
  44. package/dist/ui/components/MessageComposer.js +89 -30
  45. package/dist/ui/components/MessageComposer.js.map +1 -1
  46. package/dist/ui/safe-area.d.ts +9 -0
  47. package/dist/ui/safe-area.d.ts.map +1 -0
  48. package/dist/ui/safe-area.js +28 -0
  49. package/dist/ui/safe-area.js.map +1 -0
  50. package/package.json +11 -3
  51. package/src/api/conversation-api.ts +33 -8
  52. package/src/hooks/use-live-chat.ts +3 -0
  53. package/src/hooks/use-send-message.ts +169 -159
  54. package/src/index.ts +3 -0
  55. package/src/navigation/LiveChatPanel.tsx +26 -3
  56. package/src/provider/LiveChatContext.ts +2 -0
  57. package/src/provider/LiveChatProvider.tsx +396 -380
  58. package/src/provider/types.ts +63 -57
  59. package/src/ui/components/ConversationHeader.tsx +7 -6
  60. package/src/ui/components/ConversationListScreen.tsx +18 -5
  61. package/src/ui/components/ConversationScreen.tsx +369 -362
  62. package/src/ui/components/HomeScreen.tsx +21 -6
  63. package/src/ui/components/MessageComposer.tsx +116 -36
  64. package/src/ui/safe-area.ts +34 -0
@@ -1,57 +1,63 @@
1
- import type { VisitorProfile } from "../core/visitor-params";
2
- import type { WsConnectionState } from "../realtime/ws-client";
3
- import type { AppearanceMode, ThemeConfig } from "../ui/theme";
4
-
5
- export type EmbedConfigLoadState = "loading" | "ready" | "error";
6
-
7
- export type LiveChatProviderProps = {
8
- widgetId: string;
9
- apiBaseUrl: string;
10
- userId?: string;
11
- userToken?: string;
12
- authCallback?: () => Promise<string | null | undefined>;
13
- visitorProfile?: VisitorProfile;
14
- appearance?: AppearanceMode;
15
- useBrandThemingForChat?: boolean;
16
- theme?: Partial<ThemeConfig>;
17
- children: React.ReactNode;
18
- };
19
-
20
- export type LiveChatContextValue = {
21
- // identity
22
- widgetId: string;
23
- userId: string;
24
- userToken: string | undefined;
25
- setToken: (token: string | null | undefined) => void;
26
- logout: () => void;
27
-
28
- // visitor query params
29
- visitorProfile: VisitorProfile | undefined;
30
- visitorQueryParams: Record<string, string> | null;
31
-
32
- // widget config
33
- widgetConfig: any;
34
- widgetName: string;
35
- widgetGreeting: string;
36
- embedLoadState: EmbedConfigLoadState;
37
- embedLoadError: string | null;
38
-
39
- // unread
40
- totalUnread: number;
41
- setTotalUnread: React.Dispatch<React.SetStateAction<number>>;
42
-
43
- // chat open/visible state
44
- isOpen: boolean;
45
- open: () => void;
46
- close: () => void;
47
- isVisible: boolean;
48
- show: () => void;
49
- hide: () => void;
50
-
51
- // WS
52
- wsClient: import("../realtime/ws-client").WsClient | null;
53
- connectionState: WsConnectionState;
54
-
55
- // theme
56
- theme: ThemeConfig;
57
- };
1
+ import type { VisitorProfile } from "../core/visitor-params";
2
+ import type { WsConnectionState } from "../realtime/ws-client";
3
+ import type { AppearanceMode, ThemeConfig } from "../ui/theme";
4
+
5
+ export type EmbedConfigLoadState = "loading" | "ready" | "error";
6
+
7
+ export type LiveChatProviderProps = {
8
+ widgetId: string;
9
+ apiBaseUrl: string;
10
+ userId?: string;
11
+ userToken?: string;
12
+ authCallback?: () => Promise<string | null | undefined>;
13
+ visitorProfile?: VisitorProfile;
14
+ appearance?: AppearanceMode;
15
+ useBrandThemingForChat?: boolean;
16
+ theme?: Partial<ThemeConfig>;
17
+ fcmToken?: string;
18
+ fcmTokenPlatform?: "ios" | "android";
19
+ children: React.ReactNode;
20
+ };
21
+
22
+ export type LiveChatContextValue = {
23
+ // identity
24
+ widgetId: string;
25
+ userId: string;
26
+ userToken: string | undefined;
27
+ setToken: (token: string | null | undefined) => void;
28
+ logout: () => void;
29
+
30
+ // visitor query params
31
+ visitorProfile: VisitorProfile | undefined;
32
+ visitorQueryParams: Record<string, string> | null;
33
+
34
+ // widget config
35
+ widgetConfig: any;
36
+ widgetName: string;
37
+ widgetGreeting: string;
38
+ embedLoadState: EmbedConfigLoadState;
39
+ embedLoadError: string | null;
40
+
41
+ // unread
42
+ totalUnread: number;
43
+ setTotalUnread: React.Dispatch<React.SetStateAction<number>>;
44
+
45
+ // chat open/visible state
46
+ isOpen: boolean;
47
+ open: () => void;
48
+ close: () => void;
49
+ isVisible: boolean;
50
+ show: () => void;
51
+ hide: () => void;
52
+
53
+ // active conversation (suppress push notifications while user is viewing it)
54
+ activeConversationId: string | null;
55
+ setActiveConversationId: (id: string | null) => void;
56
+
57
+ // WS
58
+ wsClient: import("../realtime/ws-client").WsClient | null;
59
+ connectionState: WsConnectionState;
60
+
61
+ // theme
62
+ theme: ThemeConfig;
63
+ };
@@ -1,13 +1,12 @@
1
1
  import React from "react";
2
2
  import {
3
- Platform,
4
- StatusBar,
5
3
  StyleSheet,
6
4
  Text,
7
5
  TouchableOpacity,
8
6
  View,
9
7
  } from "react-native";
10
8
  import { useLiveChatContext } from "../../provider/LiveChatContext";
9
+ import { usePanelSafeAreaInsets } from "../safe-area";
11
10
  import { getUserPresenceStatus } from "../../core/visitor-params";
12
11
  import { AssigneeAvatar } from "./AssigneeAvatar";
13
12
  import { ChevronLeftIcon, CloseIcon } from "../icons";
@@ -43,6 +42,7 @@ export function ConversationHeader({
43
42
  onClose,
44
43
  }: ConversationHeaderProps) {
45
44
  const { theme: t, widgetName, widgetConfig } = useLiveChatContext();
45
+ const { top: safeTop } = usePanelSafeAreaInsets();
46
46
  const headerBg = t.colors.headerBackground;
47
47
  const headerTxt = t.colors.headerText;
48
48
 
@@ -92,7 +92,11 @@ export function ConversationHeader({
92
92
  <View
93
93
  style={[
94
94
  styles.container,
95
- { backgroundColor: headerBg, borderBottomColor: t.colors.border },
95
+ {
96
+ backgroundColor: headerBg,
97
+ borderBottomColor: t.colors.border,
98
+ paddingTop: safeTop + 10,
99
+ },
96
100
  ]}
97
101
  >
98
102
  {onBack ? (
@@ -175,13 +179,10 @@ export function ConversationHeader({
175
179
  );
176
180
  }
177
181
 
178
- const PT = Platform.OS === "ios" ? (StatusBar.currentHeight ?? 0) : 0;
179
-
180
182
  const styles = StyleSheet.create({
181
183
  container: {
182
184
  flexDirection: "row",
183
185
  alignItems: "center",
184
- paddingTop: PT + 10,
185
186
  paddingBottom: 10,
186
187
  paddingHorizontal: 8,
187
188
  borderBottomWidth: StyleSheet.hairlineWidth,
@@ -13,6 +13,7 @@ import { AssigneeAvatar } from "./AssigneeAvatar";
13
13
  import type { AssigneeType } from "./AssigneeAvatar";
14
14
  import { SendPlaneIcon, ChevronLeftIcon, CloseIcon } from "../icons";
15
15
  import { POWERED_BY_TEXT, getBrandColor, contrastingTextOnBrand } from "../theme";
16
+ import { usePanelSafeAreaInsets } from "../safe-area";
16
17
 
17
18
  // ── format date — mirrors format-list-message-date.ts ────────────────────────
18
19
 
@@ -164,6 +165,7 @@ export function ConversationListScreen({
164
165
  onClose,
165
166
  }: ConversationListScreenProps) {
166
167
  const { theme: t, visitorQueryParams, wsClient, setTotalUnread, widgetConfig } = useLiveChatContext();
168
+ const { top: safeTop, bottom: safeBottom } = usePanelSafeAreaInsets();
167
169
  const settings = widgetConfig?.widgetSettings ?? {};
168
170
  const brandColor = getBrandColor(settings);
169
171
  const contrastText = contrastingTextOnBrand(brandColor);
@@ -332,7 +334,16 @@ export function ConversationListScreen({
332
334
  return (
333
335
  <View style={[styles.flex, { backgroundColor: t.colors.background }]}>
334
336
  {/* header */}
335
- <View style={[styles.header, { backgroundColor: t.colors.headerBackground, borderBottomColor: t.colors.border }]}>
337
+ <View
338
+ style={[
339
+ styles.header,
340
+ {
341
+ backgroundColor: t.colors.headerBackground,
342
+ borderBottomColor: t.colors.border,
343
+ paddingTop: safeTop + 10,
344
+ },
345
+ ]}
346
+ >
336
347
  {onBack ? (
337
348
  <TouchableOpacity onPress={onBack} style={styles.headerBtn} accessibilityLabel="Back">
338
349
  <ChevronLeftIcon size={22} color={t.colors.headerText} />
@@ -378,13 +389,13 @@ export function ConversationListScreen({
378
389
  ListFooterComponent={loadingMore ? <ActivityIndicator color={t.colors.brand} style={{ margin: 16 }} /> : null}
379
390
  onEndReached={hasNextPage ? loadMore : undefined}
380
391
  onEndReachedThreshold={0.3}
381
- contentContainerStyle={{ paddingBottom: 80 }}
392
+ contentContainerStyle={{ paddingBottom: 80 + safeBottom }}
382
393
  />
383
394
  )}
384
395
 
385
396
  {/* send new message button — mirrors web's primary CTA */}
386
397
  {onNewConversation ? (
387
- <View style={styles.fabContainer}>
398
+ <View style={[styles.fabContainer, { bottom: 28 + safeBottom }]}>
388
399
  <TouchableOpacity
389
400
  onPress={onNewConversation}
390
401
  activeOpacity={0.85}
@@ -397,7 +408,9 @@ export function ConversationListScreen({
397
408
  </View>
398
409
  ) : null}
399
410
 
400
- <Text style={[styles.poweredBy, { color: t.colors.textMuted }]}>{POWERED_BY_TEXT}</Text>
411
+ <Text style={[styles.poweredBy, { color: t.colors.textMuted, paddingBottom: 8 + safeBottom }]}>
412
+ {POWERED_BY_TEXT}
413
+ </Text>
401
414
  </View>
402
415
  );
403
416
  }
@@ -408,7 +421,7 @@ const styles = StyleSheet.create({
408
421
  header: {
409
422
  flexDirection: "row",
410
423
  alignItems: "center",
411
- paddingVertical: 10,
424
+ paddingBottom: 10,
412
425
  paddingHorizontal: 4,
413
426
  borderBottomWidth: StyleSheet.hairlineWidth,
414
427
  },