@adminide-stack/yantra-mobile 12.0.70-alpha.4 → 12.0.70

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ChatComponents.js","sources":["../../../src/features/messaging/ChatComponents.tsx"],"sourcesContent":["/**\n * Presentational pieces for the chat surface.\n *\n * Plain react-native only - no gluestack, no NativeWind, no reanimated beyond\n * what the host already shares. A federated remote may only use what the host\n * provides, and every extra dependency is another way for the bundle to fail to\n * load on a device that the simulator will not reproduce.\n *\n * `expo-image` IS available (it is a shared singleton), so avatars get real\n * caching rather than RN's `Image`.\n *\n * Layout note: NativeWind's Metro interop can drop `gap` and flatten away\n * `flexDirection` from StyleSheet.create. Critical row layouts therefore set\n * `flexDirection: 'row'` as an inline style and use margins instead of gap.\n */\nimport * as React from 'react';\nimport { ActivityIndicator, Pressable, StyleSheet, Text, View } from 'react-native';\nimport { Image } from 'expo-image';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { mobileColors } from '../../theme/mobileTokens';\nimport { initialsOf, relativeLabel, timeLabel, type ChatConversation, type ChatMessage } from './chatModel';\n\nexport interface ChatTheme {\n bg: string;\n surface: string;\n border: string;\n text: string;\n textMuted: string;\n accent: string;\n onAccent: string;\n bubbleMine: string;\n bubbleTheirs: string;\n bubbleMineText: string;\n bubbleTheirsText: string;\n threadBg: string;\n composerBar: string;\n danger: string;\n unread: string;\n headerBg: string;\n}\n\nfunction buildChatTheme(isDark: boolean): ChatTheme {\n const c = mobileColors(isDark);\n return {\n bg: c.bg,\n surface: isDark ? c.surface : '#f8fafc',\n border: c.border,\n text: c.text,\n textMuted: c.textMuted,\n accent: c.primary,\n onAccent: '#ffffff',\n bubbleMine: isDark ? c.primarySoft : c.surfaceMuted,\n bubbleTheirs: isDark ? c.surface : c.bg,\n bubbleMineText: c.text,\n bubbleTheirsText: c.text,\n threadBg: c.bg,\n composerBar: isDark ? c.surface : '#f8fafc',\n danger: c.dangerText,\n unread: c.primary,\n headerBg: c.bg,\n };\n}\n\n/** Yantra mobile palette (`mobileTokens`) with iMessage-style layout tokens. */\nexport const chatThemes: { light: ChatTheme; dark: ChatTheme } = {\n light: buildChatTheme(false),\n dark: buildChatTheme(true),\n};\n\n/** Default avatar plate when no photo. */\nconst AVATAR_PLATE = '#dfe5e7';\nconst AVATAR_ICON = '#ffffff';\n\nexport function Avatar({\n name,\n uri,\n size = 49,\n theme,\n variant = 'silhouette',\n}: {\n name: string;\n uri?: string | null;\n size?: number;\n theme: ChatTheme;\n /** `silhouette` for thread header; `initials` for colorful Messages list avatars. */\n variant?: 'silhouette' | 'initials';\n}) {\n const [failed, setFailed] = React.useState(false);\n const radius = size / 2;\n\n if (uri && !failed) {\n return (\n <Image\n source={{ uri }}\n style={{ width: size, height: size, borderRadius: radius, backgroundColor: AVATAR_PLATE }}\n contentFit=\"cover\"\n transition={120}\n onError={() => setFailed(true)}\n accessibilityIgnoresInvertColors\n />\n );\n }\n if (variant === 'initials') {\n return (\n <View\n style={{\n width: size,\n height: size,\n borderRadius: radius,\n backgroundColor: theme.accent,\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <Text style={{ color: '#fff', fontWeight: '600', fontSize: Math.round(size * 0.38) }}>\n {initialsOf(name)}\n </Text>\n </View>\n );\n }\n return (\n <View\n style={{\n width: size,\n height: size,\n borderRadius: radius,\n backgroundColor: AVATAR_PLATE,\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <MaterialCommunityIcons name=\"account\" size={Math.round(size * 0.58)} color={AVATAR_ICON} />\n </View>\n );\n}\n\nexport function UnreadBadge({ count, theme }: { count: number; theme: ChatTheme }) {\n if (count <= 0) return null;\n return (\n <View style={[styles.badge, { backgroundColor: theme.unread }]}>\n <Text style={styles.badgeText}>{count > 99 ? '99+' : count}</Text>\n </View>\n );\n}\n\nexport function ConversationRow({\n conversation,\n theme,\n now,\n onPress,\n}: {\n conversation: ChatConversation;\n theme: ChatTheme;\n now: number;\n onPress: () => void;\n}) {\n const unread = conversation.unreadCount > 0;\n const preview = conversation.subtitle.trim();\n const timeColor = unread ? theme.unread : theme.textMuted;\n\n return (\n <Pressable\n onPress={onPress}\n accessibilityRole=\"button\"\n accessibilityLabel={\n unread ? `${conversation.title}, ${conversation.unreadCount} unread messages` : conversation.title\n }\n style={({ pressed }) => ({\n backgroundColor: pressed ? theme.surface : theme.bg,\n width: '100%',\n })}\n testID={`chat-conversation-${conversation.id}`}\n >\n {/* Inner wrapper: NativeWind can strip flexDirection from Pressable styles. */}\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n width: '100%',\n paddingLeft: 14,\n paddingRight: 16,\n paddingVertical: 10,\n minHeight: 72,\n }}\n >\n <Avatar\n name={conversation.title}\n uri={conversation.avatarUrl}\n theme={theme}\n size={52}\n variant=\"initials\"\n />\n <View style={{ flex: 1, marginLeft: 14, minWidth: 0, justifyContent: 'center' }}>\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n }}\n >\n <Text\n numberOfLines={1}\n style={{\n flex: 1,\n fontSize: 17,\n fontWeight: unread ? '700' : '600',\n color: theme.text,\n marginRight: 8,\n }}\n >\n {conversation.title}\n </Text>\n <Text style={{ fontSize: 12, color: timeColor, flexShrink: 0 }}>\n {relativeLabel(conversation.lastActivity, now)}\n </Text>\n </View>\n {(preview || unread) && (\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n marginTop: 3,\n width: '100%',\n }}\n >\n <Text\n numberOfLines={1}\n style={{\n flex: 1,\n fontSize: 15,\n color: unread ? theme.text : theme.textMuted,\n fontWeight: unread ? '600' : '400',\n marginRight: 8,\n }}\n >\n {preview}\n </Text>\n <UnreadBadge count={conversation.unreadCount} theme={theme} />\n </View>\n )}\n </View>\n </View>\n </Pressable>\n );\n}\n\nexport function MessageBubble({\n message,\n theme,\n showAuthor,\n groupWithPrevious,\n groupWithNext,\n onRetry,\n onLongPress,\n}: {\n message: ChatMessage;\n theme: ChatTheme;\n showAuthor: boolean;\n /** Same sender, message visually above (older). */\n groupWithPrevious?: boolean;\n /** Same sender, message visually below (newer). */\n groupWithNext?: boolean;\n onRetry?: () => void;\n /** Long-press: where the bubble sits on screen, so the Tapback overlay can anchor to it. */\n onLongPress?: (frame: { x: number; y: number; width: number; height: number }) => void;\n}) {\n const bubbleRef = React.useRef<View>(null);\n const reactions = message.reactions ?? [];\n const mine = message.isMine;\n const failed = message.sendState === 'failed';\n const sending = message.sendState === 'sending';\n const showTimestamp = !groupWithNext;\n\n const radii = React.useMemo(() => {\n const R = 18;\n const tail = 6;\n const join = 6;\n if (mine) {\n return {\n borderTopLeftRadius: R,\n borderTopRightRadius: groupWithPrevious ? join : R,\n borderBottomLeftRadius: R,\n borderBottomRightRadius: groupWithNext ? join : tail,\n };\n }\n return {\n borderTopLeftRadius: groupWithPrevious ? join : R,\n borderTopRightRadius: R,\n borderBottomLeftRadius: groupWithNext ? join : tail,\n borderBottomRightRadius: R,\n };\n }, [mine, groupWithPrevious, groupWithNext]);\n\n if (message.isDeleted) {\n return (\n <View style={[styles.bubbleWrap, mine ? styles.alignEnd : styles.alignStart]}>\n <View style={[styles.bubble, styles.bubbleDeleted, { borderColor: theme.border }]}>\n <Text style={[styles.deletedText, { color: theme.textMuted }]}>Message deleted</Text>\n </View>\n </View>\n );\n }\n\n return (\n <View\n style={[\n styles.bubbleWrap,\n mine ? styles.alignEnd : styles.alignStart,\n groupWithNext ? styles.bubbleWrapGrouped : null,\n ]}\n >\n {showAuthor && !mine ? (\n <Text style={[styles.author, { color: theme.textMuted }]}>{message.authorName}</Text>\n ) : null}\n <Pressable\n onLongPress={\n onLongPress\n ? () =>\n bubbleRef.current?.measureInWindow((x, y, width, height) =>\n onLongPress({ x, y, width, height }),\n )\n : undefined\n }\n delayLongPress={280}\n disabled={!onLongPress}\n accessibilityHint={onLongPress ? 'Long press for reactions and options' : undefined}\n style={[styles.bubblePress, reactions.length ? styles.bubbleReacted : null]}\n >\n <View\n ref={bubbleRef}\n collapsable={false}\n style={[\n styles.bubble,\n styles.bubbleFill,\n radii,\n { backgroundColor: mine ? theme.bubbleMine : theme.bubbleTheirs },\n failed && { borderWidth: 1, borderColor: theme.danger },\n sending && styles.bubbleSending,\n ]}\n >\n <Text style={[styles.bubbleText, { color: mine ? theme.bubbleMineText : theme.bubbleTheirsText }]}>\n {message.body}\n </Text>\n </View>\n {reactions.length ? (\n // iMessage puts the Tapback on the bubble's top corner facing the other person.\n <View\n style={[\n styles.reactionBadge,\n mine ? styles.reactionBadgeMine : styles.reactionBadgeTheirs,\n { backgroundColor: theme.surface, borderColor: theme.bg, flexDirection: 'row' },\n ]}\n accessibilityLabel={reactions.map((r) => `${r.reaction} ${r.count}`).join(', ')}\n >\n {reactions.map((r) => (\n <View key={r.reaction} style={{ flexDirection: 'row', alignItems: 'center' }}>\n <Text style={styles.reactionEmoji}>{r.reaction}</Text>\n {r.count > 1 ? (\n <Text\n style={[\n styles.reactionCount,\n { color: r.mine ? theme.accent : theme.textMuted },\n ]}\n >\n {r.count}\n </Text>\n ) : null}\n </View>\n ))}\n </View>\n ) : null}\n </Pressable>\n {showTimestamp ? (\n <View style={[styles.timestampRow, mine ? styles.alignEnd : styles.alignStart]}>\n {message.isEdited ? (\n <Text style={[styles.timestampText, { color: theme.textMuted }]}>Edited · </Text>\n ) : null}\n <Text style={[styles.timestampText, { color: theme.textMuted }]}>\n {timeLabel(message.createdAt)}\n </Text>\n {failed ? (\n <Pressable\n onPress={onRetry}\n accessibilityRole=\"button\"\n style={{ flexDirection: 'row', alignItems: 'center', marginLeft: 6 }}\n >\n <MaterialCommunityIcons name=\"alert-circle-outline\" size={12} color={theme.danger} />\n <Text style={[styles.retryText, { color: theme.danger }]}> Not Delivered</Text>\n </Pressable>\n ) : null}\n </View>\n ) : failed ? (\n <Pressable\n onPress={onRetry}\n accessibilityRole=\"button\"\n style={[styles.retry, { flexDirection: 'row', alignItems: 'center' }]}\n >\n <MaterialCommunityIcons name=\"refresh\" size={13} color={theme.danger} />\n <Text style={[styles.retryText, { color: theme.danger }]}>Not Delivered · tap to retry</Text>\n </Pressable>\n ) : null}\n </View>\n );\n}\n\nexport function DaySeparator({ label, theme }: { label: string; theme: ChatTheme }) {\n if (!label) return null;\n return (\n <View style={[styles.daySep, { flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }]}>\n <Text style={[styles.dayText, { color: theme.textMuted }]}>{label}</Text>\n </View>\n );\n}\n\nexport function InlineBanner({\n message,\n theme,\n onDismiss,\n}: {\n message: string | null;\n theme: ChatTheme;\n onDismiss?: () => void;\n}) {\n if (!message) return null;\n return (\n <View style={[styles.banner, { backgroundColor: theme.danger, flexDirection: 'row', alignItems: 'center' }]}>\n <Text style={styles.bannerText} numberOfLines={2}>\n {message}\n </Text>\n {onDismiss ? (\n <Pressable onPress={onDismiss} hitSlop={8} accessibilityRole=\"button\">\n <MaterialCommunityIcons name=\"close\" size={16} color=\"#fff\" />\n </Pressable>\n ) : null}\n </View>\n );\n}\n\nexport function ConnectionBanner({ state, theme }: { state: string; theme: ChatTheme }) {\n if (state === 'connected') return null;\n const offline = state === 'offline';\n return (\n <View style={[styles.connBanner, { backgroundColor: offline ? theme.danger : theme.textMuted }]}>\n <Text style={styles.bannerText}>{offline ? 'Waiting for network' : 'Connecting…'}</Text>\n </View>\n );\n}\n\nexport function EmptyState({\n icon,\n title,\n detail,\n theme,\n action,\n}: {\n icon: React.ComponentProps<typeof MaterialCommunityIcons>['name'];\n title: string;\n detail: string;\n theme: ChatTheme;\n action?: { label: string; onPress: () => void };\n}) {\n return (\n <View style={styles.empty}>\n <View style={[styles.emptyIcon, { backgroundColor: theme.surface }]}>\n <MaterialCommunityIcons name={icon} size={34} color={theme.accent} />\n </View>\n <Text style={[styles.emptyTitle, { color: theme.text }]}>{title}</Text>\n <Text style={[styles.emptyDetail, { color: theme.textMuted }]}>{detail}</Text>\n {action ? (\n <Pressable\n onPress={action.onPress}\n accessibilityRole=\"button\"\n style={[styles.emptyAction, { backgroundColor: theme.accent }]}\n >\n <Text style={[styles.emptyActionText, { color: theme.onAccent }]}>{action.label}</Text>\n </Pressable>\n ) : null}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n avatarFallback: { alignItems: 'center', justifyContent: 'center' },\n avatarInitials: { color: '#fff', fontWeight: '700' },\n\n badge: {\n minWidth: 20,\n height: 20,\n borderRadius: 10,\n paddingHorizontal: 6,\n alignItems: 'center',\n justifyContent: 'center',\n marginLeft: 8,\n },\n badgeText: { fontSize: 11, fontWeight: '700', color: '#fff' },\n\n row: {\n minHeight: 72,\n paddingLeft: 16,\n paddingRight: 0,\n paddingVertical: 8,\n backgroundColor: 'transparent',\n },\n avatarSlot: { marginRight: 12, flexShrink: 0 },\n rowBody: {\n paddingRight: 16,\n justifyContent: 'center',\n },\n rowTop: { marginBottom: 4 },\n rowBottom: {},\n rowTitle: { fontSize: 17, fontWeight: '600', marginRight: 8 },\n rowTitleUnread: { fontWeight: '700' },\n rowTime: { fontSize: 12, flexShrink: 0 },\n rowSubtitle: { fontSize: 15, marginRight: 8, marginTop: 2 },\n\n bubbleWrap: { paddingHorizontal: 12, marginVertical: 1, maxWidth: '100%' },\n bubbleWrapGrouped: { marginVertical: 0 },\n alignEnd: { alignItems: 'flex-end' },\n alignStart: { alignItems: 'flex-start' },\n author: { fontSize: 11, fontWeight: '500', marginBottom: 4, marginLeft: 12 },\n bubble: { maxWidth: '75%', paddingHorizontal: 14, paddingVertical: 8 },\n bubbleSending: { opacity: 0.72 },\n /** Carries the 75% width cap now that the bubble sits inside a Pressable. */\n bubblePress: { maxWidth: '75%' },\n bubbleFill: { maxWidth: '100%' },\n /** Room above the bubble for the Tapback badge so it never covers the message above. */\n bubbleReacted: { marginTop: 14 },\n reactionBadge: {\n position: 'absolute',\n top: -14,\n alignItems: 'center',\n paddingHorizontal: 6,\n paddingVertical: 2,\n borderRadius: 14,\n borderWidth: 2,\n minHeight: 26,\n },\n reactionBadgeMine: { left: -8 },\n reactionBadgeTheirs: { right: -8 },\n reactionEmoji: { fontSize: 14 },\n reactionCount: { fontSize: 12, fontWeight: '600', marginLeft: 2, marginRight: 2 },\n bubbleDeleted: { borderWidth: StyleSheet.hairlineWidth, backgroundColor: 'transparent', borderRadius: 18 },\n deletedText: { fontSize: 13, fontStyle: 'italic' },\n bubbleText: { fontSize: 17, lineHeight: 22 },\n timestampRow: { flexDirection: 'row', alignItems: 'center', marginTop: 2, marginHorizontal: 4, marginBottom: 6 },\n timestampText: { fontSize: 11 },\n retry: { marginTop: 3, marginRight: 4 },\n retryText: { fontSize: 11, marginLeft: 4 },\n\n daySep: { paddingHorizontal: 24, marginVertical: 14 },\n dayText: { fontSize: 12, fontWeight: '600' },\n\n banner: { paddingHorizontal: 14, paddingVertical: 8 },\n bannerText: { flex: 1, color: '#fff', fontSize: 12, fontWeight: '500' },\n connBanner: { paddingHorizontal: 14, paddingVertical: 6, alignItems: 'center' },\n\n empty: { flex: 1, alignItems: 'center', justifyContent: 'center', padding: 32 },\n emptyIcon: {\n width: 72,\n height: 72,\n borderRadius: 36,\n alignItems: 'center',\n justifyContent: 'center',\n marginBottom: 12,\n },\n emptyTitle: { fontSize: 20, fontWeight: '700', marginTop: 4, textAlign: 'center' },\n emptyDetail: { fontSize: 14, textAlign: 'center', lineHeight: 20, marginTop: 8 },\n emptyAction: { marginTop: 18, paddingHorizontal: 22, paddingVertical: 12, borderRadius: 24 },\n emptyActionText: { fontSize: 15, fontWeight: '700' },\n});\n"],"names":["_a"],"mappings":"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"}
1
+ {"version":3,"file":"ChatComponents.js","sources":["../../../src/features/messaging/ChatComponents.tsx"],"sourcesContent":["/**\n * Presentational pieces for the chat surface.\n *\n * Plain react-native only - no gluestack, no NativeWind, no reanimated beyond\n * what the host already shares. A federated remote may only use what the host\n * provides, and every extra dependency is another way for the bundle to fail to\n * load on a device that the simulator will not reproduce.\n *\n * `expo-image` IS available (it is a shared singleton), so avatars get real\n * caching rather than RN's `Image`.\n *\n * Layout note: NativeWind's Metro interop can drop `gap` and flatten away\n * `flexDirection` from StyleSheet.create. Critical row layouts therefore set\n * `flexDirection: 'row'` as an inline style and use margins instead of gap.\n */\nimport * as React from 'react';\nimport { ActivityIndicator, Pressable, StyleSheet, Text, View } from 'react-native';\nimport { Image } from 'expo-image';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { mobileColors } from '../../theme/mobileTokens';\nimport { initialsOf, relativeLabel, timeLabel, type ChatConversation, type ChatMessage } from './chatModel';\nimport { MessageAttachments } from './ChatAttachments';\nimport type { ChatAudioSeam } from './chatHost';\n\nexport interface ChatTheme {\n bg: string;\n surface: string;\n border: string;\n text: string;\n textMuted: string;\n accent: string;\n onAccent: string;\n bubbleMine: string;\n bubbleTheirs: string;\n bubbleMineText: string;\n bubbleTheirsText: string;\n threadBg: string;\n composerBar: string;\n danger: string;\n unread: string;\n headerBg: string;\n}\n\nfunction buildChatTheme(isDark: boolean): ChatTheme {\n const c = mobileColors(isDark);\n return {\n bg: c.bg,\n surface: isDark ? c.surface : '#f8fafc',\n border: c.border,\n text: c.text,\n textMuted: c.textMuted,\n accent: c.primary,\n onAccent: '#ffffff',\n bubbleMine: isDark ? c.primarySoft : c.surfaceMuted,\n bubbleTheirs: isDark ? c.surface : c.bg,\n bubbleMineText: c.text,\n bubbleTheirsText: c.text,\n threadBg: c.bg,\n composerBar: isDark ? c.surface : '#f8fafc',\n danger: c.dangerText,\n unread: c.primary,\n headerBg: c.bg,\n };\n}\n\n/** Yantra mobile palette (`mobileTokens`) with iMessage-style layout tokens. */\nexport const chatThemes: { light: ChatTheme; dark: ChatTheme } = {\n light: buildChatTheme(false),\n dark: buildChatTheme(true),\n};\n\n/** Default avatar plate when no photo. */\nconst AVATAR_PLATE = '#dfe5e7';\nconst AVATAR_ICON = '#ffffff';\n\nexport function Avatar({\n name,\n uri,\n size = 49,\n theme,\n variant = 'silhouette',\n}: {\n name: string;\n uri?: string | null;\n size?: number;\n theme: ChatTheme;\n /** `silhouette` for thread header; `initials` for colorful Messages list avatars. */\n variant?: 'silhouette' | 'initials';\n}) {\n const [failed, setFailed] = React.useState(false);\n const radius = size / 2;\n\n if (uri && !failed) {\n return (\n <Image\n source={{ uri }}\n style={{ width: size, height: size, borderRadius: radius, backgroundColor: AVATAR_PLATE }}\n contentFit=\"cover\"\n transition={120}\n onError={() => setFailed(true)}\n accessibilityIgnoresInvertColors\n />\n );\n }\n if (variant === 'initials') {\n return (\n <View\n style={{\n width: size,\n height: size,\n borderRadius: radius,\n backgroundColor: theme.accent,\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <Text style={{ color: '#fff', fontWeight: '600', fontSize: Math.round(size * 0.38) }}>\n {initialsOf(name)}\n </Text>\n </View>\n );\n }\n return (\n <View\n style={{\n width: size,\n height: size,\n borderRadius: radius,\n backgroundColor: AVATAR_PLATE,\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <MaterialCommunityIcons name=\"account\" size={Math.round(size * 0.58)} color={AVATAR_ICON} />\n </View>\n );\n}\n\nexport function UnreadBadge({ count, theme }: { count: number; theme: ChatTheme }) {\n if (count <= 0) return null;\n return (\n <View style={[styles.badge, { backgroundColor: theme.unread }]}>\n <Text style={styles.badgeText}>{count > 99 ? '99+' : count}</Text>\n </View>\n );\n}\n\nexport function ConversationRow({\n conversation,\n theme,\n now,\n onPress,\n}: {\n conversation: ChatConversation;\n theme: ChatTheme;\n now: number;\n onPress: () => void;\n}) {\n const unread = conversation.unreadCount > 0;\n const preview = conversation.subtitle.trim();\n const timeColor = unread ? theme.unread : theme.textMuted;\n\n return (\n <Pressable\n onPress={onPress}\n accessibilityRole=\"button\"\n accessibilityLabel={\n unread ? `${conversation.title}, ${conversation.unreadCount} unread messages` : conversation.title\n }\n style={({ pressed }) => ({\n backgroundColor: pressed ? theme.surface : theme.bg,\n width: '100%',\n })}\n testID={`chat-conversation-${conversation.id}`}\n >\n {/* Inner wrapper: NativeWind can strip flexDirection from Pressable styles. */}\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n width: '100%',\n paddingLeft: 14,\n paddingRight: 16,\n paddingVertical: 10,\n minHeight: 72,\n }}\n >\n <Avatar\n name={conversation.title}\n uri={conversation.avatarUrl}\n theme={theme}\n size={52}\n variant=\"initials\"\n />\n <View style={{ flex: 1, marginLeft: 14, minWidth: 0, justifyContent: 'center' }}>\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n }}\n >\n <Text\n numberOfLines={1}\n style={{\n flex: 1,\n fontSize: 17,\n fontWeight: unread ? '700' : '600',\n color: theme.text,\n marginRight: 8,\n }}\n >\n {conversation.title}\n </Text>\n <Text style={{ fontSize: 12, color: timeColor, flexShrink: 0 }}>\n {relativeLabel(conversation.lastActivity, now)}\n </Text>\n </View>\n {(preview || unread) && (\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n marginTop: 3,\n width: '100%',\n }}\n >\n <Text\n numberOfLines={1}\n style={{\n flex: 1,\n fontSize: 15,\n color: unread ? theme.text : theme.textMuted,\n fontWeight: unread ? '600' : '400',\n marginRight: 8,\n }}\n >\n {preview}\n </Text>\n <UnreadBadge count={conversation.unreadCount} theme={theme} />\n </View>\n )}\n </View>\n </View>\n </Pressable>\n );\n}\n\nexport function MessageBubble({\n message,\n theme,\n showAuthor,\n groupWithPrevious,\n groupWithNext,\n onRetry,\n onLongPress,\n fileBaseUrl,\n audio,\n onOpenImage,\n}: {\n message: ChatMessage;\n theme: ChatTheme;\n showAuthor: boolean;\n /** Where attachments are served from (see ChatMediaSeam.fileBaseUrl). */\n fileBaseUrl?: string | null;\n /** Plays voice notes; without it they show but cannot play. */\n audio?: ChatAudioSeam;\n onOpenImage?: (url: string) => void;\n /** Same sender, message visually above (older). */\n groupWithPrevious?: boolean;\n /** Same sender, message visually below (newer). */\n groupWithNext?: boolean;\n onRetry?: () => void;\n /** Long-press: where the bubble sits on screen, so the Tapback overlay can anchor to it. */\n onLongPress?: (frame: { x: number; y: number; width: number; height: number }) => void;\n}) {\n const bubbleRef = React.useRef<View>(null);\n const reactions = message.reactions ?? [];\n const mine = message.isMine;\n const failed = message.sendState === 'failed';\n const sending = message.sendState === 'sending';\n const showTimestamp = !groupWithNext;\n\n const radii = React.useMemo(() => {\n const R = 18;\n const tail = 6;\n const join = 6;\n if (mine) {\n return {\n borderTopLeftRadius: R,\n borderTopRightRadius: groupWithPrevious ? join : R,\n borderBottomLeftRadius: R,\n borderBottomRightRadius: groupWithNext ? join : tail,\n };\n }\n return {\n borderTopLeftRadius: groupWithPrevious ? join : R,\n borderTopRightRadius: R,\n borderBottomLeftRadius: groupWithNext ? join : tail,\n borderBottomRightRadius: R,\n };\n }, [mine, groupWithPrevious, groupWithNext]);\n\n if (message.isDeleted) {\n return (\n <View style={[styles.bubbleWrap, mine ? styles.alignEnd : styles.alignStart]}>\n <View style={[styles.bubble, styles.bubbleDeleted, { borderColor: theme.border }]}>\n <Text style={[styles.deletedText, { color: theme.textMuted }]}>Message deleted</Text>\n </View>\n </View>\n );\n }\n\n return (\n <View\n style={[\n styles.bubbleWrap,\n mine ? styles.alignEnd : styles.alignStart,\n groupWithNext ? styles.bubbleWrapGrouped : null,\n ]}\n >\n {showAuthor && !mine ? (\n <Text style={[styles.author, { color: theme.textMuted }]}>{message.authorName}</Text>\n ) : null}\n <Pressable\n onLongPress={\n onLongPress\n ? () =>\n bubbleRef.current?.measureInWindow((x, y, width, height) =>\n onLongPress({ x, y, width, height }),\n )\n : undefined\n }\n delayLongPress={280}\n disabled={!onLongPress}\n accessibilityHint={onLongPress ? 'Long press for reactions and options' : undefined}\n style={[styles.bubblePress, reactions.length ? styles.bubbleReacted : null]}\n >\n <View\n ref={bubbleRef}\n collapsable={false}\n style={[\n styles.bubble,\n styles.bubbleFill,\n radii,\n { backgroundColor: mine ? theme.bubbleMine : theme.bubbleTheirs },\n failed && { borderWidth: 1, borderColor: theme.danger },\n sending && !message.attachments.length && styles.bubbleSending,\n message.attachments.length ? styles.bubbleWithMedia : null,\n ]}\n >\n {message.attachments.length ? (\n <MessageAttachments\n attachments={message.attachments}\n mine={mine}\n theme={theme}\n fileBaseUrl={fileBaseUrl}\n audio={audio}\n uploading={sending}\n onOpenImage={onOpenImage}\n />\n ) : null}\n {message.body.trim() ? (\n <Text\n style={[\n styles.bubbleText,\n { color: mine ? theme.bubbleMineText : theme.bubbleTheirsText },\n message.attachments.length ? styles.bubbleCaption : null,\n ]}\n >\n {message.body.trim()}\n </Text>\n ) : null}\n </View>\n {reactions.length ? (\n // iMessage puts the Tapback on the bubble's top corner facing the other person.\n <View\n style={[\n styles.reactionBadge,\n mine ? styles.reactionBadgeMine : styles.reactionBadgeTheirs,\n { backgroundColor: theme.surface, borderColor: theme.bg, flexDirection: 'row' },\n ]}\n accessibilityLabel={reactions.map((r) => `${r.reaction} ${r.count}`).join(', ')}\n >\n {reactions.map((r) => (\n <View key={r.reaction} style={{ flexDirection: 'row', alignItems: 'center' }}>\n <Text style={styles.reactionEmoji}>{r.reaction}</Text>\n {r.count > 1 ? (\n <Text\n style={[\n styles.reactionCount,\n { color: r.mine ? theme.accent : theme.textMuted },\n ]}\n >\n {r.count}\n </Text>\n ) : null}\n </View>\n ))}\n </View>\n ) : null}\n </Pressable>\n {showTimestamp ? (\n <View style={[styles.timestampRow, mine ? styles.alignEnd : styles.alignStart]}>\n {message.isEdited ? (\n <Text style={[styles.timestampText, { color: theme.textMuted }]}>Edited · </Text>\n ) : null}\n <Text style={[styles.timestampText, { color: theme.textMuted }]}>\n {timeLabel(message.createdAt)}\n </Text>\n {failed ? (\n <Pressable\n onPress={onRetry}\n accessibilityRole=\"button\"\n style={{ flexDirection: 'row', alignItems: 'center', marginLeft: 6 }}\n >\n <MaterialCommunityIcons name=\"alert-circle-outline\" size={12} color={theme.danger} />\n <Text style={[styles.retryText, { color: theme.danger }]}> Not Delivered</Text>\n </Pressable>\n ) : null}\n </View>\n ) : failed ? (\n <Pressable\n onPress={onRetry}\n accessibilityRole=\"button\"\n style={[styles.retry, { flexDirection: 'row', alignItems: 'center' }]}\n >\n <MaterialCommunityIcons name=\"refresh\" size={13} color={theme.danger} />\n <Text style={[styles.retryText, { color: theme.danger }]}>Not Delivered · tap to retry</Text>\n </Pressable>\n ) : null}\n </View>\n );\n}\n\nexport function DaySeparator({ label, theme }: { label: string; theme: ChatTheme }) {\n if (!label) return null;\n return (\n <View style={[styles.daySep, { flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }]}>\n <Text style={[styles.dayText, { color: theme.textMuted }]}>{label}</Text>\n </View>\n );\n}\n\nexport function InlineBanner({\n message,\n theme,\n onDismiss,\n}: {\n message: string | null;\n theme: ChatTheme;\n onDismiss?: () => void;\n}) {\n if (!message) return null;\n return (\n <View style={[styles.banner, { backgroundColor: theme.danger, flexDirection: 'row', alignItems: 'center' }]}>\n <Text style={styles.bannerText} numberOfLines={2}>\n {message}\n </Text>\n {onDismiss ? (\n <Pressable onPress={onDismiss} hitSlop={8} accessibilityRole=\"button\">\n <MaterialCommunityIcons name=\"close\" size={16} color=\"#fff\" />\n </Pressable>\n ) : null}\n </View>\n );\n}\n\nexport function ConnectionBanner({ state, theme }: { state: string; theme: ChatTheme }) {\n if (state === 'connected') return null;\n const offline = state === 'offline';\n return (\n <View style={[styles.connBanner, { backgroundColor: offline ? theme.danger : theme.textMuted }]}>\n <Text style={styles.bannerText}>{offline ? 'Waiting for network' : 'Connecting…'}</Text>\n </View>\n );\n}\n\nexport function EmptyState({\n icon,\n title,\n detail,\n theme,\n action,\n}: {\n icon: React.ComponentProps<typeof MaterialCommunityIcons>['name'];\n title: string;\n detail: string;\n theme: ChatTheme;\n action?: { label: string; onPress: () => void };\n}) {\n return (\n <View style={styles.empty}>\n <View style={[styles.emptyIcon, { backgroundColor: theme.surface }]}>\n <MaterialCommunityIcons name={icon} size={34} color={theme.accent} />\n </View>\n <Text style={[styles.emptyTitle, { color: theme.text }]}>{title}</Text>\n <Text style={[styles.emptyDetail, { color: theme.textMuted }]}>{detail}</Text>\n {action ? (\n <Pressable\n onPress={action.onPress}\n accessibilityRole=\"button\"\n style={[styles.emptyAction, { backgroundColor: theme.accent }]}\n >\n <Text style={[styles.emptyActionText, { color: theme.onAccent }]}>{action.label}</Text>\n </Pressable>\n ) : null}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n avatarFallback: { alignItems: 'center', justifyContent: 'center' },\n avatarInitials: { color: '#fff', fontWeight: '700' },\n\n badge: {\n minWidth: 20,\n height: 20,\n borderRadius: 10,\n paddingHorizontal: 6,\n alignItems: 'center',\n justifyContent: 'center',\n marginLeft: 8,\n },\n badgeText: { fontSize: 11, fontWeight: '700', color: '#fff' },\n\n row: {\n minHeight: 72,\n paddingLeft: 16,\n paddingRight: 0,\n paddingVertical: 8,\n backgroundColor: 'transparent',\n },\n avatarSlot: { marginRight: 12, flexShrink: 0 },\n rowBody: {\n paddingRight: 16,\n justifyContent: 'center',\n },\n rowTop: { marginBottom: 4 },\n rowBottom: {},\n rowTitle: { fontSize: 17, fontWeight: '600', marginRight: 8 },\n rowTitleUnread: { fontWeight: '700' },\n rowTime: { fontSize: 12, flexShrink: 0 },\n rowSubtitle: { fontSize: 15, marginRight: 8, marginTop: 2 },\n\n bubbleWrap: { paddingHorizontal: 12, marginVertical: 1, maxWidth: '100%' },\n bubbleWrapGrouped: { marginVertical: 0 },\n alignEnd: { alignItems: 'flex-end' },\n alignStart: { alignItems: 'flex-start' },\n author: { fontSize: 11, fontWeight: '500', marginBottom: 4, marginLeft: 12 },\n bubble: { maxWidth: '75%', paddingHorizontal: 14, paddingVertical: 8 },\n bubbleSending: { opacity: 0.72 },\n /** Carries the 75% width cap now that the bubble sits inside a Pressable. */\n bubblePress: { maxWidth: '75%' },\n bubbleFill: { maxWidth: '100%' },\n /** Room above the bubble for the Tapback badge so it never covers the message above. */\n bubbleReacted: { marginTop: 14 },\n reactionBadge: {\n position: 'absolute',\n top: -14,\n alignItems: 'center',\n paddingHorizontal: 6,\n paddingVertical: 2,\n borderRadius: 14,\n borderWidth: 2,\n minHeight: 26,\n },\n reactionBadgeMine: { left: -8 },\n reactionBadgeTheirs: { right: -8 },\n reactionEmoji: { fontSize: 14 },\n reactionCount: { fontSize: 12, fontWeight: '600', marginLeft: 2, marginRight: 2 },\n bubbleDeleted: { borderWidth: StyleSheet.hairlineWidth, backgroundColor: 'transparent', borderRadius: 18 },\n deletedText: { fontSize: 13, fontStyle: 'italic' },\n bubbleText: { fontSize: 17, lineHeight: 22 },\n /** Photos sit close to the bubble edge, like iMessage. */\n bubbleWithMedia: { paddingHorizontal: 4, paddingVertical: 4 },\n bubbleCaption: { paddingHorizontal: 8, paddingTop: 4, paddingBottom: 2 },\n timestampRow: { flexDirection: 'row', alignItems: 'center', marginTop: 2, marginHorizontal: 4, marginBottom: 6 },\n timestampText: { fontSize: 11 },\n retry: { marginTop: 3, marginRight: 4 },\n retryText: { fontSize: 11, marginLeft: 4 },\n\n daySep: { paddingHorizontal: 24, marginVertical: 14 },\n dayText: { fontSize: 12, fontWeight: '600' },\n\n banner: { paddingHorizontal: 14, paddingVertical: 8 },\n bannerText: { flex: 1, color: '#fff', fontSize: 12, fontWeight: '500' },\n connBanner: { paddingHorizontal: 14, paddingVertical: 6, alignItems: 'center' },\n\n empty: { flex: 1, alignItems: 'center', justifyContent: 'center', padding: 32 },\n emptyIcon: {\n width: 72,\n height: 72,\n borderRadius: 36,\n alignItems: 'center',\n justifyContent: 'center',\n marginBottom: 12,\n },\n emptyTitle: { fontSize: 20, fontWeight: '700', marginTop: 4, textAlign: 'center' },\n emptyDetail: { fontSize: 14, textAlign: 'center', lineHeight: 20, marginTop: 8 },\n emptyAction: { marginTop: 18, paddingHorizontal: 22, paddingVertical: 12, borderRadius: 24 },\n emptyActionText: { fontSize: 15, fontWeight: '700' },\n});\n"],"names":["_a"],"mappings":"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"}
@@ -99,17 +99,7 @@ function ContactsScreen({
99
99
  }], children: "Checking your contacts\u2026" })
