@adminide-stack/yantra-mobile 12.0.69-alpha.2 → 12.0.69-alpha.20

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 (522) hide show
  1. package/lib/components/GatewayConnector/GatewayConnector.js +2 -2
  2. package/lib/components/GatewayConnector/GatewayConnector.js.map +1 -1
  3. package/lib/components/KeyboardComposerDock.js +8 -1
  4. package/lib/components/KeyboardComposerDock.js.map +1 -1
  5. package/lib/components/NavigationHeader/NavigationHeader.js +2 -2
  6. package/lib/components/NavigationHeader/NavigationHeader.js.map +1 -1
  7. package/lib/contexts/ChatLiveStreamContext.js +4 -1
  8. package/lib/contexts/ChatLiveStreamContext.js.map +1 -1
  9. package/lib/features/agent-chat/NativeAgentChat.js +2 -0
  10. package/lib/features/agent-chat/NativeAgentChat.js.map +1 -1
  11. package/lib/features/apps/AppsCatalog.js +2 -2
  12. package/lib/features/apps/AppsCatalog.js.map +1 -1
  13. package/lib/features/audio-input/MicErrorBoundary.js +2 -2
  14. package/lib/features/audio-input/MicErrorBoundary.js.map +1 -1
  15. package/lib/features/canvas/AudioEditorExperience.js +308 -0
  16. package/lib/features/canvas/AudioEditorExperience.js.map +1 -0
  17. package/lib/features/canvas/CanvasAgentChatPane.js +310 -0
  18. package/lib/features/canvas/CanvasAgentChatPane.js.map +1 -0
  19. package/lib/features/canvas/CanvasBoardsGrid.js +414 -0
  20. package/lib/features/canvas/CanvasBoardsGrid.js.map +1 -0
  21. package/lib/features/canvas/CanvasChatResultCard.js +113 -0
  22. package/lib/features/canvas/CanvasChatResultCard.js.map +1 -0
  23. package/lib/features/canvas/CanvasEditToolsPanel.js +179 -0
  24. package/lib/features/canvas/CanvasEditToolsPanel.js.map +1 -0
  25. package/lib/features/canvas/CanvasExperience.js +859 -0
  26. package/lib/features/canvas/CanvasExperience.js.map +1 -0
  27. package/lib/features/canvas/CanvasGeneratePanel.js +514 -0
  28. package/lib/features/canvas/CanvasGeneratePanel.js.map +1 -0
  29. package/lib/features/canvas/CanvasLibrarySheet.js +355 -0
  30. package/lib/features/canvas/CanvasLibrarySheet.js.map +1 -0
  31. package/lib/features/canvas/CanvasLooksPanel.js +184 -0
  32. package/lib/features/canvas/CanvasLooksPanel.js.map +1 -0
  33. package/lib/features/canvas/CanvasTasksPanel.js +138 -0
  34. package/lib/features/canvas/CanvasTasksPanel.js.map +1 -0
  35. package/lib/features/canvas/CanvasTemplatesPanel.js +226 -0
  36. package/lib/features/canvas/CanvasTemplatesPanel.js.map +1 -0
  37. package/lib/features/canvas/CanvasToolDock.js +423 -0
  38. package/lib/features/canvas/CanvasToolDock.js.map +1 -0
  39. package/lib/features/canvas/FrameExtractorExperience.js +242 -0
  40. package/lib/features/canvas/FrameExtractorExperience.js.map +1 -0
  41. package/lib/features/canvas/ImageEditorExperience.js +491 -0
  42. package/lib/features/canvas/ImageEditorExperience.js.map +1 -0
  43. package/lib/features/canvas/InfluencerStudioExperience.js +288 -0
  44. package/lib/features/canvas/InfluencerStudioExperience.js.map +1 -0
  45. package/lib/features/canvas/MoodboardExperience.js +205 -0
  46. package/lib/features/canvas/MoodboardExperience.js.map +1 -0
  47. package/lib/features/canvas/NativeCanvasViewer.js +929 -0
  48. package/lib/features/canvas/NativeCanvasViewer.js.map +1 -0
  49. package/lib/features/canvas/PromoContextFields.js +150 -0
  50. package/lib/features/canvas/PromoContextFields.js.map +1 -0
  51. package/lib/features/canvas/SetStudioExperience.js +323 -0
  52. package/lib/features/canvas/SetStudioExperience.js.map +1 -0
  53. package/lib/features/canvas/VideoClipsExperience.js +175 -0
  54. package/lib/features/canvas/VideoClipsExperience.js.map +1 -0
  55. package/lib/features/canvas/VideoEditExperience.js +824 -0
  56. package/lib/features/canvas/VideoEditExperience.js.map +1 -0
  57. package/lib/features/canvas/VideoEditorExperience.js +3050 -0
  58. package/lib/features/canvas/VideoEditorExperience.js.map +1 -0
  59. package/lib/features/canvas/VideoGeneratorExperience.js +415 -0
  60. package/lib/features/canvas/VideoGeneratorExperience.js.map +1 -0
  61. package/lib/features/canvas/aiEdit.js +53 -0
  62. package/lib/features/canvas/aiEdit.js.map +1 -0
  63. package/lib/features/canvas/canvasAgentChat.js +76 -0
  64. package/lib/features/canvas/canvasAgentChat.js.map +1 -0
  65. package/lib/features/canvas/canvasBoardsCatalog.js +59 -0
  66. package/lib/features/canvas/canvasBoardsCatalog.js.map +1 -0
  67. package/lib/features/canvas/canvasBoardsSnapshot.js +14 -1
  68. package/lib/features/canvas/canvasBoardsSnapshot.js.map +1 -1
  69. package/lib/features/canvas/canvasChatDisplay.js +38 -0
  70. package/lib/features/canvas/canvasChatDisplay.js.map +1 -0
  71. package/lib/features/canvas/canvasChatTemplates.js +219 -0
  72. package/lib/features/canvas/canvasChatTemplates.js.map +1 -0
  73. package/lib/features/canvas/canvasCore.js +138 -1
  74. package/lib/features/canvas/canvasCore.js.map +1 -1
  75. package/lib/features/canvas/canvasEditOps.js +224 -0
  76. package/lib/features/canvas/canvasEditOps.js.map +1 -0
  77. package/lib/features/canvas/canvasTasks.js +187 -0
  78. package/lib/features/canvas/canvasTasks.js.map +1 -0
  79. package/lib/features/canvas/designPromptTemplates.js +3084 -0
  80. package/lib/features/canvas/designPromptTemplates.js.map +1 -0
  81. package/lib/features/canvas/editTools.js +54 -0
  82. package/lib/features/canvas/editTools.js.map +1 -0
  83. package/lib/features/canvas/extendVideo.js +5 -0
  84. package/lib/features/canvas/extendVideo.js.map +1 -0
  85. package/lib/features/canvas/frameExtract.js +33 -0
  86. package/lib/features/canvas/frameExtract.js.map +1 -0
  87. package/lib/features/canvas/generationModels.js +201 -0
  88. package/lib/features/canvas/generationModels.js.map +1 -0
  89. package/lib/features/canvas/influencer/influencerPipeline.js +170 -0
  90. package/lib/features/canvas/influencer/influencerPipeline.js.map +1 -0
  91. package/lib/features/canvas/influencer/productReel.js +72 -0
  92. package/lib/features/canvas/influencer/productReel.js.map +1 -0
  93. package/lib/features/canvas/influencer/reelPlan.js +159 -0
  94. package/lib/features/canvas/influencer/reelPlan.js.map +1 -0
  95. package/lib/features/canvas/moodboardCore.js +13 -0
  96. package/lib/features/canvas/moodboardCore.js.map +1 -0
  97. package/lib/features/canvas/promoProjectImport.js +99 -0
  98. package/lib/features/canvas/promoProjectImport.js.map +1 -0
  99. package/lib/features/canvas/promoVideo.js +312 -0
  100. package/lib/features/canvas/promoVideo.js.map +1 -0
  101. package/lib/features/canvas/recorder/CameraRecorderExperience.js +109 -0
  102. package/lib/features/canvas/recorder/CameraRecorderExperience.js.map +1 -0
  103. package/lib/features/canvas/sessionIdentity.js +28 -1
  104. package/lib/features/canvas/sessionIdentity.js.map +1 -1
  105. package/lib/features/canvas/set/SetViewportWebView.js +133 -0
  106. package/lib/features/canvas/set/SetViewportWebView.js.map +1 -0
  107. package/lib/features/canvas/set/cameraPath.js +194 -0
  108. package/lib/features/canvas/set/cameraPath.js.map +1 -0
  109. package/lib/features/canvas/set/setProject.js +24 -0
  110. package/lib/features/canvas/set/setProject.js.map +1 -0
  111. package/lib/features/canvas/storageLibrary.js +184 -0
  112. package/lib/features/canvas/storageLibrary.js.map +1 -0
  113. package/lib/features/canvas/studioCatalog.js +129 -0
  114. package/lib/features/canvas/studioCatalog.js.map +1 -0
  115. package/lib/features/canvas/studioLooks.js +189 -0
  116. package/lib/features/canvas/studioLooks.js.map +1 -0
  117. package/lib/features/canvas/surfaceIndex.js +63 -1
  118. package/lib/features/canvas/surfaceIndex.js.map +1 -1
  119. package/lib/features/canvas/templateImport/invideoNative.js +221 -0
  120. package/lib/features/canvas/templateImport/invideoNative.js.map +1 -0
  121. package/lib/features/canvas/templateImport/loadTemplate.js +43 -0
  122. package/lib/features/canvas/templateImport/loadTemplate.js.map +1 -0
  123. package/lib/features/canvas/templateImport/renderConfig.js +93 -0
  124. package/lib/features/canvas/templateImport/renderConfig.js.map +1 -0
  125. package/lib/features/canvas/useStudioCatalogTemplates.js +134 -0
  126. package/lib/features/canvas/useStudioCatalogTemplates.js.map +1 -0
  127. package/lib/features/canvas/video3d.js +109 -0
  128. package/lib/features/canvas/video3d.js.map +1 -0
  129. package/lib/features/canvas/videoClips.js +42 -0
  130. package/lib/features/canvas/videoClips.js.map +1 -0
  131. package/lib/features/canvas/videoEditor/agent/AgentCutPane.js +120 -0
  132. package/lib/features/canvas/videoEditor/agent/AgentCutPane.js.map +1 -0
  133. package/lib/features/canvas/videoEditor/agent/agentLoop.js +69 -0
  134. package/lib/features/canvas/videoEditor/agent/agentLoop.js.map +1 -0
  135. package/lib/features/canvas/videoEditor/agent/brainClient.js +45 -0
  136. package/lib/features/canvas/videoEditor/agent/brainClient.js.map +1 -0
  137. package/lib/features/canvas/videoEditor/agent/cutTools.js +129 -0
  138. package/lib/features/canvas/videoEditor/agent/cutTools.js.map +1 -0
  139. package/lib/features/canvas/videoEditor/editorModel.js +346 -0
  140. package/lib/features/canvas/videoEditor/editorModel.js.map +1 -0
  141. package/lib/features/canvas/videoEditor/exportRenderer.js +214 -0
  142. package/lib/features/canvas/videoEditor/exportRenderer.js.map +1 -0
  143. package/lib/features/canvas/videoEditor/filters.js +41 -0
  144. package/lib/features/canvas/videoEditor/filters.js.map +1 -0
  145. package/lib/features/canvas/videoEditor/mediaActions.js +57 -0
  146. package/lib/features/canvas/videoEditor/mediaActions.js.map +1 -0
  147. package/lib/features/canvas/videoEditor/remoteMediaClient.js +129 -0
  148. package/lib/features/canvas/videoEditor/remoteMediaClient.js.map +1 -0
  149. package/lib/features/canvas/videoEditor/solidColorPng.js +115 -0
  150. package/lib/features/canvas/videoEditor/solidColorPng.js.map +1 -0
  151. package/lib/features/canvas/videoEditor/videoEditOps.js +191 -0
  152. package/lib/features/canvas/videoEditor/videoEditOps.js.map +1 -0
  153. package/lib/features/canvas/videoEditor/videoProjectsStore.js +82 -0
  154. package/lib/features/canvas/videoEditor/videoProjectsStore.js.map +1 -0
  155. package/lib/features/canvas/videoRenderer.js +8 -0
  156. package/lib/features/canvas/videoRenderer.js.map +1 -0
  157. package/lib/features/canvas/withRemoteSafeArea.js +2 -2
  158. package/lib/features/canvas/withRemoteSafeArea.js.map +1 -1
  159. package/lib/features/characters/characterStudioProps.js +14 -0
  160. package/lib/features/characters/characterStudioProps.js.map +1 -0
  161. package/lib/features/chat/ChatCodeBlock.js +7 -3
  162. package/lib/features/chat/ChatCodeBlock.js.map +1 -1
  163. package/lib/features/chat/ChatTranscript.js +7 -3
  164. package/lib/features/chat/ChatTranscript.js.map +1 -1
  165. package/lib/features/chat/ChatWidgetCard.js +13 -0
  166. package/lib/features/chat/ChatWidgetCard.js.map +1 -0
  167. package/lib/features/chat/ConnectorConnectCard.js +164 -0
  168. package/lib/features/chat/ConnectorConnectCard.js.map +1 -0
  169. package/lib/features/chat/ConnectorConnectPrompt.js +254 -0
  170. package/lib/features/chat/ConnectorConnectPrompt.js.map +1 -0
  171. package/lib/features/chat/MessageActionBar.js.map +1 -1
  172. package/lib/features/chat/QueuedFollowUps.js +71 -0
  173. package/lib/features/chat/QueuedFollowUps.js.map +1 -0
  174. package/lib/features/chat/chatWidgets.js +37 -0
  175. package/lib/features/chat/chatWidgets.js.map +1 -0
  176. package/lib/features/chat/connectorConnect.js +194 -0
  177. package/lib/features/chat/connectorConnect.js.map +1 -0
  178. package/lib/features/chat/connectorConnectHandbacks.js +55 -0
  179. package/lib/features/chat/connectorConnectHandbacks.js.map +1 -0
  180. package/lib/features/design/DesignEditorExperience.js +643 -0
  181. package/lib/features/design/DesignEditorExperience.js.map +1 -0
  182. package/lib/features/design/DesignExperience.js +444 -0
  183. package/lib/features/design/DesignExperience.js.map +1 -0
  184. package/lib/features/design/designCore.js +298 -0
  185. package/lib/features/design/designCore.js.map +1 -0
  186. package/lib/features/design/designIndex.js +150 -0
  187. package/lib/features/design/designIndex.js.map +1 -0
  188. package/lib/features/design/exportDesign.js +133 -0
  189. package/lib/features/design/exportDesign.js.map +1 -0
  190. package/lib/features/job-search/ApplicationsPanel.js +907 -0
  191. package/lib/features/job-search/ApplicationsPanel.js.map +1 -0
  192. package/lib/features/job-search/ContactsPanel.js +627 -0
  193. package/lib/features/job-search/ContactsPanel.js.map +1 -0
  194. package/lib/features/job-search/InsightsPanel.js +299 -0
  195. package/lib/features/job-search/InsightsPanel.js.map +1 -0
  196. package/lib/features/job-search/InterviewPanel.js +637 -0
  197. package/lib/features/job-search/InterviewPanel.js.map +1 -0
  198. package/lib/features/job-search/JdPastePrompt.js +130 -0
  199. package/lib/features/job-search/JdPastePrompt.js.map +1 -0
  200. package/lib/features/job-search/JobCard.js +199 -0
  201. package/lib/features/job-search/JobCard.js.map +1 -0
  202. package/lib/features/job-search/JobDetailSheet.js +255 -0
  203. package/lib/features/job-search/JobDetailSheet.js.map +1 -0
  204. package/lib/features/job-search/JobSearchAgentChatPane.js +377 -0
  205. package/lib/features/job-search/JobSearchAgentChatPane.js.map +1 -0
  206. package/lib/features/job-search/JobSearchExperience.js +1324 -0
  207. package/lib/features/job-search/JobSearchExperience.js.map +1 -0
  208. package/lib/features/job-search/JobSearchLocationField.js +231 -0
  209. package/lib/features/job-search/JobSearchLocationField.js.map +1 -0
  210. package/lib/features/job-search/ProfilePanel.js +679 -0
  211. package/lib/features/job-search/ProfilePanel.js.map +1 -0
  212. package/lib/features/job-search/RepliesPanel.js +344 -0
  213. package/lib/features/job-search/RepliesPanel.js.map +1 -0
  214. package/lib/features/job-search/SavedPanel.js +297 -0
  215. package/lib/features/job-search/SavedPanel.js.map +1 -0
  216. package/lib/features/job-search/chat/widgetContent.js +29 -0
  217. package/lib/features/job-search/chat/widgetContent.js.map +1 -0
  218. package/lib/features/job-search/cvText.js +91 -0
  219. package/lib/features/job-search/cvText.js.map +1 -0
  220. package/lib/features/job-search/jobAgentSwipe.js +7 -0
  221. package/lib/features/job-search/jobAgentSwipe.js.map +1 -0
  222. package/lib/features/job-search/jobSearchClient.js +184 -0
  223. package/lib/features/job-search/jobSearchClient.js.map +1 -0
  224. package/lib/features/job-search/jobSearchExec.js +14 -0
  225. package/lib/features/job-search/jobSearchExec.js.map +1 -0
  226. package/lib/features/job-search/jobSearchRuntime.js +50 -0
  227. package/lib/features/job-search/jobSearchRuntime.js.map +1 -0
  228. package/lib/features/job-search/jobSearchTheme.js +44 -0
  229. package/lib/features/job-search/jobSearchTheme.js.map +1 -0
  230. package/lib/features/job-search/savedJobs.js +85 -0
  231. package/lib/features/job-search/savedJobs.js.map +1 -0
  232. package/lib/features/job-search/searchHistory.js +117 -0
  233. package/lib/features/job-search/searchHistory.js.map +1 -0
  234. package/lib/features/job-search/types.js +36 -0
  235. package/lib/features/job-search/types.js.map +1 -0
  236. package/lib/features/job-search/useJobSearchSession.js +558 -0
  237. package/lib/features/job-search/useJobSearchSession.js.map +1 -0
  238. package/lib/features/messaging/ChatComponents.js +529 -0
  239. package/lib/features/messaging/ChatComponents.js.map +1 -0
  240. package/lib/features/messaging/ChatInviteDeepLink.js +116 -0
  241. package/lib/features/messaging/ChatInviteDeepLink.js.map +1 -0
  242. package/lib/features/messaging/ContactsScreen.js +230 -0
  243. package/lib/features/messaging/ContactsScreen.js.map +1 -0
  244. package/lib/features/messaging/ConversationListScreen.js +147 -0
  245. package/lib/features/messaging/ConversationListScreen.js.map +1 -0
  246. package/lib/features/messaging/MessageActions.js +283 -0
  247. package/lib/features/messaging/MessageActions.js.map +1 -0
  248. package/lib/features/messaging/NativeChatExperience.js +186 -0
  249. package/lib/features/messaging/NativeChatExperience.js.map +1 -0
  250. package/lib/features/messaging/RegistrationScreen.js +7 -7
  251. package/lib/features/messaging/RegistrationScreen.js.map +1 -1
  252. package/lib/features/messaging/ThreadScreen.js +215 -0
  253. package/lib/features/messaging/ThreadScreen.js.map +1 -0
  254. package/lib/features/messaging/chatInviteLink.js +52 -0
  255. package/lib/features/messaging/chatInviteLink.js.map +1 -0
  256. package/lib/features/messaging/chatModel.js +278 -0
  257. package/lib/features/messaging/chatModel.js.map +1 -0
  258. package/lib/features/messaging/chatOperations.js +116 -1
  259. package/lib/features/messaging/chatOperations.js.map +1 -1
  260. package/lib/features/messaging/chatRegistrationStorage.js +4 -1
  261. package/lib/features/messaging/chatRegistrationStorage.js.map +1 -1
  262. package/lib/features/messaging/emojiCatalog.js +36 -0
  263. package/lib/features/messaging/emojiCatalog.js.map +1 -0
  264. package/lib/features/messaging/nativeChatChannelQuery.js +27 -0
  265. package/lib/features/messaging/nativeChatChannelQuery.js.map +1 -0
  266. package/lib/features/messaging/phoneNumbers.js +52 -1
  267. package/lib/features/messaging/phoneNumbers.js.map +1 -1
  268. package/lib/features/messaging/sha256.js +68 -0
  269. package/lib/features/messaging/sha256.js.map +1 -0
  270. package/lib/features/messaging/useChatData.js +421 -0
  271. package/lib/features/messaging/useChatData.js.map +1 -0
  272. package/lib/features/messaging/useContactMatches.js +231 -0
  273. package/lib/features/messaging/useContactMatches.js.map +1 -0
  274. package/lib/features/messaging/usePhoneVerification.js +6 -5
  275. package/lib/features/messaging/usePhoneVerification.js.map +1 -1
  276. package/lib/features/messaging/useYantraChatMembership.js +9 -6
  277. package/lib/features/messaging/useYantraChatMembership.js.map +1 -1
  278. package/lib/features/messaging/yantraChatOrg.js +8 -3
  279. package/lib/features/messaging/yantraChatOrg.js.map +1 -1
  280. package/lib/features/resume/AnnotateModal.js +100 -0
  281. package/lib/features/resume/AnnotateModal.js.map +1 -0
  282. package/lib/features/resume/AnnotationBar.js +69 -0
  283. package/lib/features/resume/AnnotationBar.js.map +1 -0
  284. package/lib/features/resume/ExportSheet.js +105 -0
  285. package/lib/features/resume/ExportSheet.js.map +1 -0
  286. package/lib/features/resume/ResumeAgentChatPane.js +95 -0
  287. package/lib/features/resume/ResumeAgentChatPane.js.map +1 -0
  288. package/lib/features/resume/ResumeEditor.js +676 -0
  289. package/lib/features/resume/ResumeEditor.js.map +1 -0
  290. package/lib/features/resume/ResumeExperience.js +235 -0
  291. package/lib/features/resume/ResumeExperience.js.map +1 -0
  292. package/lib/features/resume/ResumeListPanel.js +262 -0
  293. package/lib/features/resume/ResumeListPanel.js.map +1 -0
  294. package/lib/features/resume/ResumeToolbar.js +236 -0
  295. package/lib/features/resume/ResumeToolbar.js.map +1 -0
  296. package/lib/features/resume/annotations.js +17 -0
  297. package/lib/features/resume/annotations.js.map +1 -0
  298. package/lib/features/resume/documentCss.js +52 -0
  299. package/lib/features/resume/documentCss.js.map +1 -0
  300. package/lib/features/resume/draft.js +89 -0
  301. package/lib/features/resume/draft.js.map +1 -0
  302. package/lib/features/resume/exportResume.js +43 -0
  303. package/lib/features/resume/exportResume.js.map +1 -0
  304. package/lib/features/resume/pickResumePhoto.js +22 -0
  305. package/lib/features/resume/pickResumePhoto.js.map +1 -0
  306. package/lib/features/resume/renderResume.js +121 -0
  307. package/lib/features/resume/renderResume.js.map +1 -0
  308. package/lib/features/resume/resumeClient.js +69 -0
  309. package/lib/features/resume/resumeClient.js.map +1 -0
  310. package/lib/features/resume/resumeExec.js +14 -0
  311. package/lib/features/resume/resumeExec.js.map +1 -0
  312. package/lib/features/resume/resumeIndex.js +244 -0
  313. package/lib/features/resume/resumeIndex.js.map +1 -0
  314. package/lib/features/resume/resumeRuntime.js +50 -0
  315. package/lib/features/resume/resumeRuntime.js.map +1 -0
  316. package/lib/features/resume/resumeTheme.js +34 -0
  317. package/lib/features/resume/resumeTheme.js.map +1 -0
  318. package/lib/features/resume/resumeToolbox.js +49 -0
  319. package/lib/features/resume/resumeToolbox.js.map +1 -0
  320. package/lib/features/resume/templates.js +90 -0
  321. package/lib/features/resume/templates.js.map +1 -0
  322. package/lib/features/resume/types.js +10 -0
  323. package/lib/features/resume/types.js.map +1 -0
  324. package/lib/features/resume/useResumeSession.js +183 -0
  325. package/lib/features/resume/useResumeSession.js.map +1 -0
  326. package/lib/features/shopping/DealsPanel.js +254 -0
  327. package/lib/features/shopping/DealsPanel.js.map +1 -0
  328. package/lib/features/shopping/HistoryPanel.js +147 -0
  329. package/lib/features/shopping/HistoryPanel.js.map +1 -0
  330. package/lib/features/shopping/OrdersPanel.js +157 -0
  331. package/lib/features/shopping/OrdersPanel.js.map +1 -0
  332. package/lib/features/shopping/ProductCard.js +326 -0
  333. package/lib/features/shopping/ProductCard.js.map +1 -0
  334. package/lib/features/shopping/ProductDetailSheet.js +313 -0
  335. package/lib/features/shopping/ProductDetailSheet.js.map +1 -0
  336. package/lib/features/shopping/ProductFilterBar.js +153 -0
  337. package/lib/features/shopping/ProductFilterBar.js.map +1 -0
  338. package/lib/features/shopping/ProductPhoto.js +27 -0
  339. package/lib/features/shopping/ProductPhoto.js.map +1 -0
  340. package/lib/features/shopping/SavedPanel.js +139 -0
  341. package/lib/features/shopping/SavedPanel.js.map +1 -0
  342. package/lib/features/shopping/ShoppingAgentChatPane.js +436 -0
  343. package/lib/features/shopping/ShoppingAgentChatPane.js.map +1 -0
  344. package/lib/features/shopping/ShoppingExperience.js +888 -0
  345. package/lib/features/shopping/ShoppingExperience.js.map +1 -0
  346. package/lib/features/shopping/TrendingSections.js +199 -0
  347. package/lib/features/shopping/TrendingSections.js.map +1 -0
  348. package/lib/features/shopping/WatchlistPanel.js +148 -0
  349. package/lib/features/shopping/WatchlistPanel.js.map +1 -0
  350. package/lib/features/shopping/catalog.js +238 -0
  351. package/lib/features/shopping/catalog.js.map +1 -0
  352. package/lib/features/shopping/chat/ShoppingChatResultCard.js +175 -0
  353. package/lib/features/shopping/chat/ShoppingChatResultCard.js.map +1 -0
  354. package/lib/features/shopping/chat/streamAssistantReply.js +34 -0
  355. package/lib/features/shopping/chat/streamAssistantReply.js.map +1 -0
  356. package/lib/features/shopping/chat/widgetContent.js +233 -0
  357. package/lib/features/shopping/chat/widgetContent.js.map +1 -0
  358. package/lib/features/shopping/hooks/useTrendingProducts.js +162 -0
  359. package/lib/features/shopping/hooks/useTrendingProducts.js.map +1 -0
  360. package/lib/features/shopping/productImage.js +42 -0
  361. package/lib/features/shopping/productImage.js.map +1 -0
  362. package/lib/features/shopping/savedProducts.js +84 -0
  363. package/lib/features/shopping/savedProducts.js.map +1 -0
  364. package/lib/features/shopping/services/catalogActions.js +166 -0
  365. package/lib/features/shopping/services/catalogActions.js.map +1 -0
  366. package/lib/features/shopping/services/parsePriceCheckIntent.js +58 -0
  367. package/lib/features/shopping/services/parsePriceCheckIntent.js.map +1 -0
  368. package/lib/features/shopping/services/parseShoppingIntent.js +67 -0
  369. package/lib/features/shopping/services/parseShoppingIntent.js.map +1 -0
  370. package/lib/features/shopping/services/productAvailability.js +25 -0
  371. package/lib/features/shopping/services/productAvailability.js.map +1 -0
  372. package/lib/features/shopping/services/productFilters.js +72 -0
  373. package/lib/features/shopping/services/productFilters.js.map +1 -0
  374. package/lib/features/shopping/services/retailerUrl.js +75 -0
  375. package/lib/features/shopping/services/retailerUrl.js.map +1 -0
  376. package/lib/features/shopping/services/shoppingChatReply.js +46 -0
  377. package/lib/features/shopping/services/shoppingChatReply.js.map +1 -0
  378. package/lib/features/shopping/services/shoppingProductSearch.js +336 -0
  379. package/lib/features/shopping/services/shoppingProductSearch.js.map +1 -0
  380. package/lib/features/shopping/services/shoppingSearchConnectorClient.js +41 -0
  381. package/lib/features/shopping/services/shoppingSearchConnectorClient.js.map +1 -0
  382. package/lib/features/shopping/shopAgentSwipe.js +7 -0
  383. package/lib/features/shopping/shopAgentSwipe.js.map +1 -0
  384. package/lib/features/shopping/shoppingCart.js +116 -0
  385. package/lib/features/shopping/shoppingCart.js.map +1 -0
  386. package/lib/features/shopping/shoppingExec.js +14 -0
  387. package/lib/features/shopping/shoppingExec.js.map +1 -0
  388. package/lib/features/shopping/shoppingHistoryStore.js +176 -0
  389. package/lib/features/shopping/shoppingHistoryStore.js.map +1 -0
  390. package/lib/features/shopping/shoppingRuntime.js +63 -0
  391. package/lib/features/shopping/shoppingRuntime.js.map +1 -0
  392. package/lib/features/shopping/timeAgo.js +14 -0
  393. package/lib/features/shopping/timeAgo.js.map +1 -0
  394. package/lib/features/shopping/useShoppingSearch.js +262 -0
  395. package/lib/features/shopping/useShoppingSearch.js.map +1 -0
  396. package/lib/features/travel/BookHeaderGlow.js +48 -0
  397. package/lib/features/travel/BookHeaderGlow.js.map +1 -0
  398. package/lib/features/travel/BookingsPanel.js +29 -0
  399. package/lib/features/travel/BookingsPanel.js.map +1 -0
  400. package/lib/features/travel/DiscoverPanel.js +155 -0
  401. package/lib/features/travel/DiscoverPanel.js.map +1 -0
  402. package/lib/features/travel/FlightCompareBar.js +86 -0
  403. package/lib/features/travel/FlightCompareBar.js.map +1 -0
  404. package/lib/features/travel/FlightDealsBoard.js +100 -0
  405. package/lib/features/travel/FlightDealsBoard.js.map +1 -0
  406. package/lib/features/travel/HistoryPanel.js +82 -0
  407. package/lib/features/travel/HistoryPanel.js.map +1 -0
  408. package/lib/features/travel/PopularDestinations.js +144 -0
  409. package/lib/features/travel/PopularDestinations.js.map +1 -0
  410. package/lib/features/travel/SavedPanel.js +27 -0
  411. package/lib/features/travel/SavedPanel.js.map +1 -0
  412. package/lib/features/travel/TravelAgentChatPane.js +303 -0
  413. package/lib/features/travel/TravelAgentChatPane.js.map +1 -0
  414. package/lib/features/travel/TravelBookHero.js +425 -0
  415. package/lib/features/travel/TravelBookHero.js.map +1 -0
  416. package/lib/features/travel/TravelDatesField.js +234 -0
  417. package/lib/features/travel/TravelDatesField.js.map +1 -0
  418. package/lib/features/travel/TravelDetailSheet.js +106 -0
  419. package/lib/features/travel/TravelDetailSheet.js.map +1 -0
  420. package/lib/features/travel/TravelExperience.js +624 -0
  421. package/lib/features/travel/TravelExperience.js.map +1 -0
  422. package/lib/features/travel/TravelGuestsField.js +85 -0
  423. package/lib/features/travel/TravelGuestsField.js.map +1 -0
  424. package/lib/features/travel/TravelLanding.js +318 -0
  425. package/lib/features/travel/TravelLanding.js.map +1 -0
  426. package/lib/features/travel/TravelLocationField.js +179 -0
  427. package/lib/features/travel/TravelLocationField.js.map +1 -0
  428. package/lib/features/travel/TravelPropertyCard.js +266 -0
  429. package/lib/features/travel/TravelPropertyCard.js.map +1 -0
  430. package/lib/features/travel/TravelPropertyPhoto.js +22 -0
  431. package/lib/features/travel/TravelPropertyPhoto.js.map +1 -0
  432. package/lib/features/travel/TravelRailFlyout.js +79 -0
  433. package/lib/features/travel/TravelRailFlyout.js.map +1 -0
  434. package/lib/features/travel/TravelResultsMap.js +126 -0
  435. package/lib/features/travel/TravelResultsMap.js.map +1 -0
  436. package/lib/features/travel/WorkspacePanel.js +148 -0
  437. package/lib/features/travel/WorkspacePanel.js.map +1 -0
  438. package/lib/features/travel/appNav.js +244 -0
  439. package/lib/features/travel/appNav.js.map +1 -0
  440. package/lib/features/travel/calendarDays.js +50 -0
  441. package/lib/features/travel/calendarDays.js.map +1 -0
  442. package/lib/features/travel/catalog.js +72 -0
  443. package/lib/features/travel/catalog.js.map +1 -0
  444. package/lib/features/travel/chat/TravelChatResultCard.js +107 -0
  445. package/lib/features/travel/chat/TravelChatResultCard.js.map +1 -0
  446. package/lib/features/travel/chat/widgetContent.js +107 -0
  447. package/lib/features/travel/chat/widgetContent.js.map +1 -0
  448. package/lib/features/travel/flightDeals.js +65 -0
  449. package/lib/features/travel/flightDeals.js.map +1 -0
  450. package/lib/features/travel/mapCoordinates.js +36 -0
  451. package/lib/features/travel/mapCoordinates.js.map +1 -0
  452. package/lib/features/travel/parseTravelIntent.js +303 -0
  453. package/lib/features/travel/parseTravelIntent.js.map +1 -0
  454. package/lib/features/travel/savedStays.js +66 -0
  455. package/lib/features/travel/savedStays.js.map +1 -0
  456. package/lib/features/travel/services/flightDealsBoard.js +111 -0
  457. package/lib/features/travel/services/flightDealsBoard.js.map +1 -0
  458. package/lib/features/travel/services/flightSearchConnectorClient.js +42 -0
  459. package/lib/features/travel/services/flightSearchConnectorClient.js.map +1 -0
  460. package/lib/features/travel/services/geocodeLocation.js +79 -0
  461. package/lib/features/travel/services/geocodeLocation.js.map +1 -0
  462. package/lib/features/travel/services/placePredictions.js +113 -0
  463. package/lib/features/travel/services/placePredictions.js.map +1 -0
  464. package/lib/features/travel/services/resolveOriginCity.js +27 -0
  465. package/lib/features/travel/services/resolveOriginCity.js.map +1 -0
  466. package/lib/features/travel/services/resortifiConnectorClient.js +76 -0
  467. package/lib/features/travel/services/resortifiConnectorClient.js.map +1 -0
  468. package/lib/features/travel/services/travelFlightSearch.js +289 -0
  469. package/lib/features/travel/services/travelFlightSearch.js.map +1 -0
  470. package/lib/features/travel/services/travelPropertySearch.js +377 -0
  471. package/lib/features/travel/services/travelPropertySearch.js.map +1 -0
  472. package/lib/features/travel/travelAgentSwipe.js +7 -0
  473. package/lib/features/travel/travelAgentSwipe.js.map +1 -0
  474. package/lib/features/travel/travelExec.js +14 -0
  475. package/lib/features/travel/travelExec.js.map +1 -0
  476. package/lib/features/travel/travelHistoryStore.js +108 -0
  477. package/lib/features/travel/travelHistoryStore.js.map +1 -0
  478. package/lib/features/travel/travelRuntime.js +62 -0
  479. package/lib/features/travel/travelRuntime.js.map +1 -0
  480. package/lib/features/travel/types.js +9 -0
  481. package/lib/features/travel/types.js.map +1 -0
  482. package/lib/features/travel/useTravelSearch.js +330 -0
  483. package/lib/features/travel/useTravelSearch.js.map +1 -0
  484. package/lib/features/travel/workspaceContent.js +548 -0
  485. package/lib/features/travel/workspaceContent.js.map +1 -0
  486. package/lib/hooks/useCdecliChannel.js +128 -6
  487. package/lib/hooks/useCdecliChannel.js.map +1 -1
  488. package/lib/hooks/useChatApi.js +4 -2
  489. package/lib/hooks/useChatApi.js.map +1 -1
  490. package/lib/hooks/useChatStream.js +77 -63
  491. package/lib/hooks/useChatStream.js.map +1 -1
  492. package/lib/hooks/useHostConnectorCard.js +24 -0
  493. package/lib/hooks/useHostConnectorCard.js.map +1 -0
  494. package/lib/hooks/useObtainSystemToken.js +23 -5
  495. package/lib/hooks/useObtainSystemToken.js.map +1 -1
  496. package/lib/hooks/webViewRetentionPolicy.js +1 -0
  497. package/lib/hooks/webViewRetentionPolicy.js.map +1 -1
  498. package/lib/index.js +1 -1
  499. package/lib/index.js.map +1 -1
  500. package/lib/screens/Chat/index.js +51 -22
  501. package/lib/screens/Chat/index.js.map +1 -1
  502. package/lib/screens/ChatNative/index.js +13 -2
  503. package/lib/screens/ChatNative/index.js.map +1 -1
  504. package/lib/screens/Home/HomeScreen.js +3 -3
  505. package/lib/screens/Home/HomeScreen.js.map +1 -1
  506. package/lib/screens/Home/components/ChatHistoryLanding.js +32 -32
  507. package/lib/screens/Home/components/ChatHistoryLanding.js.map +1 -1
  508. package/lib/screens/JobSearchNative/useJobSearchHostChat.js +12 -6
  509. package/lib/screens/JobSearchNative/useJobSearchHostChat.js.map +1 -1
  510. package/lib/screens/ResumeNative/useResumeHostChat.js +12 -6
  511. package/lib/screens/ResumeNative/useResumeHostChat.js.map +1 -1
  512. package/lib/screens/ShoppingNative/useShoppingHostChat.js +12 -6
  513. package/lib/screens/ShoppingNative/useShoppingHostChat.js.map +1 -1
  514. package/lib/screens/TravelNative/useTravelHostChat.js +12 -6
  515. package/lib/screens/TravelNative/useTravelHostChat.js.map +1 -1
  516. package/lib/screens/WebBuilder/WebViewWithNavigation.js +2 -2
  517. package/lib/screens/WebBuilder/WebViewWithNavigation.js.map +1 -1
  518. package/lib/services/brainQuickReply.js +38 -1
  519. package/lib/services/brainQuickReply.js.map +1 -1
  520. package/lib/state/chatThreadMerge.js +6 -1
  521. package/lib/state/chatThreadMerge.js.map +1 -1
  522. package/package.json +5 -4
