@repzo/widget-react-native 1.0.0 → 1.0.4

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 (153) hide show
  1. package/README.md +167 -74
  2. package/lib/commonjs/api/client.js +3 -1
  3. package/lib/commonjs/api/client.js.map +1 -1
  4. package/lib/commonjs/api/realtime.js +2 -0
  5. package/lib/commonjs/api/realtime.js.map +1 -1
  6. package/lib/commonjs/attachments/pickers.js +493 -0
  7. package/lib/commonjs/attachments/pickers.js.map +1 -0
  8. package/lib/commonjs/i18n.js +45 -0
  9. package/lib/commonjs/i18n.js.map +1 -1
  10. package/lib/commonjs/index.js.map +1 -1
  11. package/lib/commonjs/locales.js +21 -0
  12. package/lib/commonjs/locales.js.map +1 -1
  13. package/lib/commonjs/state/widget-store.js +256 -18
  14. package/lib/commonjs/state/widget-store.js.map +1 -1
  15. package/lib/commonjs/types.js +16 -0
  16. package/lib/commonjs/types.js.map +1 -1
  17. package/lib/commonjs/ui/WidgetProvider.js +70 -10
  18. package/lib/commonjs/ui/WidgetProvider.js.map +1 -1
  19. package/lib/commonjs/ui/components/AttachmentChips.js +135 -0
  20. package/lib/commonjs/ui/components/AttachmentChips.js.map +1 -0
  21. package/lib/commonjs/ui/components/AttachmentMenu.js +125 -0
  22. package/lib/commonjs/ui/components/AttachmentMenu.js.map +1 -0
  23. package/lib/commonjs/ui/components/ImageViewer.js +181 -0
  24. package/lib/commonjs/ui/components/ImageViewer.js.map +1 -0
  25. package/lib/commonjs/ui/components/InAppNotification.js +210 -0
  26. package/lib/commonjs/ui/components/InAppNotification.js.map +1 -0
  27. package/lib/commonjs/ui/components/TeamAvatars.js +63 -0
  28. package/lib/commonjs/ui/components/TeamAvatars.js.map +1 -0
  29. package/lib/commonjs/ui/components/icons.js +50 -0
  30. package/lib/commonjs/ui/components/icons.js.map +1 -1
  31. package/lib/commonjs/ui/screens/chat/ChatView.js +303 -24
  32. package/lib/commonjs/ui/screens/chat/ChatView.js.map +1 -1
  33. package/lib/commonjs/ui/screens/chat/ChatView.styles.js +70 -0
  34. package/lib/commonjs/ui/screens/chat/ChatView.styles.js.map +1 -1
  35. package/lib/module/api/client.js +3 -1
  36. package/lib/module/api/client.js.map +1 -1
  37. package/lib/module/api/realtime.js +2 -0
  38. package/lib/module/api/realtime.js.map +1 -1
  39. package/lib/module/attachments/pickers.js +479 -0
  40. package/lib/module/attachments/pickers.js.map +1 -0
  41. package/lib/module/i18n.js +44 -0
  42. package/lib/module/i18n.js.map +1 -1
  43. package/lib/module/index.js.map +1 -1
  44. package/lib/module/locales.js +21 -0
  45. package/lib/module/locales.js.map +1 -1
  46. package/lib/module/state/widget-store.js +256 -18
  47. package/lib/module/state/widget-store.js.map +1 -1
  48. package/lib/module/types.js +16 -0
  49. package/lib/module/types.js.map +1 -1
  50. package/lib/module/ui/WidgetProvider.js +71 -11
  51. package/lib/module/ui/WidgetProvider.js.map +1 -1
  52. package/lib/module/ui/components/AttachmentChips.js +131 -0
  53. package/lib/module/ui/components/AttachmentChips.js.map +1 -0
  54. package/lib/module/ui/components/AttachmentMenu.js +120 -0
  55. package/lib/module/ui/components/AttachmentMenu.js.map +1 -0
  56. package/lib/module/ui/components/ImageViewer.js +177 -0
  57. package/lib/module/ui/components/ImageViewer.js.map +1 -0
  58. package/lib/module/ui/components/InAppNotification.js +208 -0
  59. package/lib/module/ui/components/InAppNotification.js.map +1 -0
  60. package/lib/module/ui/components/TeamAvatars.js +59 -0
  61. package/lib/module/ui/components/TeamAvatars.js.map +1 -0
  62. package/lib/module/ui/components/icons.js +49 -0
  63. package/lib/module/ui/components/icons.js.map +1 -1
  64. package/lib/module/ui/screens/chat/ChatView.js +306 -27
  65. package/lib/module/ui/screens/chat/ChatView.js.map +1 -1
  66. package/lib/module/ui/screens/chat/ChatView.styles.js +70 -0
  67. package/lib/module/ui/screens/chat/ChatView.styles.js.map +1 -1
  68. package/lib/typescript/commonjs/api/client.d.ts +8 -2
  69. package/lib/typescript/commonjs/api/client.d.ts.map +1 -1
  70. package/lib/typescript/commonjs/api/realtime.d.ts.map +1 -1
  71. package/lib/typescript/commonjs/attachments/pickers.d.ts +81 -0
  72. package/lib/typescript/commonjs/attachments/pickers.d.ts.map +1 -0
  73. package/lib/typescript/commonjs/i18n.d.ts +23 -0
  74. package/lib/typescript/commonjs/i18n.d.ts.map +1 -1
  75. package/lib/typescript/commonjs/index.d.ts +1 -1
  76. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  77. package/lib/typescript/commonjs/locales.d.ts.map +1 -1
  78. package/lib/typescript/commonjs/state/widget-store.d.ts +40 -2
  79. package/lib/typescript/commonjs/state/widget-store.d.ts.map +1 -1
  80. package/lib/typescript/commonjs/types.d.ts +88 -1
  81. package/lib/typescript/commonjs/types.d.ts.map +1 -1
  82. package/lib/typescript/commonjs/ui/WidgetProvider.d.ts.map +1 -1
  83. package/lib/typescript/commonjs/ui/components/AttachmentChips.d.ts +16 -0
  84. package/lib/typescript/commonjs/ui/components/AttachmentChips.d.ts.map +1 -0
  85. package/lib/typescript/commonjs/ui/components/AttachmentMenu.d.ts +28 -0
  86. package/lib/typescript/commonjs/ui/components/AttachmentMenu.d.ts.map +1 -0
  87. package/lib/typescript/commonjs/ui/components/ImageViewer.d.ts +23 -0
  88. package/lib/typescript/commonjs/ui/components/ImageViewer.d.ts.map +1 -0
  89. package/lib/typescript/commonjs/ui/components/InAppNotification.d.ts +28 -0
  90. package/lib/typescript/commonjs/ui/components/InAppNotification.d.ts.map +1 -0
  91. package/lib/typescript/commonjs/ui/components/TeamAvatars.d.ts +17 -0
  92. package/lib/typescript/commonjs/ui/components/TeamAvatars.d.ts.map +1 -0
  93. package/lib/typescript/commonjs/ui/components/icons.d.ts +2 -0
  94. package/lib/typescript/commonjs/ui/components/icons.d.ts.map +1 -1
  95. package/lib/typescript/commonjs/ui/screens/chat/ChatView.d.ts +3 -2
  96. package/lib/typescript/commonjs/ui/screens/chat/ChatView.d.ts.map +1 -1
  97. package/lib/typescript/commonjs/ui/screens/chat/ChatView.styles.d.ts +69 -0
  98. package/lib/typescript/commonjs/ui/screens/chat/ChatView.styles.d.ts.map +1 -1
  99. package/lib/typescript/commonjs/ui/screens/chat/ChatView.types.d.ts +41 -2
  100. package/lib/typescript/commonjs/ui/screens/chat/ChatView.types.d.ts.map +1 -1
  101. package/lib/typescript/module/api/client.d.ts +8 -2
  102. package/lib/typescript/module/api/client.d.ts.map +1 -1
  103. package/lib/typescript/module/api/realtime.d.ts.map +1 -1
  104. package/lib/typescript/module/attachments/pickers.d.ts +81 -0
  105. package/lib/typescript/module/attachments/pickers.d.ts.map +1 -0
  106. package/lib/typescript/module/i18n.d.ts +23 -0
  107. package/lib/typescript/module/i18n.d.ts.map +1 -1
  108. package/lib/typescript/module/index.d.ts +1 -1
  109. package/lib/typescript/module/index.d.ts.map +1 -1
  110. package/lib/typescript/module/locales.d.ts.map +1 -1
  111. package/lib/typescript/module/state/widget-store.d.ts +40 -2
  112. package/lib/typescript/module/state/widget-store.d.ts.map +1 -1
  113. package/lib/typescript/module/types.d.ts +88 -1
  114. package/lib/typescript/module/types.d.ts.map +1 -1
  115. package/lib/typescript/module/ui/WidgetProvider.d.ts.map +1 -1
  116. package/lib/typescript/module/ui/components/AttachmentChips.d.ts +16 -0
  117. package/lib/typescript/module/ui/components/AttachmentChips.d.ts.map +1 -0
  118. package/lib/typescript/module/ui/components/AttachmentMenu.d.ts +28 -0
  119. package/lib/typescript/module/ui/components/AttachmentMenu.d.ts.map +1 -0
  120. package/lib/typescript/module/ui/components/ImageViewer.d.ts +23 -0
  121. package/lib/typescript/module/ui/components/ImageViewer.d.ts.map +1 -0
  122. package/lib/typescript/module/ui/components/InAppNotification.d.ts +28 -0
  123. package/lib/typescript/module/ui/components/InAppNotification.d.ts.map +1 -0
  124. package/lib/typescript/module/ui/components/TeamAvatars.d.ts +17 -0
  125. package/lib/typescript/module/ui/components/TeamAvatars.d.ts.map +1 -0
  126. package/lib/typescript/module/ui/components/icons.d.ts +2 -0
  127. package/lib/typescript/module/ui/components/icons.d.ts.map +1 -1
  128. package/lib/typescript/module/ui/screens/chat/ChatView.d.ts +3 -2
  129. package/lib/typescript/module/ui/screens/chat/ChatView.d.ts.map +1 -1
  130. package/lib/typescript/module/ui/screens/chat/ChatView.styles.d.ts +69 -0
  131. package/lib/typescript/module/ui/screens/chat/ChatView.styles.d.ts.map +1 -1
  132. package/lib/typescript/module/ui/screens/chat/ChatView.types.d.ts +41 -2
  133. package/lib/typescript/module/ui/screens/chat/ChatView.types.d.ts.map +1 -1
  134. package/metro.js +17 -32
  135. package/package.json +18 -1
  136. package/src/api/client.ts +5 -3
  137. package/src/api/realtime.ts +2 -0
  138. package/src/attachments/pickers.ts +515 -0
  139. package/src/i18n.ts +48 -0
  140. package/src/index.tsx +4 -0
  141. package/src/locales.ts +21 -0
  142. package/src/state/widget-store.ts +256 -19
  143. package/src/types.ts +95 -0
  144. package/src/ui/WidgetProvider.tsx +90 -9
  145. package/src/ui/components/AttachmentChips.tsx +135 -0
  146. package/src/ui/components/AttachmentMenu.tsx +132 -0
  147. package/src/ui/components/ImageViewer.tsx +178 -0
  148. package/src/ui/components/InAppNotification.tsx +225 -0
  149. package/src/ui/components/TeamAvatars.tsx +58 -0
  150. package/src/ui/components/icons.tsx +37 -0
  151. package/src/ui/screens/chat/ChatView.styles.ts +70 -0
  152. package/src/ui/screens/chat/ChatView.tsx +345 -35
  153. package/src/ui/screens/chat/ChatView.types.ts +51 -2
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Picked-but-unsent attachments above the composer: a thumbnail for images, a
5
+ * name + size card for everything else, each with its own remove button.
6
+ */
7
+
8
+ import { Image, Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
9
+ import { formatBytes, isImageAttachment } from "../../attachments/pickers.js";
10
+ import { formatLabel } from "../../i18n.js";
11
+ import { fontSize, palette, radius, spacing, withAlpha } from "../styles/theme.js";
12
+ import { START_ALIGN } from "../utils/rtl.js";
13
+ import { CloseIcon } from "./icons.js";
14
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
+ export function AttachmentChips({
16
+ attachments,
17
+ disabled,
18
+ removeLabel,
19
+ onRemove
20
+ }) {
21
+ return /*#__PURE__*/_jsx(ScrollView, {
22
+ horizontal: true,
23
+ showsHorizontalScrollIndicator: false,
24
+ keyboardShouldPersistTaps: "handled",
25
+ style: styles.scroller,
26
+ contentContainerStyle: styles.row,
27
+ children: attachments.map(attachment => /*#__PURE__*/_jsxs(View, {
28
+ style: [styles.chip, disabled && styles.chipDisabled],
29
+ children: [isImageAttachment(attachment.contentType) ? /*#__PURE__*/_jsx(Image, {
30
+ source: {
31
+ uri: attachment.previewUri
32
+ },
33
+ style: styles.thumbnail,
34
+ resizeMode: "cover",
35
+ accessible: true,
36
+ accessibilityLabel: attachment.name,
37
+ accessibilityIgnoresInvertColors: true
38
+ }) : /*#__PURE__*/_jsxs(View, {
39
+ style: styles.file,
40
+ children: [/*#__PURE__*/_jsx(Text, {
41
+ style: styles.fileName,
42
+ numberOfLines: 1,
43
+ children: attachment.name
44
+ }), /*#__PURE__*/_jsx(Text, {
45
+ style: styles.fileSize,
46
+ children: formatBytes(attachment.size)
47
+ })]
48
+ }), /*#__PURE__*/_jsx(Pressable, {
49
+ onPress: () => onRemove(attachment.id),
50
+ disabled: disabled,
51
+ accessibilityRole: "button",
52
+ accessibilityLabel: formatLabel(removeLabel, {
53
+ name: attachment.name
54
+ }),
55
+ accessibilityState: {
56
+ disabled: !!disabled
57
+ }
58
+ // 22pt badge + 11pt on every side = a 44pt target.
59
+ ,
60
+ hitSlop: 11,
61
+ style: ({
62
+ pressed
63
+ }) => [styles.remove, pressed && styles.removePressed],
64
+ children: /*#__PURE__*/_jsx(CloseIcon, {
65
+ size: 10,
66
+ color: palette.white
67
+ })
68
+ })]
69
+ }, attachment.id))
70
+ });
71
+ }
72
+ const CHIP_HEIGHT = 64;
73
+ const styles = StyleSheet.create({
74
+ scroller: {
75
+ flexGrow: 0,
76
+ marginBottom: spacing.sm
77
+ },
78
+ row: {
79
+ gap: spacing.sm
80
+ },
81
+ chip: {
82
+ height: CHIP_HEIGHT,
83
+ borderRadius: radius.md,
84
+ overflow: 'hidden',
85
+ backgroundColor: palette.surfaceAlt,
86
+ borderWidth: StyleSheet.hairlineWidth,
87
+ borderColor: palette.border
88
+ },
89
+ chipDisabled: {
90
+ opacity: 0.5
91
+ },
92
+ thumbnail: {
93
+ width: CHIP_HEIGHT,
94
+ height: CHIP_HEIGHT
95
+ },
96
+ file: {
97
+ width: 156,
98
+ height: CHIP_HEIGHT,
99
+ justifyContent: 'center',
100
+ paddingStart: spacing.md,
101
+ // Clear of the remove badge in the top corner.
102
+ paddingEnd: spacing.xl + spacing.sm
103
+ },
104
+ fileName: {
105
+ textAlign: START_ALIGN,
106
+ fontSize: fontSize.meta,
107
+ fontWeight: '600',
108
+ color: palette.ink
109
+ },
110
+ fileSize: {
111
+ textAlign: START_ALIGN,
112
+ fontSize: fontSize.caption,
113
+ color: palette.textMuted,
114
+ marginTop: 2
115
+ },
116
+ remove: {
117
+ position: 'absolute',
118
+ top: spacing.xs,
119
+ end: spacing.xs,
120
+ width: 22,
121
+ height: 22,
122
+ borderRadius: 11,
123
+ alignItems: 'center',
124
+ justifyContent: 'center',
125
+ backgroundColor: withAlpha(palette.ink, 0.72)
126
+ },
127
+ removePressed: {
128
+ opacity: 0.7
129
+ }
130
+ });
131
+ //# sourceMappingURL=AttachmentChips.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Image","Pressable","ScrollView","StyleSheet","Text","View","formatBytes","isImageAttachment","formatLabel","fontSize","palette","radius","spacing","withAlpha","START_ALIGN","CloseIcon","jsx","_jsx","jsxs","_jsxs","AttachmentChips","attachments","disabled","removeLabel","onRemove","horizontal","showsHorizontalScrollIndicator","keyboardShouldPersistTaps","style","styles","scroller","contentContainerStyle","row","children","map","attachment","chip","chipDisabled","contentType","source","uri","previewUri","thumbnail","resizeMode","accessible","accessibilityLabel","name","accessibilityIgnoresInvertColors","file","fileName","numberOfLines","fileSize","size","onPress","id","accessibilityRole","accessibilityState","hitSlop","pressed","remove","removePressed","color","white","CHIP_HEIGHT","create","flexGrow","marginBottom","sm","gap","height","borderRadius","md","overflow","backgroundColor","surfaceAlt","borderWidth","hairlineWidth","borderColor","border","opacity","width","justifyContent","paddingStart","paddingEnd","xl","textAlign","meta","fontWeight","ink","caption","textMuted","marginTop","position","top","xs","end","alignItems"],"sourceRoot":"../../../../src","sources":["ui/components/AttachmentChips.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * The attach button's choice of source.
5
+ *
6
+ * iOS gets the native action sheet. Android has no equivalent (`Alert` caps at
7
+ * three buttons, and three sources plus Cancel is four), so it gets a small
8
+ * bottom sheet in its own transparent modal — which also lets the hardware
9
+ * back button close the sheet rather than the whole widget.
10
+ */
11
+
12
+ import { ActionSheetIOS, Modal, Platform, Pressable, StyleSheet, Text, View } from 'react-native';
13
+ import { useWidgetInsets } from "../hooks/use-widget-insets.js";
14
+ import { fontSize, palette, radius, spacing } from "../styles/theme.js";
15
+ import { START_ALIGN } from "../utils/rtl.js";
16
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
17
+ /**
18
+ * iOS only: shows the native sheet and calls `onSelect` with the chosen key
19
+ * (nothing on cancel). Returns false elsewhere, so the caller shows
20
+ * `AttachmentMenu` instead.
21
+ */
22
+ export function showNativeAttachmentMenu(options, cancelLabel, onSelect) {
23
+ if (Platform.OS !== 'ios') return false;
24
+ ActionSheetIOS.showActionSheetWithOptions({
25
+ options: [...options.map(option => option.label), cancelLabel],
26
+ cancelButtonIndex: options.length
27
+ }, index => {
28
+ const chosen = options[index];
29
+ if (chosen) onSelect(chosen.key);
30
+ });
31
+ return true;
32
+ }
33
+ export function AttachmentMenu({
34
+ visible,
35
+ options,
36
+ cancelLabel,
37
+ onSelect,
38
+ onClose
39
+ }) {
40
+ const insets = useWidgetInsets();
41
+ return /*#__PURE__*/_jsxs(Modal, {
42
+ visible: visible,
43
+ transparent: true,
44
+ animationType: "fade",
45
+ statusBarTranslucent: true,
46
+ onRequestClose: onClose,
47
+ children: [/*#__PURE__*/_jsx(Pressable, {
48
+ style: styles.backdrop,
49
+ onPress: onClose,
50
+ accessibilityRole: "button",
51
+ accessibilityLabel: cancelLabel
52
+ }), /*#__PURE__*/_jsxs(View, {
53
+ style: [styles.sheet, {
54
+ paddingBottom: insets.bottom + spacing.sm
55
+ }],
56
+ accessibilityViewIsModal: true,
57
+ children: [options.map(option => /*#__PURE__*/_jsx(Pressable, {
58
+ onPress: () => onSelect(option.key),
59
+ accessibilityRole: "button",
60
+ style: ({
61
+ pressed
62
+ }) => [styles.row, pressed && styles.rowPressed],
63
+ children: /*#__PURE__*/_jsx(Text, {
64
+ style: styles.rowLabel,
65
+ children: option.label
66
+ })
67
+ }, option.key)), /*#__PURE__*/_jsx(View, {
68
+ style: styles.divider
69
+ }), /*#__PURE__*/_jsx(Pressable, {
70
+ onPress: onClose,
71
+ accessibilityRole: "button",
72
+ style: ({
73
+ pressed
74
+ }) => [styles.row, pressed && styles.rowPressed],
75
+ children: /*#__PURE__*/_jsx(Text, {
76
+ style: [styles.rowLabel, styles.cancelLabel],
77
+ children: cancelLabel
78
+ })
79
+ })]
80
+ })]
81
+ });
82
+ }
83
+ const styles = StyleSheet.create({
84
+ backdrop: {
85
+ ...StyleSheet.absoluteFillObject,
86
+ backgroundColor: 'rgba(0, 0, 0, 0.32)'
87
+ },
88
+ sheet: {
89
+ position: 'absolute',
90
+ start: 0,
91
+ end: 0,
92
+ bottom: 0,
93
+ backgroundColor: palette.white,
94
+ borderTopLeftRadius: radius.xl + 4,
95
+ borderTopRightRadius: radius.xl + 4,
96
+ paddingTop: spacing.sm
97
+ },
98
+ row: {
99
+ minHeight: 52,
100
+ justifyContent: 'center',
101
+ paddingHorizontal: spacing.xl
102
+ },
103
+ rowPressed: {
104
+ backgroundColor: palette.surfaceAlt
105
+ },
106
+ rowLabel: {
107
+ textAlign: START_ALIGN,
108
+ fontSize: fontSize.body,
109
+ color: palette.ink
110
+ },
111
+ cancelLabel: {
112
+ color: palette.textMuted
113
+ },
114
+ divider: {
115
+ height: StyleSheet.hairlineWidth,
116
+ backgroundColor: palette.border,
117
+ marginVertical: spacing.xs
118
+ }
119
+ });
120
+ //# sourceMappingURL=AttachmentMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["ActionSheetIOS","Modal","Platform","Pressable","StyleSheet","Text","View","useWidgetInsets","fontSize","palette","radius","spacing","START_ALIGN","jsx","_jsx","jsxs","_jsxs","showNativeAttachmentMenu","options","cancelLabel","onSelect","OS","showActionSheetWithOptions","map","option","label","cancelButtonIndex","length","index","chosen","key","AttachmentMenu","visible","onClose","insets","transparent","animationType","statusBarTranslucent","onRequestClose","children","style","styles","backdrop","onPress","accessibilityRole","accessibilityLabel","sheet","paddingBottom","bottom","sm","accessibilityViewIsModal","pressed","row","rowPressed","rowLabel","divider","create","absoluteFillObject","backgroundColor","position","start","end","white","borderTopLeftRadius","xl","borderTopRightRadius","paddingTop","minHeight","justifyContent","paddingHorizontal","surfaceAlt","textAlign","body","color","ink","textMuted","height","hairlineWidth","border","marginVertical","xs"],"sourceRoot":"../../../../src","sources":["ui/components/AttachmentMenu.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Full-screen viewer for image attachments, so a tap on a photo the agent sent
5
+ * stays inside the messenger instead of bouncing to the browser. Pinch-to-zoom
6
+ * uses the native ScrollView zoom (iOS); Android shows the image fitted.
7
+ */
8
+
9
+ import { useState } from 'react';
10
+ import { ActivityIndicator, Image, Modal, Platform, Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
11
+ import { useWidgetInsets } from "../hooks/use-widget-insets.js";
12
+ import { fontSize, palette, spacing } from "../styles/theme.js";
13
+ import { CloseIcon } from "./icons.js";
14
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
+ export function ImageViewer({
16
+ image,
17
+ labels,
18
+ onClose,
19
+ onOpenExternally
20
+ }) {
21
+ const insets = useWidgetInsets();
22
+ // Keyed by URL so opening another image starts from a clean loading state.
23
+ const [status, setStatus] = useState({
24
+ url: null,
25
+ state: 'loading'
26
+ });
27
+ const state = status.url === image?.url ? status.state : 'loading';
28
+ return /*#__PURE__*/_jsx(Modal, {
29
+ visible: !!image,
30
+ transparent: true,
31
+ animationType: "fade",
32
+ statusBarTranslucent: true,
33
+ onRequestClose: onClose,
34
+ children: /*#__PURE__*/_jsxs(View, {
35
+ style: styles.backdrop,
36
+ accessibilityViewIsModal: true,
37
+ children: [image ? /*#__PURE__*/_jsx(ScrollView, {
38
+ style: styles.fill,
39
+ contentContainerStyle: styles.center,
40
+ maximumZoomScale: 4,
41
+ minimumZoomScale: 1,
42
+ centerContent: true,
43
+ showsHorizontalScrollIndicator: false,
44
+ showsVerticalScrollIndicator: false,
45
+ bouncesZoom: true,
46
+ children: /*#__PURE__*/_jsx(Image, {
47
+ source: {
48
+ uri: image.url
49
+ },
50
+ style: styles.image,
51
+ resizeMode: "contain",
52
+ accessibilityLabel: image.name,
53
+ accessibilityIgnoresInvertColors: true,
54
+ onLoad: () => setStatus({
55
+ url: image.url,
56
+ state: 'ready'
57
+ }),
58
+ onError: () => setStatus({
59
+ url: image.url,
60
+ state: 'failed'
61
+ })
62
+ })
63
+ }) : null, image && state === 'loading' ? /*#__PURE__*/_jsx(ActivityIndicator, {
64
+ style: StyleSheet.absoluteFill,
65
+ color: palette.white
66
+ }) : null, image && state === 'failed' ? /*#__PURE__*/_jsxs(View, {
67
+ style: [StyleSheet.absoluteFill, styles.center, styles.failed],
68
+ children: [/*#__PURE__*/_jsx(Text, {
69
+ style: styles.failedText,
70
+ children: labels.loadFailed
71
+ }), /*#__PURE__*/_jsx(Pressable, {
72
+ onPress: () => onOpenExternally(image.url),
73
+ accessibilityRole: "button",
74
+ style: ({
75
+ pressed
76
+ }) => [styles.externalButton, pressed && styles.pressed],
77
+ children: /*#__PURE__*/_jsx(Text, {
78
+ style: styles.externalLabel,
79
+ children: labels.openExternally
80
+ })
81
+ })]
82
+ }) : null, /*#__PURE__*/_jsxs(View, {
83
+ style: [styles.header, {
84
+ paddingTop: insets.top + spacing.sm
85
+ }],
86
+ pointerEvents: "box-none",
87
+ children: [/*#__PURE__*/_jsx(Text, {
88
+ style: styles.title,
89
+ numberOfLines: 1,
90
+ children: image?.name ?? ''
91
+ }), /*#__PURE__*/_jsx(Pressable, {
92
+ onPress: onClose,
93
+ accessibilityRole: "button",
94
+ accessibilityLabel: labels.close,
95
+ hitSlop: 12,
96
+ style: ({
97
+ pressed
98
+ }) => [styles.closeButton, pressed && styles.pressed],
99
+ children: /*#__PURE__*/_jsx(CloseIcon, {
100
+ size: 20,
101
+ color: palette.white
102
+ })
103
+ })]
104
+ })]
105
+ })
106
+ });
107
+ }
108
+ const styles = StyleSheet.create({
109
+ backdrop: {
110
+ flex: 1,
111
+ backgroundColor: '#000000'
112
+ },
113
+ fill: {
114
+ flex: 1
115
+ },
116
+ center: {
117
+ flexGrow: 1,
118
+ alignItems: 'center',
119
+ justifyContent: 'center'
120
+ },
121
+ image: {
122
+ width: '100%',
123
+ height: '100%'
124
+ },
125
+ header: {
126
+ position: 'absolute',
127
+ top: 0,
128
+ left: 0,
129
+ right: 0,
130
+ flexDirection: 'row',
131
+ alignItems: 'center',
132
+ gap: spacing.md,
133
+ paddingHorizontal: spacing.lg,
134
+ paddingBottom: spacing.sm,
135
+ backgroundColor: 'rgba(0,0,0,0.45)'
136
+ },
137
+ title: {
138
+ flex: 1,
139
+ minWidth: 0,
140
+ color: palette.white,
141
+ fontSize: fontSize.body,
142
+ fontWeight: '600'
143
+ },
144
+ closeButton: {
145
+ width: 36,
146
+ height: 36,
147
+ borderRadius: 18,
148
+ alignItems: 'center',
149
+ justifyContent: 'center',
150
+ backgroundColor: 'rgba(255,255,255,0.14)'
151
+ },
152
+ pressed: {
153
+ opacity: 0.7
154
+ },
155
+ failed: {
156
+ gap: spacing.md,
157
+ paddingHorizontal: spacing.xxl
158
+ },
159
+ failedText: {
160
+ color: palette.white,
161
+ fontSize: fontSize.body,
162
+ textAlign: 'center'
163
+ },
164
+ externalButton: {
165
+ paddingHorizontal: spacing.lg,
166
+ paddingVertical: spacing.sm,
167
+ borderRadius: 999,
168
+ borderWidth: StyleSheet.hairlineWidth,
169
+ borderColor: 'rgba(255,255,255,0.5)'
170
+ },
171
+ externalLabel: {
172
+ color: palette.white,
173
+ fontSize: fontSize.meta,
174
+ fontWeight: Platform.OS === 'ios' ? '600' : 'bold'
175
+ }
176
+ });
177
+ //# sourceMappingURL=ImageViewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useState","ActivityIndicator","Image","Modal","Platform","Pressable","ScrollView","StyleSheet","Text","View","useWidgetInsets","fontSize","palette","spacing","CloseIcon","jsx","_jsx","jsxs","_jsxs","ImageViewer","image","labels","onClose","onOpenExternally","insets","status","setStatus","url","state","visible","transparent","animationType","statusBarTranslucent","onRequestClose","children","style","styles","backdrop","accessibilityViewIsModal","fill","contentContainerStyle","center","maximumZoomScale","minimumZoomScale","centerContent","showsHorizontalScrollIndicator","showsVerticalScrollIndicator","bouncesZoom","source","uri","resizeMode","accessibilityLabel","name","accessibilityIgnoresInvertColors","onLoad","onError","absoluteFill","color","white","failed","failedText","loadFailed","onPress","accessibilityRole","pressed","externalButton","externalLabel","openExternally","header","paddingTop","top","sm","pointerEvents","title","numberOfLines","close","hitSlop","closeButton","size","create","flex","backgroundColor","flexGrow","alignItems","justifyContent","width","height","position","left","right","flexDirection","gap","md","paddingHorizontal","lg","paddingBottom","minWidth","body","fontWeight","borderRadius","opacity","xxl","textAlign","paddingVertical","borderWidth","hairlineWidth","borderColor","meta","OS"],"sourceRoot":"../../../../src","sources":["ui/components/ImageViewer.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,208 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * The card that floats over the host app when a team reply arrives while the
5
+ * messenger is closed — Intercom's in-app notification. It never times out:
6
+ * tapping it opens the conversation, swiping it left or right dismisses it
7
+ * (the thread stays unread). The store takes it down on its own once the
8
+ * messenger opens or the thread is read.
9
+ *
10
+ * Pure JS gestures (PanResponder), so hosts need no gesture library.
11
+ */
12
+
13
+ import { useEffect, useMemo, useRef } from 'react';
14
+ import { AccessibilityInfo, Animated, PanResponder, Pressable, StyleSheet, Text, View, useWindowDimensions } from 'react-native';
15
+ import { formatLabel } from "../../i18n.js";
16
+ import { useReduceMotion } from "../hooks/use-reduce-motion.js";
17
+ import { fontSize, palette, radius, shadows, spacing, withAlpha } from "../styles/theme.js";
18
+ import { START_ALIGN } from "../utils/rtl.js";
19
+ import { Avatar } from "./Avatar.js";
20
+
21
+ /** Share of the card's width a drag must travel to count as a dismiss. */
22
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
23
+ const DISMISS_DISTANCE_RATIO = 0.35;
24
+ /** A quick flick dismisses even when it travels less than that. */
25
+ const DISMISS_VELOCITY = 0.6;
26
+ export function InAppNotification({
27
+ notification,
28
+ color,
29
+ bottomInset,
30
+ labels,
31
+ onOpen,
32
+ onDismiss
33
+ }) {
34
+ const {
35
+ width
36
+ } = useWindowDimensions();
37
+ const reduceMotion = useReduceMotion();
38
+ // Read as "hold still" until the setting is known (see useReduceMotion).
39
+ const animate = reduceMotion === false;
40
+ const entry = useRef(new Animated.Value(animate ? 0 : 1)).current;
41
+ const dragX = useRef(new Animated.Value(0)).current;
42
+ const preview = notification.preview || (notification.hasAttachments ? labels.attachment : '');
43
+ const sender = notification.senderName ? formatLabel(labels.replyFrom, {
44
+ name: notification.senderName
45
+ }) : labels.newReply;
46
+ const accessibilityLabel = [preview, sender].filter(Boolean).join(', ');
47
+
48
+ // Mounted once per reply (the provider keys it by message id), so this runs
49
+ // for every new card: slide it in and tell screen-reader users it arrived.
50
+ useEffect(() => {
51
+ if (animate) {
52
+ Animated.spring(entry, {
53
+ toValue: 1,
54
+ useNativeDriver: true,
55
+ speed: 16,
56
+ bounciness: 4
57
+ }).start();
58
+ }
59
+ AccessibilityInfo.announceForAccessibility(accessibilityLabel);
60
+ // eslint-disable-next-line react-hooks/exhaustive-deps
61
+ }, []);
62
+ const panResponder = useMemo(() => {
63
+ const settle = () => Animated.spring(dragX, {
64
+ toValue: 0,
65
+ useNativeDriver: true,
66
+ bounciness: 6
67
+ }).start();
68
+ return PanResponder.create({
69
+ // Capture so a horizontal drag wins over the Pressable underneath; taps
70
+ // and vertical movement still reach it.
71
+ onMoveShouldSetPanResponderCapture: (_, gesture) => Math.abs(gesture.dx) > 8 && Math.abs(gesture.dx) > Math.abs(gesture.dy) * 1.5,
72
+ onPanResponderMove: (_, gesture) => dragX.setValue(gesture.dx),
73
+ onPanResponderTerminationRequest: () => false,
74
+ onPanResponderRelease: (_, gesture) => {
75
+ const farEnough = Math.abs(gesture.dx) > width * DISMISS_DISTANCE_RATIO;
76
+ const fastEnough = Math.abs(gesture.vx) > DISMISS_VELOCITY;
77
+ if (!farEnough && !fastEnough) {
78
+ settle();
79
+ return;
80
+ }
81
+ const direction = (gesture.dx || gesture.vx) < 0 ? -1 : 1;
82
+ Animated.timing(dragX, {
83
+ toValue: direction * width,
84
+ duration: animate ? 180 : 0,
85
+ useNativeDriver: true
86
+ }).start(() => onDismiss());
87
+ },
88
+ onPanResponderTerminate: settle
89
+ });
90
+ }, [animate, dragX, onDismiss, width]);
91
+ const handleAccessibilityAction = event => {
92
+ if (event.nativeEvent.actionName === 'dismiss') onDismiss();
93
+ if (event.nativeEvent.actionName === 'activate') onOpen(notification.conversationId);
94
+ };
95
+ const opacity = Animated.multiply(entry, dragX.interpolate({
96
+ inputRange: [-width, 0, width],
97
+ outputRange: [0, 1, 0],
98
+ extrapolate: 'clamp'
99
+ }));
100
+ const translateY = entry.interpolate({
101
+ inputRange: [0, 1],
102
+ outputRange: [spacing.lg, 0]
103
+ });
104
+ return /*#__PURE__*/_jsx(View, {
105
+ pointerEvents: "box-none",
106
+ style: [styles.wrapper, {
107
+ bottom: bottomInset + spacing.md
108
+ }],
109
+ children: /*#__PURE__*/_jsx(Animated.View, {
110
+ ...panResponder.panHandlers,
111
+ style: [styles.card, {
112
+ opacity,
113
+ transform: [{
114
+ translateX: dragX
115
+ }, {
116
+ translateY
117
+ }]
118
+ }],
119
+ children: /*#__PURE__*/_jsxs(Pressable, {
120
+ onPress: () => onOpen(notification.conversationId),
121
+ accessibilityRole: "button",
122
+ accessibilityLabel: accessibilityLabel,
123
+ accessibilityHint: labels.openHint,
124
+ accessibilityActions: [{
125
+ name: 'activate'
126
+ }, {
127
+ name: 'dismiss',
128
+ label: labels.dismiss
129
+ }],
130
+ onAccessibilityAction: handleAccessibilityAction,
131
+ style: ({
132
+ pressed
133
+ }) => [styles.row, pressed && styles.pressed],
134
+ children: [/*#__PURE__*/_jsx(Avatar, {
135
+ avatar: notification.senderAvatar,
136
+ name: notification.senderName,
137
+ color: color,
138
+ size: 40,
139
+ style: styles.avatar
140
+ }), /*#__PURE__*/_jsxs(View, {
141
+ style: styles.text,
142
+ children: [preview ? /*#__PURE__*/_jsx(Text, {
143
+ numberOfLines: 2,
144
+ style: styles.preview,
145
+ children: preview
146
+ }) : null, /*#__PURE__*/_jsx(Text, {
147
+ numberOfLines: 1,
148
+ style: styles.sender,
149
+ children: sender
150
+ })]
151
+ })]
152
+ })
153
+ })
154
+ });
155
+ }
156
+ const styles = StyleSheet.create({
157
+ wrapper: {
158
+ position: 'absolute',
159
+ left: 0,
160
+ right: 0,
161
+ paddingHorizontal: spacing.lg,
162
+ alignItems: 'center',
163
+ // Above the host's navigator even when the provider is mounted before it.
164
+ zIndex: 1000,
165
+ elevation: 1000
166
+ },
167
+ card: {
168
+ width: '100%',
169
+ maxWidth: 480,
170
+ borderRadius: radius.xl,
171
+ backgroundColor: palette.text,
172
+ ...shadows.floating
173
+ },
174
+ row: {
175
+ flexDirection: 'row',
176
+ alignItems: 'center',
177
+ gap: spacing.md,
178
+ minHeight: 64,
179
+ paddingVertical: spacing.md,
180
+ paddingHorizontal: spacing.lg,
181
+ borderRadius: radius.xl
182
+ },
183
+ pressed: {
184
+ opacity: 0.85
185
+ },
186
+ avatar: {
187
+ borderWidth: 1,
188
+ borderColor: withAlpha(palette.white, 0.1)
189
+ },
190
+ text: {
191
+ flex: 1,
192
+ minWidth: 0,
193
+ gap: 2
194
+ },
195
+ preview: {
196
+ color: palette.white,
197
+ fontSize: fontSize.body,
198
+ fontWeight: '600',
199
+ lineHeight: 20,
200
+ textAlign: START_ALIGN
201
+ },
202
+ sender: {
203
+ color: withAlpha(palette.white, 0.64),
204
+ fontSize: fontSize.meta,
205
+ textAlign: START_ALIGN
206
+ }
207
+ });
208
+ //# sourceMappingURL=InAppNotification.js.map