@repzo/widget-react-native 1.0.0

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 (448) hide show
  1. package/README.md +482 -0
  2. package/lib/commonjs/agent-ui-blocks.js +159 -0
  3. package/lib/commonjs/agent-ui-blocks.js.map +1 -0
  4. package/lib/commonjs/api/client.js +267 -0
  5. package/lib/commonjs/api/client.js.map +1 -0
  6. package/lib/commonjs/api/realtime.js +193 -0
  7. package/lib/commonjs/api/realtime.js.map +1 -0
  8. package/lib/commonjs/api/sse-parser.js +58 -0
  9. package/lib/commonjs/api/sse-parser.js.map +1 -0
  10. package/lib/commonjs/controller.js +23 -0
  11. package/lib/commonjs/controller.js.map +1 -0
  12. package/lib/commonjs/device-id.js +75 -0
  13. package/lib/commonjs/device-id.js.map +1 -0
  14. package/lib/commonjs/events.js +49 -0
  15. package/lib/commonjs/events.js.map +1 -0
  16. package/lib/commonjs/i18n.js +106 -0
  17. package/lib/commonjs/i18n.js.map +1 -0
  18. package/lib/commonjs/index.js +98 -0
  19. package/lib/commonjs/index.js.map +1 -0
  20. package/lib/commonjs/locales.js +85 -0
  21. package/lib/commonjs/locales.js.map +1 -0
  22. package/lib/commonjs/package.json +1 -0
  23. package/lib/commonjs/push/push-notifications.js +208 -0
  24. package/lib/commonjs/push/push-notifications.js.map +1 -0
  25. package/lib/commonjs/state/use-widget-state.js +23 -0
  26. package/lib/commonjs/state/use-widget-state.js.map +1 -0
  27. package/lib/commonjs/state/widget-store.js +1682 -0
  28. package/lib/commonjs/state/widget-store.js.map +1 -0
  29. package/lib/commonjs/storage.js +147 -0
  30. package/lib/commonjs/storage.js.map +1 -0
  31. package/lib/commonjs/types.js +44 -0
  32. package/lib/commonjs/types.js.map +1 -0
  33. package/lib/commonjs/ui/WidgetProvider.js +404 -0
  34. package/lib/commonjs/ui/WidgetProvider.js.map +1 -0
  35. package/lib/commonjs/ui/components/AgentUiBlocks.js +864 -0
  36. package/lib/commonjs/ui/components/AgentUiBlocks.js.map +1 -0
  37. package/lib/commonjs/ui/components/Avatar.js +76 -0
  38. package/lib/commonjs/ui/components/Avatar.js.map +1 -0
  39. package/lib/commonjs/ui/components/ConversationRow.js +155 -0
  40. package/lib/commonjs/ui/components/ConversationRow.js.map +1 -0
  41. package/lib/commonjs/ui/components/ErrorBoundary.js +44 -0
  42. package/lib/commonjs/ui/components/ErrorBoundary.js.map +1 -0
  43. package/lib/commonjs/ui/components/Gradient.js +168 -0
  44. package/lib/commonjs/ui/components/Gradient.js.map +1 -0
  45. package/lib/commonjs/ui/components/Launcher.js +125 -0
  46. package/lib/commonjs/ui/components/Launcher.js.map +1 -0
  47. package/lib/commonjs/ui/components/Markdown.js +257 -0
  48. package/lib/commonjs/ui/components/Markdown.js.map +1 -0
  49. package/lib/commonjs/ui/components/OutboundMessageCard.js +157 -0
  50. package/lib/commonjs/ui/components/OutboundMessageCard.js.map +1 -0
  51. package/lib/commonjs/ui/components/WidgetPanel.js +131 -0
  52. package/lib/commonjs/ui/components/WidgetPanel.js.map +1 -0
  53. package/lib/commonjs/ui/components/icons.js +383 -0
  54. package/lib/commonjs/ui/components/icons.js.map +1 -0
  55. package/lib/commonjs/ui/hooks/use-keyboard-overlap.js +113 -0
  56. package/lib/commonjs/ui/hooks/use-keyboard-overlap.js.map +1 -0
  57. package/lib/commonjs/ui/hooks/use-reduce-motion.js +38 -0
  58. package/lib/commonjs/ui/hooks/use-reduce-motion.js.map +1 -0
  59. package/lib/commonjs/ui/hooks/use-widget-insets.js +41 -0
  60. package/lib/commonjs/ui/hooks/use-widget-insets.js.map +1 -0
  61. package/lib/commonjs/ui/screens/chat/ChatView.js +590 -0
  62. package/lib/commonjs/ui/screens/chat/ChatView.js.map +1 -0
  63. package/lib/commonjs/ui/screens/chat/ChatView.styles.js +362 -0
  64. package/lib/commonjs/ui/screens/chat/ChatView.styles.js.map +1 -0
  65. package/lib/commonjs/ui/screens/chat/ChatView.types.js +6 -0
  66. package/lib/commonjs/ui/screens/chat/ChatView.types.js.map +1 -0
  67. package/lib/commonjs/ui/screens/conversations/ConversationsList.js +150 -0
  68. package/lib/commonjs/ui/screens/conversations/ConversationsList.js.map +1 -0
  69. package/lib/commonjs/ui/screens/conversations/ConversationsList.styles.js +118 -0
  70. package/lib/commonjs/ui/screens/conversations/ConversationsList.styles.js.map +1 -0
  71. package/lib/commonjs/ui/screens/conversations/ConversationsList.types.js +6 -0
  72. package/lib/commonjs/ui/screens/conversations/ConversationsList.types.js.map +1 -0
  73. package/lib/commonjs/ui/screens/home/HomeView.js +336 -0
  74. package/lib/commonjs/ui/screens/home/HomeView.js.map +1 -0
  75. package/lib/commonjs/ui/screens/home/HomeView.styles.js +245 -0
  76. package/lib/commonjs/ui/screens/home/HomeView.styles.js.map +1 -0
  77. package/lib/commonjs/ui/screens/home/HomeView.types.js +6 -0
  78. package/lib/commonjs/ui/screens/home/HomeView.types.js.map +1 -0
  79. package/lib/commonjs/ui/screens/home/greeting.js +49 -0
  80. package/lib/commonjs/ui/screens/home/greeting.js.map +1 -0
  81. package/lib/commonjs/ui/screens/pre-chat/PreChatForm.js +229 -0
  82. package/lib/commonjs/ui/screens/pre-chat/PreChatForm.js.map +1 -0
  83. package/lib/commonjs/ui/screens/pre-chat/PreChatForm.styles.js +125 -0
  84. package/lib/commonjs/ui/screens/pre-chat/PreChatForm.styles.js.map +1 -0
  85. package/lib/commonjs/ui/screens/pre-chat/PreChatForm.types.js +6 -0
  86. package/lib/commonjs/ui/screens/pre-chat/PreChatForm.types.js.map +1 -0
  87. package/lib/commonjs/ui/styles/global.js +55 -0
  88. package/lib/commonjs/ui/styles/global.js.map +1 -0
  89. package/lib/commonjs/ui/styles/theme.js +148 -0
  90. package/lib/commonjs/ui/styles/theme.js.map +1 -0
  91. package/lib/commonjs/ui/utils/conversations.js +125 -0
  92. package/lib/commonjs/ui/utils/conversations.js.map +1 -0
  93. package/lib/commonjs/ui/utils/html.js +44 -0
  94. package/lib/commonjs/ui/utils/html.js.map +1 -0
  95. package/lib/commonjs/ui/utils/native-gradient.js +65 -0
  96. package/lib/commonjs/ui/utils/native-gradient.js.map +1 -0
  97. package/lib/commonjs/ui/utils/rtl.js +56 -0
  98. package/lib/commonjs/ui/utils/rtl.js.map +1 -0
  99. package/lib/commonjs/ui/utils/safe-url.js +67 -0
  100. package/lib/commonjs/ui/utils/safe-url.js.map +1 -0
  101. package/lib/module/agent-ui-blocks.js +152 -0
  102. package/lib/module/agent-ui-blocks.js.map +1 -0
  103. package/lib/module/api/client.js +261 -0
  104. package/lib/module/api/client.js.map +1 -0
  105. package/lib/module/api/realtime.js +189 -0
  106. package/lib/module/api/realtime.js.map +1 -0
  107. package/lib/module/api/sse-parser.js +53 -0
  108. package/lib/module/api/sse-parser.js.map +1 -0
  109. package/lib/module/controller.js +19 -0
  110. package/lib/module/controller.js.map +1 -0
  111. package/lib/module/device-id.js +69 -0
  112. package/lib/module/device-id.js.map +1 -0
  113. package/lib/module/events.js +44 -0
  114. package/lib/module/events.js.map +1 -0
  115. package/lib/module/i18n.js +99 -0
  116. package/lib/module/i18n.js.map +1 -0
  117. package/lib/module/index.js +55 -0
  118. package/lib/module/index.js.map +1 -0
  119. package/lib/module/locales.js +80 -0
  120. package/lib/module/locales.js.map +1 -0
  121. package/lib/module/package.json +1 -0
  122. package/lib/module/push/push-notifications.js +204 -0
  123. package/lib/module/push/push-notifications.js.map +1 -0
  124. package/lib/module/state/use-widget-state.js +18 -0
  125. package/lib/module/state/use-widget-state.js.map +1 -0
  126. package/lib/module/state/widget-store.js +1677 -0
  127. package/lib/module/state/widget-store.js.map +1 -0
  128. package/lib/module/storage.js +141 -0
  129. package/lib/module/storage.js.map +1 -0
  130. package/lib/module/types.js +40 -0
  131. package/lib/module/types.js.map +1 -0
  132. package/lib/module/ui/WidgetProvider.js +400 -0
  133. package/lib/module/ui/WidgetProvider.js.map +1 -0
  134. package/lib/module/ui/components/AgentUiBlocks.js +857 -0
  135. package/lib/module/ui/components/AgentUiBlocks.js.map +1 -0
  136. package/lib/module/ui/components/Avatar.js +71 -0
  137. package/lib/module/ui/components/Avatar.js.map +1 -0
  138. package/lib/module/ui/components/ConversationRow.js +150 -0
  139. package/lib/module/ui/components/ConversationRow.js.map +1 -0
  140. package/lib/module/ui/components/ErrorBoundary.js +39 -0
  141. package/lib/module/ui/components/ErrorBoundary.js.map +1 -0
  142. package/lib/module/ui/components/Gradient.js +165 -0
  143. package/lib/module/ui/components/Gradient.js.map +1 -0
  144. package/lib/module/ui/components/Launcher.js +121 -0
  145. package/lib/module/ui/components/Launcher.js.map +1 -0
  146. package/lib/module/ui/components/Markdown.js +253 -0
  147. package/lib/module/ui/components/Markdown.js.map +1 -0
  148. package/lib/module/ui/components/OutboundMessageCard.js +153 -0
  149. package/lib/module/ui/components/OutboundMessageCard.js.map +1 -0
  150. package/lib/module/ui/components/WidgetPanel.js +127 -0
  151. package/lib/module/ui/components/WidgetPanel.js.map +1 -0
  152. package/lib/module/ui/components/icons.js +370 -0
  153. package/lib/module/ui/components/icons.js.map +1 -0
  154. package/lib/module/ui/hooks/use-keyboard-overlap.js +109 -0
  155. package/lib/module/ui/hooks/use-keyboard-overlap.js.map +1 -0
  156. package/lib/module/ui/hooks/use-reduce-motion.js +34 -0
  157. package/lib/module/ui/hooks/use-reduce-motion.js.map +1 -0
  158. package/lib/module/ui/hooks/use-widget-insets.js +37 -0
  159. package/lib/module/ui/hooks/use-widget-insets.js.map +1 -0
  160. package/lib/module/ui/screens/chat/ChatView.js +586 -0
  161. package/lib/module/ui/screens/chat/ChatView.js.map +1 -0
  162. package/lib/module/ui/screens/chat/ChatView.styles.js +358 -0
  163. package/lib/module/ui/screens/chat/ChatView.styles.js.map +1 -0
  164. package/lib/module/ui/screens/chat/ChatView.types.js +4 -0
  165. package/lib/module/ui/screens/chat/ChatView.types.js.map +1 -0
  166. package/lib/module/ui/screens/conversations/ConversationsList.js +146 -0
  167. package/lib/module/ui/screens/conversations/ConversationsList.js.map +1 -0
  168. package/lib/module/ui/screens/conversations/ConversationsList.styles.js +114 -0
  169. package/lib/module/ui/screens/conversations/ConversationsList.styles.js.map +1 -0
  170. package/lib/module/ui/screens/conversations/ConversationsList.types.js +4 -0
  171. package/lib/module/ui/screens/conversations/ConversationsList.types.js.map +1 -0
  172. package/lib/module/ui/screens/home/HomeView.js +332 -0
  173. package/lib/module/ui/screens/home/HomeView.js.map +1 -0
  174. package/lib/module/ui/screens/home/HomeView.styles.js +242 -0
  175. package/lib/module/ui/screens/home/HomeView.styles.js.map +1 -0
  176. package/lib/module/ui/screens/home/HomeView.types.js +4 -0
  177. package/lib/module/ui/screens/home/HomeView.types.js.map +1 -0
  178. package/lib/module/ui/screens/home/greeting.js +44 -0
  179. package/lib/module/ui/screens/home/greeting.js.map +1 -0
  180. package/lib/module/ui/screens/pre-chat/PreChatForm.js +225 -0
  181. package/lib/module/ui/screens/pre-chat/PreChatForm.js.map +1 -0
  182. package/lib/module/ui/screens/pre-chat/PreChatForm.styles.js +121 -0
  183. package/lib/module/ui/screens/pre-chat/PreChatForm.styles.js.map +1 -0
  184. package/lib/module/ui/screens/pre-chat/PreChatForm.types.js +4 -0
  185. package/lib/module/ui/screens/pre-chat/PreChatForm.types.js.map +1 -0
  186. package/lib/module/ui/styles/global.js +51 -0
  187. package/lib/module/ui/styles/global.js.map +1 -0
  188. package/lib/module/ui/styles/theme.js +137 -0
  189. package/lib/module/ui/styles/theme.js.map +1 -0
  190. package/lib/module/ui/utils/conversations.js +115 -0
  191. package/lib/module/ui/utils/conversations.js.map +1 -0
  192. package/lib/module/ui/utils/html.js +39 -0
  193. package/lib/module/ui/utils/html.js.map +1 -0
  194. package/lib/module/ui/utils/native-gradient.js +60 -0
  195. package/lib/module/ui/utils/native-gradient.js.map +1 -0
  196. package/lib/module/ui/utils/rtl.js +49 -0
  197. package/lib/module/ui/utils/rtl.js.map +1 -0
  198. package/lib/module/ui/utils/safe-url.js +59 -0
  199. package/lib/module/ui/utils/safe-url.js.map +1 -0
  200. package/lib/typescript/commonjs/agent-ui-blocks.d.ts +20 -0
  201. package/lib/typescript/commonjs/agent-ui-blocks.d.ts.map +1 -0
  202. package/lib/typescript/commonjs/api/client.d.ts +115 -0
  203. package/lib/typescript/commonjs/api/client.d.ts.map +1 -0
  204. package/lib/typescript/commonjs/api/realtime.d.ts +39 -0
  205. package/lib/typescript/commonjs/api/realtime.d.ts.map +1 -0
  206. package/lib/typescript/commonjs/api/sse-parser.d.ts +13 -0
  207. package/lib/typescript/commonjs/api/sse-parser.d.ts.map +1 -0
  208. package/lib/typescript/commonjs/controller.d.ts +15 -0
  209. package/lib/typescript/commonjs/controller.d.ts.map +1 -0
  210. package/lib/typescript/commonjs/device-id.d.ts +15 -0
  211. package/lib/typescript/commonjs/device-id.d.ts.map +1 -0
  212. package/lib/typescript/commonjs/events.d.ts +41 -0
  213. package/lib/typescript/commonjs/events.d.ts.map +1 -0
  214. package/lib/typescript/commonjs/i18n.d.ts +78 -0
  215. package/lib/typescript/commonjs/i18n.d.ts.map +1 -0
  216. package/lib/typescript/commonjs/index.d.ts +103 -0
  217. package/lib/typescript/commonjs/index.d.ts.map +1 -0
  218. package/lib/typescript/commonjs/locales.d.ts +18 -0
  219. package/lib/typescript/commonjs/locales.d.ts.map +1 -0
  220. package/lib/typescript/commonjs/package.json +1 -0
  221. package/lib/typescript/commonjs/push/push-notifications.d.ts +71 -0
  222. package/lib/typescript/commonjs/push/push-notifications.d.ts.map +1 -0
  223. package/lib/typescript/commonjs/state/use-widget-state.d.ts +10 -0
  224. package/lib/typescript/commonjs/state/use-widget-state.d.ts.map +1 -0
  225. package/lib/typescript/commonjs/state/widget-store.d.ts +227 -0
  226. package/lib/typescript/commonjs/state/widget-store.d.ts.map +1 -0
  227. package/lib/typescript/commonjs/storage.d.ts +42 -0
  228. package/lib/typescript/commonjs/storage.d.ts.map +1 -0
  229. package/lib/typescript/commonjs/types.d.ts +391 -0
  230. package/lib/typescript/commonjs/types.d.ts.map +1 -0
  231. package/lib/typescript/commonjs/ui/WidgetProvider.d.ts +15 -0
  232. package/lib/typescript/commonjs/ui/WidgetProvider.d.ts.map +1 -0
  233. package/lib/typescript/commonjs/ui/components/AgentUiBlocks.d.ts +27 -0
  234. package/lib/typescript/commonjs/ui/components/AgentUiBlocks.d.ts.map +1 -0
  235. package/lib/typescript/commonjs/ui/components/Avatar.d.ts +19 -0
  236. package/lib/typescript/commonjs/ui/components/Avatar.d.ts.map +1 -0
  237. package/lib/typescript/commonjs/ui/components/ConversationRow.d.ts +26 -0
  238. package/lib/typescript/commonjs/ui/components/ConversationRow.d.ts.map +1 -0
  239. package/lib/typescript/commonjs/ui/components/ErrorBoundary.d.ts +27 -0
  240. package/lib/typescript/commonjs/ui/components/ErrorBoundary.d.ts.map +1 -0
  241. package/lib/typescript/commonjs/ui/components/Gradient.d.ts +33 -0
  242. package/lib/typescript/commonjs/ui/components/Gradient.d.ts.map +1 -0
  243. package/lib/typescript/commonjs/ui/components/Launcher.d.ts +18 -0
  244. package/lib/typescript/commonjs/ui/components/Launcher.d.ts.map +1 -0
  245. package/lib/typescript/commonjs/ui/components/Markdown.d.ts +19 -0
  246. package/lib/typescript/commonjs/ui/components/Markdown.d.ts.map +1 -0
  247. package/lib/typescript/commonjs/ui/components/OutboundMessageCard.d.ts +20 -0
  248. package/lib/typescript/commonjs/ui/components/OutboundMessageCard.d.ts.map +1 -0
  249. package/lib/typescript/commonjs/ui/components/WidgetPanel.d.ts +26 -0
  250. package/lib/typescript/commonjs/ui/components/WidgetPanel.d.ts.map +1 -0
  251. package/lib/typescript/commonjs/ui/components/icons.d.ts +38 -0
  252. package/lib/typescript/commonjs/ui/components/icons.d.ts.map +1 -0
  253. package/lib/typescript/commonjs/ui/hooks/use-keyboard-overlap.d.ts +33 -0
  254. package/lib/typescript/commonjs/ui/hooks/use-keyboard-overlap.d.ts.map +1 -0
  255. package/lib/typescript/commonjs/ui/hooks/use-reduce-motion.d.ts +11 -0
  256. package/lib/typescript/commonjs/ui/hooks/use-reduce-motion.d.ts.map +1 -0
  257. package/lib/typescript/commonjs/ui/hooks/use-widget-insets.d.ts +16 -0
  258. package/lib/typescript/commonjs/ui/hooks/use-widget-insets.d.ts.map +1 -0
  259. package/lib/typescript/commonjs/ui/screens/chat/ChatView.d.ts +11 -0
  260. package/lib/typescript/commonjs/ui/screens/chat/ChatView.d.ts.map +1 -0
  261. package/lib/typescript/commonjs/ui/screens/chat/ChatView.styles.d.ts +349 -0
  262. package/lib/typescript/commonjs/ui/screens/chat/ChatView.styles.d.ts.map +1 -0
  263. package/lib/typescript/commonjs/ui/screens/chat/ChatView.types.d.ts +48 -0
  264. package/lib/typescript/commonjs/ui/screens/chat/ChatView.types.d.ts.map +1 -0
  265. package/lib/typescript/commonjs/ui/screens/conversations/ConversationsList.d.ts +10 -0
  266. package/lib/typescript/commonjs/ui/screens/conversations/ConversationsList.d.ts.map +1 -0
  267. package/lib/typescript/commonjs/ui/screens/conversations/ConversationsList.styles.d.ts +113 -0
  268. package/lib/typescript/commonjs/ui/screens/conversations/ConversationsList.styles.d.ts.map +1 -0
  269. package/lib/typescript/commonjs/ui/screens/conversations/ConversationsList.types.d.ts +31 -0
  270. package/lib/typescript/commonjs/ui/screens/conversations/ConversationsList.types.d.ts.map +1 -0
  271. package/lib/typescript/commonjs/ui/screens/home/HomeView.d.ts +17 -0
  272. package/lib/typescript/commonjs/ui/screens/home/HomeView.d.ts.map +1 -0
  273. package/lib/typescript/commonjs/ui/screens/home/HomeView.styles.d.ts +227 -0
  274. package/lib/typescript/commonjs/ui/screens/home/HomeView.styles.d.ts.map +1 -0
  275. package/lib/typescript/commonjs/ui/screens/home/HomeView.types.d.ts +40 -0
  276. package/lib/typescript/commonjs/ui/screens/home/HomeView.types.d.ts.map +1 -0
  277. package/lib/typescript/commonjs/ui/screens/home/greeting.d.ts +19 -0
  278. package/lib/typescript/commonjs/ui/screens/home/greeting.d.ts.map +1 -0
  279. package/lib/typescript/commonjs/ui/screens/pre-chat/PreChatForm.d.ts +7 -0
  280. package/lib/typescript/commonjs/ui/screens/pre-chat/PreChatForm.d.ts.map +1 -0
  281. package/lib/typescript/commonjs/ui/screens/pre-chat/PreChatForm.styles.d.ts +115 -0
  282. package/lib/typescript/commonjs/ui/screens/pre-chat/PreChatForm.styles.d.ts.map +1 -0
  283. package/lib/typescript/commonjs/ui/screens/pre-chat/PreChatForm.types.d.ts +20 -0
  284. package/lib/typescript/commonjs/ui/screens/pre-chat/PreChatForm.types.d.ts.map +1 -0
  285. package/lib/typescript/commonjs/ui/styles/global.d.ts +46 -0
  286. package/lib/typescript/commonjs/ui/styles/global.d.ts.map +1 -0
  287. package/lib/typescript/commonjs/ui/styles/theme.d.ts +103 -0
  288. package/lib/typescript/commonjs/ui/styles/theme.d.ts.map +1 -0
  289. package/lib/typescript/commonjs/ui/utils/conversations.d.ts +41 -0
  290. package/lib/typescript/commonjs/ui/utils/conversations.d.ts.map +1 -0
  291. package/lib/typescript/commonjs/ui/utils/html.d.ts +10 -0
  292. package/lib/typescript/commonjs/ui/utils/html.d.ts.map +1 -0
  293. package/lib/typescript/commonjs/ui/utils/native-gradient.d.ts +61 -0
  294. package/lib/typescript/commonjs/ui/utils/native-gradient.d.ts.map +1 -0
  295. package/lib/typescript/commonjs/ui/utils/rtl.d.ts +33 -0
  296. package/lib/typescript/commonjs/ui/utils/rtl.d.ts.map +1 -0
  297. package/lib/typescript/commonjs/ui/utils/safe-url.d.ts +21 -0
  298. package/lib/typescript/commonjs/ui/utils/safe-url.d.ts.map +1 -0
  299. package/lib/typescript/module/agent-ui-blocks.d.ts +20 -0
  300. package/lib/typescript/module/agent-ui-blocks.d.ts.map +1 -0
  301. package/lib/typescript/module/api/client.d.ts +115 -0
  302. package/lib/typescript/module/api/client.d.ts.map +1 -0
  303. package/lib/typescript/module/api/realtime.d.ts +39 -0
  304. package/lib/typescript/module/api/realtime.d.ts.map +1 -0
  305. package/lib/typescript/module/api/sse-parser.d.ts +13 -0
  306. package/lib/typescript/module/api/sse-parser.d.ts.map +1 -0
  307. package/lib/typescript/module/controller.d.ts +15 -0
  308. package/lib/typescript/module/controller.d.ts.map +1 -0
  309. package/lib/typescript/module/device-id.d.ts +15 -0
  310. package/lib/typescript/module/device-id.d.ts.map +1 -0
  311. package/lib/typescript/module/events.d.ts +41 -0
  312. package/lib/typescript/module/events.d.ts.map +1 -0
  313. package/lib/typescript/module/i18n.d.ts +78 -0
  314. package/lib/typescript/module/i18n.d.ts.map +1 -0
  315. package/lib/typescript/module/index.d.ts +103 -0
  316. package/lib/typescript/module/index.d.ts.map +1 -0
  317. package/lib/typescript/module/locales.d.ts +18 -0
  318. package/lib/typescript/module/locales.d.ts.map +1 -0
  319. package/lib/typescript/module/package.json +1 -0
  320. package/lib/typescript/module/push/push-notifications.d.ts +71 -0
  321. package/lib/typescript/module/push/push-notifications.d.ts.map +1 -0
  322. package/lib/typescript/module/state/use-widget-state.d.ts +10 -0
  323. package/lib/typescript/module/state/use-widget-state.d.ts.map +1 -0
  324. package/lib/typescript/module/state/widget-store.d.ts +227 -0
  325. package/lib/typescript/module/state/widget-store.d.ts.map +1 -0
  326. package/lib/typescript/module/storage.d.ts +42 -0
  327. package/lib/typescript/module/storage.d.ts.map +1 -0
  328. package/lib/typescript/module/types.d.ts +391 -0
  329. package/lib/typescript/module/types.d.ts.map +1 -0
  330. package/lib/typescript/module/ui/WidgetProvider.d.ts +15 -0
  331. package/lib/typescript/module/ui/WidgetProvider.d.ts.map +1 -0
  332. package/lib/typescript/module/ui/components/AgentUiBlocks.d.ts +27 -0
  333. package/lib/typescript/module/ui/components/AgentUiBlocks.d.ts.map +1 -0
  334. package/lib/typescript/module/ui/components/Avatar.d.ts +19 -0
  335. package/lib/typescript/module/ui/components/Avatar.d.ts.map +1 -0
  336. package/lib/typescript/module/ui/components/ConversationRow.d.ts +26 -0
  337. package/lib/typescript/module/ui/components/ConversationRow.d.ts.map +1 -0
  338. package/lib/typescript/module/ui/components/ErrorBoundary.d.ts +27 -0
  339. package/lib/typescript/module/ui/components/ErrorBoundary.d.ts.map +1 -0
  340. package/lib/typescript/module/ui/components/Gradient.d.ts +33 -0
  341. package/lib/typescript/module/ui/components/Gradient.d.ts.map +1 -0
  342. package/lib/typescript/module/ui/components/Launcher.d.ts +18 -0
  343. package/lib/typescript/module/ui/components/Launcher.d.ts.map +1 -0
  344. package/lib/typescript/module/ui/components/Markdown.d.ts +19 -0
  345. package/lib/typescript/module/ui/components/Markdown.d.ts.map +1 -0
  346. package/lib/typescript/module/ui/components/OutboundMessageCard.d.ts +20 -0
  347. package/lib/typescript/module/ui/components/OutboundMessageCard.d.ts.map +1 -0
  348. package/lib/typescript/module/ui/components/WidgetPanel.d.ts +26 -0
  349. package/lib/typescript/module/ui/components/WidgetPanel.d.ts.map +1 -0
  350. package/lib/typescript/module/ui/components/icons.d.ts +38 -0
  351. package/lib/typescript/module/ui/components/icons.d.ts.map +1 -0
  352. package/lib/typescript/module/ui/hooks/use-keyboard-overlap.d.ts +33 -0
  353. package/lib/typescript/module/ui/hooks/use-keyboard-overlap.d.ts.map +1 -0
  354. package/lib/typescript/module/ui/hooks/use-reduce-motion.d.ts +11 -0
  355. package/lib/typescript/module/ui/hooks/use-reduce-motion.d.ts.map +1 -0
  356. package/lib/typescript/module/ui/hooks/use-widget-insets.d.ts +16 -0
  357. package/lib/typescript/module/ui/hooks/use-widget-insets.d.ts.map +1 -0
  358. package/lib/typescript/module/ui/screens/chat/ChatView.d.ts +11 -0
  359. package/lib/typescript/module/ui/screens/chat/ChatView.d.ts.map +1 -0
  360. package/lib/typescript/module/ui/screens/chat/ChatView.styles.d.ts +349 -0
  361. package/lib/typescript/module/ui/screens/chat/ChatView.styles.d.ts.map +1 -0
  362. package/lib/typescript/module/ui/screens/chat/ChatView.types.d.ts +48 -0
  363. package/lib/typescript/module/ui/screens/chat/ChatView.types.d.ts.map +1 -0
  364. package/lib/typescript/module/ui/screens/conversations/ConversationsList.d.ts +10 -0
  365. package/lib/typescript/module/ui/screens/conversations/ConversationsList.d.ts.map +1 -0
  366. package/lib/typescript/module/ui/screens/conversations/ConversationsList.styles.d.ts +113 -0
  367. package/lib/typescript/module/ui/screens/conversations/ConversationsList.styles.d.ts.map +1 -0
  368. package/lib/typescript/module/ui/screens/conversations/ConversationsList.types.d.ts +31 -0
  369. package/lib/typescript/module/ui/screens/conversations/ConversationsList.types.d.ts.map +1 -0
  370. package/lib/typescript/module/ui/screens/home/HomeView.d.ts +17 -0
  371. package/lib/typescript/module/ui/screens/home/HomeView.d.ts.map +1 -0
  372. package/lib/typescript/module/ui/screens/home/HomeView.styles.d.ts +227 -0
  373. package/lib/typescript/module/ui/screens/home/HomeView.styles.d.ts.map +1 -0
  374. package/lib/typescript/module/ui/screens/home/HomeView.types.d.ts +40 -0
  375. package/lib/typescript/module/ui/screens/home/HomeView.types.d.ts.map +1 -0
  376. package/lib/typescript/module/ui/screens/home/greeting.d.ts +19 -0
  377. package/lib/typescript/module/ui/screens/home/greeting.d.ts.map +1 -0
  378. package/lib/typescript/module/ui/screens/pre-chat/PreChatForm.d.ts +7 -0
  379. package/lib/typescript/module/ui/screens/pre-chat/PreChatForm.d.ts.map +1 -0
  380. package/lib/typescript/module/ui/screens/pre-chat/PreChatForm.styles.d.ts +115 -0
  381. package/lib/typescript/module/ui/screens/pre-chat/PreChatForm.styles.d.ts.map +1 -0
  382. package/lib/typescript/module/ui/screens/pre-chat/PreChatForm.types.d.ts +20 -0
  383. package/lib/typescript/module/ui/screens/pre-chat/PreChatForm.types.d.ts.map +1 -0
  384. package/lib/typescript/module/ui/styles/global.d.ts +46 -0
  385. package/lib/typescript/module/ui/styles/global.d.ts.map +1 -0
  386. package/lib/typescript/module/ui/styles/theme.d.ts +103 -0
  387. package/lib/typescript/module/ui/styles/theme.d.ts.map +1 -0
  388. package/lib/typescript/module/ui/utils/conversations.d.ts +41 -0
  389. package/lib/typescript/module/ui/utils/conversations.d.ts.map +1 -0
  390. package/lib/typescript/module/ui/utils/html.d.ts +10 -0
  391. package/lib/typescript/module/ui/utils/html.d.ts.map +1 -0
  392. package/lib/typescript/module/ui/utils/native-gradient.d.ts +61 -0
  393. package/lib/typescript/module/ui/utils/native-gradient.d.ts.map +1 -0
  394. package/lib/typescript/module/ui/utils/rtl.d.ts +33 -0
  395. package/lib/typescript/module/ui/utils/rtl.d.ts.map +1 -0
  396. package/lib/typescript/module/ui/utils/safe-url.d.ts +21 -0
  397. package/lib/typescript/module/ui/utils/safe-url.d.ts.map +1 -0
  398. package/metro.js +40 -0
  399. package/package.json +116 -0
  400. package/src/agent-ui-blocks.ts +302 -0
  401. package/src/api/client.ts +332 -0
  402. package/src/api/realtime.ts +225 -0
  403. package/src/api/sse-parser.ts +51 -0
  404. package/src/controller.ts +20 -0
  405. package/src/device-id.ts +71 -0
  406. package/src/events.ts +74 -0
  407. package/src/i18n.ts +114 -0
  408. package/src/index.tsx +199 -0
  409. package/src/locales.ts +80 -0
  410. package/src/push/push-notifications.ts +254 -0
  411. package/src/state/use-widget-state.ts +20 -0
  412. package/src/state/widget-store.ts +1815 -0
  413. package/src/storage.ts +153 -0
  414. package/src/types.ts +445 -0
  415. package/src/ui/WidgetProvider.tsx +434 -0
  416. package/src/ui/components/AgentUiBlocks.tsx +912 -0
  417. package/src/ui/components/Avatar.tsx +86 -0
  418. package/src/ui/components/ConversationRow.tsx +163 -0
  419. package/src/ui/components/ErrorBoundary.tsx +49 -0
  420. package/src/ui/components/Gradient.tsx +165 -0
  421. package/src/ui/components/Launcher.tsx +128 -0
  422. package/src/ui/components/Markdown.tsx +291 -0
  423. package/src/ui/components/OutboundMessageCard.tsx +154 -0
  424. package/src/ui/components/WidgetPanel.tsx +133 -0
  425. package/src/ui/components/icons.tsx +315 -0
  426. package/src/ui/hooks/use-keyboard-overlap.ts +134 -0
  427. package/src/ui/hooks/use-reduce-motion.ts +39 -0
  428. package/src/ui/hooks/use-widget-insets.ts +44 -0
  429. package/src/ui/screens/chat/ChatView.styles.ts +357 -0
  430. package/src/ui/screens/chat/ChatView.tsx +690 -0
  431. package/src/ui/screens/chat/ChatView.types.ts +46 -0
  432. package/src/ui/screens/conversations/ConversationsList.styles.ts +111 -0
  433. package/src/ui/screens/conversations/ConversationsList.tsx +144 -0
  434. package/src/ui/screens/conversations/ConversationsList.types.ts +33 -0
  435. package/src/ui/screens/home/HomeView.styles.ts +246 -0
  436. package/src/ui/screens/home/HomeView.tsx +336 -0
  437. package/src/ui/screens/home/HomeView.types.ts +42 -0
  438. package/src/ui/screens/home/greeting.ts +50 -0
  439. package/src/ui/screens/pre-chat/PreChatForm.styles.ts +120 -0
  440. package/src/ui/screens/pre-chat/PreChatForm.tsx +221 -0
  441. package/src/ui/screens/pre-chat/PreChatForm.types.ts +22 -0
  442. package/src/ui/styles/global.ts +50 -0
  443. package/src/ui/styles/theme.ts +155 -0
  444. package/src/ui/utils/conversations.ts +122 -0
  445. package/src/ui/utils/html.ts +58 -0
  446. package/src/ui/utils/native-gradient.ts +60 -0
  447. package/src/ui/utils/rtl.ts +43 -0
  448. package/src/ui/utils/safe-url.ts +63 -0
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Agent avatar with graceful fallbacks: photo → initials → person glyph.
3
+ * A broken URL must never leave a blank hole in the header or the list.
4
+ */
5
+
6
+ import { useState } from 'react';
7
+ import {
8
+ I18nManager,
9
+ Image,
10
+ StyleSheet,
11
+ Text,
12
+ View,
13
+ type ImageStyle,
14
+ type StyleProp,
15
+ type ViewStyle,
16
+ } from 'react-native';
17
+
18
+ import { PersonIcon } from './icons';
19
+ import { palette, withAlpha } from '../styles/theme';
20
+
21
+ interface AvatarProps {
22
+ avatar?: string | null;
23
+ name?: string | null;
24
+ size?: number;
25
+ /** Background when there is no photo. */
26
+ color?: string;
27
+ /** Used in the colored header, where the placeholder is a translucent white. */
28
+ translucent?: boolean;
29
+ style?: StyleProp<ViewStyle & ImageStyle>;
30
+ }
31
+
32
+ export function Avatar({
33
+ avatar,
34
+ name,
35
+ size = 40,
36
+ color = palette.disabled,
37
+ translucent = false,
38
+ style,
39
+ }: AvatarProps) {
40
+ const [broken, setBroken] = useState(false);
41
+ const dimensions = { width: size, height: size, borderRadius: size / 2 };
42
+
43
+ if (avatar && !broken) {
44
+ return (
45
+ <Image
46
+ source={{ uri: avatar }}
47
+ onError={() => setBroken(true)}
48
+ style={[dimensions, style]}
49
+ resizeMode="cover"
50
+ accessibilityIgnoresInvertColors
51
+ />
52
+ );
53
+ }
54
+
55
+ const background = translucent ? withAlpha(palette.white, 0.24) : name ? color : palette.disabled;
56
+
57
+ return (
58
+ <View style={[dimensions, styles.fallback, { backgroundColor: background }, style]}>
59
+ {name ? (
60
+ <Text style={[styles.initials, { fontSize: Math.round(size * 0.36) }]} numberOfLines={1}>
61
+ {getInitials(name)}
62
+ </Text>
63
+ ) : (
64
+ <PersonIcon size={Math.round(size * 0.5)} color={palette.white} />
65
+ )}
66
+ </View>
67
+ );
68
+ }
69
+
70
+ export function getInitials(name: string): string {
71
+ const parts = name.trim().split(/\s+/).filter(Boolean);
72
+ if (parts.length >= 2) return `${parts[0]?.[0] ?? ''}${parts[1]?.[0] ?? ''}`.toUpperCase();
73
+ return name.slice(0, 2).toUpperCase();
74
+ }
75
+
76
+ const styles = StyleSheet.create({
77
+ fallback: {
78
+ alignItems: 'center',
79
+ justifyContent: 'center',
80
+ },
81
+ initials: {
82
+ color: palette.white,
83
+ fontWeight: '700',
84
+ letterSpacing: I18nManager.isRTL ? 0 : -0.5,
85
+ },
86
+ });
@@ -0,0 +1,163 @@
1
+ /**
2
+ * One conversation in a list: who replied, when, and the last thing said.
3
+ * Shared by the Home space's recent preview and the Messages list so the two
4
+ * cannot drift apart.
5
+ */
6
+
7
+ import { Pressable, StyleSheet, Text, View } from 'react-native';
8
+
9
+ import type { Conversation } from '../../types';
10
+ import { Avatar } from './Avatar';
11
+ import { formatLabel } from '../../i18n';
12
+ import { formatRelativeTime, type RelativeTimeLabels } from '../utils/conversations';
13
+ import { ChevronIcon } from './icons';
14
+ import { forwardDirection, START_ALIGN } from '../utils/rtl';
15
+ import { fontSize, palette, spacing } from '../styles/theme';
16
+
17
+ const AVATAR_SIZE = 40;
18
+
19
+ interface ConversationRowProps {
20
+ conversation: Conversation;
21
+ color: string;
22
+ /** Stands in until an agent is assigned to the thread. */
23
+ fallbackName: string;
24
+ timeLabels: RelativeTimeLabels;
25
+ /** Replies that arrived since the visitor last opened this thread. */
26
+ unreadCount?: number;
27
+ /** Template with a `{count}` token, for screen readers. */
28
+ unreadLabel?: string;
29
+ /** Messages runs full-bleed; Home insets it inside a card. */
30
+ horizontalPadding?: number;
31
+ onPress: () => void;
32
+ }
33
+
34
+ export function ConversationRow({
35
+ conversation,
36
+ color,
37
+ fallbackName,
38
+ timeLabels,
39
+ unreadCount = 0,
40
+ unreadLabel,
41
+ horizontalPadding = spacing.xl,
42
+ onPress,
43
+ }: ConversationRowProps) {
44
+ const displayName = conversation.agentName || fallbackName;
45
+ const hasUnread = unreadCount > 0;
46
+ const unreadSuffix =
47
+ hasUnread && unreadLabel ? `. ${formatLabel(unreadLabel, { count: unreadCount })}` : '';
48
+
49
+ return (
50
+ <Pressable
51
+ onPress={onPress}
52
+ accessibilityRole="button"
53
+ accessibilityLabel={`${
54
+ conversation.snippet ? `${displayName}. ${conversation.snippet}` : displayName
55
+ }${unreadSuffix}`}
56
+ android_ripple={{ color: palette.borderSoft }}
57
+ style={({ pressed }) => [
58
+ styles.row,
59
+ { paddingHorizontal: horizontalPadding },
60
+ pressed && styles.rowPressed,
61
+ ]}>
62
+ <Avatar
63
+ avatar={conversation.agentAvatar}
64
+ name={conversation.agentName}
65
+ size={AVATAR_SIZE}
66
+ color={color}
67
+ />
68
+ <View style={styles.content}>
69
+ <View style={styles.topLine}>
70
+ <Text style={[styles.name, hasUnread && styles.nameUnread]} numberOfLines={1}>
71
+ {displayName}
72
+ </Text>
73
+ <Text style={styles.time}>
74
+ {conversation.lastMessageAt
75
+ ? formatRelativeTime(conversation.lastMessageAt, timeLabels)
76
+ : ''}
77
+ </Text>
78
+ </View>
79
+ {conversation.snippet ? (
80
+ <Text style={[styles.snippet, hasUnread && styles.snippetUnread]} numberOfLines={2}>
81
+ {conversation.snippet}
82
+ </Text>
83
+ ) : null}
84
+ </View>
85
+ {hasUnread ? (
86
+ <View style={[styles.badge, { backgroundColor: color }]}>
87
+ <Text style={styles.badgeLabel}>{unreadCount > 9 ? '9+' : unreadCount}</Text>
88
+ </View>
89
+ ) : (
90
+ <ChevronIcon size={16} direction={forwardDirection()} color={palette.textSubtle} />
91
+ )}
92
+ </Pressable>
93
+ );
94
+ }
95
+
96
+ /** Where a divider should start so it sits under the text, not the avatar. */
97
+ export function rowDividerInset(horizontalPadding: number = spacing.xl): number {
98
+ return horizontalPadding + AVATAR_SIZE + spacing.md;
99
+ }
100
+
101
+ const styles = StyleSheet.create({
102
+ row: {
103
+ flexDirection: 'row',
104
+ alignItems: 'center',
105
+ gap: spacing.md,
106
+ minHeight: 74,
107
+ paddingVertical: spacing.md,
108
+ backgroundColor: palette.white,
109
+ },
110
+ rowPressed: {
111
+ backgroundColor: palette.surface,
112
+ },
113
+ content: {
114
+ flex: 1,
115
+ minWidth: 0,
116
+ },
117
+ topLine: {
118
+ flexDirection: 'row',
119
+ alignItems: 'center',
120
+ justifyContent: 'space-between',
121
+ gap: spacing.sm,
122
+ },
123
+ name: {
124
+ textAlign: START_ALIGN,
125
+ flex: 1,
126
+ fontSize: fontSize.body,
127
+ fontWeight: '600',
128
+ color: palette.ink,
129
+ },
130
+ nameUnread: {
131
+ fontWeight: '700',
132
+ },
133
+ time: {
134
+ fontSize: fontSize.caption,
135
+ color: palette.textSubtle,
136
+ },
137
+ snippet: {
138
+ textAlign: START_ALIGN,
139
+ fontSize: fontSize.meta,
140
+ lineHeight: fontSize.meta * 1.35,
141
+ color: palette.textMuted,
142
+ marginTop: 2,
143
+ },
144
+ snippetUnread: {
145
+ color: palette.text,
146
+ fontWeight: '500',
147
+ },
148
+ // Replaces the chevron rather than crowding beside it, so the row keeps
149
+ // the same width whether or not there is anything unread.
150
+ badge: {
151
+ minWidth: 20,
152
+ height: 20,
153
+ borderRadius: 10,
154
+ paddingHorizontal: spacing.xs + 1,
155
+ alignItems: 'center',
156
+ justifyContent: 'center',
157
+ },
158
+ badgeLabel: {
159
+ color: palette.white,
160
+ fontSize: fontSize.micro,
161
+ fontWeight: '700',
162
+ },
163
+ });
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Keeps a render error inside the widget's own UI from unmounting the host
3
+ * app. `<RepzoWidgetProvider>` renders the host's `children` next to the
4
+ * modal, so an uncaught throw in, say, a malformed agent block would
5
+ * otherwise take the whole app down with it. Never wraps host children.
6
+ */
7
+
8
+ import { Component, type ReactNode } from 'react';
9
+
10
+ interface WidgetErrorBoundaryProps {
11
+ children: ReactNode;
12
+ /** Rendered instead of `children` after a crash; `reset` re-renders them. */
13
+ fallback: ReactNode | ((reset: () => void) => ReactNode);
14
+ /** Any change clears a caught error — e.g. the visitor moved to another screen. */
15
+ resetKey?: string | number | null;
16
+ }
17
+
18
+ interface WidgetErrorBoundaryState {
19
+ hasError: boolean;
20
+ }
21
+
22
+ export class WidgetErrorBoundary extends Component<
23
+ WidgetErrorBoundaryProps,
24
+ WidgetErrorBoundaryState
25
+ > {
26
+ state: WidgetErrorBoundaryState = { hasError: false };
27
+
28
+ static getDerivedStateFromError(): WidgetErrorBoundaryState {
29
+ return { hasError: true };
30
+ }
31
+
32
+ componentDidCatch(error: unknown) {
33
+ console.warn('[repzo-widget] render error caught', error);
34
+ }
35
+
36
+ componentDidUpdate(previous: WidgetErrorBoundaryProps) {
37
+ if (this.state.hasError && previous.resetKey !== this.props.resetKey) this.reset();
38
+ }
39
+
40
+ reset = () => {
41
+ this.setState({ hasError: false });
42
+ };
43
+
44
+ render() {
45
+ if (!this.state.hasError) return this.props.children;
46
+ const { fallback } = this.props;
47
+ return typeof fallback === 'function' ? fallback(this.reset) : fallback;
48
+ }
49
+ }
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Brand backgrounds drawn without a native dependency: the gradient a header
3
+ * is painted with, and the fade that washes it out into the page. Both borrow
4
+ * the host app's `react-native-linear-gradient` when it is installed and stack
5
+ * solid bands when it is not (see `utils/native-gradient.ts`).
6
+ */
7
+
8
+ import type { ReactNode } from 'react';
9
+ import { StyleSheet, View, type StyleProp, type ViewStyle } from 'react-native';
10
+
11
+ import { hexToRgb, mixHex, palette, withAlpha } from '../styles/theme';
12
+ import { DIAGONAL, getNativeGradient, VERTICAL } from '../utils/native-gradient';
13
+
14
+ /**
15
+ * How many bands a ramp needs to look continuous. Banding is a function of the
16
+ * colour delta rather than the pixel height: one band per output level is as
17
+ * smooth as 8-bit colour gets, and anything coarser shows seams on a tall
18
+ * header. A fixed count was why dark headers looked striped.
19
+ */
20
+ function bandCountFor(stops: string[]): number {
21
+ let total = 0;
22
+ for (let index = 0; index < stops.length - 1; index += 1) {
23
+ const from = hexToRgb(stops[index] as string);
24
+ const to = hexToRgb(stops[index + 1] as string);
25
+ if (!from || !to) continue;
26
+ total += Math.max(
27
+ Math.abs(from[0] - to[0]),
28
+ Math.abs(from[1] - to[1]),
29
+ Math.abs(from[2] - to[2])
30
+ );
31
+ }
32
+ // 1.25 bands per output level lands on a worst-case step of one level,
33
+ // which is as smooth as 8-bit colour can be, without paying for more views.
34
+ return Math.min(160, Math.max(24, Math.round(total * 1.25)));
35
+ }
36
+
37
+ /**
38
+ * Multi-band approximation of a CSS linear-gradient. RN has no gradient
39
+ * primitive and the SDK ships no native deps, so we stack interpolated bands.
40
+ */
41
+ export function GradientBackground({
42
+ colors,
43
+ children,
44
+ style,
45
+ bands,
46
+ }: {
47
+ colors: string[];
48
+ children?: ReactNode;
49
+ style?: StyleProp<ViewStyle>;
50
+ /** Defaults to whatever the colour ramp needs to look continuous. */
51
+ bands?: number;
52
+ }) {
53
+ const stops = colors.filter(Boolean);
54
+ if (stops.length === 0) return <View style={style}>{children}</View>;
55
+ if (stops.length === 1) {
56
+ return <View style={[style, { backgroundColor: stops[0] }]}>{children}</View>;
57
+ }
58
+
59
+ // The container is always a plain View and the fill always sits behind the
60
+ // children in an absolute layer. A native gradient is a third-party view
61
+ // that lays its children out differently under the new architecture, so it
62
+ // paints and nothing else.
63
+ return (
64
+ <View style={[style, { backgroundColor: stops[0], overflow: 'hidden' }]}>
65
+ <View style={StyleSheet.absoluteFill} pointerEvents="none">
66
+ <GradientFill colors={stops} bands={bands} />
67
+ </View>
68
+ {children}
69
+ </View>
70
+ );
71
+ }
72
+
73
+ /** The paint layer: a native ramp when the host has one, stacked bands if not. */
74
+ function GradientFill({ colors, bands }: { colors: string[]; bands?: number }) {
75
+ const NativeGradient = getNativeGradient();
76
+ if (NativeGradient) {
77
+ return (
78
+ <NativeGradient
79
+ colors={colors}
80
+ start={DIAGONAL.start}
81
+ end={DIAGONAL.end}
82
+ style={StyleSheet.absoluteFill}
83
+ />
84
+ );
85
+ }
86
+
87
+ // Horizontal strips: this path is always vertical, whatever DIAGONAL says.
88
+ const bandCount = bands ?? bandCountFor(colors);
89
+ const segments = colors.length - 1;
90
+ return (
91
+ <>
92
+ {Array.from({ length: bandCount }).map((_, index) => {
93
+ const progress = index / (bandCount - 1);
94
+ const scaled = Math.min(progress * segments, segments - 0.0001);
95
+ const segment = Math.floor(scaled);
96
+ const color = mixHex(
97
+ colors[segment] as string,
98
+ colors[segment + 1] as string,
99
+ scaled - segment
100
+ );
101
+ return <View key={index} style={[styles.band, { backgroundColor: color }]} />;
102
+ })}
103
+ </>
104
+ );
105
+ }
106
+
107
+ /**
108
+ * Washes the bottom of a header out into the page colour: a straight ramp from
109
+ * fully transparent at the top to opaque at the bottom edge, the same
110
+ * `linear-gradient(transparent, white)` the web widget draws. Callers size it
111
+ * so the ramp begins below the heading, which it would otherwise wash out.
112
+ */
113
+ export function FadeOverlay({
114
+ color = palette.white,
115
+ height = 72,
116
+ bands,
117
+ style,
118
+ }: {
119
+ color?: string;
120
+ height?: number;
121
+ /** Defaults to a count fine enough that the alpha ramp reads as continuous. */
122
+ bands?: number;
123
+ style?: ViewStyle;
124
+ }) {
125
+ const NativeGradient = getNativeGradient();
126
+ // Positioning stays on a plain View; the native ramp only ever paints
127
+ // inside it, so it never has to honour `position: absolute` itself.
128
+ return (
129
+ <View style={[styles.fadeOverlay, { height }, style]} pointerEvents="none">
130
+ {NativeGradient ? (
131
+ <NativeGradient
132
+ colors={[withAlpha(color, 0), color]}
133
+ start={VERTICAL.start}
134
+ end={VERTICAL.end}
135
+ style={StyleSheet.absoluteFill}
136
+ />
137
+ ) : (
138
+ // Alpha steps over a dark header are amplified by the contrast with
139
+ // white, so the fallback needs a finer ramp than a colour-to-colour one.
140
+ Array.from({
141
+ length: bands ?? Math.min(192, Math.max(48, Math.round(height * 2.5))),
142
+ }).map((_, index, all) => (
143
+ // The last band is fully opaque so the header ends flush with the
144
+ // body colour, with no hairline where the two meet.
145
+ <View
146
+ key={index}
147
+ style={[styles.band, { backgroundColor: withAlpha(color, (index + 1) / all.length) }]}
148
+ />
149
+ ))
150
+ )}
151
+ </View>
152
+ );
153
+ }
154
+
155
+ const styles = StyleSheet.create({
156
+ band: {
157
+ flex: 1,
158
+ },
159
+ fadeOverlay: {
160
+ position: 'absolute',
161
+ left: 0,
162
+ right: 0,
163
+ bottom: 0,
164
+ },
165
+ });
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Optional floating launcher with an unread badge — the RN counterpart of the
3
+ * web widget's `Bubble.tsx`. Apps that already have their own chat entry point
4
+ * (like Repzo's map screen) can ignore it and call `RepzoWidget.present()`
5
+ * directly; it is exported so smaller hosts get a launcher for free.
6
+ *
7
+ * It positions itself absolutely, so mount it inside a full-screen container.
8
+ */
9
+
10
+ import { Pressable, StyleSheet, Text, View } from 'react-native';
11
+
12
+ import { useWidgetState } from '../../state/use-widget-state';
13
+ import { controller } from '../../controller';
14
+ import { ChatIcon, ChevronIcon } from './icons';
15
+ import {
16
+ DEFAULT_PRIMARY_COLOR,
17
+ fontSize,
18
+ palette,
19
+ radius,
20
+ shadows,
21
+ spacing,
22
+ } from '../styles/theme';
23
+
24
+ export interface LauncherProps {
25
+ /** Overrides the widget config's position/padding when the host needs to. */
26
+ position?: 'left' | 'right';
27
+ verticalPadding?: number;
28
+ horizontalPadding?: number;
29
+ /** Hides the launcher without unmounting the provider. */
30
+ hidden?: boolean;
31
+ }
32
+
33
+ export function Launcher({
34
+ position,
35
+ verticalPadding,
36
+ horizontalPadding,
37
+ hidden = false,
38
+ }: LauncherProps) {
39
+ const state = useWidgetState();
40
+ const config = state.config;
41
+
42
+ if (hidden || !state.booted || config?.showLauncher === false) return null;
43
+
44
+ const color = config?.primaryColor || DEFAULT_PRIMARY_COLOR;
45
+ const side = position ?? config?.position ?? 'right';
46
+ const bottom = Math.max(verticalPadding ?? config?.launcherVerticalPadding ?? 20, 20);
47
+ const inset = Math.max(horizontalPadding ?? config?.launcherHorizontalPadding ?? 20, 20);
48
+ const text = config?.bubbleText;
49
+ const showText = !!text && !state.isOpen;
50
+
51
+ return (
52
+ <View
53
+ style={[styles.wrapper, { bottom }, side === 'right' ? { right: inset } : { left: inset }]}
54
+ pointerEvents="box-none">
55
+ <Pressable
56
+ onPress={() => controller.store.toggle()}
57
+ accessibilityRole="button"
58
+ accessibilityLabel={state.isOpen ? 'Close chat' : 'Open chat'}
59
+ style={({ pressed }) => [
60
+ styles.bubble,
61
+ showText ? styles.bubbleWithText : styles.bubbleRound,
62
+ { backgroundColor: color },
63
+ pressed && styles.pressed,
64
+ ]}>
65
+ {showText ? <Text style={styles.bubbleText}>{text}</Text> : null}
66
+ {state.isOpen ? (
67
+ <ChevronIcon size={24} direction="down" color={palette.white} />
68
+ ) : (
69
+ <ChatIcon size={26} color={palette.white} />
70
+ )}
71
+ </Pressable>
72
+
73
+ {!state.isOpen && state.unreadCount > 0 ? (
74
+ <View style={styles.badge} pointerEvents="none">
75
+ <Text style={styles.badgeLabel}>{state.unreadCount > 9 ? '9+' : state.unreadCount}</Text>
76
+ </View>
77
+ ) : null}
78
+ </View>
79
+ );
80
+ }
81
+
82
+ const styles = StyleSheet.create({
83
+ wrapper: {
84
+ position: 'absolute',
85
+ },
86
+ bubble: {
87
+ height: 60,
88
+ alignItems: 'center',
89
+ justifyContent: 'center',
90
+ flexDirection: 'row',
91
+ gap: spacing.sm + 2,
92
+ ...shadows.floating,
93
+ },
94
+ bubbleRound: {
95
+ width: 60,
96
+ borderRadius: 30,
97
+ },
98
+ bubbleWithText: {
99
+ borderRadius: radius.pill,
100
+ paddingHorizontal: spacing.xl,
101
+ },
102
+ bubbleText: {
103
+ color: palette.white,
104
+ fontSize: fontSize.body,
105
+ fontWeight: '700',
106
+ },
107
+ pressed: {
108
+ opacity: 0.9,
109
+ transform: [{ scale: 0.97 }],
110
+ },
111
+ badge: {
112
+ position: 'absolute',
113
+ top: -4,
114
+ right: -4,
115
+ minWidth: 22,
116
+ height: 22,
117
+ borderRadius: 11,
118
+ paddingHorizontal: spacing.xs,
119
+ backgroundColor: palette.danger,
120
+ alignItems: 'center',
121
+ justifyContent: 'center',
122
+ },
123
+ badgeLabel: {
124
+ color: palette.white,
125
+ fontSize: fontSize.caption,
126
+ fontWeight: '700',
127
+ },
128
+ });