100
100
  ] }));
101
101
  }
102
- const listHeader = permission === "granted" && limited ? /* @__PURE__ */ jsxs(View, { children: [
103
- /* @__PURE__ */ jsxs(View, { style: [styles.limitedNote, {
104
- backgroundColor: theme.surface
105
- }], children: [
106
- /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "account-lock-outline", size: 20, color: theme.textMuted }),
107
- /* @__PURE__ */ jsx(Text, { style: [styles.limitedText, {
108
- color: theme.textMuted
109
- }], children: "You shared only some contacts with Yantra. People you did not share will not show here." })
110
- ] }),
111
- onChooseMoreContacts ? /* @__PURE__ */ jsx(ActionRow, { icon: "account-multiple-plus-outline", label: "Choose more contacts", theme, onPress: onChooseMoreContacts, testID: "chat-contacts-choose-more" }) : null
112
- ] }) : null;
102
+ const listHeader = permission === "granted" && limited ? /* @__PURE__ */ jsx(View, { children: /* @__PURE__ */ jsx(ActionRow, { icon: "account-multiple-plus-outline", label: "Show all contacts", detail: "Turn on Full Access in Settings", theme, onPress: onOpenSettings, testID: "chat-contacts-allow-full-access" }) }) : null;
113
103
  return shell(/* @__PURE__ */ jsxs(Fragment, { children: [
114
104
  /* @__PURE__ */ jsx(InlineBanner, { message: error, theme, onDismiss: onDismissError }),
115
105
  /* @__PURE__ */ jsx(SectionList, { ListHeaderComponent: listHeader, sections, keyExtractor: (item) => item.id, stickySectionHeadersEnabled: false, renderSectionHeader: ({
@@ -120,7 +110,7 @@ function ContactsScreen({
120
110
  }], children: section.title }), renderItem: ({
121
111
  item,
122
112
  section
123
- }) => /* @__PURE__ */ jsx(ContactRow, { contact: item, theme, busy: busyContactId === item.id, mode: section.key === "here" ? "chat" : "invite", onPress: () => section.key === "here" ? onStartChat(item) : onInvite(item) }), ListEmptyComponent: /* @__PURE__ */ jsx(View, { style: styles.centerFill, children: /* @__PURE__ */ jsx(EmptyState, { icon: "account-search-outline", title: "No contacts found", detail: limited && !query.trim() ? "Choose more contacts to share with Yantra." : "Add phone numbers to your contacts, or search with a different name.", theme, action: {
113
+ }) => /* @__PURE__ */ jsx(ContactRow, { contact: item, theme, busy: busyContactId === item.id, mode: section.key === "here" ? "chat" : "invite", onPress: () => section.key === "here" ? onStartChat(item) : onInvite(item) }), ListEmptyComponent: /* @__PURE__ */ jsx(View, { style: styles.centerFill, children: /* @__PURE__ */ jsx(EmptyState, { icon: "account-search-outline", title: "No contacts found", detail: limited && !query.trim() ? "Turn on Full Access to contacts in Settings to see everyone you know on Yantra Chat." : "Add phone numbers to your contacts, or search with a different name.", theme, action: {
124
114
  label: "Back to chats",
125
115
  onPress: onBack
126
116
  } }) }), contentContainerStyle: sections.length === 0 ? styles.listEmptyGrow : void 0, testID: "chat-contacts-list" })
@@ -129,6 +119,7 @@ function ContactsScreen({
129
119
  function ActionRow({
130
120
  icon,
131
121
  label,
122
+ detail,
132
123
  theme,
133
124
  onPress,
134
125
  testID
@@ -142,11 +133,19 @@ function ActionRow({
142
133
  /* @__PURE__ */ jsx(View, { style: [styles.actionIcon, {
143
134
  backgroundColor: theme.surface
144
135
  }], children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: icon, size: 22, color: theme.accent }) }),
145
- /* @__PURE__ */ jsx(View, { style: [styles.rowBody, {
136
+ /* @__PURE__ */ jsxs(View, { style: [styles.rowBody, {
146
137
  borderBottomColor: theme.border
147
- }], children: /* @__PURE__ */ jsx(Text, { style: [styles.rowName, {
148
- color: theme.accent
149
- }], children: label }) })
138
+ }], children: [
139
+ /* @__PURE__ */ jsxs(View, { style: styles.rowText, children: [
140
+ /* @__PURE__ */ jsx(Text, { style: [styles.rowName, {
141
+ color: theme.accent
142
+ }], children: label }),
143
+ detail ? /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: [styles.rowPhone, {
144
+ color: theme.textMuted
145
+ }], children: detail }) : null
146
+ ] }),
147
+ /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "chevron-right", size: 22, color: theme.textMuted })
148
+ ] })
150
149
  ] }) });
151
150
  }
152
151
  function ContactRow({
@@ -1 +1 @@
1
- {"version":3,"file":"ContactsScreen.js","sources":["../../../src/features/messaging/ContactsScreen.tsx"],"sourcesContent":["/**\n * \"Find people you know\" - the contacts sync and invite screen.\n */\nimport * as React from 'react';\nimport { ActivityIndicator, Pressable, SectionList, StyleSheet, Text, TextInput, View } from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { Avatar, EmptyState, InlineBanner, type ChatTheme } from './ChatComponents';\nimport type { MatchedContact } from './useContactMatches';\nimport type { ChatPermissionStatus } from './chatHost';\n\nfunction ContactsHeader({ theme, onBack }: { theme: ChatTheme; onBack: () => void }) {\n return (\n <SafeAreaView edges={['top']} style={{ backgroundColor: theme.headerBg }}>\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n paddingHorizontal: 8,\n paddingBottom: 8,\n borderBottomWidth: StyleSheet.hairlineWidth,\n borderBottomColor: theme.border,\n backgroundColor: theme.headerBg,\n }}\n >\n <Pressable onPress={onBack} hitSlop={10} accessibilityRole=\"button\" accessibilityLabel=\"Back\">\n <MaterialCommunityIcons name=\"chevron-left\" size={28} color={theme.accent} />\n </Pressable>\n <Text\n style={{\n flex: 1,\n fontSize: 20,\n fontWeight: '700',\n color: theme.text,\n marginLeft: 8,\n }}\n >\n Select contact\n </Text>\n </View>\n </SafeAreaView>\n );\n}\n\nexport function ContactsScreen({\n permission,\n loading,\n error,\n onYantra,\n invitable,\n theme,\n busyContactId,\n onBack,\n onRequestAccess,\n onOpenSettings,\n onStartChat,\n onInvite,\n onDismissError,\n limited = false,\n onChooseMoreContacts,\n}: {\n permission: ChatPermissionStatus | 'unsupported';\n loading: boolean;\n error: string | null;\n onYantra: MatchedContact[];\n invitable: MatchedContact[];\n theme: ChatTheme;\n busyContactId: string | null;\n onBack: () => void;\n onRequestAccess: () => void;\n onOpenSettings: () => void;\n onStartChat: (contact: MatchedContact) => void;\n onInvite: (contact: MatchedContact) => void;\n onDismissError: () => void;\n /** Only some contacts are shared (iOS 18 Limited Access). */\n limited?: boolean;\n onChooseMoreContacts?: () => void;\n}) {\n const [query, setQuery] = React.useState('');\n\n const filterContact = React.useCallback(\n (c: MatchedContact) => {\n const q = query.trim().toLowerCase();\n if (!q) return true;\n const name = (c.match?.displayName || c.displayName).toLowerCase();\n const qDigits = q.replace(/\\D/g, '');\n return (\n name.includes(q) ||\n (qDigits.length > 0 &&\n [...c.e164, ...(c.rawNumbers ?? [])].some((n) => n.replace(/\\D/g, '').includes(qDigits)))\n );\n },\n [query],\n );\n\n const sections = React.useMemo(\n () =>\n [\n { key: 'here', title: 'On Yantra Chat', data: onYantra.filter(filterContact) },\n { key: 'invite', title: 'Invite to Yantra Chat', data: invitable.filter(filterContact) },\n ].filter((s) => s.data.length > 0),\n [onYantra, invitable, filterContact],\n );\n\n const hasPeople = onYantra.length > 0 || invitable.length > 0;\n\n const shell = (body: React.ReactNode) => (\n <View style={[styles.fill, { backgroundColor: theme.bg }]}>\n <ContactsHeader theme={theme} onBack={onBack} />\n {permission === 'granted' ? (\n <View style={[styles.searchWrap, { backgroundColor: theme.surface }]}>\n <MaterialCommunityIcons name=\"magnify\" size={20} color={theme.textMuted} />\n <TextInput\n value={query}\n onChangeText={setQuery}\n placeholder=\"Search name or number\"\n placeholderTextColor={theme.textMuted}\n style={[styles.searchInput, { color: theme.text }]}\n />\n </View>\n ) : null}\n {body}\n </View>\n );\n\n if (permission === 'unsupported' && !hasPeople) {\n return shell(\n <View style={styles.centerFill}>\n <EmptyState\n icon=\"cellphone-off\"\n title=\"Not available in this build\"\n detail=\"Finding people from your contacts needs a newer version of the app.\"\n theme={theme}\n action={{ label: 'Back to chats', onPress: onBack }}\n />\n </View>,\n );\n }\n\n if (permission === 'denied' && !hasPeople) {\n return shell(\n <View style={styles.centerFill}>\n <EmptyState\n icon=\"lock-outline\"\n title=\"Contacts access is off\"\n detail=\"Allow contacts access in Settings to find people you know on Yantra Chat.\"\n theme={theme}\n action={{ label: 'Open Settings', onPress: onOpenSettings }}\n />\n </View>,\n );\n }\n\n if (permission === 'undetermined' && !hasPeople) {\n return shell(\n <View style={styles.centerFill}>\n <EmptyState\n icon=\"account-multiple-outline\"\n title=\"Find people you know\"\n detail=\"Allow contacts to see who is on Yantra Chat and invite everyone else.\"\n theme={theme}\n action={{ label: 'Find from contacts', onPress: onRequestAccess }}\n />\n </View>,\n );\n }\n\n if (loading && !sections.length) {\n return shell(\n <View style={styles.centerFill}>\n <ActivityIndicator color={theme.accent} />\n <Text style={[styles.loadingText, { color: theme.textMuted }]}>Checking your contacts…</Text>\n </View>,\n );\n }\n\n // A limited selection is never a dead end: the user can share more contacts from here.\n const listHeader =\n permission === 'granted' && limited ? (\n <View>\n <View style={[styles.limitedNote, { backgroundColor: theme.surface }]}>\n <MaterialCommunityIcons name=\"account-lock-outline\" size={20} color={theme.textMuted} />\n <Text style={[styles.limitedText, { color: theme.textMuted }]}>\n You shared only some contacts with Yantra. People you did not share will not show here.\n </Text>\n </View>\n {onChooseMoreContacts ? (\n <ActionRow\n icon=\"account-multiple-plus-outline\"\n label=\"Choose more contacts\"\n theme={theme}\n onPress={onChooseMoreContacts}\n testID=\"chat-contacts-choose-more\"\n />\n ) : null}\n </View>\n ) : null;\n\n return shell(\n <>\n <InlineBanner message={error} theme={theme} onDismiss={onDismissError} />\n <SectionList\n ListHeaderComponent={listHeader}\n sections={sections}\n keyExtractor={(item) => item.id}\n stickySectionHeadersEnabled={false}\n renderSectionHeader={({ section }) => (\n <Text style={[styles.sectionTitle, { color: theme.textMuted, backgroundColor: theme.bg }]}>\n {section.title}\n </Text>\n )}\n renderItem={({ item, section }) => (\n <ContactRow\n contact={item}\n theme={theme}\n busy={busyContactId === item.id}\n mode={section.key === 'here' ? 'chat' : 'invite'}\n onPress={() => (section.key === 'here' ? onStartChat(item) : onInvite(item))}\n />\n )}\n ListEmptyComponent={\n <View style={styles.centerFill}>\n <EmptyState\n icon=\"account-search-outline\"\n title=\"No contacts found\"\n detail={\n limited && !query.trim()\n ? 'Choose more contacts to share with Yantra.'\n : 'Add phone numbers to your contacts, or search with a different name.'\n }\n theme={theme}\n action={{ label: 'Back to chats', onPress: onBack }}\n />\n </View>\n }\n contentContainerStyle={sections.length === 0 ? styles.listEmptyGrow : undefined}\n testID=\"chat-contacts-list\"\n />\n </>,\n );\n}\n\nfunction ActionRow({\n icon,\n label,\n theme,\n onPress,\n testID,\n}: {\n icon: React.ComponentProps<typeof MaterialCommunityIcons>['name'];\n label: string;\n theme: ChatTheme;\n onPress: () => void;\n testID: string;\n}) {\n return (\n <Pressable\n onPress={onPress}\n accessibilityRole=\"button\"\n accessibilityLabel={label}\n style={({ pressed }) => ({ width: '100%', backgroundColor: pressed ? theme.surface : theme.bg })}\n testID={testID}\n >\n {/* Inner wrapper: NativeWind can strip flexDirection from Pressable styles. */}\n <View style={styles.row}>\n <View style={[styles.actionIcon, { backgroundColor: theme.surface }]}>\n <MaterialCommunityIcons name={icon} size={22} color={theme.accent} />\n </View>\n <View style={[styles.rowBody, { borderBottomColor: theme.border }]}>\n <Text style={[styles.rowName, { color: theme.accent }]}>{label}</Text>\n </View>\n </View>\n </Pressable>\n );\n}\n\nfunction ContactRow({\n contact,\n theme,\n mode,\n busy,\n onPress,\n}: {\n contact: MatchedContact;\n theme: ChatTheme;\n mode: 'chat' | 'invite';\n busy: boolean;\n onPress: () => void;\n}) {\n const name = contact.match?.displayName || contact.displayName;\n return (\n <Pressable\n onPress={onPress}\n disabled={busy}\n accessibilityRole=\"button\"\n accessibilityLabel={mode === 'chat' ? `Message ${name}` : `Invite ${name}`}\n style={({ pressed }) => ({\n width: '100%',\n backgroundColor: pressed ? theme.surface : theme.bg,\n })}\n testID={`chat-contact-${contact.id}`}\n >\n {/* Inner wrapper: NativeWind can strip flexDirection from Pressable styles. */}\n <View style={styles.row}>\n <Avatar name={name} uri={contact.match?.picture ?? contact.imageUri} theme={theme} size={44} />\n <View style={[styles.rowBody, { borderBottomColor: theme.border }]}>\n <View style={styles.rowText}>\n <Text numberOfLines={1} style={[styles.rowName, { color: theme.text }]}>\n {name}\n </Text>\n <Text numberOfLines={1} style={[styles.rowPhone, { color: theme.textMuted }]}>\n {contact.rawNumbers?.[0] ?? contact.e164[0]}\n </Text>\n </View>\n {busy ? (\n <ActivityIndicator size=\"small\" color={theme.accent} />\n ) : mode === 'invite' ? (\n <View style={[styles.inviteChip, { borderColor: theme.accent }]}>\n <Text style={[styles.inviteText, { color: theme.accent }]}>Invite</Text>\n </View>\n ) : null}\n </View>\n </View>\n </Pressable>\n );\n}\n\nconst styles = StyleSheet.create({\n fill: { flex: 1 },\n centerFill: {\n flex: 1,\n alignItems: 'center',\n justifyContent: 'center',\n paddingHorizontal: 28,\n minHeight: 360,\n },\n listEmptyGrow: { flexGrow: 1 },\n loadingText: { fontSize: 14, marginTop: 12 },\n searchWrap: {\n flexDirection: 'row',\n alignItems: 'center',\n marginHorizontal: 16,\n marginVertical: 8,\n borderRadius: 10,\n paddingHorizontal: 12,\n height: 36,\n },\n searchInput: { flex: 1, marginLeft: 8, fontSize: 16, paddingVertical: 0 },\n row: { flexDirection: 'row', alignItems: 'center', width: '100%', paddingLeft: 16 },\n rowBody: {\n flex: 1,\n flexDirection: 'row',\n alignItems: 'center',\n marginLeft: 12,\n paddingVertical: 12,\n paddingRight: 16,\n minHeight: 64,\n borderBottomWidth: StyleSheet.hairlineWidth,\n },\n rowText: { flex: 1, minWidth: 0, marginRight: 12 },\n rowName: { fontSize: 16, fontWeight: '600' },\n rowPhone: { fontSize: 13, marginTop: 2 },\n actionIcon: { width: 44, height: 44, borderRadius: 22, alignItems: 'center', justifyContent: 'center' },\n limitedNote: {\n flexDirection: 'row',\n alignItems: 'flex-start',\n marginHorizontal: 16,\n marginTop: 4,\n marginBottom: 4,\n padding: 12,\n borderRadius: 10,\n },\n limitedText: { flex: 1, fontSize: 13, lineHeight: 18, marginLeft: 10 },\n inviteChip: { borderWidth: 1, borderRadius: 14, paddingHorizontal: 12, paddingVertical: 4 },\n inviteText: { fontSize: 13, fontWeight: '600' },\n sectionTitle: {\n fontSize: 13,\n fontWeight: '600',\n paddingHorizontal: 16,\n paddingTop: 14,\n paddingBottom: 6,\n },\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ContactsScreen.js","sources":["../../../src/features/messaging/ContactsScreen.tsx"],"sourcesContent":["/**\n * \"Find people you know\" - the contacts sync and invite screen.\n */\nimport * as React from 'react';\nimport { ActivityIndicator, Pressable, SectionList, StyleSheet, Text, TextInput, View } from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { Avatar, EmptyState, InlineBanner, type ChatTheme } from './ChatComponents';\nimport type { MatchedContact } from './useContactMatches';\nimport type { ChatPermissionStatus } from './chatHost';\n\nfunction ContactsHeader({ theme, onBack }: { theme: ChatTheme; onBack: () => void }) {\n return (\n <SafeAreaView edges={['top']} style={{ backgroundColor: theme.headerBg }}>\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n paddingHorizontal: 8,\n paddingBottom: 8,\n borderBottomWidth: StyleSheet.hairlineWidth,\n borderBottomColor: theme.border,\n backgroundColor: theme.headerBg,\n }}\n >\n <Pressable onPress={onBack} hitSlop={10} accessibilityRole=\"button\" accessibilityLabel=\"Back\">\n <MaterialCommunityIcons name=\"chevron-left\" size={28} color={theme.accent} />\n </Pressable>\n <Text\n style={{\n flex: 1,\n fontSize: 20,\n fontWeight: '700',\n color: theme.text,\n marginLeft: 8,\n }}\n >\n Select contact\n </Text>\n </View>\n </SafeAreaView>\n );\n}\n\nexport function ContactsScreen({\n permission,\n loading,\n error,\n onYantra,\n invitable,\n theme,\n busyContactId,\n onBack,\n onRequestAccess,\n onOpenSettings,\n onStartChat,\n onInvite,\n onDismissError,\n limited = false,\n onChooseMoreContacts,\n}: {\n permission: ChatPermissionStatus | 'unsupported';\n loading: boolean;\n error: string | null;\n onYantra: MatchedContact[];\n invitable: MatchedContact[];\n theme: ChatTheme;\n busyContactId: string | null;\n onBack: () => void;\n onRequestAccess: () => void;\n onOpenSettings: () => void;\n onStartChat: (contact: MatchedContact) => void;\n onInvite: (contact: MatchedContact) => void;\n onDismissError: () => void;\n /** Only some contacts are shared (iOS 18 Limited Access). */\n limited?: boolean;\n onChooseMoreContacts?: () => void;\n}) {\n const [query, setQuery] = React.useState('');\n\n const filterContact = React.useCallback(\n (c: MatchedContact) => {\n const q = query.trim().toLowerCase();\n if (!q) return true;\n const name = (c.match?.displayName || c.displayName).toLowerCase();\n const qDigits = q.replace(/\\D/g, '');\n return (\n name.includes(q) ||\n (qDigits.length > 0 &&\n [...c.e164, ...(c.rawNumbers ?? [])].some((n) => n.replace(/\\D/g, '').includes(qDigits)))\n );\n },\n [query],\n );\n\n const sections = React.useMemo(\n () =>\n [\n { key: 'here', title: 'On Yantra Chat', data: onYantra.filter(filterContact) },\n { key: 'invite', title: 'Invite to Yantra Chat', data: invitable.filter(filterContact) },\n ].filter((s) => s.data.length > 0),\n [onYantra, invitable, filterContact],\n );\n\n const hasPeople = onYantra.length > 0 || invitable.length > 0;\n\n const shell = (body: React.ReactNode) => (\n <View style={[styles.fill, { backgroundColor: theme.bg }]}>\n <ContactsHeader theme={theme} onBack={onBack} />\n {permission === 'granted' ? (\n <View style={[styles.searchWrap, { backgroundColor: theme.surface }]}>\n <MaterialCommunityIcons name=\"magnify\" size={20} color={theme.textMuted} />\n <TextInput\n value={query}\n onChangeText={setQuery}\n placeholder=\"Search name or number\"\n placeholderTextColor={theme.textMuted}\n style={[styles.searchInput, { color: theme.text }]}\n />\n </View>\n ) : null}\n {body}\n </View>\n );\n\n if (permission === 'unsupported' && !hasPeople) {\n return shell(\n <View style={styles.centerFill}>\n <EmptyState\n icon=\"cellphone-off\"\n title=\"Not available in this build\"\n detail=\"Finding people from your contacts needs a newer version of the app.\"\n theme={theme}\n action={{ label: 'Back to chats', onPress: onBack }}\n />\n </View>,\n );\n }\n\n if (permission === 'denied' && !hasPeople) {\n return shell(\n <View style={styles.centerFill}>\n <EmptyState\n icon=\"lock-outline\"\n title=\"Contacts access is off\"\n detail=\"Allow contacts access in Settings to find people you know on Yantra Chat.\"\n theme={theme}\n action={{ label: 'Open Settings', onPress: onOpenSettings }}\n />\n </View>,\n );\n }\n\n if (permission === 'undetermined' && !hasPeople) {\n return shell(\n <View style={styles.centerFill}>\n <EmptyState\n icon=\"account-multiple-outline\"\n title=\"Find people you know\"\n detail=\"Allow contacts to see who is on Yantra Chat and invite everyone else.\"\n theme={theme}\n action={{ label: 'Find from contacts', onPress: onRequestAccess }}\n />\n </View>,\n );\n }\n\n if (loading && !sections.length) {\n return shell(\n <View style={styles.centerFill}>\n <ActivityIndicator color={theme.accent} />\n <Text style={[styles.loadingText, { color: theme.textMuted }]}>Checking your contacts…</Text>\n </View>,\n );\n }\n\n // A limited selection is never a dead end: the user can share more contacts from here.\n const listHeader =\n permission === 'granted' && limited ? (\n <View>\n {/* Replaced by the \"Show all contacts\" row below.\n <View style={[styles.limitedNote, { backgroundColor: theme.surface }]}>\n <MaterialCommunityIcons name=\"account-lock-outline\" size={20} color={theme.textMuted} />\n <Text style={[styles.limitedText, { color: theme.textMuted }]}>\n You shared only some contacts with Yantra. People you did not share will not show here.\n </Text>\n </View>\n */}\n {/*\n * Disabled for now: Apple's in-app access picker goes blank when its search is tapped on\n * real iPhones (expo/expo#46977). Full access in Settings is offered instead.\n {onChooseMoreContacts ? (\n <ActionRow\n icon=\"account-multiple-plus-outline\"\n label=\"Choose more contacts\"\n theme={theme}\n onPress={onChooseMoreContacts}\n testID=\"chat-contacts-choose-more\"\n />\n ) : null}\n */}\n <ActionRow\n icon=\"account-multiple-plus-outline\"\n label=\"Show all contacts\"\n detail=\"Turn on Full Access in Settings\"\n theme={theme}\n onPress={onOpenSettings}\n testID=\"chat-contacts-allow-full-access\"\n />\n </View>\n ) : null;\n\n return shell(\n <>\n <InlineBanner message={error} theme={theme} onDismiss={onDismissError} />\n <SectionList\n ListHeaderComponent={listHeader}\n sections={sections}\n keyExtractor={(item) => item.id}\n stickySectionHeadersEnabled={false}\n renderSectionHeader={({ section }) => (\n <Text style={[styles.sectionTitle, { color: theme.textMuted, backgroundColor: theme.bg }]}>\n {section.title}\n </Text>\n )}\n renderItem={({ item, section }) => (\n <ContactRow\n contact={item}\n theme={theme}\n busy={busyContactId === item.id}\n mode={section.key === 'here' ? 'chat' : 'invite'}\n onPress={() => (section.key === 'here' ? onStartChat(item) : onInvite(item))}\n />\n )}\n ListEmptyComponent={\n <View style={styles.centerFill}>\n <EmptyState\n icon=\"account-search-outline\"\n title=\"No contacts found\"\n detail={\n limited && !query.trim()\n ? 'Turn on Full Access to contacts in Settings to see everyone you know on Yantra Chat.'\n : 'Add phone numbers to your contacts, or search with a different name.'\n }\n theme={theme}\n action={{ label: 'Back to chats', onPress: onBack }}\n />\n </View>\n }\n contentContainerStyle={sections.length === 0 ? styles.listEmptyGrow : undefined}\n testID=\"chat-contacts-list\"\n />\n </>,\n );\n}\n\nfunction ActionRow({\n icon,\n label,\n detail,\n theme,\n onPress,\n testID,\n}: {\n icon: React.ComponentProps<typeof MaterialCommunityIcons>['name'];\n label: string;\n detail?: string;\n theme: ChatTheme;\n onPress: () => void;\n testID: string;\n}) {\n return (\n <Pressable\n onPress={onPress}\n accessibilityRole=\"button\"\n accessibilityLabel={label}\n style={({ pressed }) => ({ width: '100%', backgroundColor: pressed ? theme.surface : theme.bg })}\n testID={testID}\n >\n {/* Inner wrapper: NativeWind can strip flexDirection from Pressable styles. */}\n <View style={styles.row}>\n <View style={[styles.actionIcon, { backgroundColor: theme.surface }]}>\n <MaterialCommunityIcons name={icon} size={22} color={theme.accent} />\n </View>\n <View style={[styles.rowBody, { borderBottomColor: theme.border }]}>\n <View style={styles.rowText}>\n <Text style={[styles.rowName, { color: theme.accent }]}>{label}</Text>\n {detail ? (\n <Text numberOfLines={1} style={[styles.rowPhone, { color: theme.textMuted }]}>\n {detail}\n </Text>\n ) : null}\n </View>\n <MaterialCommunityIcons name=\"chevron-right\" size={22} color={theme.textMuted} />\n </View>\n </View>\n </Pressable>\n );\n}\n\nfunction ContactRow({\n contact,\n theme,\n mode,\n busy,\n onPress,\n}: {\n contact: MatchedContact;\n theme: ChatTheme;\n mode: 'chat' | 'invite';\n busy: boolean;\n onPress: () => void;\n}) {\n const name = contact.match?.displayName || contact.displayName;\n return (\n <Pressable\n onPress={onPress}\n disabled={busy}\n accessibilityRole=\"button\"\n accessibilityLabel={mode === 'chat' ? `Message ${name}` : `Invite ${name}`}\n style={({ pressed }) => ({\n width: '100%',\n backgroundColor: pressed ? theme.surface : theme.bg,\n })}\n testID={`chat-contact-${contact.id}`}\n >\n {/* Inner wrapper: NativeWind can strip flexDirection from Pressable styles. */}\n <View style={styles.row}>\n <Avatar name={name} uri={contact.match?.picture ?? contact.imageUri} theme={theme} size={44} />\n <View style={[styles.rowBody, { borderBottomColor: theme.border }]}>\n <View style={styles.rowText}>\n <Text numberOfLines={1} style={[styles.rowName, { color: theme.text }]}>\n {name}\n </Text>\n <Text numberOfLines={1} style={[styles.rowPhone, { color: theme.textMuted }]}>\n {contact.rawNumbers?.[0] ?? contact.e164[0]}\n </Text>\n </View>\n {busy ? (\n <ActivityIndicator size=\"small\" color={theme.accent} />\n ) : mode === 'invite' ? (\n <View style={[styles.inviteChip, { borderColor: theme.accent }]}>\n <Text style={[styles.inviteText, { color: theme.accent }]}>Invite</Text>\n </View>\n ) : null}\n </View>\n </View>\n </Pressable>\n );\n}\n\nconst styles = StyleSheet.create({\n fill: { flex: 1 },\n centerFill: {\n flex: 1,\n alignItems: 'center',\n justifyContent: 'center',\n paddingHorizontal: 28,\n minHeight: 360,\n },\n listEmptyGrow: { flexGrow: 1 },\n loadingText: { fontSize: 14, marginTop: 12 },\n searchWrap: {\n flexDirection: 'row',\n alignItems: 'center',\n marginHorizontal: 16,\n marginVertical: 8,\n borderRadius: 10,\n paddingHorizontal: 12,\n height: 36,\n },\n searchInput: { flex: 1, marginLeft: 8, fontSize: 16, paddingVertical: 0 },\n row: { flexDirection: 'row', alignItems: 'center', width: '100%', paddingLeft: 16 },\n rowBody: {\n flex: 1,\n flexDirection: 'row',\n alignItems: 'center',\n marginLeft: 12,\n paddingVertical: 12,\n paddingRight: 16,\n minHeight: 64,\n borderBottomWidth: StyleSheet.hairlineWidth,\n },\n rowText: { flex: 1, minWidth: 0, marginRight: 12 },\n rowName: { fontSize: 16, fontWeight: '600' },\n rowPhone: { fontSize: 13, marginTop: 2 },\n actionIcon: { width: 44, height: 44, borderRadius: 22, alignItems: 'center', justifyContent: 'center' },\n limitedNote: {\n flexDirection: 'row',\n alignItems: 'flex-start',\n marginHorizontal: 16,\n marginTop: 4,\n marginBottom: 4,\n padding: 12,\n borderRadius: 10,\n },\n limitedText: { flex: 1, fontSize: 13, lineHeight: 18, marginLeft: 10 },\n inviteChip: { borderWidth: 1, borderRadius: 14, paddingHorizontal: 12, paddingVertical: 4 },\n inviteText: { fontSize: 13, fontWeight: '600' },\n sectionTitle: {\n fontSize: 13,\n fontWeight: '600',\n paddingHorizontal: 16,\n paddingTop: 14,\n paddingBottom: 6,\n },\n});\n"],"names":[],"mappings":"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"}
@@ -28,7 +28,8 @@ function NativeChatExperience({
28
28
  conversations.markRead(activeChannelId);
29
29
  }, [activeChannelId, conversations.applyConversationMessage, conversations.markRead]);
30
30
  const thread = useThread(services.gql, route === "thread" ? activeChannelId : null, viewer, {
31
- onConversationMessage: onThreadListUpdate
31
+ onConversationMessage: onThreadListUpdate,
32
+ media: services.media
32
33
  });
33
34
  useMarkRead(services.gql, route === "thread" ? activeChannelId : null, conversations.markRead);
34
35
  const threadOpenRef = React.useRef(null);
@@ -151,6 +152,9 @@ function NativeChatExperience({
151
152
  } : void 0, onShareText: services.link ? (text) => {
152
153
  var _a;
153
154
  return void ((_a = services.link) == null ? void 0 : _a.share(text));
155
+ } : void 0, media: services.media, audio: services.audio, onSendAttachments: thread.sendAttachments ? (files, caption, kind) => {
156
+ var _a;
157
+ return void ((_a = thread.sendAttachments) == null ? void 0 : _a.call(thread, files, caption, kind));
154
158
  } : void 0, onDismissError: () => setDismissedError(thread.error) }) });
155
159
  }
