@adminide-stack/yantra-mobile 12.0.69-alpha.9 → 12.0.69
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.
- package/lib/components/GatewayConnector/GatewayConnector.js +2 -2
- package/lib/components/GatewayConnector/GatewayConnector.js.map +1 -1
- package/lib/components/KeyboardComposerDock.js +8 -1
- package/lib/components/KeyboardComposerDock.js.map +1 -1
- package/lib/components/NavigationHeader/NavigationHeader.js +2 -2
- package/lib/components/NavigationHeader/NavigationHeader.js.map +1 -1
- package/lib/config/env-config.js +4 -0
- package/lib/config/env-config.js.map +1 -1
- package/lib/contexts/ChatLiveStreamContext.js +4 -1
- package/lib/contexts/ChatLiveStreamContext.js.map +1 -1
- package/lib/features/agent-chat/NativeAgentChat.js +2 -0
- package/lib/features/agent-chat/NativeAgentChat.js.map +1 -1
- package/lib/features/apps/AppsCatalog.js +2 -2
- package/lib/features/apps/AppsCatalog.js.map +1 -1
- package/lib/features/audio-input/MicErrorBoundary.js +2 -2
- package/lib/features/audio-input/MicErrorBoundary.js.map +1 -1
- package/lib/features/canvas/AudioEditorExperience.js +308 -0
- package/lib/features/canvas/AudioEditorExperience.js.map +1 -0
- package/lib/features/canvas/CanvasAgentChatPane.js +310 -0
- package/lib/features/canvas/CanvasAgentChatPane.js.map +1 -0
- package/lib/features/canvas/CanvasBoardsGrid.js +414 -0
- package/lib/features/canvas/CanvasBoardsGrid.js.map +1 -0
- package/lib/features/canvas/CanvasChatResultCard.js +113 -0
- package/lib/features/canvas/CanvasChatResultCard.js.map +1 -0
- package/lib/features/canvas/CanvasEditToolsPanel.js +179 -0
- package/lib/features/canvas/CanvasEditToolsPanel.js.map +1 -0
- package/lib/features/canvas/CanvasExperience.js +859 -0
- package/lib/features/canvas/CanvasExperience.js.map +1 -0
- package/lib/features/canvas/CanvasGeneratePanel.js +514 -0
- package/lib/features/canvas/CanvasGeneratePanel.js.map +1 -0
- package/lib/features/canvas/CanvasLibrarySheet.js +355 -0
- package/lib/features/canvas/CanvasLibrarySheet.js.map +1 -0
- package/lib/features/canvas/CanvasLooksPanel.js +184 -0
- package/lib/features/canvas/CanvasLooksPanel.js.map +1 -0
- package/lib/features/canvas/CanvasTasksPanel.js +138 -0
- package/lib/features/canvas/CanvasTasksPanel.js.map +1 -0
- package/lib/features/canvas/CanvasTemplatesPanel.js +226 -0
- package/lib/features/canvas/CanvasTemplatesPanel.js.map +1 -0
- package/lib/features/canvas/CanvasToolDock.js +423 -0
- package/lib/features/canvas/CanvasToolDock.js.map +1 -0
- package/lib/features/canvas/FrameExtractorExperience.js +242 -0
- package/lib/features/canvas/FrameExtractorExperience.js.map +1 -0
- package/lib/features/canvas/ImageEditorExperience.js +491 -0
- package/lib/features/canvas/ImageEditorExperience.js.map +1 -0
- package/lib/features/canvas/InfluencerStudioExperience.js +288 -0
- package/lib/features/canvas/InfluencerStudioExperience.js.map +1 -0
- package/lib/features/canvas/MoodboardExperience.js +205 -0
- package/lib/features/canvas/MoodboardExperience.js.map +1 -0
- package/lib/features/canvas/NativeCanvasViewer.js +929 -0
- package/lib/features/canvas/NativeCanvasViewer.js.map +1 -0
- package/lib/features/canvas/PromoContextFields.js +150 -0
- package/lib/features/canvas/PromoContextFields.js.map +1 -0
- package/lib/features/canvas/SetStudioExperience.js +323 -0
- package/lib/features/canvas/SetStudioExperience.js.map +1 -0
- package/lib/features/canvas/VideoClipsExperience.js +175 -0
- package/lib/features/canvas/VideoClipsExperience.js.map +1 -0
- package/lib/features/canvas/VideoEditExperience.js +824 -0
- package/lib/features/canvas/VideoEditExperience.js.map +1 -0
- package/lib/features/canvas/VideoEditorExperience.js +3050 -0
- package/lib/features/canvas/VideoEditorExperience.js.map +1 -0
- package/lib/features/canvas/VideoGeneratorExperience.js +415 -0
- package/lib/features/canvas/VideoGeneratorExperience.js.map +1 -0
- package/lib/features/canvas/aiEdit.js +53 -0
- package/lib/features/canvas/aiEdit.js.map +1 -0
- package/lib/features/canvas/canvasAgentChat.js +76 -0
- package/lib/features/canvas/canvasAgentChat.js.map +1 -0
- package/lib/features/canvas/canvasBoardsCatalog.js +59 -0
- package/lib/features/canvas/canvasBoardsCatalog.js.map +1 -0
- package/lib/features/canvas/canvasBoardsSnapshot.js +14 -1
- package/lib/features/canvas/canvasBoardsSnapshot.js.map +1 -1
- package/lib/features/canvas/canvasChatDisplay.js +38 -0
- package/lib/features/canvas/canvasChatDisplay.js.map +1 -0
- package/lib/features/canvas/canvasChatTemplates.js +219 -0
- package/lib/features/canvas/canvasChatTemplates.js.map +1 -0
- package/lib/features/canvas/canvasCore.js +138 -1
- package/lib/features/canvas/canvasCore.js.map +1 -1
- package/lib/features/canvas/canvasEditOps.js +224 -0
- package/lib/features/canvas/canvasEditOps.js.map +1 -0
- package/lib/features/canvas/canvasTasks.js +187 -0
- package/lib/features/canvas/canvasTasks.js.map +1 -0
- package/lib/features/canvas/designPromptTemplates.js +3084 -0
- package/lib/features/canvas/designPromptTemplates.js.map +1 -0
- package/lib/features/canvas/editTools.js +54 -0
- package/lib/features/canvas/editTools.js.map +1 -0
- package/lib/features/canvas/extendVideo.js +5 -0
- package/lib/features/canvas/extendVideo.js.map +1 -0
- package/lib/features/canvas/frameExtract.js +33 -0
- package/lib/features/canvas/frameExtract.js.map +1 -0
- package/lib/features/canvas/generationModels.js +201 -0
- package/lib/features/canvas/generationModels.js.map +1 -0
- package/lib/features/canvas/influencer/influencerPipeline.js +170 -0
- package/lib/features/canvas/influencer/influencerPipeline.js.map +1 -0
- package/lib/features/canvas/influencer/productReel.js +72 -0
- package/lib/features/canvas/influencer/productReel.js.map +1 -0
- package/lib/features/canvas/influencer/reelPlan.js +159 -0
- package/lib/features/canvas/influencer/reelPlan.js.map +1 -0
- package/lib/features/canvas/moodboardCore.js +13 -0
- package/lib/features/canvas/moodboardCore.js.map +1 -0
- package/lib/features/canvas/promoProjectImport.js +99 -0
- package/lib/features/canvas/promoProjectImport.js.map +1 -0
- package/lib/features/canvas/promoVideo.js +312 -0
- package/lib/features/canvas/promoVideo.js.map +1 -0
- package/lib/features/canvas/recorder/CameraRecorderExperience.js +109 -0
- package/lib/features/canvas/recorder/CameraRecorderExperience.js.map +1 -0
- package/lib/features/canvas/sessionIdentity.js +28 -1
- package/lib/features/canvas/sessionIdentity.js.map +1 -1
- package/lib/features/canvas/set/SetViewportWebView.js +133 -0
- package/lib/features/canvas/set/SetViewportWebView.js.map +1 -0
- package/lib/features/canvas/set/cameraPath.js +194 -0
- package/lib/features/canvas/set/cameraPath.js.map +1 -0
- package/lib/features/canvas/set/setProject.js +24 -0
- package/lib/features/canvas/set/setProject.js.map +1 -0
- package/lib/features/canvas/storageLibrary.js +184 -0
- package/lib/features/canvas/storageLibrary.js.map +1 -0
- package/lib/features/canvas/studioCatalog.js +129 -0
- package/lib/features/canvas/studioCatalog.js.map +1 -0
- package/lib/features/canvas/studioLooks.js +189 -0
- package/lib/features/canvas/studioLooks.js.map +1 -0
- package/lib/features/canvas/surfaceIndex.js +63 -1
- package/lib/features/canvas/surfaceIndex.js.map +1 -1
- package/lib/features/canvas/templateImport/invideoNative.js +221 -0
- package/lib/features/canvas/templateImport/invideoNative.js.map +1 -0
- package/lib/features/canvas/templateImport/loadTemplate.js +43 -0
- package/lib/features/canvas/templateImport/loadTemplate.js.map +1 -0
- package/lib/features/canvas/templateImport/renderConfig.js +93 -0
- package/lib/features/canvas/templateImport/renderConfig.js.map +1 -0
- package/lib/features/canvas/useStudioCatalogTemplates.js +134 -0
- package/lib/features/canvas/useStudioCatalogTemplates.js.map +1 -0
- package/lib/features/canvas/video3d.js +109 -0
- package/lib/features/canvas/video3d.js.map +1 -0
- package/lib/features/canvas/videoClips.js +42 -0
- package/lib/features/canvas/videoClips.js.map +1 -0
- package/lib/features/canvas/videoEditor/agent/AgentCutPane.js +120 -0
- package/lib/features/canvas/videoEditor/agent/AgentCutPane.js.map +1 -0
- package/lib/features/canvas/videoEditor/agent/agentLoop.js +69 -0
- package/lib/features/canvas/videoEditor/agent/agentLoop.js.map +1 -0
- package/lib/features/canvas/videoEditor/agent/brainClient.js +45 -0
- package/lib/features/canvas/videoEditor/agent/brainClient.js.map +1 -0
- package/lib/features/canvas/videoEditor/agent/cutTools.js +129 -0
- package/lib/features/canvas/videoEditor/agent/cutTools.js.map +1 -0
- package/lib/features/canvas/videoEditor/editorModel.js +346 -0
- package/lib/features/canvas/videoEditor/editorModel.js.map +1 -0
- package/lib/features/canvas/videoEditor/exportRenderer.js +214 -0
- package/lib/features/canvas/videoEditor/exportRenderer.js.map +1 -0
- package/lib/features/canvas/videoEditor/filters.js +41 -0
- package/lib/features/canvas/videoEditor/filters.js.map +1 -0
- package/lib/features/canvas/videoEditor/mediaActions.js +57 -0
- package/lib/features/canvas/videoEditor/mediaActions.js.map +1 -0
- package/lib/features/canvas/videoEditor/remoteMediaClient.js +129 -0
- package/lib/features/canvas/videoEditor/remoteMediaClient.js.map +1 -0
- package/lib/features/canvas/videoEditor/solidColorPng.js +115 -0
- package/lib/features/canvas/videoEditor/solidColorPng.js.map +1 -0
- package/lib/features/canvas/videoEditor/videoEditOps.js +191 -0
- package/lib/features/canvas/videoEditor/videoEditOps.js.map +1 -0
- package/lib/features/canvas/videoEditor/videoProjectsStore.js +82 -0
- package/lib/features/canvas/videoEditor/videoProjectsStore.js.map +1 -0
- package/lib/features/canvas/videoRenderer.js +8 -0
- package/lib/features/canvas/videoRenderer.js.map +1 -0
- package/lib/features/canvas/withRemoteSafeArea.js +2 -2
- package/lib/features/canvas/withRemoteSafeArea.js.map +1 -1
- package/lib/features/characters/characterStudioProps.js +14 -0
- package/lib/features/characters/characterStudioProps.js.map +1 -0
- package/lib/features/chat/ChatCodeBlock.js +7 -3
- package/lib/features/chat/ChatCodeBlock.js.map +1 -1
- package/lib/features/chat/ChatTranscript.js +7 -3
- package/lib/features/chat/ChatTranscript.js.map +1 -1
- package/lib/features/chat/ChatWidgetCard.js +13 -0
- package/lib/features/chat/ChatWidgetCard.js.map +1 -0
- package/lib/features/chat/ConnectorConnectCard.js +164 -0
- package/lib/features/chat/ConnectorConnectCard.js.map +1 -0
- package/lib/features/chat/ConnectorConnectPrompt.js +254 -0
- package/lib/features/chat/ConnectorConnectPrompt.js.map +1 -0
- package/lib/features/chat/MessageActionBar.js.map +1 -1
- package/lib/features/chat/QueuedFollowUps.js +71 -0
- package/lib/features/chat/QueuedFollowUps.js.map +1 -0
- package/lib/features/chat/chatWidgets.js +37 -0
- package/lib/features/chat/chatWidgets.js.map +1 -0
- package/lib/features/chat/connectorConnect.js +179 -0
- package/lib/features/chat/connectorConnect.js.map +1 -0
- package/lib/features/chat/connectorConnectHandbacks.js +55 -0
- package/lib/features/chat/connectorConnectHandbacks.js.map +1 -0
- package/lib/features/design/DesignEditorExperience.js +643 -0
- package/lib/features/design/DesignEditorExperience.js.map +1 -0
- package/lib/features/design/DesignExperience.js +444 -0
- package/lib/features/design/DesignExperience.js.map +1 -0
- package/lib/features/design/designCore.js +298 -0
- package/lib/features/design/designCore.js.map +1 -0
- package/lib/features/design/designIndex.js +150 -0
- package/lib/features/design/designIndex.js.map +1 -0
- package/lib/features/design/exportDesign.js +133 -0
- package/lib/features/design/exportDesign.js.map +1 -0
- package/lib/features/job-search/ApplicationsPanel.js +907 -0
- package/lib/features/job-search/ApplicationsPanel.js.map +1 -0
- package/lib/features/job-search/ContactsPanel.js +627 -0
- package/lib/features/job-search/ContactsPanel.js.map +1 -0
- package/lib/features/job-search/InsightsPanel.js +299 -0
- package/lib/features/job-search/InsightsPanel.js.map +1 -0
- package/lib/features/job-search/InterviewPanel.js +637 -0
- package/lib/features/job-search/InterviewPanel.js.map +1 -0
- package/lib/features/job-search/JdPastePrompt.js +130 -0
- package/lib/features/job-search/JdPastePrompt.js.map +1 -0
- package/lib/features/job-search/JobCard.js +199 -0
- package/lib/features/job-search/JobCard.js.map +1 -0
- package/lib/features/job-search/JobDetailSheet.js +255 -0
- package/lib/features/job-search/JobDetailSheet.js.map +1 -0
- package/lib/features/job-search/JobSearchAgentChatPane.js +377 -0
- package/lib/features/job-search/JobSearchAgentChatPane.js.map +1 -0
- package/lib/features/job-search/JobSearchExperience.js +1324 -0
- package/lib/features/job-search/JobSearchExperience.js.map +1 -0
- package/lib/features/job-search/JobSearchLocationField.js +231 -0
- package/lib/features/job-search/JobSearchLocationField.js.map +1 -0
- package/lib/features/job-search/ProfilePanel.js +679 -0
- package/lib/features/job-search/ProfilePanel.js.map +1 -0
- package/lib/features/job-search/RepliesPanel.js +344 -0
- package/lib/features/job-search/RepliesPanel.js.map +1 -0
- package/lib/features/job-search/SavedPanel.js +297 -0
- package/lib/features/job-search/SavedPanel.js.map +1 -0
- package/lib/features/job-search/chat/widgetContent.js +29 -0
- package/lib/features/job-search/chat/widgetContent.js.map +1 -0
- package/lib/features/job-search/cvText.js +91 -0
- package/lib/features/job-search/cvText.js.map +1 -0
- package/lib/features/job-search/jobAgentSwipe.js +7 -0
- package/lib/features/job-search/jobAgentSwipe.js.map +1 -0
- package/lib/features/job-search/jobSearchClient.js +184 -0
- package/lib/features/job-search/jobSearchClient.js.map +1 -0
- package/lib/features/job-search/jobSearchExec.js +14 -0
- package/lib/features/job-search/jobSearchExec.js.map +1 -0
- package/lib/features/job-search/jobSearchRuntime.js +50 -0
- package/lib/features/job-search/jobSearchRuntime.js.map +1 -0
- package/lib/features/job-search/jobSearchTheme.js +44 -0
- package/lib/features/job-search/jobSearchTheme.js.map +1 -0
- package/lib/features/job-search/savedJobs.js +85 -0
- package/lib/features/job-search/savedJobs.js.map +1 -0
- package/lib/features/job-search/searchHistory.js +117 -0
- package/lib/features/job-search/searchHistory.js.map +1 -0
- package/lib/features/job-search/types.js +36 -0
- package/lib/features/job-search/types.js.map +1 -0
- package/lib/features/job-search/useJobSearchSession.js +558 -0
- package/lib/features/job-search/useJobSearchSession.js.map +1 -0
- package/lib/features/messaging/ChatComponents.js +529 -0
- package/lib/features/messaging/ChatComponents.js.map +1 -0
- package/lib/features/messaging/ChatInviteDeepLink.js +116 -0
- package/lib/features/messaging/ChatInviteDeepLink.js.map +1 -0
- package/lib/features/messaging/ContactsScreen.js +288 -0
- package/lib/features/messaging/ContactsScreen.js.map +1 -0
- package/lib/features/messaging/ConversationListScreen.js +147 -0
- package/lib/features/messaging/ConversationListScreen.js.map +1 -0
- package/lib/features/messaging/MessageActions.js +290 -0
- package/lib/features/messaging/MessageActions.js.map +1 -0
- package/lib/features/messaging/NativeChatExperience.js +189 -0
- package/lib/features/messaging/NativeChatExperience.js.map +1 -0
- package/lib/features/messaging/RegistrationScreen.js +11 -14
- package/lib/features/messaging/RegistrationScreen.js.map +1 -1
- package/lib/features/messaging/ThreadScreen.js +215 -0
- package/lib/features/messaging/ThreadScreen.js.map +1 -0
- package/lib/features/messaging/chatInviteLink.js +52 -0
- package/lib/features/messaging/chatInviteLink.js.map +1 -0
- package/lib/features/messaging/chatModel.js +278 -0
- package/lib/features/messaging/chatModel.js.map +1 -0
- package/lib/features/messaging/chatOperations.js +106 -1
- package/lib/features/messaging/chatOperations.js.map +1 -1
- package/lib/features/messaging/emojiCatalog.js +60 -0
- package/lib/features/messaging/emojiCatalog.js.map +1 -0
- package/lib/features/messaging/emojiKeywords.js +1592 -0
- package/lib/features/messaging/emojiKeywords.js.map +1 -0
- package/lib/features/messaging/nativeChatChannelQuery.js +27 -0
- package/lib/features/messaging/nativeChatChannelQuery.js.map +1 -0
- package/lib/features/messaging/phoneNumbers.js +52 -1
- package/lib/features/messaging/phoneNumbers.js.map +1 -1
- package/lib/features/messaging/sha256.js +68 -0
- package/lib/features/messaging/sha256.js.map +1 -0
- package/lib/features/messaging/useChatData.js +421 -0
- package/lib/features/messaging/useChatData.js.map +1 -0
- package/lib/features/messaging/useContactMatches.js +191 -0
- package/lib/features/messaging/useContactMatches.js.map +1 -0
- package/lib/features/messaging/usePhoneVerification.js +12 -12
- package/lib/features/messaging/usePhoneVerification.js.map +1 -1
- package/lib/features/messaging/yantraChatOrg.js +8 -3
- package/lib/features/messaging/yantraChatOrg.js.map +1 -1
- package/lib/features/resume/AnnotateModal.js +100 -0
- package/lib/features/resume/AnnotateModal.js.map +1 -0
- package/lib/features/resume/AnnotationBar.js +69 -0
- package/lib/features/resume/AnnotationBar.js.map +1 -0
- package/lib/features/resume/ExportSheet.js +105 -0
- package/lib/features/resume/ExportSheet.js.map +1 -0
- package/lib/features/resume/ResumeAgentChatPane.js +95 -0
- package/lib/features/resume/ResumeAgentChatPane.js.map +1 -0
- package/lib/features/resume/ResumeEditor.js +676 -0
- package/lib/features/resume/ResumeEditor.js.map +1 -0
- package/lib/features/resume/ResumeExperience.js +235 -0
- package/lib/features/resume/ResumeExperience.js.map +1 -0
- package/lib/features/resume/ResumeListPanel.js +262 -0
- package/lib/features/resume/ResumeListPanel.js.map +1 -0
- package/lib/features/resume/ResumeToolbar.js +236 -0
- package/lib/features/resume/ResumeToolbar.js.map +1 -0
- package/lib/features/resume/annotations.js +17 -0
- package/lib/features/resume/annotations.js.map +1 -0
- package/lib/features/resume/documentCss.js +52 -0
- package/lib/features/resume/documentCss.js.map +1 -0
- package/lib/features/resume/draft.js +89 -0
- package/lib/features/resume/draft.js.map +1 -0
- package/lib/features/resume/exportResume.js +43 -0
- package/lib/features/resume/exportResume.js.map +1 -0
- package/lib/features/resume/pickResumePhoto.js +22 -0
- package/lib/features/resume/pickResumePhoto.js.map +1 -0
- package/lib/features/resume/renderResume.js +121 -0
- package/lib/features/resume/renderResume.js.map +1 -0
- package/lib/features/resume/resumeClient.js +69 -0
- package/lib/features/resume/resumeClient.js.map +1 -0
- package/lib/features/resume/resumeExec.js +14 -0
- package/lib/features/resume/resumeExec.js.map +1 -0
- package/lib/features/resume/resumeIndex.js +244 -0
- package/lib/features/resume/resumeIndex.js.map +1 -0
- package/lib/features/resume/resumeRuntime.js +50 -0
- package/lib/features/resume/resumeRuntime.js.map +1 -0
- package/lib/features/resume/resumeTheme.js +34 -0
- package/lib/features/resume/resumeTheme.js.map +1 -0
- package/lib/features/resume/resumeToolbox.js +49 -0
- package/lib/features/resume/resumeToolbox.js.map +1 -0
- package/lib/features/resume/templates.js +90 -0
- package/lib/features/resume/templates.js.map +1 -0
- package/lib/features/resume/types.js +10 -0
- package/lib/features/resume/types.js.map +1 -0
- package/lib/features/resume/useResumeSession.js +183 -0
- package/lib/features/resume/useResumeSession.js.map +1 -0
- package/lib/features/shopping/DealsPanel.js +254 -0
- package/lib/features/shopping/DealsPanel.js.map +1 -0
- package/lib/features/shopping/HistoryPanel.js +147 -0
- package/lib/features/shopping/HistoryPanel.js.map +1 -0
- package/lib/features/shopping/OrdersPanel.js +157 -0
- package/lib/features/shopping/OrdersPanel.js.map +1 -0
- package/lib/features/shopping/ProductCard.js +326 -0
- package/lib/features/shopping/ProductCard.js.map +1 -0
- package/lib/features/shopping/ProductDetailSheet.js +313 -0
- package/lib/features/shopping/ProductDetailSheet.js.map +1 -0
- package/lib/features/shopping/ProductFilterBar.js +153 -0
- package/lib/features/shopping/ProductFilterBar.js.map +1 -0
- package/lib/features/shopping/ProductPhoto.js +27 -0
- package/lib/features/shopping/ProductPhoto.js.map +1 -0
- package/lib/features/shopping/SavedPanel.js +139 -0
- package/lib/features/shopping/SavedPanel.js.map +1 -0
- package/lib/features/shopping/ShoppingAgentChatPane.js +436 -0
- package/lib/features/shopping/ShoppingAgentChatPane.js.map +1 -0
- package/lib/features/shopping/ShoppingExperience.js +888 -0
- package/lib/features/shopping/ShoppingExperience.js.map +1 -0
- package/lib/features/shopping/TrendingSections.js +199 -0
- package/lib/features/shopping/TrendingSections.js.map +1 -0
- package/lib/features/shopping/WatchlistPanel.js +148 -0
- package/lib/features/shopping/WatchlistPanel.js.map +1 -0
- package/lib/features/shopping/catalog.js +238 -0
- package/lib/features/shopping/catalog.js.map +1 -0
- package/lib/features/shopping/chat/ShoppingChatResultCard.js +175 -0
- package/lib/features/shopping/chat/ShoppingChatResultCard.js.map +1 -0
- package/lib/features/shopping/chat/streamAssistantReply.js +34 -0
- package/lib/features/shopping/chat/streamAssistantReply.js.map +1 -0
- package/lib/features/shopping/chat/widgetContent.js +233 -0
- package/lib/features/shopping/chat/widgetContent.js.map +1 -0
- package/lib/features/shopping/hooks/useTrendingProducts.js +162 -0
- package/lib/features/shopping/hooks/useTrendingProducts.js.map +1 -0
- package/lib/features/shopping/productImage.js +42 -0
- package/lib/features/shopping/productImage.js.map +1 -0
- package/lib/features/shopping/savedProducts.js +84 -0
- package/lib/features/shopping/savedProducts.js.map +1 -0
- package/lib/features/shopping/services/catalogActions.js +166 -0
- package/lib/features/shopping/services/catalogActions.js.map +1 -0
- package/lib/features/shopping/services/parsePriceCheckIntent.js +58 -0
- package/lib/features/shopping/services/parsePriceCheckIntent.js.map +1 -0
- package/lib/features/shopping/services/parseShoppingIntent.js +67 -0
- package/lib/features/shopping/services/parseShoppingIntent.js.map +1 -0
- package/lib/features/shopping/services/productAvailability.js +25 -0
- package/lib/features/shopping/services/productAvailability.js.map +1 -0
- package/lib/features/shopping/services/productFilters.js +72 -0
- package/lib/features/shopping/services/productFilters.js.map +1 -0
- package/lib/features/shopping/services/retailerUrl.js +75 -0
- package/lib/features/shopping/services/retailerUrl.js.map +1 -0
- package/lib/features/shopping/services/shoppingChatReply.js +46 -0
- package/lib/features/shopping/services/shoppingChatReply.js.map +1 -0
- package/lib/features/shopping/services/shoppingProductSearch.js +336 -0
- package/lib/features/shopping/services/shoppingProductSearch.js.map +1 -0
- package/lib/features/shopping/services/shoppingSearchConnectorClient.js +41 -0
- package/lib/features/shopping/services/shoppingSearchConnectorClient.js.map +1 -0
- package/lib/features/shopping/shopAgentSwipe.js +7 -0
- package/lib/features/shopping/shopAgentSwipe.js.map +1 -0
- package/lib/features/shopping/shoppingCart.js +116 -0
- package/lib/features/shopping/shoppingCart.js.map +1 -0
- package/lib/features/shopping/shoppingExec.js +14 -0
- package/lib/features/shopping/shoppingExec.js.map +1 -0
- package/lib/features/shopping/shoppingHistoryStore.js +176 -0
- package/lib/features/shopping/shoppingHistoryStore.js.map +1 -0
- package/lib/features/shopping/shoppingRuntime.js +63 -0
- package/lib/features/shopping/shoppingRuntime.js.map +1 -0
- package/lib/features/shopping/timeAgo.js +14 -0
- package/lib/features/shopping/timeAgo.js.map +1 -0
- package/lib/features/shopping/useShoppingSearch.js +262 -0
- package/lib/features/shopping/useShoppingSearch.js.map +1 -0
- package/lib/features/travel/BookHeaderGlow.js +48 -0
- package/lib/features/travel/BookHeaderGlow.js.map +1 -0
- package/lib/features/travel/BookingsPanel.js +29 -0
- package/lib/features/travel/BookingsPanel.js.map +1 -0
- package/lib/features/travel/DiscoverPanel.js +155 -0
- package/lib/features/travel/DiscoverPanel.js.map +1 -0
- package/lib/features/travel/FlightCompareBar.js +86 -0
- package/lib/features/travel/FlightCompareBar.js.map +1 -0
- package/lib/features/travel/FlightDealsBoard.js +100 -0
- package/lib/features/travel/FlightDealsBoard.js.map +1 -0
- package/lib/features/travel/HistoryPanel.js +82 -0
- package/lib/features/travel/HistoryPanel.js.map +1 -0
- package/lib/features/travel/PopularDestinations.js +144 -0
- package/lib/features/travel/PopularDestinations.js.map +1 -0
- package/lib/features/travel/SavedPanel.js +27 -0
- package/lib/features/travel/SavedPanel.js.map +1 -0
- package/lib/features/travel/TravelAgentChatPane.js +303 -0
- package/lib/features/travel/TravelAgentChatPane.js.map +1 -0
- package/lib/features/travel/TravelBookHero.js +425 -0
- package/lib/features/travel/TravelBookHero.js.map +1 -0
- package/lib/features/travel/TravelDatesField.js +234 -0
- package/lib/features/travel/TravelDatesField.js.map +1 -0
- package/lib/features/travel/TravelDetailSheet.js +106 -0
- package/lib/features/travel/TravelDetailSheet.js.map +1 -0
- package/lib/features/travel/TravelExperience.js +624 -0
- package/lib/features/travel/TravelExperience.js.map +1 -0
- package/lib/features/travel/TravelGuestsField.js +85 -0
- package/lib/features/travel/TravelGuestsField.js.map +1 -0
- package/lib/features/travel/TravelLanding.js +318 -0
- package/lib/features/travel/TravelLanding.js.map +1 -0
- package/lib/features/travel/TravelLocationField.js +179 -0
- package/lib/features/travel/TravelLocationField.js.map +1 -0
- package/lib/features/travel/TravelPropertyCard.js +266 -0
- package/lib/features/travel/TravelPropertyCard.js.map +1 -0
- package/lib/features/travel/TravelPropertyPhoto.js +22 -0
- package/lib/features/travel/TravelPropertyPhoto.js.map +1 -0
- package/lib/features/travel/TravelRailFlyout.js +79 -0
- package/lib/features/travel/TravelRailFlyout.js.map +1 -0
- package/lib/features/travel/TravelResultsMap.js +126 -0
- package/lib/features/travel/TravelResultsMap.js.map +1 -0
- package/lib/features/travel/WorkspacePanel.js +148 -0
- package/lib/features/travel/WorkspacePanel.js.map +1 -0
- package/lib/features/travel/appNav.js +244 -0
- package/lib/features/travel/appNav.js.map +1 -0
- package/lib/features/travel/calendarDays.js +50 -0
- package/lib/features/travel/calendarDays.js.map +1 -0
- package/lib/features/travel/catalog.js +72 -0
- package/lib/features/travel/catalog.js.map +1 -0
- package/lib/features/travel/chat/TravelChatResultCard.js +107 -0
- package/lib/features/travel/chat/TravelChatResultCard.js.map +1 -0
- package/lib/features/travel/chat/widgetContent.js +107 -0
- package/lib/features/travel/chat/widgetContent.js.map +1 -0
- package/lib/features/travel/flightDeals.js +65 -0
- package/lib/features/travel/flightDeals.js.map +1 -0
- package/lib/features/travel/mapCoordinates.js +36 -0
- package/lib/features/travel/mapCoordinates.js.map +1 -0
- package/lib/features/travel/parseTravelIntent.js +303 -0
- package/lib/features/travel/parseTravelIntent.js.map +1 -0
- package/lib/features/travel/savedStays.js +66 -0
- package/lib/features/travel/savedStays.js.map +1 -0
- package/lib/features/travel/services/flightDealsBoard.js +111 -0
- package/lib/features/travel/services/flightDealsBoard.js.map +1 -0
- package/lib/features/travel/services/flightSearchConnectorClient.js +42 -0
- package/lib/features/travel/services/flightSearchConnectorClient.js.map +1 -0
- package/lib/features/travel/services/geocodeLocation.js +79 -0
- package/lib/features/travel/services/geocodeLocation.js.map +1 -0
- package/lib/features/travel/services/placePredictions.js +113 -0
- package/lib/features/travel/services/placePredictions.js.map +1 -0
- package/lib/features/travel/services/resolveOriginCity.js +27 -0
- package/lib/features/travel/services/resolveOriginCity.js.map +1 -0
- package/lib/features/travel/services/resortifiConnectorClient.js +76 -0
- package/lib/features/travel/services/resortifiConnectorClient.js.map +1 -0
- package/lib/features/travel/services/travelFlightSearch.js +289 -0
- package/lib/features/travel/services/travelFlightSearch.js.map +1 -0
- package/lib/features/travel/services/travelPropertySearch.js +377 -0
- package/lib/features/travel/services/travelPropertySearch.js.map +1 -0
- package/lib/features/travel/travelAgentSwipe.js +7 -0
- package/lib/features/travel/travelAgentSwipe.js.map +1 -0
- package/lib/features/travel/travelExec.js +14 -0
- package/lib/features/travel/travelExec.js.map +1 -0
- package/lib/features/travel/travelHistoryStore.js +108 -0
- package/lib/features/travel/travelHistoryStore.js.map +1 -0
- package/lib/features/travel/travelRuntime.js +62 -0
- package/lib/features/travel/travelRuntime.js.map +1 -0
- package/lib/features/travel/types.js +9 -0
- package/lib/features/travel/types.js.map +1 -0
- package/lib/features/travel/useTravelSearch.js +330 -0
- package/lib/features/travel/useTravelSearch.js.map +1 -0
- package/lib/features/travel/workspaceContent.js +548 -0
- package/lib/features/travel/workspaceContent.js.map +1 -0
- package/lib/hooks/useCdecliChannel.js +128 -6
- package/lib/hooks/useCdecliChannel.js.map +1 -1
- package/lib/hooks/useChatApi.js +4 -2
- package/lib/hooks/useChatApi.js.map +1 -1
- package/lib/hooks/useChatStream.js +77 -63
- package/lib/hooks/useChatStream.js.map +1 -1
- package/lib/hooks/useHostConnectorCard.js +24 -0
- package/lib/hooks/useHostConnectorCard.js.map +1 -0
- package/lib/hooks/useObtainSystemToken.js +23 -5
- package/lib/hooks/useObtainSystemToken.js.map +1 -1
- package/lib/hooks/webViewRetentionPolicy.js +1 -0
- package/lib/hooks/webViewRetentionPolicy.js.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/screens/Chat/index.js +51 -22
- package/lib/screens/Chat/index.js.map +1 -1
- package/lib/screens/ChatNative/index.js +13 -2
- package/lib/screens/ChatNative/index.js.map +1 -1
- package/lib/screens/Home/HomeScreen.js +3 -3
- package/lib/screens/Home/HomeScreen.js.map +1 -1
- package/lib/screens/Home/components/ChatHistoryLanding.js +32 -32
- package/lib/screens/Home/components/ChatHistoryLanding.js.map +1 -1
- package/lib/screens/JobSearchNative/useJobSearchHostChat.js +12 -6
- package/lib/screens/JobSearchNative/useJobSearchHostChat.js.map +1 -1
- package/lib/screens/ResumeNative/useResumeHostChat.js +12 -6
- package/lib/screens/ResumeNative/useResumeHostChat.js.map +1 -1
- package/lib/screens/ShoppingNative/useShoppingHostChat.js +12 -6
- package/lib/screens/ShoppingNative/useShoppingHostChat.js.map +1 -1
- package/lib/screens/TravelNative/useTravelHostChat.js +12 -6
- package/lib/screens/TravelNative/useTravelHostChat.js.map +1 -1
- package/lib/screens/WebBuilder/WebViewWithNavigation.js +2 -2
- package/lib/screens/WebBuilder/WebViewWithNavigation.js.map +1 -1
- package/lib/services/brainQuickReply.js +38 -1
- package/lib/services/brainQuickReply.js.map +1 -1
- package/lib/state/chatThreadMerge.js +6 -1
- package/lib/state/chatThreadMerge.js.map +1 -1
- package/package.json +6 -4
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import*as React from'react';import {CONTACT_MATCHES_QUERY}from'./chatOperations.js';import {regionFromE164,normalizeContacts,collectLookupNumbers}from'./phoneNumbers.js';import {sha256}from'./sha256.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
|
+
function onePerUser(fromBook, viewerUserId) {
|
|
21
|
+
var _a, _b, _c, _d, _e;
|
|
22
|
+
const byUser = /* @__PURE__ */ new Map();
|
|
23
|
+
for (const row of fromBook) {
|
|
24
|
+
const uid = (_a = row.match) == null ? void 0 : _a.userId;
|
|
25
|
+
if (!uid || uid === viewerUserId || !/^[a-f0-9]{24}$/i.test(uid)) continue;
|
|
26
|
+
const existing = byUser.get(uid);
|
|
27
|
+
if (!existing) {
|
|
28
|
+
byUser.set(uid, row);
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
byUser.set(uid, __spreadProps(__spreadValues({}, existing), {
|
|
32
|
+
displayName: existing.displayName || row.displayName,
|
|
33
|
+
imageUri: existing.imageUri || row.imageUri,
|
|
34
|
+
e164: Array.from(/* @__PURE__ */ new Set([...existing.e164, ...row.e164])),
|
|
35
|
+
match: __spreadProps(__spreadValues({}, existing.match), {
|
|
36
|
+
displayName: ((_b = existing.match) == null ? void 0 : _b.displayName) || ((_c = row.match) == null ? void 0 : _c.displayName) || existing.displayName,
|
|
37
|
+
picture: ((_d = existing.match) == null ? void 0 : _d.picture) || ((_e = row.match) == null ? void 0 : _e.picture)
|
|
38
|
+
})
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
return Array.from(byUser.values()).sort((a, b) => a.displayName.localeCompare(b.displayName));
|
|
42
|
+
}
|
|
43
|
+
function readMatches(data) {
|
|
44
|
+
const raw = data == null ? void 0 : data.chatContactMatches;
|
|
45
|
+
if (Array.isArray(raw)) return raw;
|
|
46
|
+
if (raw && typeof raw === "object" && Array.isArray(raw.matches)) {
|
|
47
|
+
return raw.matches;
|
|
48
|
+
}
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
function useContactMatches(gql, contacts, viewer, phone) {
|
|
52
|
+
const [permission, setPermission] = React.useState(contacts ? "undetermined" : "unsupported");
|
|
53
|
+
const [limited, setLimited] = React.useState(false);
|
|
54
|
+
const [loading, setLoading] = React.useState(true);
|
|
55
|
+
const [error, setError] = React.useState(null);
|
|
56
|
+
const [fromBook, setFromBook] = React.useState([]);
|
|
57
|
+
const [invitable, setInvitable] = React.useState([]);
|
|
58
|
+
const mounted = React.useRef(true);
|
|
59
|
+
React.useEffect(() => {
|
|
60
|
+
mounted.current = true;
|
|
61
|
+
return () => {
|
|
62
|
+
mounted.current = false;
|
|
63
|
+
};
|
|
64
|
+
}, []);
|
|
65
|
+
const sync = React.useCallback(async () => {
|
|
66
|
+
var _a, _b, _c, _d;
|
|
67
|
+
if (!contacts) {
|
|
68
|
+
if (mounted.current) setLoading(false);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
setLoading(true);
|
|
72
|
+
setError(null);
|
|
73
|
+
try {
|
|
74
|
+
if (contacts.isLimited) {
|
|
75
|
+
const isLimited = await contacts.isLimited().catch(() => false);
|
|
76
|
+
if (mounted.current) setLimited(isLimited);
|
|
77
|
+
}
|
|
78
|
+
const raw = await contacts.read();
|
|
79
|
+
const regions = [contacts.defaultRegion, regionFromE164(viewer == null ? void 0 : viewer.phoneE164)];
|
|
80
|
+
const normalized = normalizeContacts(raw, regions, (_a = viewer == null ? void 0 : viewer.phoneE164) != null ? _a : null);
|
|
81
|
+
const numbers = collectLookupNumbers(normalized);
|
|
82
|
+
if (!numbers.length) {
|
|
83
|
+
if (!mounted.current) return;
|
|
84
|
+
setFromBook([]);
|
|
85
|
+
setInvitable(normalized);
|
|
86
|
+
setLoading(false);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
let matchedNumbers;
|
|
90
|
+
if (phone == null ? void 0 : phone.matchContacts) {
|
|
91
|
+
try {
|
|
92
|
+
const matches = await phone.matchContacts(numbers);
|
|
93
|
+
matchedNumbers = new Map(Object.entries(matches).map(([phoneE164, match]) => [phoneE164, match]));
|
|
94
|
+
} catch (err) {
|
|
95
|
+
if (!mounted.current) return;
|
|
96
|
+
setError(err instanceof Error ? err.message : "Could not match contacts");
|
|
97
|
+
setFromBook([]);
|
|
98
|
+
setInvitable(normalized);
|
|
99
|
+
setLoading(false);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
const byHash = /* @__PURE__ */ new Map();
|
|
104
|
+
for (const n of numbers) byHash.set(sha256(n), n);
|
|
105
|
+
const res = await gql.query(CONTACT_MATCHES_QUERY, {
|
|
106
|
+
phoneHashes: Array.from(byHash.keys())
|
|
107
|
+
});
|
|
108
|
+
if (!mounted.current) return;
|
|
109
|
+
matchedNumbers = /* @__PURE__ */ new Map();
|
|
110
|
+
for (const m of readMatches(res.data)) {
|
|
111
|
+
const number = (m == null ? void 0 : m.phoneHash) ? byHash.get(m.phoneHash) : void 0;
|
|
112
|
+
if (number && (m == null ? void 0 : m.userId)) matchedNumbers.set(number, m);
|
|
113
|
+
}
|
|
114
|
+
if ((_b = res.errors) == null ? void 0 : _b.length) {
|
|
115
|
+
setError(res.errors[0].message);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const here = [];
|
|
119
|
+
const rest = [];
|
|
120
|
+
for (const c of normalized) {
|
|
121
|
+
const hit = c.e164.map((n) => matchedNumbers.get(n)).find(Boolean);
|
|
122
|
+
if (hit == null ? void 0 : hit.userId) {
|
|
123
|
+
here.push(__spreadProps(__spreadValues({}, c), {
|
|
124
|
+
match: {
|
|
125
|
+
userId: String(hit.userId),
|
|
126
|
+
// Prefer the name from THEIR account over the one in
|
|
127
|
+
// your address book only when yours is missing -
|
|
128
|
+
// you called them "Mum" for a reason.
|
|
129
|
+
displayName: c.displayName || hit.displayName || hit.username || "Unknown",
|
|
130
|
+
picture: (_d = (_c = hit.avatarUrl) != null ? _c : hit.picture) != null ? _d : null
|
|
131
|
+
}
|
|
132
|
+
}));
|
|
133
|
+
} else {
|
|
134
|
+
rest.push(c);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
here.sort((a, b) => a.displayName.localeCompare(b.displayName));
|
|
138
|
+
rest.sort((a, b) => a.displayName.localeCompare(b.displayName));
|
|
139
|
+
setFromBook(here);
|
|
140
|
+
setInvitable(rest);
|
|
141
|
+
} catch (e) {
|
|
142
|
+
if (!mounted.current) return;
|
|
143
|
+
setError(e instanceof Error ? e.message : "Could not read your contacts.");
|
|
144
|
+
} finally {
|
|
145
|
+
if (mounted.current) setLoading(false);
|
|
146
|
+
}
|
|
147
|
+
}, [contacts, gql, viewer, phone]);
|
|
148
|
+
React.useEffect(() => {
|
|
149
|
+
let cancelled = false;
|
|
150
|
+
if (!contacts) {
|
|
151
|
+
setPermission("unsupported");
|
|
152
|
+
return () => void 0;
|
|
153
|
+
}
|
|
154
|
+
void (async () => {
|
|
155
|
+
const status = await contacts.getPermission();
|
|
156
|
+
if (cancelled || !mounted.current) return;
|
|
157
|
+
setPermission(status);
|
|
158
|
+
if (status === "granted") void sync();
|
|
159
|
+
else setLoading(false);
|
|
160
|
+
})();
|
|
161
|
+
return () => {
|
|
162
|
+
cancelled = true;
|
|
163
|
+
};
|
|
164
|
+
}, [contacts, sync]);
|
|
165
|
+
const requestAccess = React.useCallback(async () => {
|
|
166
|
+
if (!contacts) return;
|
|
167
|
+
const status = await contacts.requestPermission();
|
|
168
|
+
if (!mounted.current) return;
|
|
169
|
+
setPermission(status);
|
|
170
|
+
if (status === "granted") await sync();
|
|
171
|
+
else setLoading(false);
|
|
172
|
+
}, [contacts, sync]);
|
|
173
|
+
const chooseMoreContacts = React.useMemo(() => (contacts == null ? void 0 : contacts.chooseMoreContacts) ? async () => {
|
|
174
|
+
var _a;
|
|
175
|
+
await ((_a = contacts.chooseMoreContacts) == null ? void 0 : _a.call(contacts));
|
|
176
|
+
await sync();
|
|
177
|
+
} : void 0, [contacts, sync]);
|
|
178
|
+
const onYantra = React.useMemo(() => onePerUser(fromBook, viewer == null ? void 0 : viewer.userId), [fromBook, viewer == null ? void 0 : viewer.userId]);
|
|
179
|
+
return {
|
|
180
|
+
permission,
|
|
181
|
+
limited,
|
|
182
|
+
loading,
|
|
183
|
+
error,
|
|
184
|
+
onYantra,
|
|
185
|
+
invitable,
|
|
186
|
+
requestAccess,
|
|
187
|
+
refresh: sync,
|
|
188
|
+
openSettings: async () => contacts == null ? void 0 : contacts.openSettings(),
|
|
189
|
+
chooseMoreContacts
|
|
190
|
+
};
|
|
191
|
+
}export{useContactMatches};//# sourceMappingURL=useContactMatches.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useContactMatches.js","sources":["../../../src/features/messaging/useContactMatches.ts"],"sourcesContent":["/**\n * The contact sync: read the address book, work out who is already here.\n *\n * The whole pipeline runs in the remote, so all of it is fixable by a surface\n * deploy: normalise -> hash -> ask the server -> split into \"on Yantra\" and\n * \"invite\". Only the address-book read itself is a host seam, because that is\n * the one part needing a native module.\n *\n * With phone-based membership (issue #1312), contact matching delegates to\n * the ChatPhoneSeam, which calls the `yantra-messenger` connector to match\n * E.164 phone numbers against chat members.\n *\n * NOTHING LEAVES THE DEVICE IN PLAINTEXT (legacy mode). Numbers are hashed\n * before the query. See sha256.ts and the server's chat-contact-directory.ts\n * for what that does and does not buy - it is not anonymity, but it does mean\n * we never upload or store the address book of someone who never signed up.\n *\n * If a ChatPhoneSeam is available, it takes precedence for matching.\n *\n * Like WhatsApp, the list is the address book only: contacts registered for Yantra Chat\n * open a conversation, everyone else is invited. There is no directory of all members.\n */\nimport * as React from 'react';\nimport { CONTACT_MATCHES_QUERY } from './chatOperations';\nimport { collectLookupNumbers, normalizeContacts, regionFromE164, type NormalizedContact } from './phoneNumbers';\nimport { sha256 } from './sha256';\nimport type { ChatContactsSeam, ChatGraphQLSeam, ChatPermissionStatus, ChatViewer, ChatPhoneSeam } from './chatHost';\n\nexport interface MatchedContact extends NormalizedContact {\n /** Present when this contact already has an account. */\n match?: { userId: string; displayName: string; picture?: string | null };\n}\n\nexport interface ContactMatchesState {\n permission: ChatPermissionStatus | 'unsupported';\n /** Granted for selected contacts only (iOS 18 Limited Access). */\n limited: boolean;\n loading: boolean;\n error: string | null;\n /** Contacts already on Yantra - tap to open a DM. */\n onYantra: MatchedContact[];\n /** Everyone else - tap to invite. */\n invitable: MatchedContact[];\n /** Prompts, then syncs on success. */\n requestAccess: () => Promise<void>;\n /** Re-read the address book and re-match. */\n refresh: () => Promise<void>;\n openSettings: () => Promise<void>;\n /** Present when the host can show the iOS contact access picker. */\n chooseMoreContacts?: () => Promise<void>;\n}\n\n/** One row per registered person, even when they are saved under several contacts. */\nfunction onePerUser(fromBook: MatchedContact[], viewerUserId?: string | null): MatchedContact[] {\n const byUser = new Map<string, MatchedContact>();\n for (const row of fromBook) {\n const uid = row.match?.userId;\n if (!uid || uid === viewerUserId || !/^[a-f0-9]{24}$/i.test(uid)) continue;\n const existing = byUser.get(uid);\n if (!existing) {\n byUser.set(uid, row);\n continue;\n }\n byUser.set(uid, {\n ...existing,\n displayName: existing.displayName || row.displayName,\n imageUri: existing.imageUri || row.imageUri,\n e164: Array.from(new Set([...existing.e164, ...row.e164])),\n match: {\n ...existing.match!,\n displayName: existing.match?.displayName || row.match?.displayName || existing.displayName,\n picture: existing.match?.picture || row.match?.picture,\n },\n });\n }\n return Array.from(byUser.values()).sort((a, b) => a.displayName.localeCompare(b.displayName));\n}\n\ninterface WireMatch {\n phoneHash?: string;\n userId?: string;\n displayName?: string | null;\n username?: string | null;\n picture?: string | null;\n}\n\n/**\n * The server returns AnyObject, so the payload arrives untyped and possibly as\n * a bare array or wrapped. Normalising defensively here beats trusting a shape\n * the schema does not enforce.\n */\nfunction readMatches(data: unknown): WireMatch[] {\n const raw = (data as { chatContactMatches?: unknown })?.chatContactMatches;\n if (Array.isArray(raw)) return raw as WireMatch[];\n if (raw && typeof raw === 'object' && Array.isArray((raw as { matches?: unknown }).matches)) {\n return (raw as { matches: WireMatch[] }).matches;\n }\n return [];\n}\n\nexport function useContactMatches(\n gql: ChatGraphQLSeam,\n contacts: ChatContactsSeam | undefined,\n viewer: ChatViewer | null,\n phone?: ChatPhoneSeam,\n): ContactMatchesState {\n const [permission, setPermission] = React.useState<ChatPermissionStatus | 'unsupported'>(\n contacts ? 'undetermined' : 'unsupported',\n );\n const [limited, setLimited] = React.useState(false);\n const [loading, setLoading] = React.useState(true);\n const [error, setError] = React.useState<string | null>(null);\n const [fromBook, setFromBook] = React.useState<MatchedContact[]>([]);\n const [invitable, setInvitable] = React.useState<MatchedContact[]>([]);\n const mounted = React.useRef(true);\n\n React.useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n\n const sync = React.useCallback(async () => {\n if (!contacts) {\n if (mounted.current) setLoading(false);\n return;\n }\n setLoading(true);\n setError(null);\n try {\n // Re-checked on every sync: the user can widen or narrow access in Settings at any time.\n if (contacts.isLimited) {\n const isLimited = await contacts.isLimited().catch(() => false);\n if (mounted.current) setLimited(isLimited);\n }\n const raw = await contacts.read();\n // Normalisation drops unmatchable numbers and the viewer's own\n // card, which almost everyone has saved.\n // Numbers saved without a country code are read against the device region AND the\n // viewer's verified country: the device may report US for a user whose contacts are Indian.\n const regions = [contacts.defaultRegion, regionFromE164(viewer?.phoneE164)];\n const normalized = normalizeContacts(raw, regions, viewer?.phoneE164 ?? null);\n const numbers = collectLookupNumbers(normalized);\n\n if (!numbers.length) {\n if (!mounted.current) return;\n setFromBook([]);\n setInvitable(normalized);\n setLoading(false);\n return;\n }\n\n let matchedNumbers: Map<string, any>;\n\n if (phone?.matchContacts) {\n // New phone-based membership: use connector to match by E.164 phone number\n try {\n const matches = await phone.matchContacts(numbers);\n matchedNumbers = new Map(Object.entries(matches).map(([phoneE164, match]) => [phoneE164, match]));\n } catch (err) {\n if (!mounted.current) return;\n setError(err instanceof Error ? err.message : 'Could not match contacts');\n setFromBook([]);\n setInvitable(normalized);\n setLoading(false);\n return;\n }\n } else {\n // Legacy hashed directory approach\n const byHash = new Map<string, string>();\n for (const n of numbers) byHash.set(sha256(n), n);\n\n const res = await gql.query(CONTACT_MATCHES_QUERY, { phoneHashes: Array.from(byHash.keys()) });\n if (!mounted.current) return;\n\n matchedNumbers = new Map<string, any>();\n for (const m of readMatches(res.data)) {\n const number = m?.phoneHash ? byHash.get(m.phoneHash) : undefined;\n if (number && m?.userId) matchedNumbers.set(number, m);\n }\n\n if (res.errors?.length) {\n setError(res.errors[0].message);\n }\n }\n\n const here: MatchedContact[] = [];\n const rest: MatchedContact[] = [];\n for (const c of normalized) {\n const hit = c.e164.map((n) => matchedNumbers.get(n)).find(Boolean);\n if (hit?.userId) {\n here.push({\n ...c,\n match: {\n userId: String(hit.userId),\n // Prefer the name from THEIR account over the one in\n // your address book only when yours is missing -\n // you called them \"Mum\" for a reason.\n displayName: c.displayName || hit.displayName || hit.username || 'Unknown',\n picture: hit.avatarUrl ?? hit.picture ?? null,\n },\n });\n } else {\n rest.push(c);\n }\n }\n\n here.sort((a, b) => a.displayName.localeCompare(b.displayName));\n rest.sort((a, b) => a.displayName.localeCompare(b.displayName));\n setFromBook(here);\n setInvitable(rest);\n } catch (e) {\n if (!mounted.current) return;\n setError(e instanceof Error ? e.message : 'Could not read your contacts.');\n } finally {\n if (mounted.current) setLoading(false);\n }\n }, [contacts, gql, viewer, phone]);\n\n // Check the CURRENT status without prompting, so the screen can offer the\n // right action - ask, or deep-link to Settings after a previous denial.\n React.useEffect(() => {\n let cancelled = false;\n if (!contacts) {\n setPermission('unsupported');\n return () => undefined;\n }\n void (async () => {\n const status = await contacts.getPermission();\n if (cancelled || !mounted.current) return;\n setPermission(status);\n if (status === 'granted') void sync();\n else setLoading(false);\n })();\n return () => {\n cancelled = true;\n };\n }, [contacts, sync]);\n\n const requestAccess = React.useCallback(async () => {\n if (!contacts) return;\n const status = await contacts.requestPermission();\n if (!mounted.current) return;\n setPermission(status);\n if (status === 'granted') await sync();\n else setLoading(false);\n }, [contacts, sync]);\n\n // Reopens the address book afterwards: the user may have just shared more people.\n const chooseMoreContacts = React.useMemo(\n () =>\n contacts?.chooseMoreContacts\n ? async () => {\n await contacts.chooseMoreContacts?.();\n await sync();\n }\n : undefined,\n [contacts, sync],\n );\n\n const onYantra = React.useMemo(() => onePerUser(fromBook, viewer?.userId), [fromBook, viewer?.userId]);\n\n return {\n permission,\n limited,\n loading,\n error,\n onYantra,\n invitable,\n requestAccess,\n refresh: sync,\n openSettings: async () => contacts?.openSettings(),\n chooseMoreContacts,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {useState,useCallback}from'react';import {useSendPhoneOtpCodeMutation,useVerifyPhoneOtpCodeMutation}from'common/graphql';import {formatPhoneNumber,isValidPhoneNumber}from'./phoneNumbers.js';import {useObtainSystemToken}from'../../hooks/useObtainSystemToken.js';const CHAT_REGISTRATION_TEST_OTP = "123456";
|
|
1
|
+
import {useState,useCallback}from'react';import {useSendPhoneOtpCodeMutation,useVerifyPhoneOtpCodeMutation}from'common/graphql';import {formatPhoneNumber,isValidPhoneNumber}from'./phoneNumbers.js';import {useObtainSystemToken}from'../../hooks/useObtainSystemToken.js';import {config}from'../../config/env-config.js';const CHAT_REGISTRATION_TEST_OTP = "123456";
|
|
2
2
|
function isChatTestOtpCode(code) {
|
|
3
3
|
return code.replace(/\D/g, "") === CHAT_REGISTRATION_TEST_OTP;
|
|
4
4
|
}
|
|
5
|
-
function
|
|
6
|
-
|
|
7
|
-
return process.env.EXPO_PUBLIC_CHAT_ALLOW_TEST_OTP === "true";
|
|
5
|
+
function isChatTestOtpEnabled() {
|
|
6
|
+
return config.CHAT_ALLOW_TEST_OTP === true;
|
|
8
7
|
}
|
|
9
8
|
function usePhoneVerification(defaultCountryCode) {
|
|
10
9
|
const [stage, setStage] = useState("input");
|
|
@@ -19,7 +18,8 @@ function usePhoneVerification(defaultCountryCode) {
|
|
|
19
18
|
const [verifyPhoneOtpMutation] = useVerifyPhoneOtpCodeMutation();
|
|
20
19
|
const clearError = useCallback(() => setError(null), []);
|
|
21
20
|
const {
|
|
22
|
-
obtainSystemToken
|
|
21
|
+
obtainSystemToken,
|
|
22
|
+
getLastError: getLastTokenError
|
|
23
23
|
} = useObtainSystemToken();
|
|
24
24
|
const resetToInput = useCallback(() => {
|
|
25
25
|
setStage("input");
|
|
@@ -30,6 +30,7 @@ function usePhoneVerification(defaultCountryCode) {
|
|
|
30
30
|
setTestOtpMode(false);
|
|
31
31
|
}, []);
|
|
32
32
|
const continueWithTestOtp = useCallback(() => {
|
|
33
|
+
if (!isChatTestOtpEnabled()) return;
|
|
33
34
|
clearError();
|
|
34
35
|
const normalized = formatPhoneNumber(inputPhone, countryCode);
|
|
35
36
|
if (!normalized || !isValidPhoneNumber(normalized)) {
|
|
@@ -52,7 +53,7 @@ function usePhoneVerification(defaultCountryCode) {
|
|
|
52
53
|
setLoading(true);
|
|
53
54
|
try {
|
|
54
55
|
const systemToken = await obtainSystemToken();
|
|
55
|
-
if (!systemToken) throw new Error("Unable to obtain cdecli system token");
|
|
56
|
+
if (!systemToken) throw new Error(getLastTokenError() || "Unable to obtain cdecli system token");
|
|
56
57
|
const result = await sendPhoneOtpMutation({
|
|
57
58
|
variables: {
|
|
58
59
|
phoneNumber: {
|
|
@@ -74,7 +75,7 @@ function usePhoneVerification(defaultCountryCode) {
|
|
|
74
75
|
} finally {
|
|
75
76
|
setLoading(false);
|
|
76
77
|
}
|
|
77
|
-
}, [inputPhone, countryCode, sendPhoneOtpMutation, clearError, obtainSystemToken]);
|
|
78
|
+
}, [inputPhone, countryCode, sendPhoneOtpMutation, clearError, obtainSystemToken, getLastTokenError]);
|
|
78
79
|
const verifyOtp = useCallback(async () => {
|
|
79
80
|
var _a;
|
|
80
81
|
clearError();
|
|
@@ -88,8 +89,7 @@ function usePhoneVerification(defaultCountryCode) {
|
|
|
88
89
|
setError("Please enter a valid phone number");
|
|
89
90
|
return;
|
|
90
91
|
}
|
|
91
|
-
|
|
92
|
-
if (useTestBypass && isChatTestOtpCode(code)) {
|
|
92
|
+
if (isChatTestOtpEnabled() && isChatTestOtpCode(code)) {
|
|
93
93
|
setVerifiedPhone(normalized);
|
|
94
94
|
setStage("verified");
|
|
95
95
|
setTestOtpMode(false);
|
|
@@ -100,7 +100,7 @@ function usePhoneVerification(defaultCountryCode) {
|
|
|
100
100
|
setLoading(true);
|
|
101
101
|
try {
|
|
102
102
|
const systemToken = await obtainSystemToken();
|
|
103
|
-
if (!systemToken) throw new Error("Unable to obtain cdecli system token");
|
|
103
|
+
if (!systemToken) throw new Error(getLastTokenError() || "Unable to obtain cdecli system token");
|
|
104
104
|
const result = await verifyPhoneOtpMutation({
|
|
105
105
|
variables: {
|
|
106
106
|
phoneNumber: {
|
|
@@ -125,7 +125,7 @@ function usePhoneVerification(defaultCountryCode) {
|
|
|
125
125
|
} finally {
|
|
126
126
|
setLoading(false);
|
|
127
127
|
}
|
|
128
|
-
}, [otp, inputPhone, countryCode, testOtpMode, verifyPhoneOtpMutation, clearError, obtainSystemToken]);
|
|
128
|
+
}, [otp, inputPhone, countryCode, testOtpMode, verifyPhoneOtpMutation, clearError, obtainSystemToken, getLastTokenError]);
|
|
129
129
|
return {
|
|
130
130
|
stage,
|
|
131
131
|
verifiedPhone,
|
|
@@ -144,4 +144,4 @@ function usePhoneVerification(defaultCountryCode) {
|
|
|
144
144
|
resetToInput,
|
|
145
145
|
clearError
|
|
146
146
|
};
|
|
147
|
-
}export{CHAT_REGISTRATION_TEST_OTP,usePhoneVerification};//# sourceMappingURL=usePhoneVerification.js.map
|
|
147
|
+
}export{CHAT_REGISTRATION_TEST_OTP,isChatTestOtpEnabled,usePhoneVerification};//# sourceMappingURL=usePhoneVerification.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePhoneVerification.js","sources":["../../../src/features/messaging/usePhoneVerification.ts"],"sourcesContent":["/**\n * Phone number verification flow for Yantra Chat registration.\n *\n * Manages the OTP verification process for phone-number-based membership.\n * Uses adminIde's existing `sendPhoneOTP` / `verifyPhoneOtp` mutations and Auth0's\n * `passwordlessLogin` endpoint.\n *\n * Phone numbers are normalized to E.164 format and serve as the member ID.\n */\nimport { useCallback, useState } from 'react';\nimport { useSendPhoneOtpCodeMutation, useVerifyPhoneOtpCodeMutation } from 'common/graphql';\nimport { formatPhoneNumber, isValidPhoneNumber } from './phoneNumbers';\nimport { useObtainSystemToken } from '../../hooks/useObtainSystemToken';\n\n/** Fixed code for \"Continue with test OTP\" and local dev bypass (no SMS verify). */\nexport const CHAT_REGISTRATION_TEST_OTP = '123456';\n\nfunction isChatTestOtpCode(code: string): boolean {\n return code.replace(/\\D/g, '') === CHAT_REGISTRATION_TEST_OTP;\n}\n\nfunction canBypassOtpWithTestCode(): boolean {\n if (typeof __DEV__ !== 'undefined' && __DEV__) return true;\n return process.env.EXPO_PUBLIC_CHAT_ALLOW_TEST_OTP === 'true';\n}\n\nexport interface PhoneVerificationState {\n /** Current stage of the verification flow. */\n stage: 'input' | 'otp' | 'verifying' | 'verified' | 'error';\n /** The phone number in E.164 format, if successfully verified. */\n verifiedPhone: string | null;\n /** The user-entered phone (raw input, before normalization). */\n inputPhone: string;\n /** Country code (ISO-3166 alpha-2) for phone normalization. */\n countryCode: string;\n /** OTP entered by the user. */\n otp: string;\n /** Error message if verification failed. */\n error: string | null;\n /** Busy: waiting for server response. */\n loading: boolean;\n /** User chose \"Continue with test OTP\" — skip server verify when code is 123456. */\n testOtpMode: boolean;\n}\n\nexport interface PhoneVerificationActions {\n setCountryCode: (code: string) => void;\n setInputPhone: (phone: string) => void;\n setOtp: (code: string) => void;\n sendOtp: () => Promise<void>;\n verifyOtp: () => Promise<void>;\n continueWithTestOtp: () => void;\n resetToInput: () => void;\n clearError: () => void;\n}\n\nexport interface UsePhoneVerificationResult extends PhoneVerificationState, PhoneVerificationActions {}\n\n/**\n * Manages the phone verification lifecycle.\n *\n * Starts with phone input, sends OTP, then prompts for the code.\n * On success, `verifiedPhone` contains the E.164 number ready to become\n * a member ID.\n */\nexport function usePhoneVerification(defaultCountryCode?: string): UsePhoneVerificationResult {\n const [stage, setStage] = useState<PhoneVerificationState['stage']>('input');\n const [inputPhone, setInputPhone] = useState('');\n const [countryCode, setCountryCode] = useState(defaultCountryCode || 'US');\n const [otp, setOtp] = useState('');\n const [verifiedPhone, setVerifiedPhone] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n const [testOtpMode, setTestOtpMode] = useState(false);\n\n const [sendPhoneOtpMutation] = useSendPhoneOtpCodeMutation();\n const [verifyPhoneOtpMutation] = useVerifyPhoneOtpCodeMutation();\n\n const clearError = useCallback(() => setError(null), []);\n const { obtainSystemToken } = useObtainSystemToken();\n\n const resetToInput = useCallback(() => {\n setStage('input');\n setInputPhone('');\n setOtp('');\n setError(null);\n setVerifiedPhone(null);\n setTestOtpMode(false);\n }, []);\n\n const continueWithTestOtp = useCallback(() => {\n clearError();\n const normalized = formatPhoneNumber(inputPhone, countryCode);\n if (!normalized || !isValidPhoneNumber(normalized)) {\n setError('Please enter a valid mobile number');\n return;\n }\n setTestOtpMode(true);\n setOtp(CHAT_REGISTRATION_TEST_OTP);\n setStage('otp');\n }, [inputPhone, countryCode, clearError]);\n\n const sendOtp = useCallback(async () => {\n clearError();\n setTestOtpMode(false);\n const normalized = formatPhoneNumber(inputPhone, countryCode);\n\n if (!normalized || !isValidPhoneNumber(normalized)) {\n setError('Please enter a valid mobile number');\n return;\n }\n\n setLoading(true);\n try {\n const systemToken = await obtainSystemToken();\n if (!systemToken) throw new Error('Unable to obtain cdecli system token');\n\n const result = await sendPhoneOtpMutation({\n variables: { phoneNumber: { phoneNumber: normalized } },\n context: { headers: { 'x-cdecli-system-token': systemToken } },\n });\n\n if (!result.data?.sendPhoneOTPCode) throw new Error('Failed to send OTP');\n setOtp('');\n setStage('otp');\n setError(null);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to send OTP');\n } finally {\n setLoading(false);\n }\n }, [inputPhone, countryCode, sendPhoneOtpMutation, clearError, obtainSystemToken]);\n\n const verifyOtp = useCallback(async () => {\n clearError();\n\n const code = otp.replace(/\\D/g, '');\n if (!code || code.length !== 6) {\n setError('Please enter a valid 6-digit OTP');\n return;\n }\n\n const normalized = formatPhoneNumber(inputPhone, countryCode);\n if (!normalized) {\n setError('Please enter a valid phone number');\n return;\n }\n\n // Test path: skip server verify (explicit test flow or dev code 123456).\n const useTestBypass = testOtpMode || (canBypassOtpWithTestCode() && isChatTestOtpCode(code));\n if (useTestBypass && isChatTestOtpCode(code)) {\n setVerifiedPhone(normalized);\n setStage('verified');\n setTestOtpMode(false);\n setError(null);\n return;\n }\n\n setStage('verifying');\n setLoading(true);\n try {\n const systemToken = await obtainSystemToken();\n if (!systemToken) throw new Error('Unable to obtain cdecli system token');\n\n const result = await verifyPhoneOtpMutation({\n variables: { phoneNumber: { phoneNumber: normalized }, otp: code },\n context: { headers: { 'x-cdecli-system-token': systemToken } },\n });\n\n if (!result.data?.verifyPhoneOTPCode) throw new Error('Invalid or expired OTP');\n setVerifiedPhone(normalized);\n setStage('verified');\n setTestOtpMode(false);\n setError(null);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to verify OTP');\n setStage('otp');\n } finally {\n setLoading(false);\n }\n }, [otp, inputPhone, countryCode, testOtpMode, verifyPhoneOtpMutation, clearError, obtainSystemToken]);\n\n return {\n stage,\n verifiedPhone,\n inputPhone,\n countryCode,\n otp,\n error,\n loading,\n testOtpMode,\n setCountryCode,\n setInputPhone,\n setOtp,\n sendOtp,\n verifyOtp,\n continueWithTestOtp,\n resetToInput,\n clearError,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"usePhoneVerification.js","sources":["../../../src/features/messaging/usePhoneVerification.ts"],"sourcesContent":["/**\n * Phone number verification flow for Yantra Chat registration.\n *\n * Manages the OTP verification process for phone-number-based membership.\n * Uses adminIde's existing `sendPhoneOTP` / `verifyPhoneOtp` mutations and Auth0's\n * `passwordlessLogin` endpoint.\n *\n * Phone numbers are normalized to E.164 format and serve as the member ID.\n */\nimport { useCallback, useState } from 'react';\nimport { useSendPhoneOtpCodeMutation, useVerifyPhoneOtpCodeMutation } from 'common/graphql';\nimport { formatPhoneNumber, isValidPhoneNumber } from './phoneNumbers';\nimport { useObtainSystemToken } from '../../hooks/useObtainSystemToken';\nimport { config } from '../../config/env-config';\n\n/** Fixed code for \"Continue with test OTP\" (CHAT_ALLOW_TEST_OTP builds only; no SMS verify). */\nexport const CHAT_REGISTRATION_TEST_OTP = '123456';\n\nfunction isChatTestOtpCode(code: string): boolean {\n return code.replace(/\\D/g, '') === CHAT_REGISTRATION_TEST_OTP;\n}\n\n/**\n * The test OTP exists only when CHAT_ALLOW_TEST_OTP=true (dev.env locally, the build profile's env\n * in eas.json). Everywhere else the option is hidden and 123456 is checked like any code.\n */\nexport function isChatTestOtpEnabled(): boolean {\n return config.CHAT_ALLOW_TEST_OTP === true;\n}\n\nexport interface PhoneVerificationState {\n /** Current stage of the verification flow. */\n stage: 'input' | 'otp' | 'verifying' | 'verified' | 'error';\n /** The phone number in E.164 format, if successfully verified. */\n verifiedPhone: string | null;\n /** The user-entered phone (raw input, before normalization). */\n inputPhone: string;\n /** Country code (ISO-3166 alpha-2) for phone normalization. */\n countryCode: string;\n /** OTP entered by the user. */\n otp: string;\n /** Error message if verification failed. */\n error: string | null;\n /** Busy: waiting for server response. */\n loading: boolean;\n /** User chose \"Continue with test OTP\" — skip server verify when code is 123456. */\n testOtpMode: boolean;\n}\n\nexport interface PhoneVerificationActions {\n setCountryCode: (code: string) => void;\n setInputPhone: (phone: string) => void;\n setOtp: (code: string) => void;\n sendOtp: () => Promise<void>;\n verifyOtp: () => Promise<void>;\n continueWithTestOtp: () => void;\n resetToInput: () => void;\n clearError: () => void;\n}\n\nexport interface UsePhoneVerificationResult extends PhoneVerificationState, PhoneVerificationActions {}\n\n/**\n * Manages the phone verification lifecycle.\n *\n * Starts with phone input, sends OTP, then prompts for the code.\n * On success, `verifiedPhone` contains the E.164 number ready to become\n * a member ID.\n */\nexport function usePhoneVerification(defaultCountryCode?: string): UsePhoneVerificationResult {\n const [stage, setStage] = useState<PhoneVerificationState['stage']>('input');\n const [inputPhone, setInputPhone] = useState('');\n const [countryCode, setCountryCode] = useState(defaultCountryCode || 'US');\n const [otp, setOtp] = useState('');\n const [verifiedPhone, setVerifiedPhone] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n const [testOtpMode, setTestOtpMode] = useState(false);\n\n const [sendPhoneOtpMutation] = useSendPhoneOtpCodeMutation();\n const [verifyPhoneOtpMutation] = useVerifyPhoneOtpCodeMutation();\n\n const clearError = useCallback(() => setError(null), []);\n const { obtainSystemToken, getLastError: getLastTokenError } = useObtainSystemToken();\n\n const resetToInput = useCallback(() => {\n setStage('input');\n setInputPhone('');\n setOtp('');\n setError(null);\n setVerifiedPhone(null);\n setTestOtpMode(false);\n }, []);\n\n const continueWithTestOtp = useCallback(() => {\n if (!isChatTestOtpEnabled()) return;\n clearError();\n const normalized = formatPhoneNumber(inputPhone, countryCode);\n if (!normalized || !isValidPhoneNumber(normalized)) {\n setError('Please enter a valid mobile number');\n return;\n }\n setTestOtpMode(true);\n setOtp(CHAT_REGISTRATION_TEST_OTP);\n setStage('otp');\n }, [inputPhone, countryCode, clearError]);\n\n const sendOtp = useCallback(async () => {\n clearError();\n setTestOtpMode(false);\n const normalized = formatPhoneNumber(inputPhone, countryCode);\n\n if (!normalized || !isValidPhoneNumber(normalized)) {\n setError('Please enter a valid mobile number');\n return;\n }\n\n setLoading(true);\n try {\n const systemToken = await obtainSystemToken();\n if (!systemToken) throw new Error(getLastTokenError() || 'Unable to obtain cdecli system token');\n\n const result = await sendPhoneOtpMutation({\n variables: { phoneNumber: { phoneNumber: normalized } },\n context: { headers: { 'x-cdecli-system-token': systemToken } },\n });\n\n if (!result.data?.sendPhoneOTPCode) throw new Error('Failed to send OTP');\n setOtp('');\n setStage('otp');\n setError(null);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to send OTP');\n } finally {\n setLoading(false);\n }\n }, [inputPhone, countryCode, sendPhoneOtpMutation, clearError, obtainSystemToken, getLastTokenError]);\n\n const verifyOtp = useCallback(async () => {\n clearError();\n\n const code = otp.replace(/\\D/g, '');\n if (!code || code.length !== 6) {\n setError('Please enter a valid 6-digit OTP');\n return;\n }\n\n const normalized = formatPhoneNumber(inputPhone, countryCode);\n if (!normalized) {\n setError('Please enter a valid phone number');\n return;\n }\n\n // Test path (CHAT_ALLOW_TEST_OTP builds only): 123456 skips the server\n // verify and goes straight on to registration and chat.\n if (isChatTestOtpEnabled() && isChatTestOtpCode(code)) {\n setVerifiedPhone(normalized);\n setStage('verified');\n setTestOtpMode(false);\n setError(null);\n return;\n }\n\n setStage('verifying');\n setLoading(true);\n try {\n const systemToken = await obtainSystemToken();\n if (!systemToken) throw new Error(getLastTokenError() || 'Unable to obtain cdecli system token');\n\n const result = await verifyPhoneOtpMutation({\n variables: { phoneNumber: { phoneNumber: normalized }, otp: code },\n context: { headers: { 'x-cdecli-system-token': systemToken } },\n });\n\n if (!result.data?.verifyPhoneOTPCode) throw new Error('Invalid or expired OTP');\n setVerifiedPhone(normalized);\n setStage('verified');\n setTestOtpMode(false);\n setError(null);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to verify OTP');\n setStage('otp');\n } finally {\n setLoading(false);\n }\n }, [\n otp,\n inputPhone,\n countryCode,\n testOtpMode,\n verifyPhoneOtpMutation,\n clearError,\n obtainSystemToken,\n getLastTokenError,\n ]);\n\n return {\n stage,\n verifiedPhone,\n inputPhone,\n countryCode,\n otp,\n error,\n loading,\n testOtpMode,\n setCountryCode,\n setInputPhone,\n setOtp,\n sendOtp,\n verifyOtp,\n continueWithTestOtp,\n resetToInput,\n clearError,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import {CHAT_WORKSPACE}from'common';const YANTRA_CHAT_ORG_SLUG = "yantra-chat";
|
|
2
|
-
CHAT_WORKSPACE.CHAT_ORGANIZATION_ID;
|
|
3
|
-
CHAT_WORKSPACE.CHAT_ORGANIZATION_UUID;
|
|
2
|
+
const YANTRA_CHAT_ORG_MONGO_ID = CHAT_WORKSPACE.CHAT_ORGANIZATION_ID;
|
|
3
|
+
const YANTRA_CHAT_ORG_UUID = CHAT_WORKSPACE.CHAT_ORGANIZATION_UUID;
|
|
4
4
|
function isYantraChatOrgSlug(orgName) {
|
|
5
5
|
const trimmed = orgName == null ? void 0 : orgName.trim();
|
|
6
6
|
if (!trimmed) return false;
|
|
7
7
|
return trimmed === YANTRA_CHAT_ORG_SLUG;
|
|
8
8
|
}
|
|
9
|
+
function isYantraChatOrgKey(value) {
|
|
10
|
+
const trimmed = value == null ? void 0 : value.trim();
|
|
11
|
+
if (!trimmed) return false;
|
|
12
|
+
return trimmed === YANTRA_CHAT_ORG_SLUG || trimmed === YANTRA_CHAT_ORG_UUID || trimmed === YANTRA_CHAT_ORG_MONGO_ID;
|
|
13
|
+
}
|
|
9
14
|
function pickWorkspaceOrgSlug(orgs) {
|
|
10
15
|
var _a, _b;
|
|
11
16
|
if (!(orgs == null ? void 0 : orgs.length)) return null;
|
|
@@ -14,4 +19,4 @@ function pickWorkspaceOrgSlug(orgs) {
|
|
|
14
19
|
return name.length > 0 && !isYantraChatOrgSlug(name);
|
|
15
20
|
});
|
|
16
21
|
return (_b = (_a = first == null ? void 0 : first.name) == null ? void 0 : _a.trim()) != null ? _b : null;
|
|
17
|
-
}export{YANTRA_CHAT_ORG_SLUG,isYantraChatOrgSlug,pickWorkspaceOrgSlug};//# sourceMappingURL=yantraChatOrg.js.map
|
|
22
|
+
}export{YANTRA_CHAT_ORG_MONGO_ID,YANTRA_CHAT_ORG_SLUG,YANTRA_CHAT_ORG_UUID,isYantraChatOrgKey,isYantraChatOrgSlug,pickWorkspaceOrgSlug};//# sourceMappingURL=yantraChatOrg.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yantraChatOrg.js","sources":["../../../src/features/messaging/yantraChatOrg.ts"],"sourcesContent":["import { CHAT_WORKSPACE } from 'common';\n\n/**\n * Seeded Yantra Chat organization slug (issue #1312).\n * Used only for native person-to-person chat — not the user's default workspace org.\n */\nexport const YANTRA_CHAT_ORG_SLUG = 'yantra-chat';\n\nexport const YANTRA_CHAT_ORG_MONGO_ID = CHAT_WORKSPACE.CHAT_ORGANIZATION_ID;\n\nexport const YANTRA_CHAT_ORG_UUID = CHAT_WORKSPACE.CHAT_ORGANIZATION_UUID;\n\nexport function isYantraChatOrgSlug(orgName: string | null | undefined): boolean {\n const trimmed = orgName?.trim();\n if (!trimmed) return false;\n return trimmed === YANTRA_CHAT_ORG_SLUG;\n}\n\n/** Slug, filing UUID, or Mongo id — any key the chat org is stored under. */\nexport function isYantraChatOrgKey(value: string | null | undefined): boolean {\n const trimmed = value?.trim();\n if (!trimmed) return false;\n return trimmed === YANTRA_CHAT_ORG_SLUG || trimmed === YANTRA_CHAT_ORG_UUID || trimmed === YANTRA_CHAT_ORG_MONGO_ID;\n}\n\n/** Pick a default workspace org; never use the chat-only org for Home / AI chat / settings. */\nexport function pickWorkspaceOrgSlug(\n orgs: Array<{ name?: string | null; title?: string | null } | null | undefined> | null | undefined,\n): string | null {\n if (!orgs?.length) return null;\n const first = orgs.find((o) => {\n const name = typeof o?.name === 'string' ? o.name.trim() : '';\n return name.length > 0 && !isYantraChatOrgSlug(name);\n });\n return first?.name?.trim() ?? null;\n}\n"],"names":[],"mappings":"oCAMO,MAAM,oBAAuB,GAAA;
|
|
1
|
+
{"version":3,"file":"yantraChatOrg.js","sources":["../../../src/features/messaging/yantraChatOrg.ts"],"sourcesContent":["import { CHAT_WORKSPACE } from 'common';\n\n/**\n * Seeded Yantra Chat organization slug (issue #1312).\n * Used only for native person-to-person chat — not the user's default workspace org.\n */\nexport const YANTRA_CHAT_ORG_SLUG = 'yantra-chat';\n\nexport const YANTRA_CHAT_ORG_MONGO_ID = CHAT_WORKSPACE.CHAT_ORGANIZATION_ID;\n\nexport const YANTRA_CHAT_ORG_UUID = CHAT_WORKSPACE.CHAT_ORGANIZATION_UUID;\n\nexport function isYantraChatOrgSlug(orgName: string | null | undefined): boolean {\n const trimmed = orgName?.trim();\n if (!trimmed) return false;\n return trimmed === YANTRA_CHAT_ORG_SLUG;\n}\n\n/** Slug, filing UUID, or Mongo id — any key the chat org is stored under. */\nexport function isYantraChatOrgKey(value: string | null | undefined): boolean {\n const trimmed = value?.trim();\n if (!trimmed) return false;\n return trimmed === YANTRA_CHAT_ORG_SLUG || trimmed === YANTRA_CHAT_ORG_UUID || trimmed === YANTRA_CHAT_ORG_MONGO_ID;\n}\n\n/** Pick a default workspace org; never use the chat-only org for Home / AI chat / settings. */\nexport function pickWorkspaceOrgSlug(\n orgs: Array<{ name?: string | null; title?: string | null } | null | undefined> | null | undefined,\n): string | null {\n if (!orgs?.length) return null;\n const first = orgs.find((o) => {\n const name = typeof o?.name === 'string' ? o.name.trim() : '';\n return name.length > 0 && !isYantraChatOrgSlug(name);\n });\n return first?.name?.trim() ?? null;\n}\n"],"names":[],"mappings":"oCAMO,MAAM,oBAAuB,GAAA;AAC7B,MAAM,2BAA2B,cAAe,CAAA;AAChD,MAAM,uBAAuB,cAAe,CAAA;AAC5C,SAAS,oBAAoB,OAA6C,EAAA;AAC/E,EAAA,MAAM,UAAU,OAAS,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAA,IAAA,EAAA;AACzB,EAAI,IAAA,CAAC,SAAgB,OAAA,KAAA;AACrB,EAAA,OAAO,OAAY,KAAA,oBAAA;AACrB;AAGO,SAAS,mBAAmB,KAA2C,EAAA;AAC5E,EAAA,MAAM,UAAU,KAAO,IAAA,IAAA,GAAA,MAAA,GAAA,KAAA,CAAA,IAAA,EAAA;AACvB,EAAI,IAAA,CAAC,SAAgB,OAAA,KAAA;AACrB,EAAA,OAAO,OAAY,KAAA,oBAAA,IAAwB,OAAY,KAAA,oBAAA,IAAwB,OAAY,KAAA,wBAAA;AAC7F;AAGO,SAAS,qBAAqB,IAGoB,EAAA;AA1BzD,EAAA,IAAA,EAAA,EAAA,EAAA;AA2BE,EAAI,IAAA,EAAC,IAAM,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAA,MAAA,CAAA,EAAe,OAAA,IAAA;AAC1B,EAAM,MAAA,KAAA,GAAQ,IAAK,CAAA,IAAA,CAAK,CAAK,CAAA,KAAA;AAC3B,IAAM,MAAA,IAAA,GAAO,QAAO,CAAG,IAAA,IAAA,GAAA,MAAA,GAAA,CAAA,CAAA,IAAA,CAAA,KAAS,WAAW,CAAE,CAAA,IAAA,CAAK,MAAS,GAAA,EAAA;AAC3D,IAAA,OAAO,IAAK,CAAA,MAAA,GAAS,CAAK,IAAA,CAAC,oBAAoB,IAAI,CAAA;AAAA,GACpD,CAAA;AACD,EAAA,OAAA,CAAO,EAAO,GAAA,CAAA,EAAA,GAAA,KAAA,IAAA,IAAA,GAAA,MAAA,GAAA,KAAA,CAAA,IAAA,KAAP,IAAa,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,EAAA,KAAb,IAAuB,GAAA,EAAA,GAAA,IAAA;AAChC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import {jsx,jsxs}from'react/jsx-runtime';import {useState}from'react';import {StyleSheet,Modal,Pressable,Text,TextInput,View}from'react-native';function AnnotateModal({
|
|
2
|
+
field,
|
|
3
|
+
text,
|
|
4
|
+
onAdd,
|
|
5
|
+
onCancel,
|
|
6
|
+
theme
|
|
7
|
+
}) {
|
|
8
|
+
const [comment, setComment] = useState("");
|
|
9
|
+
return /* @__PURE__ */ jsx(Modal, { transparent: true, animationType: "fade", onRequestClose: onCancel, children: /* @__PURE__ */ jsx(Pressable, { style: styles.backdrop, onPress: onCancel, children: /* @__PURE__ */ jsxs(Pressable, { style: [styles.sheet, {
|
|
10
|
+
backgroundColor: theme.card,
|
|
11
|
+
borderColor: theme.border
|
|
12
|
+
}], onPress: (e) => e.stopPropagation(), children: [
|
|
13
|
+
/* @__PURE__ */ jsxs(Text, { style: [styles.title, {
|
|
14
|
+
color: theme.ink
|
|
15
|
+
}], children: [
|
|
16
|
+
"Annotate \xB7 ",
|
|
17
|
+
field
|
|
18
|
+
] }),
|
|
19
|
+
text ? /* @__PURE__ */ jsxs(Text, { style: [styles.quote, {
|
|
20
|
+
color: theme.muted
|
|
21
|
+
}], numberOfLines: 2, children: [
|
|
22
|
+
"\u201C",
|
|
23
|
+
text,
|
|
24
|
+
"\u201D"
|
|
25
|
+
] }) : null,
|
|
26
|
+
/* @__PURE__ */ jsx(TextInput, { value: comment, onChangeText: setComment, placeholder: "What should change?", placeholderTextColor: theme.muted, multiline: true, autoFocus: true, style: [styles.input, {
|
|
27
|
+
color: theme.ink,
|
|
28
|
+
borderColor: theme.border,
|
|
29
|
+
backgroundColor: theme.screen
|
|
30
|
+
}] }),
|
|
31
|
+
/* @__PURE__ */ jsxs(View, { style: styles.row, children: [
|
|
32
|
+
/* @__PURE__ */ jsx(Pressable, { onPress: onCancel, style: [styles.btn, {
|
|
33
|
+
borderColor: theme.border
|
|
34
|
+
}], children: /* @__PURE__ */ jsx(Text, { style: {
|
|
35
|
+
color: theme.muted,
|
|
36
|
+
fontWeight: "600"
|
|
37
|
+
}, children: "Cancel" }) }),
|
|
38
|
+
/* @__PURE__ */ jsx(Pressable, { onPress: () => onAdd(comment.trim(), false), disabled: !comment.trim(), style: [styles.btn, {
|
|
39
|
+
borderColor: theme.border,
|
|
40
|
+
opacity: comment.trim() ? 1 : 0.5
|
|
41
|
+
}], children: /* @__PURE__ */ jsx(Text, { style: {
|
|
42
|
+
color: theme.ink,
|
|
43
|
+
fontWeight: "600"
|
|
44
|
+
}, children: "Add" }) }),
|
|
45
|
+
/* @__PURE__ */ jsx(Pressable, { onPress: () => onAdd(comment.trim(), true), disabled: !comment.trim(), style: [styles.btn, styles.primary, {
|
|
46
|
+
backgroundColor: theme.accent,
|
|
47
|
+
opacity: comment.trim() ? 1 : 0.5
|
|
48
|
+
}], children: /* @__PURE__ */ jsx(Text, { style: {
|
|
49
|
+
color: theme.accentInk,
|
|
50
|
+
fontWeight: "700"
|
|
51
|
+
}, children: "Send" }) })
|
|
52
|
+
] })
|
|
53
|
+
] }) }) });
|
|
54
|
+
}
|
|
55
|
+
const styles = StyleSheet.create({
|
|
56
|
+
backdrop: {
|
|
57
|
+
flex: 1,
|
|
58
|
+
backgroundColor: "rgba(15,23,42,0.45)",
|
|
59
|
+
justifyContent: "center",
|
|
60
|
+
padding: 24
|
|
61
|
+
},
|
|
62
|
+
sheet: {
|
|
63
|
+
borderRadius: 16,
|
|
64
|
+
borderWidth: StyleSheet.hairlineWidth,
|
|
65
|
+
padding: 16
|
|
66
|
+
},
|
|
67
|
+
title: {
|
|
68
|
+
fontSize: 16,
|
|
69
|
+
fontWeight: "700",
|
|
70
|
+
marginBottom: 6
|
|
71
|
+
},
|
|
72
|
+
quote: {
|
|
73
|
+
fontSize: 12,
|
|
74
|
+
fontStyle: "italic",
|
|
75
|
+
marginBottom: 10
|
|
76
|
+
},
|
|
77
|
+
input: {
|
|
78
|
+
minHeight: 88,
|
|
79
|
+
borderWidth: StyleSheet.hairlineWidth,
|
|
80
|
+
borderRadius: 10,
|
|
81
|
+
padding: 12,
|
|
82
|
+
fontSize: 14,
|
|
83
|
+
textAlignVertical: "top"
|
|
84
|
+
},
|
|
85
|
+
row: {
|
|
86
|
+
flexDirection: "row",
|
|
87
|
+
gap: 8,
|
|
88
|
+
marginTop: 14,
|
|
89
|
+
justifyContent: "flex-end"
|
|
90
|
+
},
|
|
91
|
+
btn: {
|
|
92
|
+
borderWidth: StyleSheet.hairlineWidth,
|
|
93
|
+
borderRadius: 10,
|
|
94
|
+
paddingHorizontal: 14,
|
|
95
|
+
paddingVertical: 10
|
|
96
|
+
},
|
|
97
|
+
primary: {
|
|
98
|
+
borderWidth: 0
|
|
99
|
+
}
|
|
100
|
+
});export{AnnotateModal};//# sourceMappingURL=AnnotateModal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnnotateModal.js","sources":["../../../src/features/resume/AnnotateModal.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { Modal, Pressable, StyleSheet, Text, TextInput, View } from 'react-native';\nimport type { ResumeTheme } from './resumeTheme';\n\nexport function AnnotateModal({\n field,\n text,\n onAdd,\n onCancel,\n theme,\n}: {\n field: string;\n text: string;\n onAdd: (comment: string, sendNow: boolean) => void;\n onCancel: () => void;\n theme: ResumeTheme;\n}) {\n const [comment, setComment] = useState('');\n return (\n <Modal transparent animationType=\"fade\" onRequestClose={onCancel}>\n <Pressable style={styles.backdrop} onPress={onCancel}>\n <Pressable\n style={[styles.sheet, { backgroundColor: theme.card, borderColor: theme.border }]}\n onPress={(e) => e.stopPropagation()}\n >\n <Text style={[styles.title, { color: theme.ink }]}>Annotate · {field}</Text>\n {text ? (\n <Text style={[styles.quote, { color: theme.muted }]} numberOfLines={2}>\n “{text}”\n </Text>\n ) : null}\n <TextInput\n value={comment}\n onChangeText={setComment}\n placeholder=\"What should change?\"\n placeholderTextColor={theme.muted}\n multiline\n autoFocus\n style={[\n styles.input,\n { color: theme.ink, borderColor: theme.border, backgroundColor: theme.screen },\n ]}\n />\n <View style={styles.row}>\n <Pressable onPress={onCancel} style={[styles.btn, { borderColor: theme.border }]}>\n <Text style={{ color: theme.muted, fontWeight: '600' }}>Cancel</Text>\n </Pressable>\n <Pressable\n onPress={() => onAdd(comment.trim(), false)}\n disabled={!comment.trim()}\n style={[styles.btn, { borderColor: theme.border, opacity: comment.trim() ? 1 : 0.5 }]}\n >\n <Text style={{ color: theme.ink, fontWeight: '600' }}>Add</Text>\n </Pressable>\n <Pressable\n onPress={() => onAdd(comment.trim(), true)}\n disabled={!comment.trim()}\n style={[\n styles.btn,\n styles.primary,\n { backgroundColor: theme.accent, opacity: comment.trim() ? 1 : 0.5 },\n ]}\n >\n <Text style={{ color: theme.accentInk, fontWeight: '700' }}>Send</Text>\n </Pressable>\n </View>\n </Pressable>\n </Pressable>\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n backdrop: {\n flex: 1,\n backgroundColor: 'rgba(15,23,42,0.45)',\n justifyContent: 'center',\n padding: 24,\n },\n sheet: { borderRadius: 16, borderWidth: StyleSheet.hairlineWidth, padding: 16 },\n title: { fontSize: 16, fontWeight: '700', marginBottom: 6 },\n quote: { fontSize: 12, fontStyle: 'italic', marginBottom: 10 },\n input: {\n minHeight: 88,\n borderWidth: StyleSheet.hairlineWidth,\n borderRadius: 10,\n padding: 12,\n fontSize: 14,\n textAlignVertical: 'top',\n },\n row: { flexDirection: 'row', gap: 8, marginTop: 14, justifyContent: 'flex-end' },\n btn: {\n borderWidth: StyleSheet.hairlineWidth,\n borderRadius: 10,\n paddingHorizontal: 14,\n paddingVertical: 10,\n },\n primary: { borderWidth: 0 },\n});\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import {jsxs,jsx}from'react/jsx-runtime';import {StyleSheet,View,ScrollView,Text,Pressable}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';function AnnotationBar({
|
|
2
|
+
picks,
|
|
3
|
+
onRemove,
|
|
4
|
+
onSend,
|
|
5
|
+
busy,
|
|
6
|
+
theme
|
|
7
|
+
}) {
|
|
8
|
+
if (!picks.length) return null;
|
|
9
|
+
return /* @__PURE__ */ jsxs(View, { style: [styles.wrap, {
|
|
10
|
+
backgroundColor: theme.card,
|
|
11
|
+
borderTopColor: theme.border
|
|
12
|
+
}], children: [
|
|
13
|
+
/* @__PURE__ */ jsx(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, contentContainerStyle: styles.chips, children: picks.map((p, i) => /* @__PURE__ */ jsxs(View, { style: [styles.chip, {
|
|
14
|
+
backgroundColor: theme.accentSoft
|
|
15
|
+
}], children: [
|
|
16
|
+
/* @__PURE__ */ jsxs(Text, { style: {
|
|
17
|
+
color: theme.accent,
|
|
18
|
+
fontSize: 11,
|
|
19
|
+
fontWeight: "600",
|
|
20
|
+
maxWidth: 140
|
|
21
|
+
}, numberOfLines: 1, children: [
|
|
22
|
+
p.field,
|
|
23
|
+
": ",
|
|
24
|
+
p.comment
|
|
25
|
+
] }),
|
|
26
|
+
/* @__PURE__ */ jsx(Pressable, { onPress: () => onRemove(i), hitSlop: 6, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "close", size: 14, color: theme.accent }) })
|
|
27
|
+
] }, `${p.field}-${i}`)) }),
|
|
28
|
+
/* @__PURE__ */ jsx(Pressable, { onPress: onSend, disabled: busy, style: [styles.send, {
|
|
29
|
+
backgroundColor: theme.accent,
|
|
30
|
+
opacity: busy ? 0.6 : 1
|
|
31
|
+
}], children: /* @__PURE__ */ jsxs(Text, { style: {
|
|
32
|
+
color: theme.accentInk,
|
|
33
|
+
fontWeight: "700",
|
|
34
|
+
fontSize: 13
|
|
35
|
+
}, children: [
|
|
36
|
+
"Send ",
|
|
37
|
+
picks.length,
|
|
38
|
+
" edit",
|
|
39
|
+
picks.length === 1 ? "" : "s"
|
|
40
|
+
] }) })
|
|
41
|
+
] });
|
|
42
|
+
}
|
|
43
|
+
const styles = StyleSheet.create({
|
|
44
|
+
wrap: {
|
|
45
|
+
borderTopWidth: StyleSheet.hairlineWidth,
|
|
46
|
+
paddingVertical: 8,
|
|
47
|
+
paddingHorizontal: 10,
|
|
48
|
+
gap: 8
|
|
49
|
+
},
|
|
50
|
+
chips: {
|
|
51
|
+
gap: 8,
|
|
52
|
+
alignItems: "center",
|
|
53
|
+
paddingRight: 8
|
|
54
|
+
},
|
|
55
|
+
chip: {
|
|
56
|
+
flexDirection: "row",
|
|
57
|
+
alignItems: "center",
|
|
58
|
+
gap: 6,
|
|
59
|
+
borderRadius: 16,
|
|
60
|
+
paddingHorizontal: 10,
|
|
61
|
+
paddingVertical: 6
|
|
62
|
+
},
|
|
63
|
+
send: {
|
|
64
|
+
alignSelf: "flex-end",
|
|
65
|
+
borderRadius: 10,
|
|
66
|
+
paddingHorizontal: 14,
|
|
67
|
+
paddingVertical: 10
|
|
68
|
+
}
|
|
69
|
+
});export{AnnotationBar};//# sourceMappingURL=AnnotationBar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnnotationBar.js","sources":["../../../src/features/resume/AnnotationBar.tsx"],"sourcesContent":["import React from 'react';\nimport { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport type { AnnotationPick } from './annotations';\nimport type { ResumeTheme } from './resumeTheme';\n\nexport function AnnotationBar({\n picks,\n onRemove,\n onSend,\n busy,\n theme,\n}: {\n picks: AnnotationPick[];\n onRemove: (index: number) => void;\n onSend: () => void;\n busy?: boolean;\n theme: ResumeTheme;\n}) {\n if (!picks.length) return null;\n return (\n <View style={[styles.wrap, { backgroundColor: theme.card, borderTopColor: theme.border }]}>\n <ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.chips}>\n {picks.map((p, i) => (\n <View key={`${p.field}-${i}`} style={[styles.chip, { backgroundColor: theme.accentSoft }]}>\n <Text\n style={{ color: theme.accent, fontSize: 11, fontWeight: '600', maxWidth: 140 }}\n numberOfLines={1}\n >\n {p.field}: {p.comment}\n </Text>\n <Pressable onPress={() => onRemove(i)} hitSlop={6}>\n <MaterialCommunityIcons name=\"close\" size={14} color={theme.accent} />\n </Pressable>\n </View>\n ))}\n </ScrollView>\n <Pressable\n onPress={onSend}\n disabled={busy}\n style={[styles.send, { backgroundColor: theme.accent, opacity: busy ? 0.6 : 1 }]}\n >\n <Text style={{ color: theme.accentInk, fontWeight: '700', fontSize: 13 }}>\n Send {picks.length} edit{picks.length === 1 ? '' : 's'}\n </Text>\n </Pressable>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n wrap: {\n borderTopWidth: StyleSheet.hairlineWidth,\n paddingVertical: 8,\n paddingHorizontal: 10,\n gap: 8,\n },\n chips: { gap: 8, alignItems: 'center', paddingRight: 8 },\n chip: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 6,\n borderRadius: 16,\n paddingHorizontal: 10,\n paddingVertical: 6,\n },\n send: {\n alignSelf: 'flex-end',\n borderRadius: 10,\n paddingHorizontal: 14,\n paddingVertical: 10,\n },\n});\n"],"names":[],"mappings":"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"}
|