@adminide-stack/yantra-mobile 12.0.28-alpha.9 → 12.0.28-alpha.92

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 (85) hide show
  1. package/lib/api/stt.js +54 -0
  2. package/lib/api/stt.js.map +1 -0
  3. package/lib/assets/icon.png +0 -0
  4. package/lib/components/CustomDrawer.js +479 -0
  5. package/lib/components/CustomDrawer.js.map +1 -0
  6. package/lib/components/GatewayConnector/GatewayConnector.js +18 -0
  7. package/lib/components/GatewayConnector/GatewayConnector.js.map +1 -0
  8. package/lib/components/GatewayToolbarButtonMobile.js +84 -0
  9. package/lib/components/GatewayToolbarButtonMobile.js.map +1 -0
  10. package/lib/components/NavigationHeader/NavigationHeader.js +214 -0
  11. package/lib/components/NavigationHeader/NavigationHeader.js.map +1 -0
  12. package/lib/components/ThinkingIndicator.js +55 -0
  13. package/lib/components/ThinkingIndicator.js.map +1 -0
  14. package/lib/components/YantraBrandLoader.js +94 -0
  15. package/lib/components/YantraBrandLoader.js.map +1 -0
  16. package/lib/compute.js +114 -5
  17. package/lib/compute.js.map +1 -1
  18. package/lib/config/constants.js +18 -0
  19. package/lib/config/constants.js.map +1 -0
  20. package/lib/config/env-config.js +75 -19
  21. package/lib/config/env-config.js.map +1 -1
  22. package/lib/contexts/CdecliConnectionContext.js +47 -0
  23. package/lib/contexts/CdecliConnectionContext.js.map +1 -0
  24. package/lib/contexts/GatewayContext.js +77 -0
  25. package/lib/contexts/GatewayContext.js.map +1 -0
  26. package/lib/features/audio-input/AudioRecorderPanel.js +220 -0
  27. package/lib/features/audio-input/AudioRecorderPanel.js.map +1 -0
  28. package/lib/features/audio-input/MicErrorBoundary.js +34 -0
  29. package/lib/features/audio-input/MicErrorBoundary.js.map +1 -0
  30. package/lib/features/audio-input/useAudioPermission.js +24 -0
  31. package/lib/features/audio-input/useAudioPermission.js.map +1 -0
  32. package/lib/graphql/agentGatewayDocuments.js +53 -0
  33. package/lib/graphql/agentGatewayDocuments.js.map +1 -0
  34. package/lib/hooks/useAccountDefaultSettings.js +38 -0
  35. package/lib/hooks/useAccountDefaultSettings.js.map +1 -0
  36. package/lib/hooks/useCdecliAutoConnect.js +244 -0
  37. package/lib/hooks/useCdecliAutoConnect.js.map +1 -0
  38. package/lib/hooks/useCdecliChannel.js +161 -0
  39. package/lib/hooks/useCdecliChannel.js.map +1 -0
  40. package/lib/hooks/useChatApi.js +386 -170
  41. package/lib/hooks/useChatApi.js.map +1 -1
  42. package/lib/hooks/useChatStream.js +179 -137
  43. package/lib/hooks/useChatStream.js.map +1 -1
  44. package/lib/hooks/useGatewayConnection.js +123 -0
  45. package/lib/hooks/useGatewayConnection.js.map +1 -0
  46. package/lib/hooks/useGatewayRegistry.js +28 -0
  47. package/lib/hooks/useGatewayRegistry.js.map +1 -0
  48. package/lib/hooks/usePrerequisiteIds.js +209 -0
  49. package/lib/hooks/usePrerequisiteIds.js.map +1 -0
  50. package/lib/hooks/useWorkspaceProvisioner.js +236 -0
  51. package/lib/hooks/useWorkspaceProvisioner.js.map +1 -0
  52. package/lib/index.js +1 -1
  53. package/lib/index.js.map +1 -1
  54. package/lib/routes.json +120 -5
  55. package/lib/screens/Chat/index.js +409 -0
  56. package/lib/screens/Chat/index.js.map +1 -0
  57. package/lib/screens/ChatHistory/index.js +56 -0
  58. package/lib/screens/ChatHistory/index.js.map +1 -0
  59. package/lib/screens/Home/HomeScreen.js +364 -144
  60. package/lib/screens/Home/HomeScreen.js.map +1 -1
  61. package/lib/screens/Home/components/ChatHistoryLanding.js +487 -0
  62. package/lib/screens/Home/components/ChatHistoryLanding.js.map +1 -0
  63. package/lib/screens/Home/components/DeepSearchModal.js +349 -0
  64. package/lib/screens/Home/components/DeepSearchModal.js.map +1 -0
  65. package/lib/screens/Home/deepSearchUtils.js +41 -0
  66. package/lib/screens/Home/deepSearchUtils.js.map +1 -0
  67. package/lib/screens/NewChat/index.js +43 -0
  68. package/lib/screens/NewChat/index.js.map +1 -0
  69. package/lib/services/agentSessionManager.js +451 -0
  70. package/lib/services/agentSessionManager.js.map +1 -0
  71. package/lib/services/gatewayApiKeyBridge.js +4 -0
  72. package/lib/services/gatewayApiKeyBridge.js.map +1 -0
  73. package/lib/services/gatewayClient.js +470 -0
  74. package/lib/services/gatewayClient.js.map +1 -0
  75. package/lib/theme/mobileTokens.js +18 -0
  76. package/lib/theme/mobileTokens.js.map +1 -0
  77. package/lib/utils/cdecodeUri.js +68 -0
  78. package/lib/utils/cdecodeUri.js.map +1 -0
  79. package/lib/utils/gatewaySelectionStorage.js +21 -0
  80. package/lib/utils/gatewaySelectionStorage.js.map +1 -0
  81. package/lib/utils/syncMobileOrgRouteContext.js +61 -0
  82. package/lib/utils/syncMobileOrgRouteContext.js.map +1 -0
  83. package/package.json +7 -3
  84. package/lib/api/chatApi.js +0 -102
  85. package/lib/api/chatApi.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatHistoryLanding.js","sources":["../../../../src/screens/Home/components/ChatHistoryLanding.tsx"],"sourcesContent":["import React from 'react';\nimport {\n ActivityIndicator,\n Pressable,\n RefreshControl,\n SectionList,\n StyleSheet,\n View,\n useColorScheme,\n useWindowDimensions,\n} from 'react-native';\nimport { Feather, MaterialCommunityIcons } from '@expo/vector-icons';\nimport { Text } from '@admin-layout/gluestack-ui-mobile';\nimport { useFocusEffect } from '@react-navigation/native';\nimport {\n HISTORY_PAGE_SIZE,\n chatHistorySessionsFromChannels,\n getHistoryChannelsQueryVariables,\n useChatHistorySessionsFromChannels,\n type ChatHistoryMode,\n type ChatHistorySession,\n} from '../../../hooks/useChatApi';\nimport { useApolloClient } from '@apollo/client';\nimport { GetChannelsByUserWithLastMessageDocument } from 'common/graphql';\nimport { usePrerequisiteIds } from '../../../hooks/usePrerequisiteIds';\nimport ThinkingIndicator from '../../../components/ThinkingIndicator';\nimport { mobileTokens } from '../../../theme/mobileTokens';\n\n/**\n * Chat history list for mobile.\n *\n * Data: `useGetChannelsByUserWithLastMessageQuery` returning one row per channel\n * with `lastMessage` carrying the parent user prompt and the assistant reply.\n *\n * Layout: Manus-style two-line row — 40×40 leading mode tile, **line 1** =\n * `lastMessage.propsConfiguration.contents.parent.message` (user prompt),\n * **line 2** = `lastMessage.message` (latest post body, including agent errors\n * such as lines starting with ⚠), right-aligned short date. Indigo-tinted\n * neutrals so the surface stays in the Yantra brand register.\n *\n * Mode tile carries real information (chat vs deep-search), not decoration —\n * different modes get different glyphs and tints.\n */\ninterface ChatHistoryLandingProps {\n /**\n * `mode` is derived per-row via `detectMode(channel)` so the Chat screen can\n * render its composer in the correct mode (deep-search vs chat) without\n * needing to re-fetch the channel after navigation. Plain chat threads get\n * `'chat'` here even though it's the default — being explicit at the\n * boundary keeps the consumer's switch statement total.\n */\n onSelectSession: (channelId: string, mode: ChatHistoryMode) => void;\n /** Kept in the contract; not surfaced here — new-chat lives in the screen header. */\n onCompose: () => void;\n}\n\ninterface SessionRow extends ChatHistorySession {\n id: string;\n /** Pre-truncated title for one-line render. */\n titleForRender: string;\n /** Pre-truncated preview for one-line render (empty if suppressed upstream). */\n previewForRender: string;\n /** Cached unix-ms for bucketing / sorting. */\n sortAt: number;\n}\n\ninterface SessionSection {\n key: 'today' | 'yesterday' | 'week' | 'earlier';\n title: string;\n data: SessionRow[];\n}\n\nfunction truncate(text: string, max = 96): string {\n const cleaned = text.replace(/\\s+/g, ' ').trim();\n if (cleaned.length <= max) return cleaned;\n return `${cleaned.slice(0, max).trim()}...`;\n}\n\nconst WEEKDAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\n\nfunction relativeTime(ts: number, now: number): string {\n const deltaMs = now - ts;\n if (deltaMs < 60_000) return 'now';\n const minutes = Math.floor(deltaMs / 60_000);\n if (minutes < 60) return `${minutes}m`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h`;\n const days = Math.floor(hours / 24);\n if (days < 7) {\n const d = new Date(ts);\n return WEEKDAYS[d.getDay()] ?? `${days}d`;\n }\n /**\n * 7d+: numeric short date (e.g. \"2/18\" matching the Manus reference). Year only\n * appears when crossing into a previous year, to keep the right column compact.\n */\n const d = new Date(ts);\n const sameYear = d.getFullYear() === new Date(now).getFullYear();\n const m = d.getMonth() + 1;\n const day = d.getDate();\n return sameYear ? `${m}/${day}` : `${m}/${day}/${String(d.getFullYear()).slice(2)}`;\n}\n\nfunction bucketFor(ts: number, now: number): SessionSection['key'] {\n const a = new Date(ts);\n const b = new Date(now);\n const startOf = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();\n const today = startOf(b);\n const yesterday = today - 24 * 60 * 60 * 1000;\n const weekAgo = today - 7 * 24 * 60 * 60 * 1000;\n const tsDay = startOf(a);\n if (tsDay >= today) return 'today';\n if (tsDay >= yesterday) return 'yesterday';\n if (tsDay >= weekAgo) return 'week';\n return 'earlier';\n}\n\nfunction buildSections(rows: SessionRow[], now: number): SessionSection[] {\n const buckets: Record<SessionSection['key'], SessionRow[]> = {\n today: [],\n yesterday: [],\n week: [],\n earlier: [],\n };\n for (const row of rows) {\n buckets[bucketFor(row.sortAt, now)].push(row);\n }\n const out: SessionSection[] = [];\n if (buckets.today.length) out.push({ key: 'today', title: 'Today', data: buckets.today });\n if (buckets.yesterday.length) out.push({ key: 'yesterday', title: 'Yesterday', data: buckets.yesterday });\n if (buckets.week.length) out.push({ key: 'week', title: 'This week', data: buckets.week });\n if (buckets.earlier.length) out.push({ key: 'earlier', title: 'Earlier', data: buckets.earlier });\n return out;\n}\n\n/**\n * Theme tokens.\n *\n * Color strategy: Monochrome ink. Chrome (section labels, chat tile, load-more\n * pill, end-of-list dot, press wash, refresh spinner) is rendered in tinted\n * neutrals so the only real color on the screen is the deep-search amber —\n * which then reliably signals a mode, not decoration. Neutrals carry chroma\n * 0.005–0.01 toward the brand hue (no pure `#fff` / `#000`).\n */\ninterface ThemeTokens {\n bg: string;\n surface: string;\n title: string;\n preview: string;\n meta: string;\n muted: string;\n divider: string;\n sectionLabel: string;\n /** Mode tile (chat) — neutral ink on neutral fill. */\n tileChatBg: string;\n tileChatIcon: string;\n /** Mode tile (deep-search) — amber kept as the one real mode color. */\n tileSearchBg: string;\n tileSearchIcon: string;\n pressed: string;\n loadMoreText: string;\n loadMoreBorder: string;\n loadMoreBg: string;\n refreshTint: string;\n endDot: string;\n /**\n * Empty-state mark — circular soft-neutral disk holding a chat glyph.\n * Matches the web reference (gray-on-gray circle), not the row mode tile.\n */\n emptyMarkBg: string;\n emptyMarkIcon: string;\n}\n\nfunction buildTheme(isDark: boolean): ThemeTokens {\n if (isDark) {\n return {\n bg: '#0b1220',\n surface: mobileTokens.color.surface,\n title: '#f1f5f9',\n preview: '#94a3b8',\n meta: '#9aa0b8',\n muted: '#7a809a',\n divider: 'rgba(148, 163, 184, 0.12)',\n sectionLabel: '#cbd5e1',\n tileChatBg: 'rgba(148, 163, 184, 0.16)',\n tileChatIcon: '#e2e8f0',\n tileSearchBg: 'rgba(251, 191, 36, 0.16)',\n tileSearchIcon: '#fde68a',\n pressed: 'rgba(148, 163, 184, 0.10)',\n loadMoreText: '#e2e8f0',\n loadMoreBorder: 'rgba(148, 163, 184, 0.28)',\n loadMoreBg: 'rgba(148, 163, 184, 0.10)',\n refreshTint: '#cbd5e1',\n endDot: '#94a3b8',\n emptyMarkBg: 'rgba(148, 163, 184, 0.18)',\n emptyMarkIcon: '#b4bccc',\n };\n }\n return {\n bg: mobileTokens.color.bg,\n surface: mobileTokens.color.surface,\n title: '#0b1424',\n preview: '#525a73',\n meta: '#7b8197',\n muted: '#94a3b8',\n divider: 'rgba(15, 23, 42, 0.06)',\n sectionLabel: '#374151',\n tileChatBg: 'rgba(15, 23, 42, 0.06)',\n tileChatIcon: '#1f2937',\n tileSearchBg: 'rgba(217, 119, 6, 0.10)',\n tileSearchIcon: '#b45309',\n pressed: 'rgba(15, 23, 42, 0.05)',\n loadMoreText: '#1f2937',\n loadMoreBorder: 'rgba(15, 23, 42, 0.15)',\n loadMoreBg: 'rgba(15, 23, 42, 0.04)',\n refreshTint: '#374151',\n endDot: '#9ca3af',\n emptyMarkBg: 'rgba(15, 23, 42, 0.07)',\n emptyMarkIcon: '#6b7280',\n };\n}\n\n/**\n * Leading 40×40 mode tile. Background and glyph reflect the conversation mode:\n * - chat → Lucide-style message bubble on indigo-tinted neutral\n * - deep-search → lightning glyph on amber-tinted neutral\n *\n * Chat uses Feather (a Lucide port) so the row tile, the empty-state mark, and\n * the web header all share one bubble silhouette. Deep-search stays on MCI —\n * Feather has no acceptable lightning glyph and the amber/indigo split is\n * already the primary mode signal.\n *\n * Real information per row, not decoration.\n */\nfunction ModeTile({ mode, theme }: { mode: ChatHistoryMode; theme: ThemeTokens }) {\n const isSearch = mode === 'deep-search';\n return (\n <View style={[styles.tile, { backgroundColor: isSearch ? theme.tileSearchBg : theme.tileChatBg }]}>\n {isSearch ? (\n <MaterialCommunityIcons name=\"lightning-bolt-outline\" size={18} color={theme.tileSearchIcon} />\n ) : (\n <Feather name=\"message-circle\" size={18} color={theme.tileChatIcon} />\n )}\n </View>\n );\n}\n\nfunction ChatHistoryRow({\n session,\n onSelectSession,\n theme,\n timeLabel,\n}: {\n session: SessionRow;\n onSelectSession: (channelId: string, mode: ChatHistoryMode) => void;\n theme: ThemeTokens;\n timeLabel: string;\n}) {\n const titleColor = session.isPlaceholder ? theme.preview : theme.title;\n const titleStyle = [\n styles.rowTitle,\n { color: titleColor },\n session.isPlaceholder ? styles.rowTitlePlaceholder : null,\n ];\n return (\n <Pressable\n onPress={() => onSelectSession(session.channelId, session.mode)}\n style={({ pressed }) => [styles.row, pressed && { backgroundColor: theme.pressed }]}\n accessibilityRole=\"button\"\n accessibilityLabel={\n session.previewForRender\n ? `Open conversation: ${session.titleForRender}. ${session.previewForRender}. ${timeLabel}`\n : `Open conversation: ${session.titleForRender}, ${timeLabel}`\n }\n >\n <ModeTile mode={session.mode} theme={theme} />\n <View style={styles.rowBody}>\n <View style={styles.rowHeader}>\n <Text style={titleStyle} numberOfLines={1} ellipsizeMode=\"tail\">\n {session.titleForRender}\n </Text>\n <Text style={[styles.rowDate, { color: theme.meta }]} numberOfLines={1}>\n {timeLabel}\n </Text>\n </View>\n {session.previewForRender ? (\n <Text style={[styles.rowPreview, { color: theme.preview }]} numberOfLines={1} ellipsizeMode=\"tail\">\n {session.previewForRender}\n </Text>\n ) : null}\n </View>\n </Pressable>\n );\n}\n\nexport default function ChatHistoryLanding({ onSelectSession }: ChatHistoryLandingProps) {\n const { width: screenWidth } = useWindowDimensions();\n const colorScheme = useColorScheme();\n const isDark = colorScheme === 'dark';\n const theme = React.useMemo(() => buildTheme(isDark), [isDark]);\n\n const apollo = useApolloClient();\n const { orgName, loading: idsLoading } = usePrerequisiteIds();\n\n const {\n sessions: liveSessions,\n sessionsLoaded,\n refetch,\n sourceChannelCount,\n } = useChatHistorySessionsFromChannels(orgName, { skip: !orgName });\n\n /** \"Now\" reference recomputed on refresh so relative timestamps re-evaluate cleanly. */\n const [nowTs, setNowTs] = React.useState(() => Date.now());\n const [refreshing, setRefreshing] = React.useState(false);\n /** Manually fetched older pages (channel-paginated, appended). */\n const [olderSessions, setOlderSessions] = React.useState<ChatHistorySession[]>([]);\n /** True only when the last fetch returned a full page of channels (there may be more). */\n const [hasMore, setHasMore] = React.useState(false);\n const [loadingMore, setLoadingMore] = React.useState(false);\n\n /**\n * \"Load older\" eligibility tracks the live first page's raw channel count.\n * When older pages are appended, `onLoadMore` updates `hasMore` from its\n * own response. When older pages are reset (refresh), this effect realigns.\n */\n React.useEffect(() => {\n if (olderSessions.length > 0) return;\n setHasMore(sourceChannelCount >= HISTORY_PAGE_SIZE);\n }, [sourceChannelCount, olderSessions.length]);\n\n /** Re-fetch first page on focus (e.g. returning from a chat). */\n useFocusEffect(\n React.useCallback(() => {\n if (!orgName) return;\n void refetch(getHistoryChannelsQueryVariables(orgName)).catch(() => {\n /* network errors surface in the watched query state. */\n });\n }, [orgName, refetch]),\n );\n\n const onRefresh = React.useCallback(async () => {\n if (!orgName) return;\n setRefreshing(true);\n try {\n await refetch(getHistoryChannelsQueryVariables(orgName));\n setOlderSessions([]);\n setNowTs(Date.now());\n } catch {\n /* refetch errors surface via loading state. */\n } finally {\n setRefreshing(false);\n }\n }, [orgName, refetch]);\n\n /**\n * \"Load older\": one-off `client.query` against `channelsByUser` with the next\n * `skip`. We don't bump the watched query's variables (that would re-key the\n * cache slot and shrink `liveSessions`).\n */\n const onLoadMore = React.useCallback(async () => {\n if (!orgName || loadingMore || !hasMore) return;\n setLoadingMore(true);\n try {\n const nextSkip = liveSessions.length + olderSessions.length;\n const result = await apollo.query({\n query: GetChannelsByUserWithLastMessageDocument,\n variables: getHistoryChannelsQueryVariables(orgName, {\n skip: nextSkip,\n limit: HISTORY_PAGE_SIZE,\n }),\n fetchPolicy: 'network-only',\n });\n const rawCount = (result.data?.channelsByUser ?? []).length;\n const nextBatch = chatHistorySessionsFromChannels(result.data as any);\n if (nextBatch.length === 0) {\n setHasMore(false);\n } else {\n setOlderSessions((prev) => {\n const map = new Map<string, ChatHistorySession>();\n for (const s of prev) map.set(s.channelId, s);\n for (const s of nextBatch) map.set(s.channelId, s);\n return Array.from(map.values());\n });\n setHasMore(rawCount >= HISTORY_PAGE_SIZE);\n }\n } catch {\n /* next \"Load older\" tap retries the same skip. */\n } finally {\n setLoadingMore(false);\n }\n }, [apollo, hasMore, liveSessions.length, loadingMore, olderSessions, orgName]);\n\n /**\n * Merge live + older, dedupe on channelId (live wins so streaming title /\n * lastMessage updates are reflected), sort descending by activity, then\n * pre-truncate strings for one-line render.\n */\n const sessions: SessionRow[] = React.useMemo(() => {\n const map = new Map<string, ChatHistorySession>();\n for (const s of olderSessions) map.set(s.channelId, s);\n for (const s of liveSessions) map.set(s.channelId, s);\n return Array.from(map.values())\n .sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime())\n .map((s) => ({\n ...s,\n id: s.channelId,\n titleForRender: truncate(s.title, 64),\n previewForRender: s.preview ? truncate(s.preview, 96) : '',\n sortAt: s.updatedAt.getTime(),\n }));\n }, [liveSessions, olderSessions]);\n\n const sections = React.useMemo(() => buildSections(sessions, nowTs), [sessions, nowTs]);\n /**\n * Initial-load window: the loader shows ONLY before we have data we can\n * render — i.e. before prerequisite ids resolve or before Apollo has served\n * a result (cache or network) for this org.\n *\n * Critically, `sessionsLoaded` (`data !== undefined`) flips true synchronously\n * on a cache hit, so revisiting the screen does not re-flash the loader while\n * Apollo revalidates in the background. We also do NOT gate on\n * `sessions.length === 0` here — a cached-but-empty list should drop straight\n * into the dedicated empty state, not the spinner.\n */\n const initialLoading = !sessionsLoaded || idsLoading || !orgName;\n const contentMaxWidth = Math.min(720, Math.max(360, screenWidth - 24));\n const containerStyle = { maxWidth: contentMaxWidth, alignSelf: 'center' as const, width: '100%' as const };\n\n const listFooter = hasMore ? (\n <View style={[styles.footer, containerStyle]}>\n <Pressable\n onPress={() => void onLoadMore()}\n disabled={loadingMore}\n style={({ pressed }) => [\n styles.loadMore,\n {\n backgroundColor: theme.loadMoreBg,\n borderColor: theme.loadMoreBorder,\n },\n loadingMore && { opacity: 0.7 },\n pressed && !loadingMore && { opacity: 0.8 },\n ]}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Load older conversations\"\n >\n {loadingMore ? (\n <ActivityIndicator size=\"small\" color={theme.loadMoreText} />\n ) : (\n <Text style={[styles.loadMoreText, { color: theme.loadMoreText }]}>Load older</Text>\n )}\n </Pressable>\n </View>\n ) : !hasMore && sessions.length > 0 ? (\n <View style={[styles.endHint, containerStyle]}>\n <View style={[styles.endHintDot, { backgroundColor: theme.endDot, opacity: 0.5 }]} />\n <Text style={[styles.endHintText, { color: theme.muted }]}>{\"You're all caught up\"}</Text>\n </View>\n ) : (\n <View style={{ height: 24 }} />\n );\n\n /**\n * Hairline divider between rows, inset to start where the title column does\n * (past the 40px tile + 14px gap = 54px). Quieter than full-bleed; confirms\n * the column the eye is scanning.\n */\n const renderItemSeparator = React.useCallback(\n () => <View style={[styles.divider, { backgroundColor: theme.divider }]} />,\n [theme.divider],\n );\n\n return (\n <View style={[styles.container, { backgroundColor: theme.bg }]}>\n {initialLoading ? (\n /**\n * Initial-fetch state mirrors the web composer's \"Thinking…\" pill\n * (see `packages-modules/account/browser/src/pages/chat/ChatSessionPage.tsx`):\n * a thin spinning arc + 12px muted caption, both tinted with\n * `theme.muted` so the indicator reads as a quiet status row\n * rather than a brand-stamped loading screen.\n */\n <View style={styles.emptyStateWrap}>\n <ThinkingIndicator color={theme.muted} />\n </View>\n ) : sessions.length === 0 ? (\n <View style={styles.emptyStateWrap}>\n {/**\n * Empty-state mark: circular neutral disk with a Lucide-style chat\n * bubble. Uses Feather (same glyph family as the web's lucide-react\n * `MessageCircle`) instead of MCI so the rounded body + tail proportions\n * match the web reference 1:1. Glyph fills ~55% of the disk so it\n * reads as a real focal point, not decoration.\n */}\n <View style={[styles.emptyMark, { backgroundColor: theme.emptyMarkBg }]}>\n <Feather name=\"message-circle\" size={40} color={theme.emptyMarkIcon} />\n </View>\n <Text style={[styles.emptyTitle, { color: theme.title }]}>No conversations yet</Text>\n <Text style={[styles.emptySubtitle, { color: theme.muted }]}>\n Start your first chat to see your conversation history here.\n </Text>\n </View>\n ) : (\n <SectionList\n sections={sections}\n keyExtractor={(item) => item.channelId}\n stickySectionHeadersEnabled={false}\n contentContainerStyle={[styles.listContent, containerStyle, { paddingBottom: 32 }]}\n ListFooterComponent={listFooter}\n ItemSeparatorComponent={renderItemSeparator}\n refreshControl={\n <RefreshControl\n refreshing={refreshing}\n onRefresh={() => void onRefresh()}\n tintColor={theme.refreshTint}\n colors={[theme.refreshTint]}\n />\n }\n renderSectionHeader={({ section }) => (\n <View style={styles.sectionHeader}>\n <Text style={[styles.sectionLabel, { color: theme.sectionLabel }]}>{section.title}</Text>\n </View>\n )}\n renderItem={({ item }) => (\n <ChatHistoryRow\n session={item}\n onSelectSession={onSelectSession}\n theme={theme}\n timeLabel={relativeTime(item.sortAt, nowTs)}\n />\n )}\n showsVerticalScrollIndicator={false}\n />\n )}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n },\n listContent: {\n paddingHorizontal: 20,\n paddingTop: 4,\n },\n /**\n * Section header: sentence case, indigo-tinted, modest size. 28px top padding\n * establishes rhythm between groups without dead air below the label.\n */\n sectionHeader: {\n paddingTop: 28,\n paddingBottom: 10,\n paddingHorizontal: 2,\n },\n sectionLabel: {\n fontSize: 12,\n fontWeight: '600',\n letterSpacing: 0.2,\n textTransform: 'none',\n },\n /**\n * Row: leading 40×40 mode tile, two-line body (title + preview), right-aligned\n * date aligned to the title's baseline. 14px gap matches the tile-to-text\n * rhythm in Manus / iOS Mail.\n */\n row: {\n flexDirection: 'row',\n alignItems: 'center',\n paddingVertical: 12,\n paddingHorizontal: 2,\n gap: 14,\n },\n tile: {\n width: 40,\n height: 40,\n borderRadius: 12,\n alignItems: 'center',\n justifyContent: 'center',\n },\n rowBody: {\n flex: 1,\n minWidth: 0,\n },\n rowHeader: {\n flexDirection: 'row',\n alignItems: 'baseline',\n gap: 10,\n },\n rowTitle: {\n flex: 1,\n fontSize: 16,\n fontWeight: '600',\n letterSpacing: -0.1,\n lineHeight: 22,\n },\n rowTitlePlaceholder: {\n fontWeight: '500',\n fontStyle: 'italic',\n },\n rowDate: {\n fontSize: 12.5,\n fontWeight: '500',\n fontVariant: ['tabular-nums'],\n },\n rowPreview: {\n marginTop: 2,\n fontSize: 13.5,\n lineHeight: 19,\n fontWeight: '400',\n letterSpacing: -0.05,\n },\n /**\n * Indented hairline: starts past the tile column (40 + 14 = 54) so the rule\n * aligns with the title's leading edge. Mail-style.\n */\n divider: {\n height: StyleSheet.hairlineWidth,\n marginLeft: 56,\n },\n footer: {\n paddingTop: 28,\n paddingBottom: 8,\n alignItems: 'center',\n },\n /** Bordered ink-neutral pill. Label is the affordance, no leading icon, no chevron. */\n loadMore: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n paddingVertical: 10,\n paddingHorizontal: 18,\n borderRadius: 999,\n borderWidth: 1,\n minWidth: 132,\n },\n loadMoreText: {\n fontSize: 13.5,\n fontWeight: '600',\n letterSpacing: -0.05,\n },\n endHint: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n paddingTop: 32,\n paddingBottom: 12,\n },\n endHintDot: {\n width: 4,\n height: 4,\n borderRadius: 2,\n },\n endHintText: {\n fontSize: 12.5,\n fontWeight: '500',\n letterSpacing: 0.1,\n },\n /**\n * Empty state: stack a 64×64 indigo-tinted mark over title + subtitle.\n * Generous vertical gap (16) between mark and title; tighter gap (6)\n * between title and subtitle so the pair reads as one unit hanging off\n * the mark, not three independent items.\n */\n emptyStateWrap: {\n flex: 1,\n minHeight: 420,\n alignItems: 'center',\n justifyContent: 'center',\n paddingHorizontal: 32,\n },\n emptyMark: {\n width: 72,\n height: 72,\n borderRadius: 36,\n alignItems: 'center',\n justifyContent: 'center',\n marginBottom: 18,\n },\n emptyTitle: {\n fontSize: 20,\n fontWeight: '700',\n letterSpacing: -0.3,\n textAlign: 'center',\n marginBottom: 6,\n },\n emptySubtitle: {\n fontSize: 14,\n lineHeight: 20,\n textAlign: 'center',\n maxWidth: 340,\n },\n});\n"],"names":["d"],"mappings":"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"}
@@ -0,0 +1,349 @@
1
+ import {jsx,jsxs}from'react/jsx-runtime';import {useRef,useMemo,useEffect}from'react';import {useWindowDimensions,Modal,View,StyleSheet,Pressable,ScrollView,Linking,Share}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {Text}from'@admin-layout/gluestack-ui-mobile';import Markdown from'react-native-markdown-display';import {mobileTokens}from'../../../theme/mobileTokens.js';function DeepSearchModal({
2
+ visible,
3
+ query,
4
+ summaryText,
5
+ sources,
6
+ isStreaming,
7
+ researchProcessOpen,
8
+ sourcesAccordionOpen,
9
+ onToggleResearchProcess,
10
+ onToggleSourcesAccordion,
11
+ onRetry,
12
+ onStop,
13
+ onClose
14
+ }) {
15
+ const {
16
+ width: screenWidth
17
+ } = useWindowDimensions();
18
+ const modalScrollRef = useRef(null);
19
+ const displayMarkdown = useMemo(() => {
20
+ if (!summaryText) return "";
21
+ const hasResearchHeading = /research summary\s*:/i.test(summaryText);
22
+ if (hasResearchHeading) return summaryText;
23
+ const heading = query ? `## Research Summary: ${query}` : "## Research Summary";
24
+ return `${heading}
25
+
26
+ ${summaryText}`;
27
+ }, [summaryText, query]);
28
+ useEffect(() => {
29
+ if (!visible) return;
30
+ requestAnimationFrame(() => {
31
+ var _a;
32
+ (_a = modalScrollRef.current) == null ? void 0 : _a.scrollToEnd({
33
+ animated: true
34
+ });
35
+ });
36
+ }, [visible, displayMarkdown, sources.length, isStreaming]);
37
+ const handleShare = async () => {
38
+ if (!summaryText) return;
39
+ try {
40
+ await Share.share({
41
+ message: `${summaryText}
42
+
43
+ Query: ${query != null ? query : ""}`
44
+ });
45
+ } catch (error) {
46
+ console.error("[DeepSearchModal] Failed to share summary:", error);
47
+ }
48
+ };
49
+ return /* @__PURE__ */ jsx(Modal, { visible, transparent: true, animationType: "fade", onRequestClose: onClose, children: /* @__PURE__ */ jsx(View, { style: styles.modalBackdrop, children: /* @__PURE__ */ jsxs(View, { style: [styles.modalCard, {
50
+ width: Math.min(760, screenWidth - 24)
51
+ }], children: [
52
+ /* @__PURE__ */ jsxs(View, { style: styles.modalHeaderRow, children: [
53
+ /* @__PURE__ */ jsxs(View, { style: styles.modalHeaderLeft, children: [
54
+ /* @__PURE__ */ jsx(Text, { fontSize: "$md", fontWeight: "$semibold", color: "$gray900", children: "Deep Search" }),
55
+ isStreaming ? /* @__PURE__ */ jsx(Text, { fontSize: "$xs", color: "$gray600", children: "Running..." }) : null
56
+ ] }),
57
+ /* @__PURE__ */ jsx(Pressable, { onPress: onClose, style: styles.iconButton, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "close", size: 18, color: "#6b7280" }) })
58
+ ] }),
59
+ /* @__PURE__ */ jsxs(ScrollView, { ref: modalScrollRef, style: styles.modalBody, contentContainerStyle: styles.modalBodyContent, nestedScrollEnabled: true, keyboardShouldPersistTaps: "handled", showsVerticalScrollIndicator: true, onContentSizeChange: () => {
60
+ var _a;
61
+ (_a = modalScrollRef.current) == null ? void 0 : _a.scrollToEnd({
62
+ animated: true
63
+ });
64
+ }, children: [
65
+ /* @__PURE__ */ jsxs(View, { style: styles.summaryCard, children: [
66
+ (displayMarkdown || (isStreaming ? "Researching..." : "")).length > 0 ? /* @__PURE__ */ jsx(Markdown, { style: markdownStyles, onLinkPress: (url) => {
67
+ void Linking.openURL(url);
68
+ return true;
69
+ }, children: displayMarkdown }) : /* @__PURE__ */ jsx(Text, { fontSize: "$sm", color: "$gray700", children: "No summary yet." }),
70
+ /* @__PURE__ */ jsxs(View, { style: styles.summaryActionRow, children: [
71
+ /* @__PURE__ */ jsx(Pressable, { onPress: handleShare, style: styles.summaryActionButton, children: /* @__PURE__ */ jsx(Text, { fontSize: "$xs", color: "$gray900", children: "Share" }) }),
72
+ /* @__PURE__ */ jsx(Pressable, { onPress: onRetry, disabled: isStreaming || !query, style: ({
73
+ pressed
74
+ }) => [styles.summaryActionButton, (isStreaming || !query) && styles.summaryActionDisabled, pressed && styles.sourceRowPressed], children: /* @__PURE__ */ jsx(Text, { fontSize: "$xs", color: "$gray900", children: "Retry" }) })
75
+ ] })
76
+ ] }),
77
+ /* @__PURE__ */ jsxs(View, { style: styles.accordionCard, children: [
78
+ /* @__PURE__ */ jsxs(Pressable, { onPress: onToggleResearchProcess, style: styles.accordionHeader, children: [
79
+ /* @__PURE__ */ jsx(Text, { fontSize: "$sm", color: "$gray900", fontWeight: "$semibold", children: "Research Process" }),
80
+ /* @__PURE__ */ jsxs(View, { style: styles.accordionHeaderRight, children: [
81
+ /* @__PURE__ */ jsx(Text, { fontSize: "$xs", color: "$gray600", children: query ? "1 query" : "0 query" }),
82
+ /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: researchProcessOpen ? "chevron-up" : "chevron-down", size: 16, color: "#6b7280" })
83
+ ] })
84
+ ] }),
85
+ researchProcessOpen && /* @__PURE__ */ jsx(View, { style: styles.accordionBody, children: query ? /* @__PURE__ */ jsxs(View, { style: styles.processItem, children: [
86
+ /* @__PURE__ */ jsx(View, { style: [styles.processDot, {
87
+ backgroundColor: isStreaming ? "#f59e0b" : "#22c55e"
88
+ }] }),
89
+ /* @__PURE__ */ jsxs(View, { style: {
90
+ flex: 1
91
+ }, children: [
92
+ /* @__PURE__ */ jsx(Text, { fontSize: "$sm", color: "$gray900", numberOfLines: 2, children: query }),
93
+ /* @__PURE__ */ jsx(Text, { fontSize: "$xs", color: "$gray600", children: isStreaming ? "Running deep-search..." : `Completed with ${sources.length} sources` })
94
+ ] })
95
+ ] }) : /* @__PURE__ */ jsx(Text, { fontSize: "$sm", color: "$gray600", children: "No query started yet." }) })
96
+ ] }),
97
+ /* @__PURE__ */ jsxs(View, { style: styles.accordionCard, children: [
98
+ /* @__PURE__ */ jsxs(Pressable, { onPress: onToggleSourcesAccordion, style: styles.accordionHeader, children: [
99
+ /* @__PURE__ */ jsx(Text, { fontSize: "$sm", color: "$gray900", fontWeight: "$semibold", children: "Sources" }),
100
+ /* @__PURE__ */ jsxs(View, { style: styles.accordionHeaderRight, children: [
101
+ /* @__PURE__ */ jsxs(Text, { fontSize: "$xs", color: "$gray600", children: [
102
+ sources.length,
103
+ " sources"
104
+ ] }),
105
+ /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: sourcesAccordionOpen ? "chevron-up" : "chevron-down", size: 16, color: "#6b7280" })
106
+ ] })
107
+ ] }),
108
+ sourcesAccordionOpen && /* @__PURE__ */ jsx(View, { style: styles.accordionBody, children: sources.length > 0 ? sources.map((item, index) => {
109
+ var _a;
110
+ return /* @__PURE__ */ jsxs(Pressable, { onPress: () => {
111
+ if (item.url) {
112
+ void Linking.openURL(item.url);
113
+ }
114
+ }, disabled: !item.url, style: ({
115
+ pressed
116
+ }) => [styles.sourceRow, !item.url && styles.sourceRowNoLink, pressed && item.url ? styles.sourceRowPressed : void 0], children: [
117
+ /* @__PURE__ */ jsxs(Text, { fontSize: "$xs", color: "$green800", mb: "$1", fontWeight: "$semibold", children: [
118
+ index + 1,
119
+ ". ",
120
+ item.title || "Source"
121
+ ] }),
122
+ item.url ? /* @__PURE__ */ jsx(Text, { fontSize: "$xs", color: "$gray700", numberOfLines: 1, children: item.url }) : /* @__PURE__ */ jsx(Text, { fontSize: "$xs", color: "$gray500", numberOfLines: 1, children: "Source title detected from summary" })
123
+ ] }, `${(_a = item.url) != null ? _a : item.title}-${index}`);
124
+ }) : /* @__PURE__ */ jsx(Text, { fontSize: "$sm", color: "$gray700", children: isStreaming ? "Collecting sources..." : "No source links detected in the response." }) })
125
+ ] })
126
+ ] }),
127
+ /* @__PURE__ */ jsxs(View, { style: styles.modalActionsRow, children: [
128
+ isStreaming ? /* @__PURE__ */ jsx(Pressable, { onPress: onStop, style: styles.modalActionButton, children: /* @__PURE__ */ jsx(Text, { fontSize: "$sm", color: "$gray900", children: "Stop" }) }) : null,
129
+ /* @__PURE__ */ jsx(Pressable, { onPress: onClose, style: styles.modalActionButton, children: /* @__PURE__ */ jsx(Text, { fontSize: "$sm", color: "$gray900", children: "Close" }) })
130
+ ] })
131
+ ] }) }) });
132
+ }
133
+ const styles = StyleSheet.create({
134
+ modalBackdrop: {
135
+ flex: 1,
136
+ backgroundColor: "rgba(15, 23, 42, 0.45)",
137
+ justifyContent: "center",
138
+ padding: 16
139
+ },
140
+ modalCard: {
141
+ maxHeight: "88%",
142
+ backgroundColor: mobileTokens.color.surface,
143
+ borderRadius: 18,
144
+ padding: 16,
145
+ width: "100%",
146
+ borderWidth: 1,
147
+ borderColor: mobileTokens.color.border
148
+ },
149
+ modalHeaderRow: {
150
+ flexDirection: "row",
151
+ justifyContent: "space-between",
152
+ alignItems: "center",
153
+ marginBottom: 10,
154
+ paddingBottom: 10,
155
+ borderBottomWidth: 1,
156
+ borderBottomColor: mobileTokens.color.border
157
+ },
158
+ modalHeaderLeft: {
159
+ flexDirection: "column"
160
+ },
161
+ iconButton: {
162
+ width: 32,
163
+ height: 32,
164
+ borderRadius: 16,
165
+ alignItems: "center",
166
+ justifyContent: "center",
167
+ backgroundColor: mobileTokens.color.surfaceMuted
168
+ },
169
+ modalBody: {
170
+ flexGrow: 1,
171
+ minHeight: 140,
172
+ marginBottom: 10
173
+ },
174
+ modalBodyContent: {
175
+ paddingBottom: 8
176
+ },
177
+ summaryCard: {
178
+ backgroundColor: mobileTokens.color.surfaceMuted,
179
+ borderWidth: 1,
180
+ borderColor: mobileTokens.color.border,
181
+ borderRadius: 14,
182
+ padding: 12,
183
+ marginBottom: 10
184
+ },
185
+ summaryActionRow: {
186
+ marginTop: 8,
187
+ borderTopWidth: 1,
188
+ borderTopColor: "#e5e7eb",
189
+ paddingTop: 8,
190
+ flexDirection: "row",
191
+ justifyContent: "flex-start",
192
+ gap: 8
193
+ },
194
+ summaryActionButton: {
195
+ paddingVertical: 6,
196
+ paddingHorizontal: 12,
197
+ borderRadius: 10,
198
+ backgroundColor: mobileTokens.color.surface,
199
+ borderWidth: 1,
200
+ borderColor: mobileTokens.color.border
201
+ },
202
+ summaryActionDisabled: {
203
+ opacity: 0.5
204
+ },
205
+ accordionCard: {
206
+ backgroundColor: mobileTokens.color.surface,
207
+ borderWidth: 1,
208
+ borderColor: mobileTokens.color.border,
209
+ borderRadius: 12,
210
+ marginBottom: 10,
211
+ overflow: "hidden"
212
+ },
213
+ accordionHeader: {
214
+ paddingHorizontal: 10,
215
+ paddingVertical: 10,
216
+ flexDirection: "row",
217
+ justifyContent: "space-between",
218
+ alignItems: "center"
219
+ },
220
+ accordionHeaderRight: {
221
+ flexDirection: "row",
222
+ alignItems: "center",
223
+ gap: 6
224
+ },
225
+ accordionBody: {
226
+ borderTopWidth: 1,
227
+ borderTopColor: "#e5e7eb",
228
+ padding: 10
229
+ },
230
+ processItem: {
231
+ flexDirection: "row",
232
+ alignItems: "flex-start",
233
+ gap: 8
234
+ },
235
+ processDot: {
236
+ marginTop: 6,
237
+ width: 8,
238
+ height: 8,
239
+ borderRadius: 4
240
+ },
241
+ markdownBody: {
242
+ color: "#111827",
243
+ fontSize: 14,
244
+ lineHeight: 20
245
+ },
246
+ markdownHeading1: {
247
+ color: "#111827",
248
+ fontSize: 18,
249
+ marginTop: 6,
250
+ marginBottom: 6,
251
+ fontWeight: "700"
252
+ },
253
+ markdownHeading2: {
254
+ color: "#111827",
255
+ fontSize: 16,
256
+ marginTop: 6,
257
+ marginBottom: 6,
258
+ fontWeight: "700"
259
+ },
260
+ markdownHeading3: {
261
+ color: "#111827",
262
+ fontSize: 15,
263
+ marginTop: 6,
264
+ marginBottom: 6,
265
+ fontWeight: "700"
266
+ },
267
+ markdownParagraph: {
268
+ color: "#111827",
269
+ fontSize: 14,
270
+ lineHeight: 20,
271
+ marginTop: 2,
272
+ marginBottom: 8
273
+ },
274
+ markdownList: {
275
+ marginTop: 2,
276
+ marginBottom: 8
277
+ },
278
+ markdownListItem: {
279
+ color: "#111827",
280
+ fontSize: 14,
281
+ lineHeight: 20
282
+ },
283
+ markdownLink: {
284
+ color: "#166534",
285
+ textDecorationLine: "underline"
286
+ },
287
+ markdownBlockquote: {
288
+ borderLeftColor: "#d1d5db",
289
+ borderLeftWidth: 3,
290
+ paddingLeft: 8,
291
+ color: "#4b5563"
292
+ },
293
+ markdownInlineCode: {
294
+ backgroundColor: "#f3f4f6",
295
+ color: "#111827",
296
+ paddingHorizontal: 4,
297
+ borderRadius: 4
298
+ },
299
+ markdownCodeBlock: {
300
+ backgroundColor: "#f3f4f6",
301
+ color: "#111827",
302
+ padding: 8,
303
+ borderRadius: 6
304
+ },
305
+ sourceRow: {
306
+ backgroundColor: mobileTokens.color.surface,
307
+ borderWidth: 1,
308
+ borderColor: mobileTokens.color.border,
309
+ borderRadius: 10,
310
+ padding: 10,
311
+ marginBottom: 6
312
+ },
313
+ sourceRowPressed: {
314
+ opacity: 0.7
315
+ },
316
+ sourceRowNoLink: {
317
+ backgroundColor: "#f3f4f6"
318
+ },
319
+ modalActionsRow: {
320
+ marginTop: 12,
321
+ flexDirection: "row",
322
+ justifyContent: "flex-end",
323
+ gap: 10
324
+ },
325
+ modalActionButton: {
326
+ minHeight: 38,
327
+ paddingVertical: 8,
328
+ paddingHorizontal: 16,
329
+ borderRadius: 11,
330
+ backgroundColor: mobileTokens.color.surfaceMuted,
331
+ borderWidth: 1,
332
+ borderColor: mobileTokens.color.border,
333
+ justifyContent: "center"
334
+ }
335
+ });
336
+ const markdownStyles = {
337
+ body: styles.markdownBody,
338
+ heading1: styles.markdownHeading1,
339
+ heading2: styles.markdownHeading2,
340
+ heading3: styles.markdownHeading3,
341
+ bullet_list: styles.markdownList,
342
+ ordered_list: styles.markdownList,
343
+ list_item: styles.markdownListItem,
344
+ link: styles.markdownLink,
345
+ paragraph: styles.markdownParagraph,
346
+ blockquote: styles.markdownBlockquote,
347
+ code_inline: styles.markdownInlineCode,
348
+ code_block: styles.markdownCodeBlock
349
+ };export{DeepSearchModal as default};//# sourceMappingURL=DeepSearchModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeepSearchModal.js","sources":["../../../../src/screens/Home/components/DeepSearchModal.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useRef } from 'react';\nimport {\n ActivityIndicator,\n Modal,\n Pressable,\n ScrollView,\n Share,\n StyleSheet,\n View,\n useWindowDimensions,\n} from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { Text } from '@admin-layout/gluestack-ui-mobile';\nimport Markdown from 'react-native-markdown-display';\nimport { Linking } from 'react-native';\nimport type { DeepSearchSourceItem } from '../deepSearchUtils';\nimport { mobileTokens } from '../../../theme/mobileTokens';\n\ninterface DeepSearchModalProps {\n visible: boolean;\n query: string | null;\n summaryText: string;\n sources: DeepSearchSourceItem[];\n isStreaming: boolean;\n researchProcessOpen: boolean;\n sourcesAccordionOpen: boolean;\n onToggleResearchProcess: () => void;\n onToggleSourcesAccordion: () => void;\n onRetry: () => void;\n onStop: () => void;\n onClose: () => void;\n}\n\nexport default function DeepSearchModal({\n visible,\n query,\n summaryText,\n sources,\n isStreaming,\n researchProcessOpen,\n sourcesAccordionOpen,\n onToggleResearchProcess,\n onToggleSourcesAccordion,\n onRetry,\n onStop,\n onClose,\n}: DeepSearchModalProps) {\n const { width: screenWidth } = useWindowDimensions();\n const modalScrollRef = useRef<ScrollView | null>(null);\n\n const displayMarkdown = useMemo(() => {\n if (!summaryText) return '';\n const hasResearchHeading = /research summary\\s*:/i.test(summaryText);\n if (hasResearchHeading) return summaryText;\n const heading = query ? `## Research Summary: ${query}` : '## Research Summary';\n return `${heading}\\n\\n${summaryText}`;\n }, [summaryText, query]);\n\n useEffect(() => {\n if (!visible) return;\n requestAnimationFrame(() => {\n modalScrollRef.current?.scrollToEnd({ animated: true });\n });\n }, [visible, displayMarkdown, sources.length, isStreaming]);\n\n const handleShare = async () => {\n if (!summaryText) return;\n try {\n await Share.share({\n message: `${summaryText}\\n\\nQuery: ${query ?? ''}`,\n });\n } catch (error) {\n console.error('[DeepSearchModal] Failed to share summary:', error);\n }\n };\n\n return (\n <Modal visible={visible} transparent animationType=\"fade\" onRequestClose={onClose}>\n <View style={styles.modalBackdrop}>\n <View style={[styles.modalCard, { width: Math.min(760, screenWidth - 24) }]}>\n <View style={styles.modalHeaderRow}>\n <View style={styles.modalHeaderLeft}>\n <Text fontSize=\"$md\" fontWeight=\"$semibold\" color=\"$gray900\">\n Deep Search\n </Text>\n {isStreaming ? (\n <Text fontSize=\"$xs\" color=\"$gray600\">\n Running...\n </Text>\n ) : null}\n </View>\n <Pressable onPress={onClose} style={styles.iconButton}>\n <MaterialCommunityIcons name=\"close\" size={18} color=\"#6b7280\" />\n </Pressable>\n </View>\n <ScrollView\n ref={modalScrollRef}\n style={styles.modalBody}\n contentContainerStyle={styles.modalBodyContent}\n nestedScrollEnabled\n keyboardShouldPersistTaps=\"handled\"\n showsVerticalScrollIndicator\n onContentSizeChange={() => {\n modalScrollRef.current?.scrollToEnd({ animated: true });\n }}\n >\n <View style={styles.summaryCard}>\n {(displayMarkdown || (isStreaming ? 'Researching...' : '')).length > 0 ? (\n <Markdown\n style={markdownStyles}\n onLinkPress={(url) => {\n void Linking.openURL(url);\n return true;\n }}\n >\n {displayMarkdown}\n </Markdown>\n ) : (\n <Text fontSize=\"$sm\" color=\"$gray700\">\n No summary yet.\n </Text>\n )}\n <View style={styles.summaryActionRow}>\n <Pressable onPress={handleShare} style={styles.summaryActionButton}>\n <Text fontSize=\"$xs\" color=\"$gray900\">\n Share\n </Text>\n </Pressable>\n <Pressable\n onPress={onRetry}\n disabled={isStreaming || !query}\n style={({ pressed }) => [\n styles.summaryActionButton,\n (isStreaming || !query) && styles.summaryActionDisabled,\n pressed && styles.sourceRowPressed,\n ]}\n >\n <Text fontSize=\"$xs\" color=\"$gray900\">\n Retry\n </Text>\n </Pressable>\n </View>\n </View>\n\n <View style={styles.accordionCard}>\n <Pressable onPress={onToggleResearchProcess} style={styles.accordionHeader}>\n <Text fontSize=\"$sm\" color=\"$gray900\" fontWeight=\"$semibold\">\n Research Process\n </Text>\n <View style={styles.accordionHeaderRight}>\n <Text fontSize=\"$xs\" color=\"$gray600\">\n {query ? '1 query' : '0 query'}\n </Text>\n <MaterialCommunityIcons\n name={researchProcessOpen ? 'chevron-up' : 'chevron-down'}\n size={16}\n color=\"#6b7280\"\n />\n </View>\n </Pressable>\n {researchProcessOpen && (\n <View style={styles.accordionBody}>\n {query ? (\n <View style={styles.processItem}>\n <View\n style={[\n styles.processDot,\n { backgroundColor: isStreaming ? '#f59e0b' : '#22c55e' },\n ]}\n />\n <View style={{ flex: 1 }}>\n <Text fontSize=\"$sm\" color=\"$gray900\" numberOfLines={2}>\n {query}\n </Text>\n <Text fontSize=\"$xs\" color=\"$gray600\">\n {isStreaming\n ? 'Running deep-search...'\n : `Completed with ${sources.length} sources`}\n </Text>\n </View>\n </View>\n ) : (\n <Text fontSize=\"$sm\" color=\"$gray600\">\n No query started yet.\n </Text>\n )}\n </View>\n )}\n </View>\n\n <View style={styles.accordionCard}>\n <Pressable onPress={onToggleSourcesAccordion} style={styles.accordionHeader}>\n <Text fontSize=\"$sm\" color=\"$gray900\" fontWeight=\"$semibold\">\n Sources\n </Text>\n <View style={styles.accordionHeaderRight}>\n <Text fontSize=\"$xs\" color=\"$gray600\">\n {sources.length} sources\n </Text>\n <MaterialCommunityIcons\n name={sourcesAccordionOpen ? 'chevron-up' : 'chevron-down'}\n size={16}\n color=\"#6b7280\"\n />\n </View>\n </Pressable>\n {sourcesAccordionOpen && (\n <View style={styles.accordionBody}>\n {sources.length > 0 ? (\n sources.map((item, index) => (\n <Pressable\n key={`${item.url ?? item.title}-${index}`}\n onPress={() => {\n if (item.url) {\n void Linking.openURL(item.url);\n }\n }}\n disabled={!item.url}\n style={({ pressed }) => [\n styles.sourceRow,\n !item.url && styles.sourceRowNoLink,\n pressed && item.url ? styles.sourceRowPressed : undefined,\n ]}\n >\n <Text fontSize=\"$xs\" color=\"$green800\" mb=\"$1\" fontWeight=\"$semibold\">\n {index + 1}. {item.title || 'Source'}\n </Text>\n {item.url ? (\n <Text fontSize=\"$xs\" color=\"$gray700\" numberOfLines={1}>\n {item.url}\n </Text>\n ) : (\n <Text fontSize=\"$xs\" color=\"$gray500\" numberOfLines={1}>\n Source title detected from summary\n </Text>\n )}\n </Pressable>\n ))\n ) : (\n <Text fontSize=\"$sm\" color=\"$gray700\">\n {isStreaming\n ? 'Collecting sources...'\n : 'No source links detected in the response.'}\n </Text>\n )}\n </View>\n )}\n </View>\n </ScrollView>\n <View style={styles.modalActionsRow}>\n {isStreaming ? (\n <Pressable onPress={onStop} style={styles.modalActionButton}>\n <Text fontSize=\"$sm\" color=\"$gray900\">\n Stop\n </Text>\n </Pressable>\n ) : null}\n <Pressable onPress={onClose} style={styles.modalActionButton}>\n <Text fontSize=\"$sm\" color=\"$gray900\">\n Close\n </Text>\n </Pressable>\n </View>\n </View>\n </View>\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n modalBackdrop: {\n flex: 1,\n backgroundColor: 'rgba(15, 23, 42, 0.45)',\n justifyContent: 'center',\n padding: 16,\n },\n modalCard: {\n maxHeight: '88%',\n backgroundColor: mobileTokens.color.surface,\n borderRadius: 18,\n padding: 16,\n width: '100%',\n borderWidth: 1,\n borderColor: mobileTokens.color.border,\n },\n modalHeaderRow: {\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'center',\n marginBottom: 10,\n paddingBottom: 10,\n borderBottomWidth: 1,\n borderBottomColor: mobileTokens.color.border,\n },\n modalHeaderLeft: {\n flexDirection: 'column',\n },\n iconButton: {\n width: 32,\n height: 32,\n borderRadius: 16,\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: mobileTokens.color.surfaceMuted,\n },\n modalBody: {\n flexGrow: 1,\n minHeight: 140,\n marginBottom: 10,\n },\n modalBodyContent: {\n paddingBottom: 8,\n },\n summaryCard: {\n backgroundColor: mobileTokens.color.surfaceMuted,\n borderWidth: 1,\n borderColor: mobileTokens.color.border,\n borderRadius: 14,\n padding: 12,\n marginBottom: 10,\n },\n summaryActionRow: {\n marginTop: 8,\n borderTopWidth: 1,\n borderTopColor: '#e5e7eb',\n paddingTop: 8,\n flexDirection: 'row',\n justifyContent: 'flex-start',\n gap: 8,\n },\n summaryActionButton: {\n paddingVertical: 6,\n paddingHorizontal: 12,\n borderRadius: 10,\n backgroundColor: mobileTokens.color.surface,\n borderWidth: 1,\n borderColor: mobileTokens.color.border,\n },\n summaryActionDisabled: {\n opacity: 0.5,\n },\n accordionCard: {\n backgroundColor: mobileTokens.color.surface,\n borderWidth: 1,\n borderColor: mobileTokens.color.border,\n borderRadius: 12,\n marginBottom: 10,\n overflow: 'hidden',\n },\n accordionHeader: {\n paddingHorizontal: 10,\n paddingVertical: 10,\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'center',\n },\n accordionHeaderRight: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 6,\n },\n accordionBody: {\n borderTopWidth: 1,\n borderTopColor: '#e5e7eb',\n padding: 10,\n },\n processItem: {\n flexDirection: 'row',\n alignItems: 'flex-start',\n gap: 8,\n },\n processDot: {\n marginTop: 6,\n width: 8,\n height: 8,\n borderRadius: 4,\n },\n markdownBody: {\n color: '#111827',\n fontSize: 14,\n lineHeight: 20,\n },\n markdownHeading1: {\n color: '#111827',\n fontSize: 18,\n marginTop: 6,\n marginBottom: 6,\n fontWeight: '700',\n },\n markdownHeading2: {\n color: '#111827',\n fontSize: 16,\n marginTop: 6,\n marginBottom: 6,\n fontWeight: '700',\n },\n markdownHeading3: {\n color: '#111827',\n fontSize: 15,\n marginTop: 6,\n marginBottom: 6,\n fontWeight: '700',\n },\n markdownParagraph: {\n color: '#111827',\n fontSize: 14,\n lineHeight: 20,\n marginTop: 2,\n marginBottom: 8,\n },\n markdownList: {\n marginTop: 2,\n marginBottom: 8,\n },\n markdownListItem: {\n color: '#111827',\n fontSize: 14,\n lineHeight: 20,\n },\n markdownLink: {\n color: '#166534',\n textDecorationLine: 'underline',\n },\n markdownBlockquote: {\n borderLeftColor: '#d1d5db',\n borderLeftWidth: 3,\n paddingLeft: 8,\n color: '#4b5563',\n },\n markdownInlineCode: {\n backgroundColor: '#f3f4f6',\n color: '#111827',\n paddingHorizontal: 4,\n borderRadius: 4,\n },\n markdownCodeBlock: {\n backgroundColor: '#f3f4f6',\n color: '#111827',\n padding: 8,\n borderRadius: 6,\n },\n sourceRow: {\n backgroundColor: mobileTokens.color.surface,\n borderWidth: 1,\n borderColor: mobileTokens.color.border,\n borderRadius: 10,\n padding: 10,\n marginBottom: 6,\n },\n sourceRowPressed: {\n opacity: 0.7,\n },\n sourceRowNoLink: {\n backgroundColor: '#f3f4f6',\n },\n modalActionsRow: {\n marginTop: 12,\n flexDirection: 'row',\n justifyContent: 'flex-end',\n gap: 10,\n },\n modalActionButton: {\n minHeight: 38,\n paddingVertical: 8,\n paddingHorizontal: 16,\n borderRadius: 11,\n backgroundColor: mobileTokens.color.surfaceMuted,\n borderWidth: 1,\n borderColor: mobileTokens.color.border,\n justifyContent: 'center',\n },\n});\n\nconst markdownStyles = {\n body: styles.markdownBody,\n heading1: styles.markdownHeading1,\n heading2: styles.markdownHeading2,\n heading3: styles.markdownHeading3,\n bullet_list: styles.markdownList,\n ordered_list: styles.markdownList,\n list_item: styles.markdownListItem,\n link: styles.markdownLink,\n paragraph: styles.markdownParagraph,\n blockquote: styles.markdownBlockquote,\n code_inline: styles.markdownInlineCode,\n code_block: styles.markdownCodeBlock,\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ function normalizeSummaryText(content) {
2
+ return content.replace(/\r\n/g, "\n").trim();
3
+ }
4
+ function extractDeepSearchSources(content) {
5
+ const markdownLinks = Array.from(content.matchAll(/\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g)).map((m) => ({
6
+ title: m[1].trim(),
7
+ url: m[2].trim()
8
+ }));
9
+ const plainUrls = Array.from(content.matchAll(/https?:\/\/[^\s)]+/g)).map((m) => ({
10
+ title: "Source",
11
+ url: m[0].trim()
12
+ }));
13
+ const numberedTitleLines = content.split("\n").map((line) => line.trim()).filter((line) => /^\d+\.\s+/.test(line)).map((line) => ({
14
+ title: line.replace(/^\d+\.\s+/, "").trim(),
15
+ url: void 0
16
+ }));
17
+ const merged = [...markdownLinks, ...plainUrls, ...numberedTitleLines];
18
+ const seen = /* @__PURE__ */ new Set();
19
+ const seenTitleOnly = /* @__PURE__ */ new Set();
20
+ const unique = [];
21
+ for (const item of merged) {
22
+ let isUnique = false;
23
+ if (item.url) {
24
+ if (!seen.has(item.url)) {
25
+ seen.add(item.url);
26
+ isUnique = true;
27
+ }
28
+ } else {
29
+ const normalizedTitle = item.title.toLowerCase();
30
+ if (normalizedTitle && !seenTitleOnly.has(normalizedTitle)) {
31
+ seenTitleOnly.add(normalizedTitle);
32
+ isUnique = true;
33
+ }
34
+ }
35
+ if (isUnique) {
36
+ unique.push(item);
37
+ if (unique.length >= 30) break;
38
+ }
39
+ }
40
+ return unique;
41
+ }export{extractDeepSearchSources,normalizeSummaryText};//# sourceMappingURL=deepSearchUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deepSearchUtils.js","sources":["../../../src/screens/Home/deepSearchUtils.ts"],"sourcesContent":["export interface DeepSearchSourceItem {\n title: string;\n url?: string;\n}\n\nexport function normalizeSummaryText(content: string): string {\n return content.replace(/\\r\\n/g, '\\n').trim();\n}\n\nexport function extractDeepSearchSources(content: string): DeepSearchSourceItem[] {\n const markdownLinks = Array.from(content.matchAll(/\\[([^\\]]+)\\]\\((https?:\\/\\/[^\\s)]+)\\)/g)).map((m) => ({\n title: m[1].trim(),\n url: m[2].trim(),\n }));\n const plainUrls = Array.from(content.matchAll(/https?:\\/\\/[^\\s)]+/g)).map((m) => ({\n title: 'Source',\n url: m[0].trim(),\n }));\n const numberedTitleLines = content\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => /^\\d+\\.\\s+/.test(line))\n .map((line) => ({\n title: line.replace(/^\\d+\\.\\s+/, '').trim(),\n url: undefined as string | undefined,\n }));\n\n const merged = [...markdownLinks, ...plainUrls, ...numberedTitleLines];\n const seen = new Set<string>();\n const seenTitleOnly = new Set<string>();\n const unique: DeepSearchSourceItem[] = [];\n\n for (const item of merged) {\n let isUnique = false;\n if (item.url) {\n if (!seen.has(item.url)) {\n seen.add(item.url);\n isUnique = true;\n }\n } else {\n const normalizedTitle = item.title.toLowerCase();\n if (normalizedTitle && !seenTitleOnly.has(normalizedTitle)) {\n seenTitleOnly.add(normalizedTitle);\n isUnique = true;\n }\n }\n if (isUnique) {\n unique.push(item);\n if (unique.length >= 30) break;\n }\n }\n return unique;\n}\n"],"names":[],"mappings":"AAIO,SAAS,qBAAqB,OAAyB,EAAA;AAC5D,EAAA,OAAO,OAAQ,CAAA,OAAA,CAAQ,OAAS,EAAA,IAAI,EAAE,IAAK,EAAA;AAC7C;AACO,SAAS,yBAAyB,OAAyC,EAAA;AAChF,EAAM,MAAA,aAAA,GAAgB,MAAM,IAAK,CAAA,OAAA,CAAQ,SAAS,uCAAuC,CAAC,CAAE,CAAA,GAAA,CAAI,CAAM,CAAA,MAAA;AAAA,IACpG,KAAO,EAAA,CAAA,CAAE,CAAC,CAAA,CAAE,IAAK,EAAA;AAAA,IACjB,GAAK,EAAA,CAAA,CAAE,CAAC,CAAA,CAAE,IAAK;AAAA,GACf,CAAA,CAAA;AACF,EAAM,MAAA,SAAA,GAAY,MAAM,IAAK,CAAA,OAAA,CAAQ,SAAS,qBAAqB,CAAC,CAAE,CAAA,GAAA,CAAI,CAAM,CAAA,MAAA;AAAA,IAC9E,KAAO,EAAA,QAAA;AAAA,IACP,GAAK,EAAA,CAAA,CAAE,CAAC,CAAA,CAAE,IAAK;AAAA,GACf,CAAA,CAAA;AACF,EAAA,MAAM,qBAAqB,OAAQ,CAAA,KAAA,CAAM,IAAI,CAAE,CAAA,GAAA,CAAI,UAAQ,IAAK,CAAA,IAAA,EAAM,CAAE,CAAA,MAAA,CAAO,UAAQ,WAAY,CAAA,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,IAAI,CAAS,IAAA,MAAA;AAAA,IAC1H,OAAO,IAAK,CAAA,OAAA,CAAQ,WAAa,EAAA,EAAE,EAAE,IAAK,EAAA;AAAA,IAC1C,GAAK,EAAA;AAAA,GACL,CAAA,CAAA;AACF,EAAA,MAAM,SAAS,CAAC,GAAG,eAAe,GAAG,SAAA,EAAW,GAAG,kBAAkB,CAAA;AACrE,EAAM,MAAA,IAAA,uBAAW,GAAY,EAAA;AAC7B,EAAM,MAAA,aAAA,uBAAoB,GAAY,EAAA;AACtC,EAAA,MAAM,SAAiC,EAAC;AACxC,EAAA,KAAA,MAAW,QAAQ,MAAQ,EAAA;AACzB,IAAA,IAAI,QAAW,GAAA,KAAA;AACf,IAAA,IAAI,KAAK,GAAK,EAAA;AACZ,MAAA,IAAI,CAAC,IAAA,CAAK,GAAI,CAAA,IAAA,CAAK,GAAG,CAAG,EAAA;AACvB,QAAK,IAAA,CAAA,GAAA,CAAI,KAAK,GAAG,CAAA;AACjB,QAAW,QAAA,GAAA,IAAA;AAAA;AACb,KACK,MAAA;AACL,MAAM,MAAA,eAAA,GAAkB,IAAK,CAAA,KAAA,CAAM,WAAY,EAAA;AAC/C,MAAA,IAAI,eAAmB,IAAA,CAAC,aAAc,CAAA,GAAA,CAAI,eAAe,CAAG,EAAA;AAC1D,QAAA,aAAA,CAAc,IAAI,eAAe,CAAA;AACjC,QAAW,QAAA,GAAA,IAAA;AAAA;AACb;AAEF,IAAA,IAAI,QAAU,EAAA;AACZ,MAAA,MAAA,CAAO,KAAK,IAAI,CAAA;AAChB,MAAI,IAAA,MAAA,CAAO,UAAU,EAAI,EAAA;AAAA;AAC3B;AAEF,EAAO,OAAA,MAAA;AACT"}
@@ -0,0 +1,43 @@
1
+ import {jsxs,jsx}from'react/jsx-runtime';import {useRef,useEffect}from'react';import {View}from'react-native';import {useNavigation,useRoute}from'@react-navigation/native';import {navigationRef}from'@common-stack/client-react';import {usePrerequisiteIds}from'../../hooks/usePrerequisiteIds.js';import {Text}from'@admin-layout/gluestack-ui-mobile';import {YantraBrandLoader}from'../../components/YantraBrandLoader.js';import {mobileTokens}from'../../theme/mobileTokens.js';function NewChat() {
2
+ var _a, _b;
3
+ const navigation = useNavigation();
4
+ const route = useRoute();
5
+ const {
6
+ orgName: prerequisiteOrgName,
7
+ orgLoading
8
+ } = usePrerequisiteIds();
9
+ const routeOrgName = ((_b = (_a = route == null ? void 0 : route.params) == null ? void 0 : _a.orgName) == null ? void 0 : _b.trim()) || null;
10
+ const resolvedOrgName = prerequisiteOrgName || routeOrgName || null;
11
+ const hasNavigatedRef = useRef(false);
12
+ const waitingForOrg = !routeOrgName && (orgLoading || !resolvedOrgName);
13
+ useEffect(() => {
14
+ if (hasNavigatedRef.current || waitingForOrg) return;
15
+ const go = (org) => {
16
+ if (hasNavigatedRef.current) return;
17
+ const params = org ? {
18
+ orgName: org
19
+ } : void 0;
20
+ if (navigationRef.isReady()) {
21
+ navigationRef.navigate("MainStack", {
22
+ screen: "MainStack.Layout.Home",
23
+ params
24
+ });
25
+ hasNavigatedRef.current = true;
26
+ return;
27
+ }
28
+ navigation.navigate("MainStack.Layout.Home", params);
29
+ hasNavigatedRef.current = true;
30
+ };
31
+ go(resolvedOrgName);
32
+ }, [resolvedOrgName, waitingForOrg, navigation]);
33
+ return /* @__PURE__ */ jsxs(View, { style: {
34
+ flex: 1,
35
+ alignItems: "center",
36
+ justifyContent: "center",
37
+ backgroundColor: mobileTokens.color.bg,
38
+ gap: 10
39
+ }, children: [
40
+ /* @__PURE__ */ jsx(YantraBrandLoader, {}),
41
+ /* @__PURE__ */ jsx(Text, { color: mobileTokens.color.textMuted, fontSize: "$sm", children: "Preparing your workspace..." })
42
+ ] });
43
+ }export{NewChat as default};//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../src/screens/NewChat/index.tsx"],"sourcesContent":["import React, { useEffect, useRef } from 'react';\nimport { View } from 'react-native';\nimport { useNavigation, useRoute } from '@react-navigation/native';\nimport { navigationRef } from '@common-stack/client-react';\nimport { usePrerequisiteIds } from '../../hooks/usePrerequisiteIds';\nimport { Text } from '@admin-layout/gluestack-ui-mobile';\nimport { YantraBrandLoader } from '../../components/YantraBrandLoader';\nimport { mobileTokens } from '../../theme/mobileTokens';\n\nexport default function NewChat() {\n const navigation = useNavigation<any>();\n const route = useRoute<any>();\n const { orgName: prerequisiteOrgName, orgLoading } = usePrerequisiteIds();\n\n const routeOrgName = (route?.params?.orgName as string | undefined)?.trim() || null;\n const resolvedOrgName = prerequisiteOrgName || routeOrgName || null;\n const hasNavigatedRef = useRef(false);\n const waitingForOrg = !routeOrgName && (orgLoading || !resolvedOrgName);\n\n useEffect(() => {\n if (hasNavigatedRef.current || waitingForOrg) return;\n\n const go = (org?: string | null) => {\n if (hasNavigatedRef.current) return;\n const params = org ? { orgName: org } : undefined;\n if (navigationRef.isReady()) {\n navigationRef.navigate(\n 'MainStack' as never,\n {\n screen: 'MainStack.Layout.Home',\n params,\n } as never,\n );\n hasNavigatedRef.current = true;\n return;\n }\n navigation.navigate('MainStack.Layout.Home', params);\n hasNavigatedRef.current = true;\n };\n\n // Navigate only when orgName is available so backend context URI is correct.\n go(resolvedOrgName);\n }, [resolvedOrgName, waitingForOrg, navigation]);\n\n return (\n <View\n style={{\n flex: 1,\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: mobileTokens.color.bg,\n gap: 10,\n }}\n >\n <YantraBrandLoader />\n <Text color={mobileTokens.color.textMuted} fontSize=\"$sm\">\n Preparing your workspace...\n </Text>\n </View>\n );\n}\n"],"names":[],"mappings":"wdAQA,SAAwB,OAAU,GAAA;AARlC,EAAA,IAAA,EAAA,EAAA,EAAA;AASE,EAAA,MAAM,aAAa,aAAmB,EAAA;AACtC,EAAA,MAAM,QAAQ,QAAc,EAAA;AAC5B,EAAM,MAAA;AAAA,IACJ,OAAS,EAAA,mBAAA;AAAA,IACT;AAAA,MACE,kBAAmB,EAAA;AACvB,EAAA,MAAM,iBAAgB,EAAO,GAAA,CAAA,EAAA,GAAA,KAAA,IAAA,IAAA,GAAA,MAAA,GAAA,KAAA,CAAA,MAAA,KAAP,IAAe,GAAA,MAAA,GAAA,EAAA,CAAA,OAAA,KAAf,mBAA+C,IAAU,EAAA,KAAA,IAAA;AAC/E,EAAM,MAAA,eAAA,GAAkB,uBAAuB,YAAgB,IAAA,IAAA;AAC/D,EAAM,MAAA,eAAA,GAAkB,OAAO,KAAK,CAAA;AACpC,EAAA,MAAM,aAAgB,GAAA,CAAC,YAAiB,KAAA,UAAA,IAAc,CAAC,eAAA,CAAA;AACvD,EAAA,SAAA,CAAU,MAAM;AACd,IAAI,IAAA,eAAA,CAAgB,WAAW,aAAe,EAAA;AAC9C,IAAM,MAAA,EAAA,GAAK,CAAC,GAAwB,KAAA;AAClC,MAAA,IAAI,gBAAgB,OAAS,EAAA;AAC7B,MAAA,MAAM,SAAS,GAAM,GAAA;AAAA,QACnB,OAAS,EAAA;AAAA,OACP,GAAA,MAAA;AACJ,MAAI,IAAA,aAAA,CAAc,SAAW,EAAA;AAC3B,QAAA,aAAA,CAAc,SAAS,WAAsB,EAAA;AAAA,UAC3C,MAAQ,EAAA,uBAAA;AAAA,UACR;AAAA,SACQ,CAAA;AACV,QAAA,eAAA,CAAgB,OAAU,GAAA,IAAA;AAC1B,QAAA;AAAA;AAEF,MAAW,UAAA,CAAA,QAAA,CAAS,yBAAyB,MAAM,CAAA;AACnD,MAAA,eAAA,CAAgB,OAAU,GAAA,IAAA;AAAA,KAC5B;AAGA,IAAA,EAAA,CAAG,eAAe,CAAA;AAAA,GACjB,EAAA,CAAC,eAAiB,EAAA,aAAA,EAAe,UAAU,CAAC,CAAA;AAC/C,EAAO,uBAAA,IAAA,CAAC,QAAK,KAAO,EAAA;AAAA,IAClB,IAAM,EAAA,CAAA;AAAA,IACN,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA,QAAA;AAAA,IAChB,eAAA,EAAiB,aAAa,KAAM,CAAA,EAAA;AAAA,IACpC,GAAK,EAAA;AAAA,GAEG,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,iBAAkB,EAAA,EAAA,CAAA;AAAA,oBACnB,GAAA,CAAC,QAAK,KAAO,EAAA,YAAA,CAAa,MAAM,SAAW,EAAA,QAAA,EAAS,OAAM,QAE1D,EAAA,6BAAA,EAAA;AAAA,GACJ,EAAA,CAAA;AACR"}