156
160
  if (route === "contacts") {
@@ -1 +1 @@
1
- {"version":3,"file":"NativeChatExperience.js","sources":["../../../src/features/messaging/NativeChatExperience.tsx"],"sourcesContent":["/**\n * The chat remote's exposed root (`chat_native/Chat`).\n *\n * Owns its own navigation as local state - the remote must not import\n * @react-navigation, because a second copy of the navigator would not share the\n * host's container. Android hardware back is handled with RN's own BackHandler.\n *\n * Everything here is plain react-native (plus expo-image and\n * @expo/vector-icons, both host-shared singletons) - no gluestack, no\n * NativeWind, no Apollo - because a federated remote may only use what the host\n * shares, and every extra dependency is another way to fail to load on a device\n * in a way the simulator will not reproduce.\n */\nimport * as React from 'react';\nimport { ActivityIndicator, AppState, BackHandler, Platform, StyleSheet, Text, View } from 'react-native';\nimport type { NativeChatExperienceProps } from './chatHost';\nimport { chatThemes, EmptyState } from './ChatComponents';\nimport { useAppTheme } from '../../theme/AppThemeProvider';\nimport { ConversationListScreen } from './ConversationListScreen';\nimport { ContactsScreen } from './ContactsScreen';\nimport { ThreadScreen } from './ThreadScreen';\nimport { useConversations, useMarkRead, useThread } from './useChatData';\nimport { VIEW_CHANNEL_MUTATION, YANTRA_CHAT_INVITER_QUERY } from './chatOperations';\nimport { buildChatInviteUrl, chatInviteMessage } from './chatInviteLink';\n\n/** Used only when the host predates `chatInviteUrl`; the host supplies the per-environment domain. */\nconst DEFAULT_INVITE_WEB_BASE = 'https://yantra.app';\nimport { useContactMatches, type MatchedContact } from './useContactMatches';\nimport type { WirePost } from './chatModel';\n\n/** The screens the remote routes between internally. */\nexport type ChatRoute = 'list' | 'thread' | 'contacts' | 'newGroup' | 'groupInfo';\n\nexport function NativeChatExperience({\n viewer,\n sessionError,\n services,\n initialChannelId,\n initialPeer,\n onActiveChannelChange,\n onInternalRouteChange,\n testID,\n}: NativeChatExperienceProps) {\n const { isDark } = useAppTheme();\n const theme = isDark ? chatThemes.dark : chatThemes.light;\n\n const [route, setRoute] = React.useState<ChatRoute>(initialChannelId ? 'thread' : 'list');\n const [activeChannelId, setActiveChannelId] = React.useState<string | null>(initialChannelId ?? null);\n const [dismissedError, setDismissedError] = React.useState<string | null>(null);\n\n const conversations = useConversations(services, viewer, { syncListRealtime: route === 'list' });\n const contactMatches = useContactMatches(services.gql, services.contacts, viewer, services.phone);\n const [busyContactId, setBusyContactId] = React.useState<string | null>(null);\n const [startChatError, setStartChatError] = React.useState<string | null>(null);\n const onThreadListUpdate = React.useCallback(\n (post: WirePost) => {\n if (!activeChannelId) return;\n conversations.applyConversationMessage(activeChannelId, post);\n // The viewer is looking at this thread, so a message arriving here is already read.\n conversations.markRead(activeChannelId);\n },\n [activeChannelId, conversations.applyConversationMessage, conversations.markRead],\n );\n const thread = useThread(services.gql, route === 'thread' ? activeChannelId : null, viewer, {\n onConversationMessage: onThreadListUpdate,\n });\n\n // Clearing the badge is local-first; the mutation is fire-and-forget.\n useMarkRead(services.gql, route === 'thread' ? activeChannelId : null, conversations.markRead);\n\n // Mark read again on LEAVING a thread, so messages that arrived while it was open\n // are not counted as unread by the server on the next list load.\n const threadOpenRef = React.useRef<string | null>(null);\n React.useEffect(() => {\n const open = route === 'thread' ? activeChannelId : null;\n const left = threadOpenRef.current;\n if (left && left !== open) void services.gql.mutate(VIEW_CHANNEL_MUTATION, { id: left });\n threadOpenRef.current = open;\n }, [route, activeChannelId, services.gql]);\n\n // The host suppresses a foreground push banner for the conversation already\n // on screen, so it has to be told every time that changes.\n React.useEffect(() => {\n onActiveChannelChange?.(route === 'thread' ? activeChannelId : null);\n }, [route, activeChannelId, onActiveChannelChange]);\n\n React.useEffect(() => {\n const internal: 'list' | 'thread' | 'contacts' | 'register' =\n route === 'thread' ? 'thread' : route === 'contacts' ? 'contacts' : 'list';\n onInternalRouteChange?.(internal);\n }, [route, onInternalRouteChange]);\n\n // The address book changes outside the app, so re-read it whenever the picker opens\n // and whenever the app returns to the foreground while the picker is showing.\n const refreshContactsRef = React.useRef(contactMatches.refresh);\n refreshContactsRef.current = contactMatches.refresh;\n const contactsGranted = contactMatches.permission === 'granted';\n React.useEffect(() => {\n if (route !== 'contacts' || !contactsGranted) return undefined;\n void refreshContactsRef.current();\n const sub = AppState.addEventListener('change', (state) => {\n if (state === 'active') void refreshContactsRef.current();\n });\n return () => sub.remove();\n }, [route, contactsGranted]);\n\n const activeConversation = React.useMemo(\n () => conversations.conversations.find((c) => c.id === activeChannelId) ?? null,\n [conversations.conversations, activeChannelId],\n );\n\n // Android back pops the internal stack before the host's navigator sees it.\n React.useEffect(() => {\n if (Platform.OS !== 'android') return undefined;\n const sub = BackHandler.addEventListener('hardwareBackPress', () => {\n if (route === 'list') return false;\n setRoute('list');\n return true;\n });\n return () => sub.remove();\n }, [route]);\n\n const openThread = React.useCallback((id: string) => {\n setActiveChannelId(id);\n setRoute('thread');\n }, []);\n\n /**\n * Open (or reuse) the conversation with a matched contact. createDirectChannel\n * is idempotent server-side, so tapping someone you already talk to lands in\n * the existing thread rather than making a second one.\n */\n const startChatWith = React.useCallback(\n async (contact: MatchedContact) => {\n if (!contact.match || busyContactId) return;\n setBusyContactId(contact.id);\n setStartChatError(null);\n try {\n const id = await conversations.openDirect(contact.match.userId, contact.match.displayName);\n if (id) openThread(id);\n else setStartChatError('Could not start this conversation. Please try again.');\n } finally {\n setBusyContactId(null);\n }\n },\n [conversations, openThread, busyContactId],\n );\n\n // Opened from a chat invite link: go straight into the conversation with the inviter\n // (createDirectChannel is idempotent, so reopening an old invite lands in the same thread).\n // The link is editable by anyone, so the server has to vouch for the inviter first, and\n // its name is used - never the one in the link.\n // Tracks the invite object, not the user: every tap on a link arrives as a new object,\n // so reopening a link retries, while re-renders of the same one do not.\n const openedPeer = React.useRef<typeof initialPeer | null>(null);\n const [inviteNotice, setInviteNotice] = React.useState<string | null>(null);\n const { openDirect } = conversations;\n React.useEffect(() => {\n const peer = initialPeer;\n if (!peer?.userId || !viewer?.userId || peer.userId === viewer.userId) return;\n if (openedPeer.current === peer) return;\n openedPeer.current = peer;\n void (async () => {\n const res = await services.gql.query<{\n yantraChatInviter?: { userId: string; displayName: string } | null;\n }>(YANTRA_CHAT_INVITER_QUERY, { userId: peer.userId }, { fetchPolicy: 'network-only' });\n const inviter = res.data?.yantraChatInviter;\n if (!inviter) {\n setInviteNotice(\n res.errors?.length\n ? 'Could not open this invite. Check your connection and open the link again.'\n : 'This invite link is not valid anymore. Ask for a new one.',\n );\n return;\n }\n const id = await openDirect(inviter.userId, inviter.displayName);\n if (id) openThread(id);\n else setInviteNotice(`Could not start a conversation with ${inviter.displayName}. Please try again.`);\n })();\n }, [initialPeer, viewer?.userId, services.gql, openDirect, openThread]);\n\n /**\n * Invite someone who is not here yet.\n *\n * With phone-based membership (issue #1312):\n * 1. Call the connector to generate a deep link\n * 2. Open SMS composer with the deep link (user approves before sending)\n * 3. Fall back to share sheet where SMS is unavailable (simulators)\n *\n * The deep link includes the invitee's phone and the inviter's phone,\n * enabling install-then-attribute and direct link-back to the inviter\n * after the app is installed.\n */\n const inviteContact = React.useCallback(\n async (contact: MatchedContact) => {\n const link = services.link;\n\n if (!link || !viewer?.userId) return;\n const smsTo = contact.rawNumbers?.length ? contact.rawNumbers.slice(0, 1) : contact.e164.slice(0, 1);\n if (!smsTo.length) return;\n\n // The link names the inviter (so the app can open this conversation on arrival) and\n // carries no phone numbers.\n const invite = { inviterId: viewer.userId, inviterName: viewer.displayName ?? null };\n const url = services.phone?.chatInviteUrl?.(invite) ?? buildChatInviteUrl(DEFAULT_INVITE_WEB_BASE, invite);\n const body = chatInviteMessage(viewer.displayName, url);\n\n // Saved numbers, not our E.164 guesses: the phone dials them in its own region.\n const result = await link.composeSms(smsTo, body);\n if (result === 'unavailable') await link.share(body);\n },\n [services.link, services.phone, viewer],\n );\n\n const activeTitle = React.useMemo(\n () => conversations.conversations.find((c) => c.id === activeChannelId)?.title ?? 'Chat',\n [conversations.conversations, activeChannelId],\n );\n\n if (sessionError) {\n return (\n <Shell theme={theme} testID={testID}>\n <EmptyState\n icon=\"alert-circle-outline\"\n title=\"Chat is unavailable\"\n detail={sessionError}\n theme={theme}\n />\n </Shell>\n );\n }\n\n // Session still resolving: a spinner, never an error. org/user arrive a beat\n // after mount and a flash of failure reads as a broken feature.\n if (!viewer) {\n return (\n <Shell theme={theme} testID={testID}>\n <View style={styles.center}>\n <ActivityIndicator />\n </View>\n </Shell>\n );\n }\n\n if (route === 'thread' && activeChannelId) {\n const threadError = thread.error === dismissedError ? null : thread.error;\n return (\n <Shell theme={theme} testID={testID}>\n <ThreadScreen\n title={activeTitle}\n avatarUrl={activeConversation?.avatarUrl}\n messages={thread.messages}\n loading={thread.loading}\n loadingMore={thread.loadingMore}\n error={threadError}\n theme={theme}\n connectionState={services.gql.connectionState}\n haptics={services.haptics}\n onBack={() => setRoute('list')}\n onSend={(body) => void thread.send(body)}\n onLoadMore={thread.loadMore}\n onRetry={thread.retry}\n onReact={(messageId, emoji) => {\n const current = thread.messages\n .find((m) => m.id === messageId)\n ?.reactions.find((r) => r.mine)?.reaction;\n // Tapping your current Tapback removes it, as in iMessage.\n thread.react(messageId, current === emoji ? null : emoji);\n }}\n onCopyText={services.clipboard ? (text) => void services.clipboard?.copy(text) : undefined}\n onShareText={services.link ? (text) => void services.link?.share(text) : undefined}\n onDismissError={() => setDismissedError(thread.error)}\n />\n </Shell>\n );\n }\n\n if (route === 'contacts') {\n return (\n <Shell theme={theme} testID={testID}>\n <ContactsScreen\n permission={contactMatches.permission}\n loading={contactMatches.loading}\n error={startChatError ?? contactMatches.error}\n onYantra={contactMatches.onYantra}\n invitable={contactMatches.invitable}\n theme={theme}\n busyContactId={busyContactId}\n onBack={() => setRoute('list')}\n onRequestAccess={() => void contactMatches.requestAccess()}\n onOpenSettings={() => void contactMatches.openSettings()}\n onStartChat={(c) => void startChatWith(c)}\n onInvite={(c) => void inviteContact(c)}\n limited={contactMatches.limited}\n onChooseMoreContacts={\n contactMatches.chooseMoreContacts ? () => void contactMatches.chooseMoreContacts?.() : undefined\n }\n onDismissError={() => {\n if (startChatError) setStartChatError(null);\n else void contactMatches.refresh();\n }}\n />\n </Shell>\n );\n }\n\n const listError = conversations.error === dismissedError ? null : conversations.error;\n return (\n <Shell theme={theme} testID={testID}>\n <ConversationListScreen\n conversations={conversations.conversations}\n loading={conversations.loading}\n refreshing={conversations.refreshing}\n error={listError}\n theme={theme}\n connectionState={services.gql.connectionState}\n canInvite\n onRefresh={() => {\n conversations.refresh();\n void contactMatches.refresh();\n }}\n onRetry={conversations.refresh}\n loadingMore={conversations.loadingMore}\n onLoadMore={conversations.loadMore}\n onOpen={openThread}\n onNewChat={() => setRoute('contacts')}\n onDismissError={() => setDismissedError(conversations.error)}\n notice={inviteNotice}\n onDismissNotice={() => setInviteNotice(null)}\n />\n </Shell>\n );\n}\n\nfunction Shell({ theme, testID, children }: { theme: { bg: string }; testID?: string; children: React.ReactNode }) {\n return (\n <View testID={testID ?? 'chat-native'} style={[styles.fill, { backgroundColor: theme.bg }]}>\n {children}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n fill: { flex: 1 },\n center: { flex: 1, alignItems: 'center', justifyContent: 'center' },\n});\n\nexport default NativeChatExperience;\n"],"names":[],"mappings":"ksBA0BA,MAAM,uBAA0B,GAAA,oBAAA;AAMzB,SAAS,oBAAqB,CAAA;AAAA,EACnC,MAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA,gBAAA;AAAA,EACA,WAAA;AAAA,EACA,qBAAA;AAAA,EACA,qBAAA;AAAA,EACA;AACF,CAA8B,EAAA;AAC5B,EAAM,MAAA;AAAA,IACJ;AAAA,MACE,WAAY,EAAA;AAChB,EAAA,MAAM,KAAQ,GAAA,MAAA,GAAS,UAAW,CAAA,IAAA,GAAO,UAAW,CAAA,KAAA;AACpD,EAAM,MAAA,CAAC,OAAO,QAAQ,CAAA,GAAI,MAAM,QAAoB,CAAA,gBAAA,GAAmB,WAAW,MAAM,CAAA;AACxF,EAAA,MAAM,CAAC,eAAiB,EAAA,kBAAkB,IAAI,KAAM,CAAA,QAAA,CAAwB,8CAAoB,IAAI,CAAA;AACpG,EAAA,MAAM,CAAC,cAAgB,EAAA,iBAAiB,CAAI,GAAA,KAAA,CAAM,SAAwB,IAAI,CAAA;AAC9E,EAAM,MAAA,aAAA,GAAgB,gBAAiB,CAAA,QAAA,EAAU,MAAQ,EAAA;AAAA,IACvD,kBAAkB,KAAU,KAAA;AAAA,GAC7B,CAAA;AACD,EAAM,MAAA,cAAA,GAAiB,kBAAkB,QAAS,CAAA,GAAA,EAAK,SAAS,QAAU,EAAA,MAAA,EAAQ,SAAS,KAAK,CAAA;AAChG,EAAA,MAAM,CAAC,aAAe,EAAA,gBAAgB,CAAI,GAAA,KAAA,CAAM,SAAwB,IAAI,CAAA;AAC5E,EAAA,MAAM,CAAC,cAAgB,EAAA,iBAAiB,CAAI,GAAA,KAAA,CAAM,SAAwB,IAAI,CAAA;AAC9E,EAAA,MAAM,kBAAqB,GAAA,KAAA,CAAM,WAAY,CAAA,CAAC,IAAmB,KAAA;AAC/D,IAAA,IAAI,CAAC,eAAiB,EAAA;AACtB,IAAc,aAAA,CAAA,wBAAA,CAAyB,iBAAiB,IAAI,CAAA;AAE5D,IAAA,aAAA,CAAc,SAAS,eAAe,CAAA;AAAA,KACrC,CAAC,eAAA,EAAiB,cAAc,wBAA0B,EAAA,aAAA,CAAc,QAAQ,CAAC,CAAA;AACpF,EAAM,MAAA,MAAA,GAAS,UAAU,QAAS,CAAA,GAAA,EAAK,UAAU,QAAW,GAAA,eAAA,GAAkB,MAAM,MAAQ,EAAA;AAAA,IAC1F,qBAAuB,EAAA;AAAA,GACxB,CAAA;AAGD,EAAA,WAAA,CAAY,SAAS,GAAK,EAAA,KAAA,KAAU,WAAW,eAAkB,GAAA,IAAA,EAAM,cAAc,QAAQ,CAAA;AAI7F,EAAM,MAAA,aAAA,GAAgB,KAAM,CAAA,MAAA,CAAsB,IAAI,CAAA;AACtD,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAM,MAAA,IAAA,GAAO,KAAU,KAAA,QAAA,GAAW,eAAkB,GAAA,IAAA;AACpD,IAAA,MAAM,OAAO,aAAc,CAAA,OAAA;AAC3B,IAAA,IAAI,QAAQ,IAAS,KAAA,IAAA,OAAW,QAAS,CAAA,GAAA,CAAI,OAAO,qBAAuB,EAAA;AAAA,MACzE,EAAI,EAAA;AAAA,KACL,CAAA;AACD,IAAA,aAAA,CAAc,OAAU,GAAA,IAAA;AAAA,KACvB,CAAC,KAAA,EAAO,eAAiB,EAAA,QAAA,CAAS,GAAG,CAAC,CAAA;AAIzC,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAwB,qBAAA,IAAA,IAAA,GAAA,MAAA,GAAA,qBAAA,CAAA,KAAA,KAAU,WAAW,eAAkB,GAAA,IAAA,CAAA;AAAA,GAC9D,EAAA,CAAC,KAAO,EAAA,eAAA,EAAiB,qBAAqB,CAAC,CAAA;AAClD,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAA,MAAM,WAAwD,KAAU,KAAA,QAAA,GAAW,QAAW,GAAA,KAAA,KAAU,aAAa,UAAa,GAAA,MAAA;AAClI,IAAwB,qBAAA,IAAA,IAAA,GAAA,MAAA,GAAA,qBAAA,CAAA,QAAA,CAAA;AAAA,GACvB,EAAA,CAAC,KAAO,EAAA,qBAAqB,CAAC,CAAA;AAIjC,EAAA,MAAM,kBAAqB,GAAA,KAAA,CAAM,MAAO,CAAA,cAAA,CAAe,OAAO,CAAA;AAC9D,EAAA,kBAAA,CAAmB,UAAU,cAAe,CAAA,OAAA;AAC5C,EAAM,MAAA,eAAA,GAAkB,eAAe,UAAe,KAAA,SAAA;AACtD,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAA,IAAI,KAAU,KAAA,UAAA,IAAc,CAAC,eAAA,EAAwB,OAAA,MAAA;AACrD,IAAA,KAAK,mBAAmB,OAAQ,EAAA;AAChC,IAAA,MAAM,GAAM,GAAA,QAAA,CAAS,gBAAiB,CAAA,QAAA,EAAU,CAAS,KAAA,KAAA;AACvD,MAAA,IAAI,KAAU,KAAA,QAAA,EAAe,KAAA,kBAAA,CAAmB,OAAQ,EAAA;AAAA,KACzD,CAAA;AACD,IAAO,OAAA,MAAM,IAAI,MAAO,EAAA;AAAA,GACvB,EAAA,CAAC,KAAO,EAAA,eAAe,CAAC,CAAA;AAC3B,EAAM,MAAA,kBAAA,GAAqB,KAAM,CAAA,OAAA,CAAQ,MAAG;AAvG9C,IAAA,IAAA,EAAA;AAuGiD,IAAA,OAAA,CAAA,EAAA,GAAA,aAAA,CAAc,cAAc,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,EAAO,KAAA,eAAe,MAA9D,IAAmE,GAAA,EAAA,GAAA,IAAA;AAAA,GAAA,EAAM,CAAC,aAAA,CAAc,aAAe,EAAA,eAAe,CAAC,CAAA;AAGtK,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAI,IAAA,QAAA,CAAS,EAAO,KAAA,SAAA,EAAkB,OAAA,MAAA;AACtC,IAAA,MAAM,GAAM,GAAA,WAAA,CAAY,gBAAiB,CAAA,mBAAA,EAAqB,MAAM;AAClE,MAAI,IAAA,KAAA,KAAU,QAAe,OAAA,KAAA;AAC7B,MAAA,QAAA,CAAS,MAAM,CAAA;AACf,MAAO,OAAA,IAAA;AAAA,KACR,CAAA;AACD,IAAO,OAAA,MAAM,IAAI,MAAO,EAAA;AAAA,GAC1B,EAAG,CAAC,KAAK,CAAC,CAAA;AACV,EAAA,MAAM,UAAa,GAAA,KAAA,CAAM,WAAY,CAAA,CAAC,EAAe,KAAA;AACnD,IAAA,kBAAA,CAAmB,EAAE,CAAA;AACrB,IAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,GACnB,EAAG,EAAE,CAAA;AAOL,EAAA,MAAM,aAAgB,GAAA,KAAA,CAAM,WAAY,CAAA,OAAO,OAA4B,KAAA;AACzE,IAAI,IAAA,CAAC,OAAQ,CAAA,KAAA,IAAS,aAAe,EAAA;AACrC,IAAA,gBAAA,CAAiB,QAAQ,EAAE,CAAA;AAC3B,IAAA,iBAAA,CAAkB,IAAI,CAAA;AACtB,IAAI,IAAA;AACF,MAAM,MAAA,EAAA,GAAK,MAAM,aAAc,CAAA,UAAA,CAAW,QAAQ,KAAM,CAAA,MAAA,EAAQ,OAAQ,CAAA,KAAA,CAAM,WAAW,CAAA;AACzF,MAAI,IAAA,EAAA,aAAe,EAAE,CAAA;AAAA,6BAAyB,sDAAsD,CAAA;AAAA,KACpG,SAAA;AACA,MAAA,gBAAA,CAAiB,IAAI,CAAA;AAAA;AACvB,GACC,EAAA,CAAC,aAAe,EAAA,UAAA,EAAY,aAAa,CAAC,CAAA;AAQ7C,EAAM,MAAA,UAAA,GAAa,KAAM,CAAA,MAAA,CAAkC,IAAI,CAAA;AAC/D,EAAA,MAAM,CAAC,YAAc,EAAA,eAAe,CAAI,GAAA,KAAA,CAAM,SAAwB,IAAI,CAAA;AAC1E,EAAM,MAAA;AAAA,IACJ;AAAA,GACE,GAAA,aAAA;AACJ,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAA,MAAM,IAAO,GAAA,WAAA;AACb,IAAI,IAAA,EAAC,6BAAM,MAAU,CAAA,IAAA,EAAC,iCAAQ,MAAU,CAAA,IAAA,IAAA,CAAK,MAAW,KAAA,MAAA,CAAO,MAAQ,EAAA;AACvE,IAAI,IAAA,UAAA,CAAW,YAAY,IAAM,EAAA;AACjC,IAAA,UAAA,CAAW,OAAU,GAAA,IAAA;AACrB,IAAA,KAAA,CAAM,YAAY;AAzJtB,MAAA,IAAA,EAAA,EAAA,EAAA;AA0JM,MAAA,MAAM,GAAM,GAAA,MAAM,QAAS,CAAA,GAAA,CAAI,MAK5B,yBAA2B,EAAA;AAAA,QAC5B,QAAQ,IAAK,CAAA;AAAA,OACZ,EAAA;AAAA,QACD,WAAa,EAAA;AAAA,OACd,CAAA;AACD,MAAM,MAAA,OAAA,GAAA,CAAU,EAAI,GAAA,GAAA,CAAA,IAAA,KAAJ,IAAU,GAAA,MAAA,GAAA,EAAA,CAAA,iBAAA;AAC1B,MAAA,IAAI,CAAC,OAAS,EAAA;AACZ,QAAA,eAAA,CAAA,CAAA,CAAgB,EAAI,GAAA,GAAA,CAAA,MAAA,KAAJ,IAAY,GAAA,MAAA,GAAA,EAAA,CAAA,MAAA,IAAS,+EAA+E,2DAA2D,CAAA;AAC/K,QAAA;AAAA;AAEF,MAAA,MAAM,KAAK,MAAM,UAAA,CAAW,OAAQ,CAAA,MAAA,EAAQ,QAAQ,WAAW,CAAA;AAC/D,MAAI,IAAA,EAAA,aAAe,EAAE,CAAA;AAAA,WAAuB,eAAA,CAAA,CAAA,oCAAA,EAAuC,OAAQ,CAAA,WAAW,CAAqB,mBAAA,CAAA,CAAA;AAAA,KAC1H,GAAA;AAAA,GACL,EAAG,CAAC,WAAa,EAAA,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,QAAQ,QAAS,CAAA,GAAA,EAAK,UAAY,EAAA,UAAU,CAAC,CAAA;AActE,EAAA,MAAM,aAAgB,GAAA,KAAA,CAAM,WAAY,CAAA,OAAO,OAA4B,KAAA;AA1L7E,IAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA2LI,IAAA,MAAM,OAAO,QAAS,CAAA,IAAA;AACtB,IAAA,IAAI,CAAC,IAAA,IAAQ,EAAC,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,MAAQ,CAAA,EAAA;AAC9B,IAAA,MAAM,KAAQ,GAAA,CAAA,CAAA,EAAA,GAAA,OAAA,CAAQ,UAAR,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAoB,UAAS,OAAQ,CAAA,UAAA,CAAW,KAAM,CAAA,CAAA,EAAG,CAAC,CAAI,GAAA,OAAA,CAAQ,IAAK,CAAA,KAAA,CAAM,GAAG,CAAC,CAAA;AACnG,IAAI,IAAA,CAAC,MAAM,MAAQ,EAAA;AAInB,IAAA,MAAM,MAAS,GAAA;AAAA,MACb,WAAW,MAAO,CAAA,MAAA;AAAA,MAClB,WAAA,EAAA,CAAa,EAAO,GAAA,MAAA,CAAA,WAAA,KAAP,IAAsB,GAAA,EAAA,GAAA;AAAA,KACrC;AACA,IAAM,MAAA,GAAA,GAAA,CAAM,EAAS,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,QAAA,CAAA,KAAA,KAAT,IAAgB,GAAA,MAAA,GAAA,EAAA,CAAA,aAAA,KAAhB,4BAAgC,MAAhC,CAAA,KAAA,IAAA,GAAA,EAAA,GAA2C,kBAAmB,CAAA,uBAAA,EAAyB,MAAM,CAAA;AACzG,IAAA,MAAM,IAAO,GAAA,iBAAA,CAAkB,MAAO,CAAA,WAAA,EAAa,GAAG,CAAA;AAGtD,IAAA,MAAM,MAAS,GAAA,MAAM,IAAK,CAAA,UAAA,CAAW,OAAO,IAAI,CAAA;AAChD,IAAA,IAAI,MAAW,KAAA,aAAA,EAAqB,MAAA,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,KAClD,CAAC,QAAA,CAAS,MAAM,QAAS,CAAA,KAAA,EAAO,MAAM,CAAC,CAAA;AAC1C,EAAM,MAAA,WAAA,GAAc,KAAM,CAAA,OAAA,CAAQ,MAAG;AA7MvC,IAAA,IAAA,EAAA,EAAA,EAAA;AA6M0C,IAAc,OAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,aAAA,CAAA,aAAA,CAAc,KAAK,CAAK,CAAA,KAAA,CAAA,CAAE,OAAO,eAAe,CAAA,KAA9D,IAAiE,GAAA,MAAA,GAAA,EAAA,CAAA,KAAA,KAAjE,IAA0E,GAAA,EAAA,GAAA,MAAA;AAAA,GAAA,EAAQ,CAAC,aAAA,CAAc,aAAe,EAAA,eAAe,CAAC,CAAA;AACxK,EAAA,IAAI,YAAc,EAAA;AAChB,IAAA,uBAAQ,GAAA,CAAA,KAAA,EAAA,EAAM,KAAc,EAAA,MAAA,EAChB,QAAC,kBAAA,GAAA,CAAA,UAAA,EAAA,EAAW,IAAK,EAAA,sBAAA,EAAuB,KAAM,EAAA,qBAAA,EAAsB,MAAQ,EAAA,YAAA,EAAc,OAAc,CAC5G,EAAA,CAAA;AAAA;AAKV,EAAA,IAAI,CAAC,MAAQ,EAAA;AACX,IAAA,uBAAQ,GAAA,CAAA,KAAA,EAAA,EAAM,KAAc,EAAA,MAAA,EAChB,QAAC,kBAAA,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,MAAA,CAAO,MAChB,EAAA,QAAA,kBAAA,GAAA,CAAC,iBAAkB,EAAA,EAAA,CAAA,EACvB,CACJ,EAAA,CAAA;AAAA;AAEV,EAAI,IAAA,KAAA,KAAU,YAAY,eAAiB,EAAA;AACzC,IAAA,MAAM,WAAc,GAAA,MAAA,CAAO,KAAU,KAAA,cAAA,GAAiB,OAAO,MAAO,CAAA,KAAA;AACpE,IAAO,uBAAA,GAAA,CAAC,SAAM,KAAc,EAAA,MAAA,EAChB,8BAAC,YAAa,EAAA,EAAA,KAAA,EAAO,WAAa,EAAA,SAAA,EAAW,kBAAoB,IAAA,IAAA,GAAA,MAAA,GAAA,kBAAA,CAAA,SAAA,EAAW,UAAU,MAAO,CAAA,QAAA,EAAU,OAAS,EAAA,MAAA,CAAO,OAAS,EAAA,WAAA,EAAa,OAAO,WAAa,EAAA,KAAA,EAAO,WAAa,EAAA,KAAA,EAAc,eAAiB,EAAA,QAAA,CAAS,IAAI,eAAiB,EAAA,OAAA,EAAS,QAAS,CAAA,OAAA,EAAS,MAAQ,EAAA,MAAM,SAAS,MAAM,CAAA,EAAG,MAAQ,EAAA,CAAA,IAAA,KAAQ,KAAK,MAAA,CAAO,KAAK,IAAI,CAAA,EAAG,UAAY,EAAA,MAAA,CAAO,QAAU,EAAA,OAAA,EAAS,OAAO,KAAO,EAAA,OAAA,EAAS,CAAC,SAAA,EAAW,KAAU,KAAA;AAhOxb,MAAA,IAAA,EAAA,EAAA,EAAA;AAiOQ,MAAA,MAAM,OAAU,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,MAAA,CAAO,QAAS,CAAA,IAAA,CAAK,OAAK,CAAE,CAAA,EAAA,KAAO,SAAS,CAAA,KAA5C,mBAA+C,SAAU,CAAA,IAAA,CAAK,CAAK,CAAA,KAAA,CAAA,CAAE,UAArE,IAA4E,GAAA,MAAA,GAAA,EAAA,CAAA,QAAA;AAE5F,MAAA,MAAA,CAAO,KAAM,CAAA,SAAA,EAAW,OAAY,KAAA,KAAA,GAAQ,OAAO,KAAK,CAAA;AAAA,KACvD,EAAA,UAAA,EAAY,QAAS,CAAA,SAAA,GAAY,CAAK,IAAA,KAAA;AApO/C,MAAA,IAAA,EAAA;AAoOkD,MAAK,OAAA,MAAA,CAAA,EAAA,GAAA,QAAA,CAAS,SAAT,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAoB,IAAK,CAAA,IAAA,CAAA,CAAA;AAAA,KAAA,GAAQ,MAAW,EAAA,WAAA,EAAa,QAAS,CAAA,IAAA,GAAO,CAAK,IAAA,KAAA;AApOrI,MAAA,IAAA,EAAA;AAoOwI,MAAK,OAAA,MAAA,CAAA,EAAA,GAAA,QAAA,CAAS,IAAT,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAe,KAAM,CAAA,IAAA,CAAA,CAAA;AAAA,KAAA,GAAQ,QAAW,cAAgB,EAAA,MAAM,kBAAkB,MAAO,CAAA,KAAK,GAAG,CAChO,EAAA,CAAA;AAAA;AAEV,EAAA,IAAI,UAAU,UAAY,EAAA;AACxB,IAAO,uBAAA,GAAA,CAAC,KAAM,EAAA,EAAA,KAAA,EAAc,MAChB,EAAA,QAAA,kBAAA,GAAA,CAAC,cAAe,EAAA,EAAA,UAAA,EAAY,cAAe,CAAA,UAAA,EAAY,OAAS,EAAA,cAAA,CAAe,OAAS,EAAA,KAAA,EAAO,cAAkB,IAAA,IAAA,GAAA,cAAA,GAAA,cAAA,CAAe,KAAO,EAAA,QAAA,EAAU,cAAe,CAAA,QAAA,EAAU,SAAW,EAAA,cAAA,CAAe,SAAW,EAAA,KAAA,EAAc,aAA8B,EAAA,MAAA,EAAQ,MAAM,QAAA,CAAS,MAAM,CAAA,EAAG,eAAiB,EAAA,MAAM,KAAK,cAAA,CAAe,aAAc,EAAA,EAAG,cAAgB,EAAA,MAAM,KAAK,cAAA,CAAe,YAAa,EAAA,EAAG,WAAa,EAAA,CAAA,CAAA,KAAK,KAAK,aAAA,CAAc,CAAC,CAAA,EAAG,QAAU,EAAA,CAAA,CAAA,KAAK,KAAK,aAAA,CAAc,CAAC,CAAA,EAAG,OAAS,EAAA,cAAA,CAAe,OAAS,EAAA,oBAAA,EAAsB,cAAe,CAAA,kBAAA,GAAqB,MAAG;AAzO9kB,MAAA,IAAA,EAAA;AAyOilB,MAAA,OAAA,MAAA,CAAK,oBAAe,kBAAf,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,CAAA,cAAA,CAAA,CAAA;AAAA,KAAwC,GAAA,MAAA,EAAW,gBAAgB,MAAM;AACvpB,MAAI,IAAA,cAAA,oBAAkC,IAAI,CAAA;AAAA,WAAO,KAAK,eAAe,OAAQ,EAAA;AAAA,OAC5E,CACG,EAAA,CAAA;AAAA;AAEV,EAAA,MAAM,SAAY,GAAA,aAAA,CAAc,KAAU,KAAA,cAAA,GAAiB,OAAO,aAAc,CAAA,KAAA;AAChF,EAAO,uBAAA,GAAA,CAAC,KAAM,EAAA,EAAA,KAAA,EAAc,MAClB,EAAA,QAAA,kBAAA,GAAA,CAAC,0BAAuB,aAAe,EAAA,aAAA,CAAc,aAAe,EAAA,OAAA,EAAS,aAAc,CAAA,OAAA,EAAS,YAAY,aAAc,CAAA,UAAA,EAAY,KAAO,EAAA,SAAA,EAAW,KAAc,EAAA,eAAA,EAAiB,QAAS,CAAA,GAAA,CAAI,eAAiB,EAAA,SAAA,EAAS,IAAC,EAAA,SAAA,EAAW,MAAM;AAC1P,IAAA,aAAA,CAAc,OAAQ,EAAA;AACtB,IAAA,KAAK,eAAe,OAAQ,EAAA;AAAA,GAC3B,EAAA,OAAA,EAAS,aAAc,CAAA,OAAA,EAAS,WAAa,EAAA,aAAA,CAAc,WAAa,EAAA,UAAA,EAAY,aAAc,CAAA,QAAA,EAAU,MAAQ,EAAA,UAAA,EAAY,WAAW,MAAM,QAAA,CAAS,UAAU,CAAA,EAAG,cAAgB,EAAA,MAAM,iBAAkB,CAAA,aAAA,CAAc,KAAK,CAAA,EAAG,MAAQ,EAAA,YAAA,EAAc,eAAiB,EAAA,MAAM,eAAgB,CAAA,IAAI,GAAG,CACxS,EAAA,CAAA;AACR;AACA,SAAS,KAAM,CAAA;AAAA,EACb,KAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAMG,EAAA;AACD,EAAO,uBAAA,GAAA,CAAC,QAAK,MAAQ,EAAA,MAAA,IAAA,IAAA,GAAA,MAAA,GAAU,eAAe,KAAO,EAAA,CAAC,OAAO,IAAM,EAAA;AAAA,IACjE,iBAAiB,KAAM,CAAA;AAAA,GACxB,GACU,QACL,EAAA,CAAA;AACR;AACA,MAAM,MAAA,GAAS,WAAW,MAAO,CAAA;AAAA,EAC/B,IAAM,EAAA;AAAA,IACJ,IAAM,EAAA;AAAA,GACR;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,IAAM,EAAA,CAAA;AAAA,IACN,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA;AAAA;AAEpB,CAAC,CAAA"}
1
+ {"version":3,"file":"NativeChatExperience.js","sources":["../../../src/features/messaging/NativeChatExperience.tsx"],"sourcesContent":["/**\n * The chat remote's exposed root (`chat_native/Chat`).\n *\n * Owns its own navigation as local state - the remote must not import\n * @react-navigation, because a second copy of the navigator would not share the\n * host's container. Android hardware back is handled with RN's own BackHandler.\n *\n * Everything here is plain react-native (plus expo-image and\n * @expo/vector-icons, both host-shared singletons) - no gluestack, no\n * NativeWind, no Apollo - because a federated remote may only use what the host\n * shares, and every extra dependency is another way to fail to load on a device\n * in a way the simulator will not reproduce.\n */\nimport * as React from 'react';\nimport { ActivityIndicator, AppState, BackHandler, Platform, StyleSheet, Text, View } from 'react-native';\nimport type { NativeChatExperienceProps } from './chatHost';\nimport { chatThemes, EmptyState } from './ChatComponents';\nimport { useAppTheme } from '../../theme/AppThemeProvider';\nimport { ConversationListScreen } from './ConversationListScreen';\nimport { ContactsScreen } from './ContactsScreen';\nimport { ThreadScreen } from './ThreadScreen';\nimport { useConversations, useMarkRead, useThread } from './useChatData';\nimport { VIEW_CHANNEL_MUTATION, YANTRA_CHAT_INVITER_QUERY } from './chatOperations';\nimport { buildChatInviteUrl, chatInviteMessage } from './chatInviteLink';\n\n/** Used only when the host predates `chatInviteUrl`; the host supplies the per-environment domain. */\nconst DEFAULT_INVITE_WEB_BASE = 'https://yantra.app';\nimport { useContactMatches, type MatchedContact } from './useContactMatches';\nimport type { WirePost } from './chatModel';\n\n/** The screens the remote routes between internally. */\nexport type ChatRoute = 'list' | 'thread' | 'contacts' | 'newGroup' | 'groupInfo';\n\nexport function NativeChatExperience({\n viewer,\n sessionError,\n services,\n initialChannelId,\n initialPeer,\n onActiveChannelChange,\n onInternalRouteChange,\n testID,\n}: NativeChatExperienceProps) {\n const { isDark } = useAppTheme();\n const theme = isDark ? chatThemes.dark : chatThemes.light;\n\n const [route, setRoute] = React.useState<ChatRoute>(initialChannelId ? 'thread' : 'list');\n const [activeChannelId, setActiveChannelId] = React.useState<string | null>(initialChannelId ?? null);\n const [dismissedError, setDismissedError] = React.useState<string | null>(null);\n\n const conversations = useConversations(services, viewer, { syncListRealtime: route === 'list' });\n const contactMatches = useContactMatches(services.gql, services.contacts, viewer, services.phone);\n const [busyContactId, setBusyContactId] = React.useState<string | null>(null);\n const [startChatError, setStartChatError] = React.useState<string | null>(null);\n const onThreadListUpdate = React.useCallback(\n (post: WirePost) => {\n if (!activeChannelId) return;\n conversations.applyConversationMessage(activeChannelId, post);\n // The viewer is looking at this thread, so a message arriving here is already read.\n conversations.markRead(activeChannelId);\n },\n [activeChannelId, conversations.applyConversationMessage, conversations.markRead],\n );\n const thread = useThread(services.gql, route === 'thread' ? activeChannelId : null, viewer, {\n onConversationMessage: onThreadListUpdate,\n media: services.media,\n });\n\n // Clearing the badge is local-first; the mutation is fire-and-forget.\n useMarkRead(services.gql, route === 'thread' ? activeChannelId : null, conversations.markRead);\n\n // Mark read again on LEAVING a thread, so messages that arrived while it was open\n // are not counted as unread by the server on the next list load.\n const threadOpenRef = React.useRef<string | null>(null);\n React.useEffect(() => {\n const open = route === 'thread' ? activeChannelId : null;\n const left = threadOpenRef.current;\n if (left && left !== open) void services.gql.mutate(VIEW_CHANNEL_MUTATION, { id: left });\n threadOpenRef.current = open;\n }, [route, activeChannelId, services.gql]);\n\n // The host suppresses a foreground push banner for the conversation already\n // on screen, so it has to be told every time that changes.\n React.useEffect(() => {\n onActiveChannelChange?.(route === 'thread' ? activeChannelId : null);\n }, [route, activeChannelId, onActiveChannelChange]);\n\n React.useEffect(() => {\n const internal: 'list' | 'thread' | 'contacts' | 'register' =\n route === 'thread' ? 'thread' : route === 'contacts' ? 'contacts' : 'list';\n onInternalRouteChange?.(internal);\n }, [route, onInternalRouteChange]);\n\n // The address book changes outside the app, so re-read it whenever the picker opens\n // and whenever the app returns to the foreground while the picker is showing.\n const refreshContactsRef = React.useRef(contactMatches.refresh);\n refreshContactsRef.current = contactMatches.refresh;\n const contactsGranted = contactMatches.permission === 'granted';\n React.useEffect(() => {\n if (route !== 'contacts' || !contactsGranted) return undefined;\n void refreshContactsRef.current();\n const sub = AppState.addEventListener('change', (state) => {\n if (state === 'active') void refreshContactsRef.current();\n });\n return () => sub.remove();\n }, [route, contactsGranted]);\n\n const activeConversation = React.useMemo(\n () => conversations.conversations.find((c) => c.id === activeChannelId) ?? null,\n [conversations.conversations, activeChannelId],\n );\n\n // Android back pops the internal stack before the host's navigator sees it.\n React.useEffect(() => {\n if (Platform.OS !== 'android') return undefined;\n const sub = BackHandler.addEventListener('hardwareBackPress', () => {\n if (route === 'list') return false;\n setRoute('list');\n return true;\n });\n return () => sub.remove();\n }, [route]);\n\n const openThread = React.useCallback((id: string) => {\n setActiveChannelId(id);\n setRoute('thread');\n }, []);\n\n /**\n * Open (or reuse) the conversation with a matched contact. createDirectChannel\n * is idempotent server-side, so tapping someone you already talk to lands in\n * the existing thread rather than making a second one.\n */\n const startChatWith = React.useCallback(\n async (contact: MatchedContact) => {\n if (!contact.match || busyContactId) return;\n setBusyContactId(contact.id);\n setStartChatError(null);\n try {\n const id = await conversations.openDirect(contact.match.userId, contact.match.displayName);\n if (id) openThread(id);\n else setStartChatError('Could not start this conversation. Please try again.');\n } finally {\n setBusyContactId(null);\n }\n },\n [conversations, openThread, busyContactId],\n );\n\n // Opened from a chat invite link: go straight into the conversation with the inviter\n // (createDirectChannel is idempotent, so reopening an old invite lands in the same thread).\n // The link is editable by anyone, so the server has to vouch for the inviter first, and\n // its name is used - never the one in the link.\n // Tracks the invite object, not the user: every tap on a link arrives as a new object,\n // so reopening a link retries, while re-renders of the same one do not.\n const openedPeer = React.useRef<typeof initialPeer | null>(null);\n const [inviteNotice, setInviteNotice] = React.useState<string | null>(null);\n const { openDirect } = conversations;\n React.useEffect(() => {\n const peer = initialPeer;\n if (!peer?.userId || !viewer?.userId || peer.userId === viewer.userId) return;\n if (openedPeer.current === peer) return;\n openedPeer.current = peer;\n void (async () => {\n const res = await services.gql.query<{\n yantraChatInviter?: { userId: string; displayName: string } | null;\n }>(YANTRA_CHAT_INVITER_QUERY, { userId: peer.userId }, { fetchPolicy: 'network-only' });\n const inviter = res.data?.yantraChatInviter;\n if (!inviter) {\n setInviteNotice(\n res.errors?.length\n ? 'Could not open this invite. Check your connection and open the link again.'\n : 'This invite link is not valid anymore. Ask for a new one.',\n );\n return;\n }\n const id = await openDirect(inviter.userId, inviter.displayName);\n if (id) openThread(id);\n else setInviteNotice(`Could not start a conversation with ${inviter.displayName}. Please try again.`);\n })();\n }, [initialPeer, viewer?.userId, services.gql, openDirect, openThread]);\n\n /**\n * Invite someone who is not here yet.\n *\n * With phone-based membership (issue #1312):\n * 1. Call the connector to generate a deep link\n * 2. Open SMS composer with the deep link (user approves before sending)\n * 3. Fall back to share sheet where SMS is unavailable (simulators)\n *\n * The deep link includes the invitee's phone and the inviter's phone,\n * enabling install-then-attribute and direct link-back to the inviter\n * after the app is installed.\n */\n const inviteContact = React.useCallback(\n async (contact: MatchedContact) => {\n const link = services.link;\n\n if (!link || !viewer?.userId) return;\n const smsTo = contact.rawNumbers?.length ? contact.rawNumbers.slice(0, 1) : contact.e164.slice(0, 1);\n if (!smsTo.length) return;\n\n // The link names the inviter (so the app can open this conversation on arrival) and\n // carries no phone numbers.\n const invite = { inviterId: viewer.userId, inviterName: viewer.displayName ?? null };\n const url = services.phone?.chatInviteUrl?.(invite) ?? buildChatInviteUrl(DEFAULT_INVITE_WEB_BASE, invite);\n const body = chatInviteMessage(viewer.displayName, url);\n\n // Saved numbers, not our E.164 guesses: the phone dials them in its own region.\n const result = await link.composeSms(smsTo, body);\n if (result === 'unavailable') await link.share(body);\n },\n [services.link, services.phone, viewer],\n );\n\n const activeTitle = React.useMemo(\n () => conversations.conversations.find((c) => c.id === activeChannelId)?.title ?? 'Chat',\n [conversations.conversations, activeChannelId],\n );\n\n if (sessionError) {\n return (\n <Shell theme={theme} testID={testID}>\n <EmptyState\n icon=\"alert-circle-outline\"\n title=\"Chat is unavailable\"\n detail={sessionError}\n theme={theme}\n />\n </Shell>\n );\n }\n\n // Session still resolving: a spinner, never an error. org/user arrive a beat\n // after mount and a flash of failure reads as a broken feature.\n if (!viewer) {\n return (\n <Shell theme={theme} testID={testID}>\n <View style={styles.center}>\n <ActivityIndicator />\n </View>\n </Shell>\n );\n }\n\n if (route === 'thread' && activeChannelId) {\n const threadError = thread.error === dismissedError ? null : thread.error;\n return (\n <Shell theme={theme} testID={testID}>\n <ThreadScreen\n title={activeTitle}\n avatarUrl={activeConversation?.avatarUrl}\n messages={thread.messages}\n loading={thread.loading}\n loadingMore={thread.loadingMore}\n error={threadError}\n theme={theme}\n connectionState={services.gql.connectionState}\n haptics={services.haptics}\n onBack={() => setRoute('list')}\n onSend={(body) => void thread.send(body)}\n onLoadMore={thread.loadMore}\n onRetry={thread.retry}\n onReact={(messageId, emoji) => {\n const current = thread.messages\n .find((m) => m.id === messageId)\n ?.reactions.find((r) => r.mine)?.reaction;\n // Tapping your current Tapback removes it, as in iMessage.\n thread.react(messageId, current === emoji ? null : emoji);\n }}\n onCopyText={services.clipboard ? (text) => void services.clipboard?.copy(text) : undefined}\n onShareText={services.link ? (text) => void services.link?.share(text) : undefined}\n media={services.media}\n audio={services.audio}\n onSendAttachments={\n thread.sendAttachments\n ? (files, caption, kind) => void thread.sendAttachments?.(files, caption, kind)\n : undefined\n }\n onDismissError={() => setDismissedError(thread.error)}\n />\n </Shell>\n );\n }\n\n if (route === 'contacts') {\n return (\n <Shell theme={theme} testID={testID}>\n <ContactsScreen\n permission={contactMatches.permission}\n loading={contactMatches.loading}\n error={startChatError ?? contactMatches.error}\n onYantra={contactMatches.onYantra}\n invitable={contactMatches.invitable}\n theme={theme}\n busyContactId={busyContactId}\n onBack={() => setRoute('list')}\n onRequestAccess={() => void contactMatches.requestAccess()}\n onOpenSettings={() => void contactMatches.openSettings()}\n onStartChat={(c) => void startChatWith(c)}\n onInvite={(c) => void inviteContact(c)}\n limited={contactMatches.limited}\n onChooseMoreContacts={\n contactMatches.chooseMoreContacts ? () => void contactMatches.chooseMoreContacts?.() : undefined\n }\n onDismissError={() => {\n if (startChatError) setStartChatError(null);\n else void contactMatches.refresh();\n }}\n />\n </Shell>\n );\n }\n\n const listError = conversations.error === dismissedError ? null : conversations.error;\n return (\n <Shell theme={theme} testID={testID}>\n <ConversationListScreen\n conversations={conversations.conversations}\n loading={conversations.loading}\n refreshing={conversations.refreshing}\n error={listError}\n theme={theme}\n connectionState={services.gql.connectionState}\n canInvite\n onRefresh={() => {\n conversations.refresh();\n void contactMatches.refresh();\n }}\n onRetry={conversations.refresh}\n loadingMore={conversations.loadingMore}\n onLoadMore={conversations.loadMore}\n onOpen={openThread}\n onNewChat={() => setRoute('contacts')}\n onDismissError={() => setDismissedError(conversations.error)}\n notice={inviteNotice}\n onDismissNotice={() => setInviteNotice(null)}\n />\n </Shell>\n );\n}\n\nfunction Shell({ theme, testID, children }: { theme: { bg: string }; testID?: string; children: React.ReactNode }) {\n return (\n <View testID={testID ?? 'chat-native'} style={[styles.fill, { backgroundColor: theme.bg }]}>\n {children}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n fill: { flex: 1 },\n center: { flex: 1, alignItems: 'center', justifyContent: 'center' },\n});\n\nexport default NativeChatExperience;\n"],"names":[],"mappings":"ksBA0BA,MAAM,uBAA0B,GAAA,oBAAA;AAMzB,SAAS,oBAAqB,CAAA;AAAA,EACnC,MAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA,gBAAA;AAAA,EACA,WAAA;AAAA,EACA,qBAAA;AAAA,EACA,qBAAA;AAAA,EACA;AACF,CAA8B,EAAA;AAC5B,EAAM,MAAA;AAAA,IACJ;AAAA,MACE,WAAY,EAAA;AAChB,EAAA,MAAM,KAAQ,GAAA,MAAA,GAAS,UAAW,CAAA,IAAA,GAAO,UAAW,CAAA,KAAA;AACpD,EAAM,MAAA,CAAC,OAAO,QAAQ,CAAA,GAAI,MAAM,QAAoB,CAAA,gBAAA,GAAmB,WAAW,MAAM,CAAA;AACxF,EAAA,MAAM,CAAC,eAAiB,EAAA,kBAAkB,IAAI,KAAM,CAAA,QAAA,CAAwB,8CAAoB,IAAI,CAAA;AACpG,EAAA,MAAM,CAAC,cAAgB,EAAA,iBAAiB,CAAI,GAAA,KAAA,CAAM,SAAwB,IAAI,CAAA;AAC9E,EAAM,MAAA,aAAA,GAAgB,gBAAiB,CAAA,QAAA,EAAU,MAAQ,EAAA;AAAA,IACvD,kBAAkB,KAAU,KAAA;AAAA,GAC7B,CAAA;AACD,EAAM,MAAA,cAAA,GAAiB,kBAAkB,QAAS,CAAA,GAAA,EAAK,SAAS,QAAU,EAAA,MAAA,EAAQ,SAAS,KAAK,CAAA;AAChG,EAAA,MAAM,CAAC,aAAe,EAAA,gBAAgB,CAAI,GAAA,KAAA,CAAM,SAAwB,IAAI,CAAA;AAC5E,EAAA,MAAM,CAAC,cAAgB,EAAA,iBAAiB,CAAI,GAAA,KAAA,CAAM,SAAwB,IAAI,CAAA;AAC9E,EAAA,MAAM,kBAAqB,GAAA,KAAA,CAAM,WAAY,CAAA,CAAC,IAAmB,KAAA;AAC/D,IAAA,IAAI,CAAC,eAAiB,EAAA;AACtB,IAAc,aAAA,CAAA,wBAAA,CAAyB,iBAAiB,IAAI,CAAA;AAE5D,IAAA,aAAA,CAAc,SAAS,eAAe,CAAA;AAAA,KACrC,CAAC,eAAA,EAAiB,cAAc,wBAA0B,EAAA,aAAA,CAAc,QAAQ,CAAC,CAAA;AACpF,EAAM,MAAA,MAAA,GAAS,UAAU,QAAS,CAAA,GAAA,EAAK,UAAU,QAAW,GAAA,eAAA,GAAkB,MAAM,MAAQ,EAAA;AAAA,IAC1F,qBAAuB,EAAA,kBAAA;AAAA,IACvB,OAAO,QAAS,CAAA;AAAA,GACjB,CAAA;AAGD,EAAA,WAAA,CAAY,SAAS,GAAK,EAAA,KAAA,KAAU,WAAW,eAAkB,GAAA,IAAA,EAAM,cAAc,QAAQ,CAAA;AAI7F,EAAM,MAAA,aAAA,GAAgB,KAAM,CAAA,MAAA,CAAsB,IAAI,CAAA;AACtD,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAM,MAAA,IAAA,GAAO,KAAU,KAAA,QAAA,GAAW,eAAkB,GAAA,IAAA;AACpD,IAAA,MAAM,OAAO,aAAc,CAAA,OAAA;AAC3B,IAAA,IAAI,QAAQ,IAAS,KAAA,IAAA,OAAW,QAAS,CAAA,GAAA,CAAI,OAAO,qBAAuB,EAAA;AAAA,MACzE,EAAI,EAAA;AAAA,KACL,CAAA;AACD,IAAA,aAAA,CAAc,OAAU,GAAA,IAAA;AAAA,KACvB,CAAC,KAAA,EAAO,eAAiB,EAAA,QAAA,CAAS,GAAG,CAAC,CAAA;AAIzC,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAwB,qBAAA,IAAA,IAAA,GAAA,MAAA,GAAA,qBAAA,CAAA,KAAA,KAAU,WAAW,eAAkB,GAAA,IAAA,CAAA;AAAA,GAC9D,EAAA,CAAC,KAAO,EAAA,eAAA,EAAiB,qBAAqB,CAAC,CAAA;AAClD,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAA,MAAM,WAAwD,KAAU,KAAA,QAAA,GAAW,QAAW,GAAA,KAAA,KAAU,aAAa,UAAa,GAAA,MAAA;AAClI,IAAwB,qBAAA,IAAA,IAAA,GAAA,MAAA,GAAA,qBAAA,CAAA,QAAA,CAAA;AAAA,GACvB,EAAA,CAAC,KAAO,EAAA,qBAAqB,CAAC,CAAA;AAIjC,EAAA,MAAM,kBAAqB,GAAA,KAAA,CAAM,MAAO,CAAA,cAAA,CAAe,OAAO,CAAA;AAC9D,EAAA,kBAAA,CAAmB,UAAU,cAAe,CAAA,OAAA;AAC5C,EAAM,MAAA,eAAA,GAAkB,eAAe,UAAe,KAAA,SAAA;AACtD,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAA,IAAI,KAAU,KAAA,UAAA,IAAc,CAAC,eAAA,EAAwB,OAAA,MAAA;AACrD,IAAA,KAAK,mBAAmB,OAAQ,EAAA;AAChC,IAAA,MAAM,GAAM,GAAA,QAAA,CAAS,gBAAiB,CAAA,QAAA,EAAU,CAAS,KAAA,KAAA;AACvD,MAAA,IAAI,KAAU,KAAA,QAAA,EAAe,KAAA,kBAAA,CAAmB,OAAQ,EAAA;AAAA,KACzD,CAAA;AACD,IAAO,OAAA,MAAM,IAAI,MAAO,EAAA;AAAA,GACvB,EAAA,CAAC,KAAO,EAAA,eAAe,CAAC,CAAA;AAC3B,EAAM,MAAA,kBAAA,GAAqB,KAAM,CAAA,OAAA,CAAQ,MAAG;AAxG9C,IAAA,IAAA,EAAA;AAwGiD,IAAA,OAAA,CAAA,EAAA,GAAA,aAAA,CAAc,cAAc,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,EAAO,KAAA,eAAe,MAA9D,IAAmE,GAAA,EAAA,GAAA,IAAA;AAAA,GAAA,EAAM,CAAC,aAAA,CAAc,aAAe,EAAA,eAAe,CAAC,CAAA;AAGtK,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAI,IAAA,QAAA,CAAS,EAAO,KAAA,SAAA,EAAkB,OAAA,MAAA;AACtC,IAAA,MAAM,GAAM,GAAA,WAAA,CAAY,gBAAiB,CAAA,mBAAA,EAAqB,MAAM;AAClE,MAAI,IAAA,KAAA,KAAU,QAAe,OAAA,KAAA;AAC7B,MAAA,QAAA,CAAS,MAAM,CAAA;AACf,MAAO,OAAA,IAAA;AAAA,KACR,CAAA;AACD,IAAO,OAAA,MAAM,IAAI,MAAO,EAAA;AAAA,GAC1B,EAAG,CAAC,KAAK,CAAC,CAAA;AACV,EAAA,MAAM,UAAa,GAAA,KAAA,CAAM,WAAY,CAAA,CAAC,EAAe,KAAA;AACnD,IAAA,kBAAA,CAAmB,EAAE,CAAA;AACrB,IAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,GACnB,EAAG,EAAE,CAAA;AAOL,EAAA,MAAM,aAAgB,GAAA,KAAA,CAAM,WAAY,CAAA,OAAO,OAA4B,KAAA;AACzE,IAAI,IAAA,CAAC,OAAQ,CAAA,KAAA,IAAS,aAAe,EAAA;AACrC,IAAA,gBAAA,CAAiB,QAAQ,EAAE,CAAA;AAC3B,IAAA,iBAAA,CAAkB,IAAI,CAAA;AACtB,IAAI,IAAA;AACF,MAAM,MAAA,EAAA,GAAK,MAAM,aAAc,CAAA,UAAA,CAAW,QAAQ,KAAM,CAAA,MAAA,EAAQ,OAAQ,CAAA,KAAA,CAAM,WAAW,CAAA;AACzF,MAAI,IAAA,EAAA,aAAe,EAAE,CAAA;AAAA,6BAAyB,sDAAsD,CAAA;AAAA,KACpG,SAAA;AACA,MAAA,gBAAA,CAAiB,IAAI,CAAA;AAAA;AACvB,GACC,EAAA,CAAC,aAAe,EAAA,UAAA,EAAY,aAAa,CAAC,CAAA;AAQ7C,EAAM,MAAA,UAAA,GAAa,KAAM,CAAA,MAAA,CAAkC,IAAI,CAAA;AAC/D,EAAA,MAAM,CAAC,YAAc,EAAA,eAAe,CAAI,GAAA,KAAA,CAAM,SAAwB,IAAI,CAAA;AAC1E,EAAM,MAAA;AAAA,IACJ;AAAA,GACE,GAAA,aAAA;AACJ,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAA,MAAM,IAAO,GAAA,WAAA;AACb,IAAI,IAAA,EAAC,6BAAM,MAAU,CAAA,IAAA,EAAC,iCAAQ,MAAU,CAAA,IAAA,IAAA,CAAK,MAAW,KAAA,MAAA,CAAO,MAAQ,EAAA;AACvE,IAAI,IAAA,UAAA,CAAW,YAAY,IAAM,EAAA;AACjC,IAAA,UAAA,CAAW,OAAU,GAAA,IAAA;AACrB,IAAA,KAAA,CAAM,YAAY;AA1JtB,MAAA,IAAA,EAAA,EAAA,EAAA;AA2JM,MAAA,MAAM,GAAM,GAAA,MAAM,QAAS,CAAA,GAAA,CAAI,MAK5B,yBAA2B,EAAA;AAAA,QAC5B,QAAQ,IAAK,CAAA;AAAA,OACZ,EAAA;AAAA,QACD,WAAa,EAAA;AAAA,OACd,CAAA;AACD,MAAM,MAAA,OAAA,GAAA,CAAU,EAAI,GAAA,GAAA,CAAA,IAAA,KAAJ,IAAU,GAAA,MAAA,GAAA,EAAA,CAAA,iBAAA;AAC1B,MAAA,IAAI,CAAC,OAAS,EAAA;AACZ,QAAA,eAAA,CAAA,CAAA,CAAgB,EAAI,GAAA,GAAA,CAAA,MAAA,KAAJ,IAAY,GAAA,MAAA,GAAA,EAAA,CAAA,MAAA,IAAS,+EAA+E,2DAA2D,CAAA;AAC/K,QAAA;AAAA;AAEF,MAAA,MAAM,KAAK,MAAM,UAAA,CAAW,OAAQ,CAAA,MAAA,EAAQ,QAAQ,WAAW,CAAA;AAC/D,MAAI,IAAA,EAAA,aAAe,EAAE,CAAA;AAAA,WAAuB,eAAA,CAAA,CAAA,oCAAA,EAAuC,OAAQ,CAAA,WAAW,CAAqB,mBAAA,CAAA,CAAA;AAAA,KAC1H,GAAA;AAAA,GACL,EAAG,CAAC,WAAa,EAAA,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,QAAQ,QAAS,CAAA,GAAA,EAAK,UAAY,EAAA,UAAU,CAAC,CAAA;AActE,EAAA,MAAM,aAAgB,GAAA,KAAA,CAAM,WAAY,CAAA,OAAO,OAA4B,KAAA;AA3L7E,IAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA4LI,IAAA,MAAM,OAAO,QAAS,CAAA,IAAA;AACtB,IAAA,IAAI,CAAC,IAAA,IAAQ,EAAC,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,MAAQ,CAAA,EAAA;AAC9B,IAAA,MAAM,KAAQ,GAAA,CAAA,CAAA,EAAA,GAAA,OAAA,CAAQ,UAAR,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAoB,UAAS,OAAQ,CAAA,UAAA,CAAW,KAAM,CAAA,CAAA,EAAG,CAAC,CAAI,GAAA,OAAA,CAAQ,IAAK,CAAA,KAAA,CAAM,GAAG,CAAC,CAAA;AACnG,IAAI,IAAA,CAAC,MAAM,MAAQ,EAAA;AAInB,IAAA,MAAM,MAAS,GAAA;AAAA,MACb,WAAW,MAAO,CAAA,MAAA;AAAA,MAClB,WAAA,EAAA,CAAa,EAAO,GAAA,MAAA,CAAA,WAAA,KAAP,IAAsB,GAAA,EAAA,GAAA;AAAA,KACrC;AACA,IAAM,MAAA,GAAA,GAAA,CAAM,EAAS,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,QAAA,CAAA,KAAA,KAAT,IAAgB,GAAA,MAAA,GAAA,EAAA,CAAA,aAAA,KAAhB,4BAAgC,MAAhC,CAAA,KAAA,IAAA,GAAA,EAAA,GAA2C,kBAAmB,CAAA,uBAAA,EAAyB,MAAM,CAAA;AACzG,IAAA,MAAM,IAAO,GAAA,iBAAA,CAAkB,MAAO,CAAA,WAAA,EAAa,GAAG,CAAA;AAGtD,IAAA,MAAM,MAAS,GAAA,MAAM,IAAK,CAAA,UAAA,CAAW,OAAO,IAAI,CAAA;AAChD,IAAA,IAAI,MAAW,KAAA,aAAA,EAAqB,MAAA,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,KAClD,CAAC,QAAA,CAAS,MAAM,QAAS,CAAA,KAAA,EAAO,MAAM,CAAC,CAAA;AAC1C,EAAM,MAAA,WAAA,GAAc,KAAM,CAAA,OAAA,CAAQ,MAAG;AA9MvC,IAAA,IAAA,EAAA,EAAA,EAAA;AA8M0C,IAAc,OAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,aAAA,CAAA,aAAA,CAAc,KAAK,CAAK,CAAA,KAAA,CAAA,CAAE,OAAO,eAAe,CAAA,KAA9D,IAAiE,GAAA,MAAA,GAAA,EAAA,CAAA,KAAA,KAAjE,IAA0E,GAAA,EAAA,GAAA,MAAA;AAAA,GAAA,EAAQ,CAAC,aAAA,CAAc,aAAe,EAAA,eAAe,CAAC,CAAA;AACxK,EAAA,IAAI,YAAc,EAAA;AAChB,IAAA,uBAAQ,GAAA,CAAA,KAAA,EAAA,EAAM,KAAc,EAAA,MAAA,EAChB,QAAC,kBAAA,GAAA,CAAA,UAAA,EAAA,EAAW,IAAK,EAAA,sBAAA,EAAuB,KAAM,EAAA,qBAAA,EAAsB,MAAQ,EAAA,YAAA,EAAc,OAAc,CAC5G,EAAA,CAAA;AAAA;AAKV,EAAA,IAAI,CAAC,MAAQ,EAAA;AACX,IAAA,uBAAQ,GAAA,CAAA,KAAA,EAAA,EAAM,KAAc,EAAA,MAAA,EAChB,QAAC,kBAAA,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,MAAA,CAAO,MAChB,EAAA,QAAA,kBAAA,GAAA,CAAC,iBAAkB,EAAA,EAAA,CAAA,EACvB,CACJ,EAAA,CAAA;AAAA;AAEV,EAAI,IAAA,KAAA,KAAU,YAAY,eAAiB,EAAA;AACzC,IAAA,MAAM,WAAc,GAAA,MAAA,CAAO,KAAU,KAAA,cAAA,GAAiB,OAAO,MAAO,CAAA,KAAA;AACpE,IAAO,uBAAA,GAAA,CAAC,SAAM,KAAc,EAAA,MAAA,EAChB,8BAAC,YAAa,EAAA,EAAA,KAAA,EAAO,WAAa,EAAA,SAAA,EAAW,kBAAoB,IAAA,IAAA,GAAA,MAAA,GAAA,kBAAA,CAAA,SAAA,EAAW,UAAU,MAAO,CAAA,QAAA,EAAU,OAAS,EAAA,MAAA,CAAO,OAAS,EAAA,WAAA,EAAa,OAAO,WAAa,EAAA,KAAA,EAAO,WAAa,EAAA,KAAA,EAAc,eAAiB,EAAA,QAAA,CAAS,IAAI,eAAiB,EAAA,OAAA,EAAS,QAAS,CAAA,OAAA,EAAS,MAAQ,EAAA,MAAM,SAAS,MAAM,CAAA,EAAG,MAAQ,EAAA,CAAA,IAAA,KAAQ,KAAK,MAAA,CAAO,KAAK,IAAI,CAAA,EAAG,UAAY,EAAA,MAAA,CAAO,QAAU,EAAA,OAAA,EAAS,OAAO,KAAO,EAAA,OAAA,EAAS,CAAC,SAAA,EAAW,KAAU,KAAA;AAjOxb,MAAA,IAAA,EAAA,EAAA,EAAA;AAkOQ,MAAA,MAAM,OAAU,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,MAAA,CAAO,QAAS,CAAA,IAAA,CAAK,OAAK,CAAE,CAAA,EAAA,KAAO,SAAS,CAAA,KAA5C,mBAA+C,SAAU,CAAA,IAAA,CAAK,CAAK,CAAA,KAAA,CAAA,CAAE,UAArE,IAA4E,GAAA,MAAA,GAAA,EAAA,CAAA,QAAA;AAE5F,MAAA,MAAA,CAAO,KAAM,CAAA,SAAA,EAAW,OAAY,KAAA,KAAA,GAAQ,OAAO,KAAK,CAAA;AAAA,KACvD,EAAA,UAAA,EAAY,QAAS,CAAA,SAAA,GAAY,CAAK,IAAA,KAAA;AArO/C,MAAA,IAAA,EAAA;AAqOkD,MAAK,OAAA,MAAA,CAAA,EAAA,GAAA,QAAA,CAAS,SAAT,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAoB,IAAK,CAAA,IAAA,CAAA,CAAA;AAAA,KAAA,GAAQ,MAAW,EAAA,WAAA,EAAa,QAAS,CAAA,IAAA,GAAO,CAAK,IAAA,KAAA;AArOrI,MAAA,IAAA,EAAA;AAqOwI,MAAK,OAAA,MAAA,CAAA,EAAA,GAAA,QAAA,CAAS,IAAT,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAe,KAAM,CAAA,IAAA,CAAA,CAAA;AAAA,KAAA,GAAQ,MAAW,EAAA,KAAA,EAAO,QAAS,CAAA,KAAA,EAAO,KAAO,EAAA,QAAA,CAAS,KAAO,EAAA,iBAAA,EAAmB,MAAO,CAAA,eAAA,GAAkB,CAAC,KAAA,EAAO,SAAS,IAAM,KAAA;AArOtS,MAAA,IAAA,EAAA;AAqOyS,MAAA,OAAA,MAAA,CAAK,EAAO,GAAA,MAAA,CAAA,eAAA,KAAP,IAAyB,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,CAAA,MAAA,EAAA,KAAA,EAAO,OAAS,EAAA,IAAA,CAAA,CAAA;AAAA,KAAA,GAAQ,QAAW,cAAgB,EAAA,MAAM,kBAAkB,MAAO,CAAA,KAAK,GAAG,CACrZ,EAAA,CAAA;AAAA;AAEV,EAAA,IAAI,UAAU,UAAY,EAAA;AACxB,IAAO,uBAAA,GAAA,CAAC,KAAM,EAAA,EAAA,KAAA,EAAc,MAChB,EAAA,QAAA,kBAAA,GAAA,CAAC,cAAe,EAAA,EAAA,UAAA,EAAY,cAAe,CAAA,UAAA,EAAY,OAAS,EAAA,cAAA,CAAe,OAAS,EAAA,KAAA,EAAO,cAAkB,IAAA,IAAA,GAAA,cAAA,GAAA,cAAA,CAAe,KAAO,EAAA,QAAA,EAAU,cAAe,CAAA,QAAA,EAAU,SAAW,EAAA,cAAA,CAAe,SAAW,EAAA,KAAA,EAAc,aAA8B,EAAA,MAAA,EAAQ,MAAM,QAAA,CAAS,MAAM,CAAA,EAAG,eAAiB,EAAA,MAAM,KAAK,cAAA,CAAe,aAAc,EAAA,EAAG,cAAgB,EAAA,MAAM,KAAK,cAAA,CAAe,YAAa,EAAA,EAAG,WAAa,EAAA,CAAA,CAAA,KAAK,KAAK,aAAA,CAAc,CAAC,CAAA,EAAG,QAAU,EAAA,CAAA,CAAA,KAAK,KAAK,aAAA,CAAc,CAAC,CAAA,EAAG,OAAS,EAAA,cAAA,CAAe,OAAS,EAAA,oBAAA,EAAsB,cAAe,CAAA,kBAAA,GAAqB,MAAG;AA1O9kB,MAAA,IAAA,EAAA;AA0OilB,MAAA,OAAA,MAAA,CAAK,oBAAe,kBAAf,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,CAAA,cAAA,CAAA,CAAA;AAAA,KAAwC,GAAA,MAAA,EAAW,gBAAgB,MAAM;AACvpB,MAAI,IAAA,cAAA,oBAAkC,IAAI,CAAA;AAAA,WAAO,KAAK,eAAe,OAAQ,EAAA;AAAA,OAC5E,CACG,EAAA,CAAA;AAAA;AAEV,EAAA,MAAM,SAAY,GAAA,aAAA,CAAc,KAAU,KAAA,cAAA,GAAiB,OAAO,aAAc,CAAA,KAAA;AAChF,EAAO,uBAAA,GAAA,CAAC,KAAM,EAAA,EAAA,KAAA,EAAc,MAClB,EAAA,QAAA,kBAAA,GAAA,CAAC,0BAAuB,aAAe,EAAA,aAAA,CAAc,aAAe,EAAA,OAAA,EAAS,aAAc,CAAA,OAAA,EAAS,YAAY,aAAc,CAAA,UAAA,EAAY,KAAO,EAAA,SAAA,EAAW,KAAc,EAAA,eAAA,EAAiB,QAAS,CAAA,GAAA,CAAI,eAAiB,EAAA,SAAA,EAAS,IAAC,EAAA,SAAA,EAAW,MAAM;AAC1P,IAAA,aAAA,CAAc,OAAQ,EAAA;AACtB,IAAA,KAAK,eAAe,OAAQ,EAAA;AAAA,GAC3B,EAAA,OAAA,EAAS,aAAc,CAAA,OAAA,EAAS,WAAa,EAAA,aAAA,CAAc,WAAa,EAAA,UAAA,EAAY,aAAc,CAAA,QAAA,EAAU,MAAQ,EAAA,UAAA,EAAY,WAAW,MAAM,QAAA,CAAS,UAAU,CAAA,EAAG,cAAgB,EAAA,MAAM,iBAAkB,CAAA,aAAA,CAAc,KAAK,CAAA,EAAG,MAAQ,EAAA,YAAA,EAAc,eAAiB,EAAA,MAAM,eAAgB,CAAA,IAAI,GAAG,CACxS,EAAA,CAAA;AACR;AACA,SAAS,KAAM,CAAA;AAAA,EACb,KAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAMG,EAAA;AACD,EAAO,uBAAA,GAAA,CAAC,QAAK,MAAQ,EAAA,MAAA,IAAA,IAAA,GAAA,MAAA,GAAU,eAAe,KAAO,EAAA,CAAC,OAAO,IAAM,EAAA;AAAA,IACjE,iBAAiB,KAAM,CAAA;AAAA,GACxB,GACU,QACL,EAAA,CAAA;AACR;AACA,MAAM,MAAA,GAAS,WAAW,MAAO,CAAA;AAAA,EAC/B,IAAM,EAAA;AAAA,IACJ,IAAM,EAAA;AAAA,GACR;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,IAAM,EAAA,CAAA;AAAA,IACN,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA;AAAA;AAEpB,CAAC,CAAA"}