@@ -91,6 +91,57 @@ function toE164(raw, defaultRegion) {
91
91
  if (digits.startsWith("0")) return null;
92
92
  return `+${digits}`;
93
93
  }
94
+ function regionFromE164(e164) {
95
+ var _a;
96
+ if (!e164 || !e164.startsWith("+")) return null;
97
+ const digits = e164.slice(1);
98
+ let best = null;
99
+ for (const [region, cc] of Object.entries(CALLING_CODES)) {
100
+ if (digits.startsWith(cc) && (!best || cc.length > best.len)) best = {
101
+ region,
102
+ len: cc.length
103
+ };
104
+ }
105
+ return (_a = best == null ? void 0 : best.region) != null ? _a : null;
106
+ }
107
+ function contactE164s(phoneNumbers, defaultRegion) {
108
+ const regions = Array.isArray(defaultRegion) ? defaultRegion : [defaultRegion];
109
+ const seen = /* @__PURE__ */ new Set();
110
+ for (const raw of phoneNumbers) {
111
+ for (const region of regions) {
112
+ const e164 = toE164(raw, region);
113
+ if (e164) seen.add(e164);
114
+ }
115
+ }
116
+ return Array.from(seen);
117
+ }
118
+ function normalizeContacts(contacts, defaultRegion, viewerE164) {
119
+ var _a, _b, _c;
120
+ const mine = new Set(viewerE164 ? contactE164s([viewerE164], defaultRegion) : []);
121
+ const out = [];
122
+ for (const c of contacts) {
123
+ const e164 = contactE164s((_a = c.phoneNumbers) != null ? _a : [], defaultRegion);
124
+ if (!e164.length || e164.some((n) => mine.has(n))) continue;
125
+ out.push({
126
+ id: c.id,
127
+ displayName: c.displayName,
128
+ imageUri: (_b = c.imageUri) != null ? _b : null,
129
+ e164,
130
+ rawNumbers: ((_c = c.phoneNumbers) != null ? _c : []).map((n) => n.trim()).filter(Boolean)
131
+ });
132
+ }
133
+ return out;
134
+ }
135
+ function collectLookupNumbers(contacts, limit = 1e3) {
136
+ const seen = /* @__PURE__ */ new Set();
137
+ for (const c of contacts) {
138
+ for (const n of c.e164) {
139
+ seen.add(n);
140
+ if (seen.size >= limit) return Array.from(seen);
141
+ }
142
+ }
143
+ return Array.from(seen);
144
+ }
94
145
  function formatPhoneNumber(input, defaultRegion) {
95
146
  return toE164(input, defaultRegion);
96
147
  }
@@ -99,4 +150,4 @@ function isValidPhoneNumber(phoneNumber) {
99
150
  if (!phoneNumber.startsWith("+")) return false;
100
151
  const digits = phoneNumber.slice(1).replace(/\D/g, "");
101
152
  return digits.length >= MIN_E164_DIGITS && digits.length <= MAX_E164_DIGITS;
102
- }export{formatPhoneNumber,isValidPhoneNumber,toE164};//# sourceMappingURL=phoneNumbers.js.map
153
+ }export{collectLookupNumbers,contactE164s,formatPhoneNumber,isValidPhoneNumber,normalizeContacts,regionFromE164,toE164};//# sourceMappingURL=phoneNumbers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"phoneNumbers.js","sources":["../../../src/features/messaging/phoneNumbers.ts"],"sourcesContent":["/**\n * Turning what the address book gives you into something matchable.\n *\n * This lives in the REMOTE, not the host, on purpose: it is pure logic with no\n * native dependency, it is where contact-matching actually goes wrong, and\n * keeping it here means a normalisation bug is a surface deploy rather than an\n * App Store release. The `contacts` seam hands over RAW strings plus a region\n * hint precisely so this can own the problem.\n *\n * Deliberately NOT libphonenumber. That library is ~500KB and every byte ships\n * in the remote bundle on every cold launch. What follows handles the cases\n * that actually occur in an address book; anything it cannot confidently place\n * is DROPPED rather than guessed, because a wrong match shows someone a\n * stranger's name attached to their friend's number, which is far worse than\n * simply not finding them.\n */\n\n/** National trunk prefixes stripped before applying a country code. */\nconst TRUNK_PREFIXES: Record<string, string> = {\n // The overwhelmingly common case: a single leading 0.\n DEFAULT: '0',\n // Italy is the notable exception - the leading 0 is part of the number.\n IT: '',\n};\n\n/** Country calling codes for the regions a device is likely to report. */\nconst CALLING_CODES: Record<string, string> = {\n US: '1',\n CA: '1',\n GB: '44',\n IE: '353',\n FR: '33',\n DE: '49',\n ES: '34',\n IT: '39',\n NL: '31',\n BE: '32',\n CH: '41',\n AT: '43',\n SE: '46',\n NO: '47',\n DK: '45',\n FI: '358',\n PL: '48',\n PT: '351',\n GR: '30',\n CZ: '420',\n RO: '40',\n HU: '36',\n UA: '380',\n RU: '7',\n TR: '90',\n IL: '972',\n AE: '971',\n SA: '966',\n QA: '974',\n KW: '965',\n IN: '91',\n PK: '92',\n BD: '880',\n LK: '94',\n NP: '977',\n CN: '86',\n JP: '81',\n KR: '82',\n TW: '886',\n HK: '852',\n SG: '65',\n MY: '60',\n TH: '66',\n VN: '84',\n PH: '63',\n ID: '62',\n AU: '61',\n NZ: '64',\n ZA: '27',\n NG: '234',\n KE: '254',\n EG: '20',\n GH: '233',\n BR: '55',\n MX: '52',\n AR: '54',\n CL: '56',\n CO: '57',\n PE: '51',\n};\n\n/** Longest calling code is 4 digits; shortest E.164 subscriber part is ~4. */\nconst MIN_E164_DIGITS = 7;\nconst MAX_E164_DIGITS = 15;\n\n/**\n * Normalise one raw address-book string to E.164 (`+<digits>`), or null.\n *\n * Returns null rather than a best guess whenever the result would be\n * speculative - see the file header for why a miss beats a wrong match.\n */\nexport function toE164(raw: string, defaultRegion?: string | null): string | null {\n if (typeof raw !== 'string') return null;\n\n // Strip everything a human might type: spaces, dashes, dots, parens,\n // and the invisible bidi marks iOS inserts around RTL-locale numbers.\n const cleaned = raw.replace(/[\\s\\-().‎‏؜]/g, '');\n if (!cleaned) return null;\n\n // Extensions are not diallable identity - \"555123456x89\" is one person.\n const withoutExt = cleaned.split(/[,;xX#]/)[0];\n if (!withoutExt) return null;\n\n let digits: string;\n if (withoutExt.startsWith('+')) {\n digits = withoutExt.slice(1).replace(/\\D/g, '');\n } else if (withoutExt.startsWith('00')) {\n // The international prefix used across most of Europe and Asia.\n digits = withoutExt.slice(2).replace(/\\D/g, '');\n } else {\n const region = (defaultRegion ?? '').toUpperCase();\n const cc = CALLING_CODES[region];\n // No region and no international prefix: the number is meaningless\n // without knowing where it was dialled from. Drop it.\n if (!cc) return null;\n\n let national = withoutExt.replace(/\\D/g, '');\n const trunk = region in TRUNK_PREFIXES ? TRUNK_PREFIXES[region] : TRUNK_PREFIXES.DEFAULT;\n if (trunk && national.startsWith(trunk)) national = national.slice(trunk.length);\n\n // A number that already begins with its own country code and is\n // plausibly full-length is international-without-the-plus, not a\n // national number that happens to start with those digits.\n digits =\n national.startsWith(cc) && national.length >= MIN_E164_DIGITS + cc.length - 1 ? national : cc + national;\n }\n\n if (digits.length < MIN_E164_DIGITS || digits.length > MAX_E164_DIGITS) return null;\n // A leading zero after the country code means the trunk prefix survived.\n if (digits.startsWith('0')) return null;\n\n return `+${digits}`;\n}\n\n/**\n * Region implied by an E.164 number's calling code (longest match wins), or null.\n * `+1` resolves to US, which parses identically to CA.\n */\nexport function regionFromE164(e164: string | null | undefined): string | null {\n if (!e164 || !e164.startsWith('+')) return null;\n const digits = e164.slice(1);\n let best: { region: string; len: number } | null = null;\n for (const [region, cc] of Object.entries(CALLING_CODES)) {\n if (digits.startsWith(cc) && (!best || cc.length > best.len)) best = { region, len: cc.length };\n }\n return best?.region ?? null;\n}\n\n/**\n * Every distinct E.164 number a contact has, in address-book order.\n *\n * De-duplicated because the same person routinely appears with the same number\n * written two ways (\"+1 555…\" and \"(555) …\"), and matching the same number\n * twice would show them twice in the results.\n */\nexport function contactE164s(\n phoneNumbers: readonly string[],\n defaultRegion?: string | null | readonly (string | null | undefined)[],\n): string[] {\n // A number saved without a country code is ambiguous, so each candidate region\n // contributes an interpretation. The server only matches verified member numbers,\n // so extra candidates cannot produce a match that is not real.\n const regions = Array.isArray(defaultRegion) ? defaultRegion : [defaultRegion as string | null | undefined];\n const seen = new Set<string>();\n for (const raw of phoneNumbers) {\n for (const region of regions) {\n const e164 = toE164(raw, region);\n if (e164) seen.add(e164);\n }\n }\n return Array.from(seen);\n}\n\nexport interface NormalizedContact {\n /** The device's stable id, echoed back so a match can be re-attached. */\n id: string;\n displayName: string;\n imageUri?: string | null;\n /** Distinct E.164 candidates; never empty (contacts without any are dropped). */\n e164: string[];\n /** Numbers exactly as saved in the address book, for display and SMS. */\n rawNumbers?: string[];\n}\n\n/**\n * Normalise a whole address book, dropping anything unmatchable.\n *\n * Also drops the viewer's OWN number, so nobody is offered a chat with\n * themselves - which happens on essentially every real device, because people\n * save their own contact card.\n */\nexport function normalizeContacts(\n contacts: ReadonlyArray<{ id: string; displayName: string; phoneNumbers: string[]; imageUri?: string | null }>,\n defaultRegion?: string | null | readonly (string | null | undefined)[],\n viewerE164?: string | null,\n): NormalizedContact[] {\n const mine = new Set(viewerE164 ? contactE164s([viewerE164], defaultRegion) : []);\n const out: NormalizedContact[] = [];\n for (const c of contacts) {\n const e164 = contactE164s(c.phoneNumbers ?? [], defaultRegion);\n // Any interpretation equal to the viewer's own number means this is their own card.\n if (!e164.length || e164.some((n) => mine.has(n))) continue;\n out.push({\n id: c.id,\n displayName: c.displayName,\n imageUri: c.imageUri ?? null,\n e164,\n rawNumbers: (c.phoneNumbers ?? []).map((n) => n.trim()).filter(Boolean),\n });\n }\n return out;\n}\n\n/**\n * The full set of numbers to ask the server about, capped.\n *\n * Address books of several thousand entries are ordinary, and the cap keeps one\n * request from becoming megabytes. Callers page through the rest.\n */\nexport function collectLookupNumbers(contacts: readonly NormalizedContact[], limit = 1000): string[] {\n const seen = new Set<string>();\n for (const c of contacts) {\n for (const n of c.e164) {\n seen.add(n);\n if (seen.size >= limit) return Array.from(seen);\n }\n }\n return Array.from(seen);\n}\n\n/**\n * Format a phone number string (user input) to E.164 format.\n * Used by the registration screen to normalize phone input before verification.\n */\nexport function formatPhoneNumber(input: string, defaultRegion?: string): string | null {\n return toE164(input, defaultRegion);\n}\n\n/**\n * Validate if a phone number string is a valid E.164 number.\n * Returns true if the number can be normalized to E.164 format.\n */\nexport function isValidPhoneNumber(phoneNumber: string | null): boolean {\n if (!phoneNumber) return false;\n if (!phoneNumber.startsWith('+')) return false;\n const digits = phoneNumber.slice(1).replace(/\\D/g, '');\n return digits.length >= MIN_E164_DIGITS && digits.length <= MAX_E164_DIGITS;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"phoneNumbers.js","sources":["../../../src/features/messaging/phoneNumbers.ts"],"sourcesContent":["/**\n * Turning what the address book gives you into something matchable.\n *\n * This lives in the REMOTE, not the host, on purpose: it is pure logic with no\n * native dependency, it is where contact-matching actually goes wrong, and\n * keeping it here means a normalisation bug is a surface deploy rather than an\n * App Store release. The `contacts` seam hands over RAW strings plus a region\n * hint precisely so this can own the problem.\n *\n * Deliberately NOT libphonenumber. That library is ~500KB and every byte ships\n * in the remote bundle on every cold launch. What follows handles the cases\n * that actually occur in an address book; anything it cannot confidently place\n * is DROPPED rather than guessed, because a wrong match shows someone a\n * stranger's name attached to their friend's number, which is far worse than\n * simply not finding them.\n */\n\n/** National trunk prefixes stripped before applying a country code. */\nconst TRUNK_PREFIXES: Record<string, string> = {\n // The overwhelmingly common case: a single leading 0.\n DEFAULT: '0',\n // Italy is the notable exception - the leading 0 is part of the number.\n IT: '',\n};\n\n/** Country calling codes for the regions a device is likely to report. */\nconst CALLING_CODES: Record<string, string> = {\n US: '1',\n CA: '1',\n GB: '44',\n IE: '353',\n FR: '33',\n DE: '49',\n ES: '34',\n IT: '39',\n NL: '31',\n BE: '32',\n CH: '41',\n AT: '43',\n SE: '46',\n NO: '47',\n DK: '45',\n FI: '358',\n PL: '48',\n PT: '351',\n GR: '30',\n CZ: '420',\n RO: '40',\n HU: '36',\n UA: '380',\n RU: '7',\n TR: '90',\n IL: '972',\n AE: '971',\n SA: '966',\n QA: '974',\n KW: '965',\n IN: '91',\n PK: '92',\n BD: '880',\n LK: '94',\n NP: '977',\n CN: '86',\n JP: '81',\n KR: '82',\n TW: '886',\n HK: '852',\n SG: '65',\n MY: '60',\n TH: '66',\n VN: '84',\n PH: '63',\n ID: '62',\n AU: '61',\n NZ: '64',\n ZA: '27',\n NG: '234',\n KE: '254',\n EG: '20',\n GH: '233',\n BR: '55',\n MX: '52',\n AR: '54',\n CL: '56',\n CO: '57',\n PE: '51',\n};\n\n/** Longest calling code is 4 digits; shortest E.164 subscriber part is ~4. */\nconst MIN_E164_DIGITS = 7;\nconst MAX_E164_DIGITS = 15;\n\n/**\n * Normalise one raw address-book string to E.164 (`+<digits>`), or null.\n *\n * Returns null rather than a best guess whenever the result would be\n * speculative - see the file header for why a miss beats a wrong match.\n */\nexport function toE164(raw: string, defaultRegion?: string | null): string | null {\n if (typeof raw !== 'string') return null;\n\n // Strip everything a human might type: spaces, dashes, dots, parens,\n // and the invisible bidi marks iOS inserts around RTL-locale numbers.\n const cleaned = raw.replace(/[\\s\\-().‎‏؜]/g, '');\n if (!cleaned) return null;\n\n // Extensions are not diallable identity - \"555123456x89\" is one person.\n const withoutExt = cleaned.split(/[,;xX#]/)[0];\n if (!withoutExt) return null;\n\n let digits: string;\n if (withoutExt.startsWith('+')) {\n digits = withoutExt.slice(1).replace(/\\D/g, '');\n } else if (withoutExt.startsWith('00')) {\n // The international prefix used across most of Europe and Asia.\n digits = withoutExt.slice(2).replace(/\\D/g, '');\n } else {\n const region = (defaultRegion ?? '').toUpperCase();\n const cc = CALLING_CODES[region];\n // No region and no international prefix: the number is meaningless\n // without knowing where it was dialled from. Drop it.\n if (!cc) return null;\n\n let national = withoutExt.replace(/\\D/g, '');\n const trunk = region in TRUNK_PREFIXES ? TRUNK_PREFIXES[region] : TRUNK_PREFIXES.DEFAULT;\n if (trunk && national.startsWith(trunk)) national = national.slice(trunk.length);\n\n // A number that already begins with its own country code and is\n // plausibly full-length is international-without-the-plus, not a\n // national number that happens to start with those digits.\n digits =\n national.startsWith(cc) && national.length >= MIN_E164_DIGITS + cc.length - 1 ? national : cc + national;\n }\n\n if (digits.length < MIN_E164_DIGITS || digits.length > MAX_E164_DIGITS) return null;\n // A leading zero after the country code means the trunk prefix survived.\n if (digits.startsWith('0')) return null;\n\n return `+${digits}`;\n}\n\n/**\n * Region implied by an E.164 number's calling code (longest match wins), or null.\n * `+1` resolves to US, which parses identically to CA.\n */\nexport function regionFromE164(e164: string | null | undefined): string | null {\n if (!e164 || !e164.startsWith('+')) return null;\n const digits = e164.slice(1);\n let best: { region: string; len: number } | null = null;\n for (const [region, cc] of Object.entries(CALLING_CODES)) {\n if (digits.startsWith(cc) && (!best || cc.length > best.len)) best = { region, len: cc.length };\n }\n return best?.region ?? null;\n}\n\n/**\n * Every distinct E.164 number a contact has, in address-book order.\n *\n * De-duplicated because the same person routinely appears with the same number\n * written two ways (\"+1 555…\" and \"(555) …\"), and matching the same number\n * twice would show them twice in the results.\n */\nexport function contactE164s(\n phoneNumbers: readonly string[],\n defaultRegion?: string | null | readonly (string | null | undefined)[],\n): string[] {\n // A number saved without a country code is ambiguous, so each candidate region\n // contributes an interpretation. The server only matches verified member numbers,\n // so extra candidates cannot produce a match that is not real.\n const regions = Array.isArray(defaultRegion) ? defaultRegion : [defaultRegion as string | null | undefined];\n const seen = new Set<string>();\n for (const raw of phoneNumbers) {\n for (const region of regions) {\n const e164 = toE164(raw, region);\n if (e164) seen.add(e164);\n }\n }\n return Array.from(seen);\n}\n\nexport interface NormalizedContact {\n /** The device's stable id, echoed back so a match can be re-attached. */\n id: string;\n displayName: string;\n imageUri?: string | null;\n /** Distinct E.164 candidates; never empty (contacts without any are dropped). */\n e164: string[];\n /** Numbers exactly as saved in the address book, for display and SMS. */\n rawNumbers?: string[];\n}\n\n/**\n * Normalise a whole address book, dropping anything unmatchable.\n *\n * Also drops the viewer's OWN number, so nobody is offered a chat with\n * themselves - which happens on essentially every real device, because people\n * save their own contact card.\n */\nexport function normalizeContacts(\n contacts: ReadonlyArray<{ id: string; displayName: string; phoneNumbers: string[]; imageUri?: string | null }>,\n defaultRegion?: string | null | readonly (string | null | undefined)[],\n viewerE164?: string | null,\n): NormalizedContact[] {\n const mine = new Set(viewerE164 ? contactE164s([viewerE164], defaultRegion) : []);\n const out: NormalizedContact[] = [];\n for (const c of contacts) {\n const e164 = contactE164s(c.phoneNumbers ?? [], defaultRegion);\n // Any interpretation equal to the viewer's own number means this is their own card.\n if (!e164.length || e164.some((n) => mine.has(n))) continue;\n out.push({\n id: c.id,\n displayName: c.displayName,\n imageUri: c.imageUri ?? null,\n e164,\n rawNumbers: (c.phoneNumbers ?? []).map((n) => n.trim()).filter(Boolean),\n });\n }\n return out;\n}\n\n/**\n * The full set of numbers to ask the server about, capped.\n *\n * Address books of several thousand entries are ordinary, and the cap keeps one\n * request from becoming megabytes. Callers page through the rest.\n */\nexport function collectLookupNumbers(contacts: readonly NormalizedContact[], limit = 1000): string[] {\n const seen = new Set<string>();\n for (const c of contacts) {\n for (const n of c.e164) {\n seen.add(n);\n if (seen.size >= limit) return Array.from(seen);\n }\n }\n return Array.from(seen);\n}\n\n/**\n * Format a phone number string (user input) to E.164 format.\n * Used by the registration screen to normalize phone input before verification.\n */\nexport function formatPhoneNumber(input: string, defaultRegion?: string): string | null {\n return toE164(input, defaultRegion);\n}\n\n/**\n * Validate if a phone number string is a valid E.164 number.\n * Returns true if the number can be normalized to E.164 format.\n */\nexport function isValidPhoneNumber(phoneNumber: string | null): boolean {\n if (!phoneNumber) return false;\n if (!phoneNumber.startsWith('+')) return false;\n const digits = phoneNumber.slice(1).replace(/\\D/g, '');\n return digits.length >= MIN_E164_DIGITS && digits.length <= MAX_E164_DIGITS;\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ const K = new Uint32Array([1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, 2453635748, 2870763221, 3624381080, 310598401, 607225278, 1426881987, 1925078388, 2162078206, 2614888103, 3248222580, 3835390401, 4022224774, 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, 2554220882, 2821834349, 2952996808, 3210313671, 3336571891, 3584528711, 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, 1695183700, 1986661051, 2177026350, 2456956037, 2730485921, 2820302411, 3259730800, 3345764771, 3516065817, 3600352804, 4094571909, 275423344, 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, 1955562222, 2024104815, 2227730452, 2361852424, 2428436474, 2756734187, 3204031479, 3329325298]);
2
+ function utf8Bytes(str) {
3
+ const out = [];
4
+ for (let i = 0; i < str.length; i += 1) {
5
+ let c = str.charCodeAt(i);
6
+ if (c < 128) {
7
+ out.push(c);
8
+ } else if (c < 2048) {
9
+ out.push(192 | c >> 6, 128 | c & 63);
10
+ } else if (c >= 55296 && c <= 56319 && i + 1 < str.length) {
11
+ const lo = str.charCodeAt(i + 1);
12
+ c = 65536 + (c - 55296 << 10) + (lo - 56320);
13
+ i += 1;
14
+ out.push(240 | c >> 18, 128 | c >> 12 & 63, 128 | c >> 6 & 63, 128 | c & 63);
15
+ } else {
16
+ out.push(224 | c >> 12, 128 | c >> 6 & 63, 128 | c & 63);
17
+ }
18
+ }
19
+ return new Uint8Array(out);
20
+ }
21
+ const rotr = (x, n) => x >>> n | x << 32 - n;
22
+ function sha256(message) {
23
+ const bytes = utf8Bytes(message);
24
+ const bitLen = bytes.length * 8;
25
+ const padded = new Uint8Array((bytes.length + 8 >> 6) + 1 << 6);
26
+ padded.set(bytes);
27
+ padded[bytes.length] = 128;
28
+ const dv = new DataView(padded.buffer);
29
+ dv.setUint32(padded.length - 4, bitLen >>> 0, false);
30
+ const h = new Uint32Array([1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225]);
31
+ const w = new Uint32Array(64);
32
+ for (let off = 0; off < padded.length; off += 64) {
33
+ for (let i = 0; i < 16; i += 1) w[i] = dv.getUint32(off + i * 4, false);
34
+ for (let i = 16; i < 64; i += 1) {
35
+ const s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ w[i - 15] >>> 3;
36
+ const s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ w[i - 2] >>> 10;
37
+ w[i] = w[i - 16] + s0 + w[i - 7] + s1 >>> 0;
38
+ }
39
+ let [a, b, c, d, e, f, g, hh] = h;
40
+ for (let i = 0; i < 64; i += 1) {
41
+ const S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
42
+ const ch = e & f ^ ~e & g;
43
+ const t1 = hh + S1 + ch + K[i] + w[i] >>> 0;
44
+ const S0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
45
+ const maj = a & b ^ a & c ^ b & c;
46
+ const t2 = S0 + maj >>> 0;
47
+ hh = g;
48
+ g = f;
49
+ f = e;
50
+ e = d + t1 >>> 0;
51
+ d = c;
52
+ c = b;
53
+ b = a;
54
+ a = t1 + t2 >>> 0;
55
+ }
56
+ h[0] = h[0] + a >>> 0;
57
+ h[1] = h[1] + b >>> 0;
58
+ h[2] = h[2] + c >>> 0;
59
+ h[3] = h[3] + d >>> 0;
60
+ h[4] = h[4] + e >>> 0;
61
+ h[5] = h[5] + f >>> 0;
62
+ h[6] = h[6] + g >>> 0;
63
+ h[7] = h[7] + hh >>> 0;
64
+ }
65
+ let hex = "";
66
+ for (let i = 0; i < 8; i += 1) hex += h[i].toString(16).padStart(8, "0");
67
+ return hex;
68
+ }export{sha256};//# sourceMappingURL=sha256.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sha256.js","sources":["../../../src/features/messaging/sha256.ts"],"sourcesContent":["/**\n * SHA-256, in plain JavaScript.\n *\n * The chat remote hashes phone numbers before sending them, so the server never\n * receives a plaintext address book. It cannot use `node:crypto` (not in React\n * Native) and it cannot use `expo-crypto` (a native module - a federated remote\n * adds zero native code, and routing it through a host seam would mean an app\n * build every time the hashing changed). So: ~60 lines of arithmetic, no\n * dependency, fixable over the air.\n *\n * Speed is adequate for the job. A 2000-entry address book is ~2000 hashes of a\n * ~13-byte input, which is a single block each - milliseconds in total, done\n * once per contact sync rather than per render.\n *\n * `sha256.test.ts` checks it against the published NIST vectors AND against\n * Node's own crypto over a spread of inputs, because a subtly wrong hash here\n * would not crash - it would silently match nobody, which is the hardest kind\n * of bug to see.\n */\n\n/** First 32 bits of the fractional parts of the cube roots of the first 64 primes. */\nconst K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98,\n 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,\n 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8,\n 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,\n 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,\n 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,\n 0xc67178f2,\n]);\n\n/** UTF-8 bytes. Phone numbers are ASCII, but names and junk input may not be. */\nfunction utf8Bytes(str: string): Uint8Array {\n const out: number[] = [];\n for (let i = 0; i < str.length; i += 1) {\n let c = str.charCodeAt(i);\n if (c < 0x80) {\n out.push(c);\n } else if (c < 0x800) {\n out.push(0xc0 | (c >> 6), 0x80 | (c & 0x3f));\n } else if (c >= 0xd800 && c <= 0xdbff && i + 1 < str.length) {\n // Surrogate pair -> one code point.\n const lo = str.charCodeAt(i + 1);\n c = 0x10000 + ((c - 0xd800) << 10) + (lo - 0xdc00);\n i += 1;\n out.push(0xf0 | (c >> 18), 0x80 | ((c >> 12) & 0x3f), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f));\n } else {\n out.push(0xe0 | (c >> 12), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f));\n }\n }\n return new Uint8Array(out);\n}\n\nconst rotr = (x: number, n: number) => (x >>> n) | (x << (32 - n));\n\n/** Lowercase hex digest of the UTF-8 bytes of `message`. */\nexport function sha256(message: string): string {\n const bytes = utf8Bytes(message);\n const bitLen = bytes.length * 8;\n\n // Pad to a multiple of 64 bytes: 0x80, zeros, then the length as a 64-bit\n // big-endian integer.\n const padded = new Uint8Array((((bytes.length + 8) >> 6) + 1) << 6);\n padded.set(bytes);\n padded[bytes.length] = 0x80;\n // Lengths beyond 2^32 bits cannot occur here, so the high word stays zero.\n const dv = new DataView(padded.buffer);\n dv.setUint32(padded.length - 4, bitLen >>> 0, false);\n\n const h = new Uint32Array([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n ]);\n const w = new Uint32Array(64);\n\n for (let off = 0; off < padded.length; off += 64) {\n for (let i = 0; i < 16; i += 1) w[i] = dv.getUint32(off + i * 4, false);\n for (let i = 16; i < 64; i += 1) {\n const s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ (w[i - 15] >>> 3);\n const s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ (w[i - 2] >>> 10);\n w[i] = (w[i - 16] + s0 + w[i - 7] + s1) >>> 0;\n }\n\n let [a, b, c, d, e, f, g, hh] = h;\n for (let i = 0; i < 64; i += 1) {\n const S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);\n const ch = (e & f) ^ (~e & g);\n const t1 = (hh + S1 + ch + K[i] + w[i]) >>> 0;\n const S0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);\n const maj = (a & b) ^ (a & c) ^ (b & c);\n const t2 = (S0 + maj) >>> 0;\n hh = g;\n g = f;\n f = e;\n e = (d + t1) >>> 0;\n d = c;\n c = b;\n b = a;\n a = (t1 + t2) >>> 0;\n }\n h[0] = (h[0] + a) >>> 0;\n h[1] = (h[1] + b) >>> 0;\n h[2] = (h[2] + c) >>> 0;\n h[3] = (h[3] + d) >>> 0;\n h[4] = (h[4] + e) >>> 0;\n h[5] = (h[5] + f) >>> 0;\n h[6] = (h[6] + g) >>> 0;\n h[7] = (h[7] + hh) >>> 0;\n }\n\n let hex = '';\n for (let i = 0; i < 8; i += 1) hex += h[i].toString(16).padStart(8, '0');\n return hex;\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,421 @@
1
+ import*as React from'react';import {CHANNELS_QUERY,MESSAGE_ADDED_SUBSCRIPTION_WS,CREATE_DIRECT_CHANNEL_MUTATION,MESSAGES_QUERY,SEND_MESSAGE_MUTATION,REACTION_CHANGED_SUBSCRIPTION_WS,SET_MESSAGE_REACTION_MUTATION,VIEW_CHANNEL_MUTATION}from'./chatOperations.js';import {mergeConversations,toConversation,patchConversationAfterPost,sortConversations,mergeMessages,toChatMessage,reconcileOptimistic,applyReactionSummary,withViewerReaction}from'./chatModel.js';import {NATIVE_CHAT_CHANNELS_QUERY_VARS,isNativeMessengerChannel,NATIVE_CHAT_LIST_PAGE_SIZE,isMongoAccountId}from'./nativeChatChannelQuery.js';var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ const PAGE_SIZE = 20;
21
+ function firstErrorMessage(errors) {
22
+ if (!(errors == null ? void 0 : errors.length)) return null;
23
+ const raw = errors[0].message || "Something went wrong.";
24
+ if (/Cannot return null for non-nullable field Channel\.id/i.test(raw)) return null;
25
+ if (/status code 400/i.test(raw)) return "Could not load messages for this chat.";
26
+ if (/status code 401/i.test(raw) || /status code 403/i.test(raw)) return "You do not have access to this conversation.";
27
+ return raw;
28
+ }
29
+ function sortChannelsByRecentActivity(rows) {
30
+ return [...rows].sort((left, right) => {
31
+ const leftTime = left.lastPostAt ? new Date(left.lastPostAt).getTime() : 0;
32
+ const rightTime = right.lastPostAt ? new Date(right.lastPostAt).getTime() : 0;
33
+ return rightTime - leftTime;
34
+ });
35
+ }
36
+ function useConversations(services, viewer, opts) {
37
+ var _a;
38
+ const {
39
+ gql
40
+ } = services;
41
+ const [conversations, setConversations] = React.useState([]);
42
+ const [loading, setLoading] = React.useState(true);
43
+ const [refreshing, setRefreshing] = React.useState(false);
44
+ const [error, setError] = React.useState(null);
45
+ const [hasMore, setHasMore] = React.useState(false);
46
+ const [loadingMore, setLoadingMore] = React.useState(false);
47
+ const viewerId = (_a = viewer == null ? void 0 : viewer.userId) != null ? _a : null;
48
+ const mounted = React.useRef(true);
49
+ const conversationsRef = React.useRef([]);
50
+ const serverOffset = React.useRef(0);
51
+ React.useEffect(() => {
52
+ conversationsRef.current = conversations;
53
+ }, [conversations]);
54
+ const listQueryEnabled = (opts == null ? void 0 : opts.listQueryEnabled) !== false;
55
+ const load = React.useCallback(async (mode) => {
56
+ var _a2, _b, _c, _d;
57
+ if (!viewerId || !listQueryEnabled) return;
58
+ if (mode === "refresh") setRefreshing(true);
59
+ if (mode === "initial") {
60
+ const cached = await gql.query(CHANNELS_QUERY, NATIVE_CHAT_CHANNELS_QUERY_VARS, {
61
+ fetchPolicy: "cache-only"
62
+ });
63
+ const cachedRows = ((_b = (_a2 = cached.data) == null ? void 0 : _a2.channelsByUser) != null ? _b : []).filter(Boolean).filter(isNativeMessengerChannel);
64
+ if (mounted.current && cachedRows.length) {
65
+ setConversations(mergeConversations([], sortChannelsByRecentActivity(cachedRows).map((c) => toConversation(c, viewerId))));
66
+ setLoading(false);
67
+ }
68
+ }
69
+ const res = await gql.query(
70
+ CHANNELS_QUERY,
71
+ NATIVE_CHAT_CHANNELS_QUERY_VARS,
72
+ // network-only: a stale conversation list is the single most
73
+ // visible staleness in a chat app, and this is one small page.
74
+ {
75
+ fetchPolicy: "network-only"
76
+ }
77
+ );
78
+ if (!mounted.current) return;
79
+ const message = firstErrorMessage(res.errors);
80
+ const raw = ((_d = (_c = res.data) == null ? void 0 : _c.channelsByUser) != null ? _d : []).filter(Boolean);
81
+ const rows = raw.filter(isNativeMessengerChannel);
82
+ if (rows.length || !message) {
83
+ setConversations(mergeConversations([], sortChannelsByRecentActivity(rows).map((c) => toConversation(c, viewerId))));
84
+ serverOffset.current = raw.length;
85
+ setHasMore(raw.length >= NATIVE_CHAT_LIST_PAGE_SIZE);
86
+ }
87
+ setError(message);
88
+ setLoading(false);
89
+ setRefreshing(false);
90
+ }, [gql, viewerId, listQueryEnabled]);
91
+ const loadMore = React.useCallback(async () => {
92
+ var _a2, _b;
93
+ if (!viewerId || !listQueryEnabled || !hasMore || loadingMore || loading) return;
94
+ setLoadingMore(true);
95
+ const res = await gql.query(CHANNELS_QUERY, __spreadProps(__spreadValues({}, NATIVE_CHAT_CHANNELS_QUERY_VARS), {
96
+ skip: serverOffset.current
97
+ }), {
98
+ fetchPolicy: "network-only"
99
+ });
100
+ if (!mounted.current) return;
101
+ const message = firstErrorMessage(res.errors);
102
+ const raw = ((_b = (_a2 = res.data) == null ? void 0 : _a2.channelsByUser) != null ? _b : []).filter(Boolean);
103
+ const rows = raw.filter(isNativeMessengerChannel);
104
+ if (rows.length) {
105
+ setConversations((prev) => mergeConversations(prev, rows.map((c) => toConversation(c, viewerId))));
106
+ }
107
+ if (!message) {
108
+ serverOffset.current += raw.length;
109
+ setHasMore(raw.length >= NATIVE_CHAT_LIST_PAGE_SIZE);
110
+ }
111
+ setError(message);
112
+ setLoadingMore(false);
113
+ }, [gql, viewerId, listQueryEnabled, hasMore, loadingMore, loading]);
114
+ React.useEffect(() => {
115
+ if (!listQueryEnabled) {
116
+ setLoading(true);
117
+ return;
118
+ }
119
+ void load("initial");
120
+ }, [load, listQueryEnabled]);
121
+ React.useEffect(() => {
122
+ if (gql.reconnectEpoch > 0) void load("refresh");
123
+ }, [gql.reconnectEpoch]);
124
+ const markRead = React.useCallback((channelId) => {
125
+ setConversations((prev) => prev.map((c) => c.id === channelId ? __spreadProps(__spreadValues({}, c), {
126
+ unreadCount: 0
127
+ }) : c));
128
+ }, []);
129
+ const applyConversationMessage = React.useCallback((channelId, post) => {
130
+ if (!viewerId) return;
131
+ setConversations((prev) => {
132
+ const idx = prev.findIndex((c) => c.id === channelId);
133
+ if (idx < 0) return prev;
134
+ const updated = patchConversationAfterPost(prev[idx], post, viewerId);
135
+ const rest = prev.filter((c) => c.id !== channelId);
136
+ return sortConversations([updated, ...rest]);
137
+ });
138
+ }, [viewerId]);
139
+ const listSyncKey = (opts == null ? void 0 : opts.syncListRealtime) ? conversations.map((c) => c.id).slice(0, 12).join("|") : "";
140
+ React.useEffect(() => {
141
+ if (!(opts == null ? void 0 : opts.syncListRealtime) || !viewerId || !listSyncKey) return void 0;
142
+ const channelIds = listSyncKey.split("|").filter(Boolean);
143
+ const unsubs = channelIds.map((channelId) => gql.subscribe(MESSAGE_ADDED_SUBSCRIPTION_WS, {
144
+ channelId
145
+ }, {
146
+ next: (data) => {
147
+ var _a2;
148
+ const post = data == null ? void 0 : data.chatMessageAdded;
149
+ if (!post || !mounted.current) return;
150
+ applyConversationMessage(channelId, post);
151
+ (_a2 = gql.patchChannelListAfterMessage) == null ? void 0 : _a2.call(gql, channelId, post);
152
+ }
153
+ }));
154
+ return () => {
155
+ unsubs.forEach((off) => off());
156
+ };
157
+ }, [gql, viewerId, listSyncKey, opts == null ? void 0 : opts.syncListRealtime, applyConversationMessage]);
158
+ React.useEffect(() => {
159
+ mounted.current = true;
160
+ return () => {
161
+ mounted.current = false;
162
+ };
163
+ }, []);
164
+ const findExistingDirect = React.useCallback((peerUserId, peerName) => {
165
+ const peerKey = String(peerUserId);
166
+ const nameKey = peerName.trim().toLowerCase();
167
+ return conversationsRef.current.find((c) => {
168
+ var _a2, _b;
169
+ return c.isDirect && (((_a2 = c.peer) == null ? void 0 : _a2.id) && String(c.peer.id) === peerKey || !((_b = c.peer) == null ? void 0 : _b.id) && c.title.trim().toLowerCase() === nameKey);
170
+ });
171
+ }, []);
172
+ const openDirect = React.useCallback(async (peerUserId, peerName) => {
173
+ var _a2;
174
+ if (!isMongoAccountId(peerUserId) || peerUserId === viewerId) return null;
175
+ const existing = findExistingDirect(peerUserId, peerName);
176
+ if (existing) return existing.id;
177
+ const res = await gql.mutate(CREATE_DIRECT_CHANNEL_MUTATION, {
178
+ receiver: [peerUserId],
179
+ displayName: peerName
180
+ });
181
+ const message = firstErrorMessage(res.errors);
182
+ if (message) {
183
+ setError(message);
184
+ return null;
185
+ }
186
+ const channel = (_a2 = res.data) == null ? void 0 : _a2.createDirectChannel;
187
+ if (!(channel == null ? void 0 : channel.id) || !viewerId) {
188
+ setError("Could not start this conversation. Please try again.");
189
+ return null;
190
+ }
191
+ setConversations((prev) => mergeConversations(prev, [toConversation(channel, viewerId)]));
192
+ return String(channel.id);
193
+ }, [gql, viewerId, findExistingDirect]);
194
+ return {
195
+ conversations,
196
+ loading,
197
+ error,
198
+ refreshing,
199
+ refresh: () => void load("refresh"),
200
+ hasMore,
201
+ loadingMore,
202
+ loadMore: () => void loadMore(),
203
+ markRead,
204
+ applyConversationMessage,
205
+ openDirect
206
+ };
207
+ }
208
+ function useThread(gql, channelId, viewer, opts) {
209
+ var _a;
210
+ const [messages, setMessages] = React.useState([]);
211
+ const [loading, setLoading] = React.useState(true);
212
+ const [loadingMore, setLoadingMore] = React.useState(false);
213
+ const [hasMore, setHasMore] = React.useState(true);
214
+ const [error, setError] = React.useState(null);
215
+ const viewerId = (_a = viewer == null ? void 0 : viewer.userId) != null ? _a : null;
216
+ const mounted = React.useRef(true);
217
+ const pending = React.useRef(/* @__PURE__ */ new Map());
218
+ const onConversationMessage = opts == null ? void 0 : opts.onConversationMessage;
219
+ const notifyList = React.useCallback((post) => {
220
+ var _a2;
221
+ if (!channelId) return;
222
+ onConversationMessage == null ? void 0 : onConversationMessage(post);
223
+ (_a2 = gql.patchChannelListAfterMessage) == null ? void 0 : _a2.call(gql, channelId, post);
224
+ }, [channelId, gql, onConversationMessage]);
225
+ React.useEffect(() => {
226
+ mounted.current = true;
227
+ return () => {
228
+ mounted.current = false;
229
+ };
230
+ }, []);
231
+ const fetchPage = React.useCallback(async (skip) => {
232
+ var _a2, _b, _c, _d, _e;
233
+ if (!channelId || !viewerId) return;
234
+ const res = await gql.query(MESSAGES_QUERY, {
235
+ channelId,
236
+ limit: PAGE_SIZE,
237
+ skip
238
+ }, {
239
+ fetchPolicy: "network-only"
240
+ });
241
+ if (!mounted.current) return;
242
+ const rows = ((_c = (_b = (_a2 = res.data) == null ? void 0 : _a2.messages) == null ? void 0 : _b.data) != null ? _c : []).filter(Boolean);
243
+ setMessages((prev) => mergeMessages(prev, rows.map((p) => toChatMessage(p, viewerId))));
244
+ const total = (_e = (_d = res.data) == null ? void 0 : _d.messages) == null ? void 0 : _e.totalCount;
245
+ setHasMore(typeof total === "number" ? skip + rows.length < total : rows.length >= PAGE_SIZE);
246
+ setError(firstErrorMessage(res.errors));
247
+ setLoading(false);
248
+ setLoadingMore(false);
249
+ }, [gql, channelId, viewerId]);
250
+ React.useEffect(() => {
251
+ let cancelled = false;
252
+ setMessages([]);
253
+ setHasMore(true);
254
+ setLoading(true);
255
+ pending.current.clear();
256
+ if (channelId && viewerId) {
257
+ void gql.query(MESSAGES_QUERY, {
258
+ channelId,
259
+ limit: PAGE_SIZE,
260
+ skip: 0
261
+ }, {
262
+ fetchPolicy: "cache-only"
263
+ }).then((cached) => {
264
+ var _a2, _b, _c;
265
+ const rows = ((_c = (_b = (_a2 = cached.data) == null ? void 0 : _a2.messages) == null ? void 0 : _b.data) != null ? _c : []).filter(Boolean);
266
+ if (cancelled || !mounted.current || !rows.length) return;
267
+ setMessages((prev) => prev.length ? prev : mergeMessages([], rows.map((p) => toChatMessage(p, viewerId))));
268
+ setLoading(false);
269
+ });
270
+ }
271
+ void fetchPage(0);
272
+ return () => {
273
+ cancelled = true;
274
+ };
275
+ }, [fetchPage, gql, channelId, viewerId]);
276
+ React.useEffect(() => {
277
+ if (gql.reconnectEpoch > 0) void fetchPage(0);
278
+ }, [gql.reconnectEpoch]);
279
+ React.useEffect(() => {
280
+ if (!channelId || !viewerId) return void 0;
281
+ return gql.subscribe(MESSAGE_ADDED_SUBSCRIPTION_WS, {
282
+ channelId
283
+ }, {
284
+ next: (data) => {
285
+ const post = data == null ? void 0 : data.chatMessageAdded;
286
+ if (!post || !mounted.current) return;
287
+ const incoming = toChatMessage(post, viewerId);
288
+ setMessages((prev) => reconcileOptimistic(prev, incoming));
289
+ notifyList(post);
290
+ },
291
+ error: (err) => mounted.current && setError(err.message)
292
+ });
293
+ }, [gql, channelId, viewerId, notifyList]);
294
+ const send = React.useCallback(async (body) => {
295
+ var _a2, _b, _c;
296
+ const text = body.trim();
297
+ if (!text || !channelId || !viewerId) return;
298
+ const clientId = `pending-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
299
+ const optimistic = {
300
+ id: clientId,
301
+ body: text,
302
+ createdAt: Date.now(),
303
+ authorId: viewerId,
304
+ authorName: (_a2 = viewer == null ? void 0 : viewer.displayName) != null ? _a2 : "You",
305
+ authorAvatar: (_b = viewer == null ? void 0 : viewer.avatarUrl) != null ? _b : null,
306
+ isMine: true,
307
+ isDeleted: false,
308
+ isEdited: false,
309
+ attachments: [],
310
+ reactions: [],
311
+ sendState: "sending"
312
+ };
313
+ pending.current.set(clientId, text);
314
+ setMessages((prev) => mergeMessages(prev, [optimistic]));
315
+ onConversationMessage == null ? void 0 : onConversationMessage({
316
+ id: clientId,
317
+ message: text,
318
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
319
+ creator: {
320
+ id: viewerId
321
+ }
322
+ });
323
+ const res = await gql.mutate(SEND_MESSAGE_MUTATION, {
324
+ channelId,
325
+ messageInput: {
326
+ content: text
327
+ }
328
+ });
329
+ if (!mounted.current) return;
330
+ const message = firstErrorMessage(res.errors);
331
+ const saved = (_c = res.data) == null ? void 0 : _c.sendMessage;
332
+ if (message || !saved) {
333
+ setMessages((prev) => prev.map((m) => m.id === clientId ? __spreadProps(__spreadValues({}, m), {
334
+ sendState: "failed"
335
+ }) : m));
336
+ setError(message);
337
+ return;
338
+ }
339
+ pending.current.delete(clientId);
340
+ setMessages((prev) => reconcileOptimistic(prev, toChatMessage(saved, viewerId)));
341
+ notifyList(saved);
342
+ }, [gql, channelId, viewerId, viewer, notifyList, onConversationMessage]);
343
+ const retry = React.useCallback((messageId) => {
344
+ const body = pending.current.get(messageId);
345
+ if (!body) return;
346
+ pending.current.delete(messageId);
347
+ setMessages((prev) => prev.filter((m) => m.id !== messageId));
348
+ void send(body);
349
+ }, [send]);
350
+ const loadMore = React.useCallback(() => {
351
+ if (loadingMore || !hasMore || loading) return;
352
+ setLoadingMore(true);
353
+ void fetchPage(messages.filter((m) => !m.sendState || m.sendState === "sent").length);
354
+ }, [fetchPage, loadingMore, hasMore, loading, messages]);
355
+ React.useEffect(() => {
356
+ if (!channelId || !viewerId) return void 0;
357
+ return gql.subscribe(REACTION_CHANGED_SUBSCRIPTION_WS, {
358
+ channelId
359
+ }, {
360
+ next: (data) => {
361
+ const event = data == null ? void 0 : data.chatReactionChanged;
362
+ if (!(event == null ? void 0 : event.postId) || !mounted.current) return;
363
+ setMessages((prev) => applyReactionSummary(prev, String(event.postId), event.reactions, viewerId));
364
+ }
365
+ });
366
+ }, [gql, channelId, viewerId]);
367
+ const messagesRef = React.useRef(messages);
368
+ messagesRef.current = messages;
369
+ const react = React.useCallback((messageId, emoji) => {
370
+ var _a2, _b;
371
+ if (!channelId || !viewerId) return;
372
+ const target = messagesRef.current.find((m) => m.id === messageId);
373
+ if (!target || target.sendState && target.sendState !== "sent") return;
374
+ const before = target.reactions;
375
+ const after = withViewerReaction(before, emoji, viewerId);
376
+ const next = (_b = (_a2 = after.find((r) => r.mine)) == null ? void 0 : _a2.reaction) != null ? _b : null;
377
+ setMessages((prev) => prev.map((m) => m.id === messageId ? __spreadProps(__spreadValues({}, m), {
378
+ reactions: after
379
+ }) : m));
380
+ void (async () => {
381
+ var _a3, _b2, _c;
382
+ const res = await gql.mutate(SET_MESSAGE_REACTION_MUTATION, {
383
+ channelId,
384
+ postId: messageId,
385
+ reaction: next
386
+ });
387
+ if (!mounted.current) return;
388
+ if (((_a3 = res.errors) == null ? void 0 : _a3.length) || !((_b2 = res.data) == null ? void 0 : _b2.setMessageReaction)) {
389
+ setMessages((prev) => prev.map((m) => m.id === messageId ? __spreadProps(__spreadValues({}, m), {
390
+ reactions: before
391
+ }) : m));
392
+ setError((_c = firstErrorMessage(res.errors)) != null ? _c : "Could not update the reaction.");
393
+ return;
394
+ }
395
+ setMessages((prev) => {
396
+ var _a4;
397
+ return applyReactionSummary(prev, messageId, (_a4 = res.data) == null ? void 0 : _a4.setMessageReaction, viewerId);
398
+ });
399
+ })();
400
+ }, [gql, channelId, viewerId]);
401
+ return {
402
+ messages,
403
+ loading,
404
+ loadingMore,
405
+ hasMore,
406
+ error,
407
+ send,
408
+ loadMore,
409
+ retry,
410
+ react
411
+ };
412
+ }
413
+ function useMarkRead(gql, channelId, onMarked) {
414
+ React.useEffect(() => {
415
+ if (!channelId) return;
416
+ onMarked(channelId);
417
+ void gql.mutate(VIEW_CHANNEL_MUTATION, {
418
+ id: channelId
419
+ });
420
+ }, [channelId]);
421
+ }export{useConversations,useMarkRead,useThread};//# sourceMappingURL=useChatData.js.map