@adminide-stack/yantra-mobile 12.0.105 → 12.0.106-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/features/messaging/BlockedContactsScreen.js +127 -0
- package/lib/features/messaging/BlockedContactsScreen.js.map +1 -0
- package/lib/features/messaging/ChatAttachments.js +4 -2
- package/lib/features/messaging/ChatAttachments.js.map +1 -1
- package/lib/features/messaging/ChatComponents.js +194 -10
- package/lib/features/messaging/ChatComponents.js.map +1 -1
- package/lib/features/messaging/ChatInfoScreen.js +173 -17
- package/lib/features/messaging/ChatInfoScreen.js.map +1 -1
- package/lib/features/messaging/ConversationListScreen.js +17 -1
- package/lib/features/messaging/ConversationListScreen.js.map +1 -1
- package/lib/features/messaging/MediaGalleryScreen.js +264 -0
- package/lib/features/messaging/MediaGalleryScreen.js.map +1 -0
- package/lib/features/messaging/NativeChatExperience.js +137 -18
- package/lib/features/messaging/NativeChatExperience.js.map +1 -1
- package/lib/features/messaging/NewGroupScreen.js +191 -0
- package/lib/features/messaging/NewGroupScreen.js.map +1 -0
- package/lib/features/messaging/PollComposer.js +137 -0
- package/lib/features/messaging/PollComposer.js.map +1 -0
- package/lib/features/messaging/PollVotesScreen.js +122 -0
- package/lib/features/messaging/PollVotesScreen.js.map +1 -0
- package/lib/features/messaging/ThreadScreen.js +180 -13
- package/lib/features/messaging/ThreadScreen.js.map +1 -1
- package/lib/features/messaging/chatLinks.js +39 -2
- package/lib/features/messaging/chatLinks.js.map +1 -1
- package/lib/features/messaging/chatModel.js +186 -19
- package/lib/features/messaging/chatModel.js.map +1 -1
- package/lib/features/messaging/chatOperations.js +111 -2
- package/lib/features/messaging/chatOperations.js.map +1 -1
- package/lib/features/messaging/nativeChatChannelQuery.js +7 -2
- package/lib/features/messaging/nativeChatChannelQuery.js.map +1 -1
- package/lib/features/messaging/useChatData.js +248 -10
- package/lib/features/messaging/useChatData.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThreadScreen.js","sources":["../../../src/features/messaging/ThreadScreen.tsx"],"sourcesContent":["/**\n * One conversation, laid out like WhatsApp: a header you tap for chat info, the\n * transcript on a wallpaper, an unread band where the new messages start, a\n * jump-to-latest button, swipe-to-reply, and the `+ | field | camera mic` composer\n * that turns into a send button once there is something to send.\n *\n * The list is INVERTED. That is the standard trick for a chat transcript - it\n * pins to the bottom for free, keeps position when older pages prepend, and\n * makes \"scrolled to newest\" simply `offset === 0`. The data is therefore\n * reversed for rendering while `chatModel` keeps it oldest-first everywhere\n * else, which is the order every merge and comparison reasons about.\n */\nimport * as React from 'react';\nimport {\n ActivityIndicator,\n Animated,\n FlatList,\n PanResponder,\n Platform,\n Pressable,\n StyleSheet,\n Text,\n TextInput,\n View,\n type NativeScrollEvent,\n type NativeSyntheticEvent,\n} from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { AppKeyboardAvoidingView } from '../../components/AppKeyboardAvoidingView';\nimport {\n Avatar,\n ConnectionBanner,\n DaySeparator,\n InlineBanner,\n MessageBubble,\n ReplyQuote,\n UnreadDivider,\n type ChatTheme,\n} from './ChatComponents';\nimport { ActionSheet, type SheetAction } from './ActionSheet';\nimport {\n canDeleteForEveryone,\n canEditMessage,\n dayLabel,\n firstUnreadId,\n messageStatus,\n timeLabel,\n replyRefOf,\n type ChatMessage,\n type ChatReplyRef,\n type ChatAttachmentKind,\n} from './chatModel';\nimport { MessageActionsOverlay, type BubbleFrame, type MessageAction } from './MessageActions';\nimport type { ChatAudioSeam, ChatConnectionState, ChatHapticsSeam, ChatMediaSeam, ChatPickedImage } from './chatHost';\nimport type { LinkPreviewLoader } from './linkPreview';\nimport { AttachSheet, ImageViewer, RecordingBar, StagedAttachments } from './ChatAttachments';\n\n/** One search result in a chat. */\nexport interface ChatSearchHit {\n id: string;\n body: string;\n createdAt: number;\n authorName: string;\n}\n\n/** How far up (px) the transcript must be scrolled before the jump-to-latest button shows. */\nconst JUMP_BUTTON_OFFSET = 320;\n/** Swipe distance that arms a reply, and the furthest a bubble follows the finger. */\nconst REPLY_SWIPE_TRIGGER = 56;\nconst REPLY_SWIPE_MAX = 80;\n\n/**\n * Swipe a message right to reply to it, as in WhatsApp. RN's own PanResponder and\n * Animated - no gesture library - and it claims the touch only for a clearly\n * horizontal rightward drag, so vertical scrolling and long-press are untouched.\n */\nfunction SwipeToReply({\n enabled,\n theme,\n onReply,\n children,\n}: {\n enabled: boolean;\n theme: ChatTheme;\n onReply: () => void;\n children: React.ReactNode;\n}) {\n const dx = React.useRef(new Animated.Value(0)).current;\n const armed = React.useRef(false);\n const onReplyRef = React.useRef(onReply);\n onReplyRef.current = onReply;\n\n const responder = React.useMemo(\n () =>\n PanResponder.create({\n onMoveShouldSetPanResponder: (_, g) => enabled && g.dx > 12 && Math.abs(g.dx) > Math.abs(g.dy) * 2,\n onPanResponderMove: (_, g) => {\n const x = Math.max(0, Math.min(REPLY_SWIPE_MAX, g.dx));\n dx.setValue(x);\n armed.current = x >= REPLY_SWIPE_TRIGGER;\n },\n onPanResponderRelease: () => {\n if (armed.current) onReplyRef.current();\n armed.current = false;\n Animated.spring(dx, { toValue: 0, useNativeDriver: true, bounciness: 6 }).start();\n },\n onPanResponderTerminate: () => {\n armed.current = false;\n Animated.spring(dx, { toValue: 0, useNativeDriver: true }).start();\n },\n onPanResponderTerminationRequest: () => true,\n }),\n [dx, enabled],\n );\n\n const iconOpacity = dx.interpolate({\n inputRange: [0, REPLY_SWIPE_TRIGGER],\n outputRange: [0, 1],\n extrapolate: 'clamp',\n });\n\n return (\n <View>\n <Animated.View pointerEvents=\"none\" style={[styles.swipeIcon, { opacity: iconOpacity }]}>\n <View style={[styles.swipeIconPlate, { backgroundColor: theme.isDark ? theme.surface : theme.chipBg }]}>\n <MaterialCommunityIcons name=\"reply\" size={18} color={theme.textMuted} />\n </View>\n </Animated.View>\n <Animated.View style={{ transform: [{ translateX: dx }] }} {...responder.panHandlers}>\n {children}\n </Animated.View>\n </View>\n );\n}\n\nexport function ThreadScreen({\n title,\n subtitle,\n avatarUrl,\n isGroup,\n muted,\n viewerId,\n readWatermark,\n deliveredWatermark,\n initialUnreadCount,\n typingText,\n infoLabel,\n onDraftChange,\n onEdit,\n onDeleteForEveryone,\n onDeleteForMe,\n onStar,\n onForward,\n onSearch,\n onLoadUntil,\n initialJumpTo,\n initialDraft,\n onShowInfo,\n messages,\n loading,\n loadingMore,\n error,\n theme,\n connectionState,\n haptics,\n onBack,\n onOpenInfo,\n onSend,\n onLoadMore,\n onRetry,\n onDismissError,\n onReact,\n onCopyText,\n onShareText,\n media,\n audio,\n onSendAttachments,\n linkPreviews,\n onOpenLink,\n}: {\n title: string;\n /** Under the name: a group's members, or \"Muted\" / a hint to tap for info. */\n subtitle?: string;\n avatarUrl?: string | null;\n /** Groups label each sender's run with their name. */\n isGroup?: boolean;\n muted?: boolean;\n viewerId?: string | null;\n /** Everyone else has read up to here (epoch millis); drives the blue ticks. */\n readWatermark?: number;\n /** Everyone else's phones have the messages up to here (epoch millis); two gray ticks. */\n deliveredWatermark?: number;\n /** Unread when the chat was opened; places the unread band. */\n initialUnreadCount?: number;\n /** \"typing…\" / \"Asha is typing…\": replaces the subtitle, in green, while someone types. */\n typingText?: string;\n /** \"Contact info\" or \"Group info\", for the chat menu. */\n infoLabel?: string;\n /** Every composer change (drives the viewer's own \"typing…\"). */\n onDraftChange?: (text: string) => void;\n /** Save an edit to one of the viewer's messages. */\n onEdit?: (messageId: string, body: string) => void;\n onDeleteForEveryone?: (messageId: string) => void;\n onDeleteForMe?: (messageId: string) => void;\n onStar?: (messageId: string, starred: boolean) => void;\n /** Pick chats to forward a message to. */\n onForward?: (message: ChatMessage) => void;\n /** Search this chat; without it the menu has no Search. */\n onSearch?: (query: string) => Promise<ChatSearchHit[]>;\n /** Page back until a message is loaded, so a jump can reach it. */\n onLoadUntil?: (messageId: string) => Promise<boolean>;\n /** Open at this message (from Starred messages) instead of the newest. */\n initialJumpTo?: string | null;\n /** The unsent text the viewer left in this chat, restored into the composer. */\n initialDraft?: string;\n /** Message info for one of the viewer's messages (Read by / Delivered to). */\n onShowInfo?: (message: ChatMessage) => void;\n messages: ChatMessage[];\n loading: boolean;\n loadingMore: boolean;\n error: string | null;\n theme: ChatTheme;\n connectionState: ChatConnectionState;\n haptics?: ChatHapticsSeam;\n onBack: () => void;\n /** Tapping the header opens chat info (mute, notifications). */\n onOpenInfo?: () => void;\n onSend: (body: string, replyTo?: ChatReplyRef | null) => void;\n onLoadMore: () => void;\n onRetry: (id: string) => void;\n onDismissError: () => void;\n /** Pick or remove the viewer's reaction; absent disables long-press reactions. */\n onReact?: (messageId: string, emoji: string) => void;\n /** Present only when the host provides a clipboard. */\n onCopyText?: (text: string) => void;\n onShareText?: (text: string) => void;\n /** Photos / camera; without it (or `onSendAttachments`) the \"+\" and camera buttons are hidden. */\n media?: ChatMediaSeam;\n /** Voice notes; without it the mic button is hidden. */\n audio?: ChatAudioSeam;\n onSendAttachments?: (\n files: ChatPickedImage[],\n caption: string,\n kind: ChatAttachmentKind,\n replyTo?: ChatReplyRef | null,\n ) => void;\n /** A link's card, from the gateway; without it links show no card. */\n linkPreviews?: LinkPreviewLoader;\n /** Opens a tapped link; without it links are not tappable. */\n onOpenLink?: (url: string) => void;\n}) {\n const [draft, setDraft] = React.useState(initialDraft ?? '');\n // The draft can arrive after the chat opened (the list loads it); take it once, and only\n // while the composer is still empty, so it never overwrites what the person is typing.\n const draftRestored = React.useRef(Boolean(initialDraft));\n React.useEffect(() => {\n if (draftRestored.current || !initialDraft) return;\n draftRestored.current = true;\n setDraft((current) => current || initialDraft);\n }, [initialDraft]);\n const [staged, setStaged] = React.useState<ChatPickedImage[]>([]);\n const [attachOpen, setAttachOpen] = React.useState(false);\n const [recordingSince, setRecordingSince] = React.useState<number | null>(null);\n const [viewerUrl, setViewerUrl] = React.useState<string | null>(null);\n const [composerError, setComposerError] = React.useState<string | null>(null);\n const [replyTo, setReplyTo] = React.useState<ChatReplyRef | null>(null);\n /** The message being edited in the composer, WhatsApp-style. */\n const [editing, setEditing] = React.useState<{ id: string; original: string; draftBefore: string } | null>(null);\n const [deleteTarget, setDeleteTarget] = React.useState<ChatMessage | null>(null);\n const [menuOpen, setMenuOpen] = React.useState(false);\n const [searchOpen, setSearchOpen] = React.useState(false);\n const [searchQuery, setSearchQuery] = React.useState('');\n const [searchHits, setSearchHits] = React.useState<ChatSearchHit[] | null>(null);\n const [searching, setSearching] = React.useState(false);\n const [highlightId, setHighlightId] = React.useState<string | null>(null);\n const inputRef = React.useRef<TextInput>(null);\n const listRef = React.useRef<FlatList<ChatMessage>>(null);\n const canAttach = Boolean(media && onSendAttachments);\n const canRecord = Boolean(audio && onSendAttachments);\n const [selected, setSelected] = React.useState<{ id: string; frame: BubbleFrame } | null>(null);\n const selectedMessage = React.useMemo(\n () => (selected ? (messages.find((m) => m.id === selected.id) ?? null) : null),\n [selected, messages],\n );\n const closeActions = React.useCallback(() => setSelected(null), []);\n // Share must open AFTER the overlay's modal is gone: iOS refuses to present the\n // share sheet from a view controller that is still dismissing, and fails silently.\n const pendingShare = React.useRef<string | null>(null);\n const flushPendingShare = React.useCallback(() => {\n const text = pendingShare.current;\n pendingShare.current = null;\n if (text) onShareText?.(text);\n }, [onShareText]);\n\n const startReply = React.useCallback(\n (message: ChatMessage) => {\n haptics?.impact('light');\n setReplyTo(replyRefOf(message));\n inputRef.current?.focus();\n },\n [haptics],\n );\n\n const actions = React.useMemo<MessageAction[]>(() => {\n const body = selectedMessage?.body.trim() ?? '';\n const list: MessageAction[] = [];\n const at = Date.now();\n if (selectedMessage) {\n const target = selectedMessage;\n list.push({\n key: 'reply',\n label: 'Reply',\n icon: 'reply',\n onPress: () => {\n setSelected(null);\n startReply(target);\n },\n });\n if (onForward && body) {\n list.push({\n key: 'forward',\n label: 'Forward',\n icon: 'share',\n onPress: () => {\n setSelected(null);\n onForward(target);\n },\n });\n }\n }\n if (onCopyText && body) {\n list.push({\n key: 'copy',\n label: 'Copy',\n icon: 'content-copy',\n onPress: () => {\n onCopyText(body);\n setSelected(null);\n },\n });\n }\n if (onShareText && body) {\n list.push({\n key: 'share',\n label: 'Share',\n icon: 'export-variant',\n onPress: () => {\n pendingShare.current = body;\n setSelected(null);\n // Android has no Modal onDismiss; its modal is gone after the fade.\n if (Platform.OS !== 'ios') setTimeout(flushPendingShare, 300);\n },\n });\n }\n if (\n selectedMessage &&\n onShowInfo &&\n selectedMessage.isMine &&\n !selectedMessage.isDeleted &&\n (!selectedMessage.sendState || selectedMessage.sendState === 'sent')\n ) {\n const target = selectedMessage;\n list.push({\n key: 'info',\n label: 'Info',\n icon: 'information-outline',\n onPress: () => {\n setSelected(null);\n onShowInfo(target);\n },\n });\n }\n if (selectedMessage && onStar) {\n const target = selectedMessage;\n list.push({\n key: 'star',\n label: target.starred ? 'Unstar' : 'Star',\n icon: target.starred ? 'star-off-outline' : 'star-outline',\n onPress: () => {\n setSelected(null);\n onStar(target.id, !target.starred);\n },\n });\n }\n if (selectedMessage && onEdit && canEditMessage(selectedMessage, at)) {\n const target = selectedMessage;\n list.push({\n key: 'edit',\n label: 'Edit',\n icon: 'pencil-outline',\n onPress: () => {\n setSelected(null);\n setReplyTo(null);\n // The composer holds the message while editing; the chat's own draft comes back after.\n setEditing({ id: target.id, original: target.body, draftBefore: draft });\n setDraft(target.body);\n inputRef.current?.focus();\n },\n });\n }\n if (selectedMessage && (onDeleteForMe || onDeleteForEveryone)) {\n const target = selectedMessage;\n list.push({\n key: 'delete',\n label: 'Delete',\n icon: 'delete-outline',\n onPress: () => {\n setSelected(null);\n setDeleteTarget(target);\n },\n });\n }\n return list;\n }, [\n selectedMessage,\n onCopyText,\n onShareText,\n flushPendingShare,\n startReply,\n onForward,\n onStar,\n onEdit,\n onDeleteForMe,\n onDeleteForEveryone,\n onShowInfo,\n draft,\n ]);\n\n const deleteActions = React.useMemo<SheetAction[]>(() => {\n const target = deleteTarget;\n if (!target) return [];\n const list: SheetAction[] = [];\n if (onDeleteForEveryone && canDeleteForEveryone(target, Date.now())) {\n list.push({\n key: 'delete-everyone',\n label: 'Delete for everyone',\n icon: 'delete-outline',\n destructive: true,\n onPress: () => onDeleteForEveryone(target.id),\n });\n }\n if (onDeleteForMe) {\n list.push({\n key: 'delete-me',\n label: 'Delete for me',\n icon: 'delete-outline',\n destructive: true,\n onPress: () => onDeleteForMe(target.id),\n });\n }\n return list;\n }, [deleteTarget, onDeleteForEveryone, onDeleteForMe]);\n\n const [now, setNow] = React.useState(() => Date.now());\n React.useEffect(() => {\n // Day chips roll over at midnight while a chat stays open.\n const t = setInterval(() => setNow(Date.now()), 60_000);\n return () => clearInterval(t);\n }, []);\n const rendered = React.useMemo(() => messages.slice().reverse(), [messages]);\n const canSend = draft.trim().length > 0 || staged.length > 0;\n\n // The unread band is placed ONCE, from the count the chat opened with, and stays put\n // while the chat is open - messages arriving now are being read as they land.\n const [unreadAnchor, setUnreadAnchor] = React.useState<{ id: string; count: number } | null>(null);\n const anchorDecided = React.useRef(false);\n React.useEffect(() => {\n if (anchorDecided.current || loading || !messages.length) return;\n anchorDecided.current = true;\n const id = firstUnreadId(messages, initialUnreadCount ?? 0);\n if (id) setUnreadAnchor({ id, count: initialUnreadCount ?? 0 });\n }, [loading, messages, initialUnreadCount]);\n\n // Jump-to-latest button, with a count of messages that arrived while scrolled up.\n const [scrolledUp, setScrolledUp] = React.useState(false);\n const [missed, setMissed] = React.useState(0);\n const newestId = messages.length ? messages[messages.length - 1].id : null;\n const lastNewest = React.useRef(newestId);\n React.useEffect(() => {\n const previous = lastNewest.current;\n lastNewest.current = newestId;\n if (!previous || previous === newestId || !scrolledUp) return;\n const newest = messages[messages.length - 1];\n if (newest && !newest.isMine) setMissed((n) => n + 1);\n }, [newestId, scrolledUp, messages]);\n const onScroll = React.useCallback((e: NativeSyntheticEvent<NativeScrollEvent>) => {\n const up = e.nativeEvent.contentOffset.y > JUMP_BUTTON_OFFSET;\n setScrolledUp(up);\n if (!up) setMissed(0);\n }, []);\n const jumpToLatest = React.useCallback(() => {\n listRef.current?.scrollToOffset({ offset: 0, animated: true });\n setMissed(0);\n }, []);\n\n const renderedRef = React.useRef(rendered);\n renderedRef.current = rendered;\n const scrollTo = React.useCallback((messageId: string): boolean => {\n const index = renderedRef.current.findIndex((m) => m.id === messageId);\n if (index < 0) return false;\n listRef.current?.scrollToIndex({ index, animated: true, viewPosition: 0.5 });\n setHighlightId(messageId);\n setTimeout(() => setHighlightId((id) => (id === messageId ? null : id)), 1400);\n return true;\n }, []);\n const jumpToMessage = React.useCallback(\n (messageId: string) => {\n if (scrollTo(messageId) || !onLoadUntil) return;\n // Further up than what is loaded: page back to it, then scroll once it has rendered.\n void onLoadUntil(messageId).then((found) => {\n if (found) setTimeout(() => scrollTo(messageId), 120);\n else setComposerError('That message is too far back to show here.');\n });\n },\n [scrollTo, onLoadUntil],\n );\n\n // Opened from Starred messages: go to that message once the transcript is in.\n const jumpedTo = React.useRef<string | null>(null);\n React.useEffect(() => {\n if (!initialJumpTo || loading || jumpedTo.current === initialJumpTo) return;\n jumpedTo.current = initialJumpTo;\n setTimeout(() => jumpToMessage(initialJumpTo), 250);\n }, [initialJumpTo, loading, jumpToMessage]);\n\n const runSearch = React.useCallback(\n async (query: string) => {\n const q = query.trim();\n if (!onSearch || q.length < 2) {\n setSearchHits(null);\n return;\n }\n setSearching(true);\n try {\n setSearchHits(await onSearch(q));\n } catch {\n setSearchHits([]);\n } finally {\n setSearching(false);\n }\n },\n [onSearch],\n );\n React.useEffect(() => {\n if (!searchOpen) return undefined;\n const t = setTimeout(() => void runSearch(searchQuery), 350);\n return () => clearTimeout(t);\n }, [searchOpen, searchQuery, runSearch]);\n const closeSearch = React.useCallback(() => {\n setSearchOpen(false);\n setSearchQuery('');\n setSearchHits(null);\n }, []);\n\n const menuActions = React.useMemo<SheetAction[]>(() => {\n const list: SheetAction[] = [];\n if (onOpenInfo) {\n list.push({\n key: 'info',\n label: infoLabel ?? 'Chat info',\n icon: 'information-outline',\n onPress: onOpenInfo,\n });\n }\n if (onSearch) {\n list.push({ key: 'search', label: 'Search', icon: 'magnify', onPress: () => setSearchOpen(true) });\n }\n return list;\n }, [onOpenInfo, onSearch, infoLabel]);\n\n const submit = React.useCallback(() => {\n const text = draft.trim();\n const quote = replyTo;\n if (editing) {\n if (text && text !== editing.original.trim()) onEdit?.(editing.id, text);\n setEditing(null);\n setDraft(editing.draftBefore);\n return;\n }\n if (staged.length && onSendAttachments) {\n setDraft('');\n setStaged([]);\n setReplyTo(null);\n haptics?.impact('light');\n onSendAttachments(staged, text, 'image', quote);\n jumpToLatest();\n return;\n }\n if (!text) return;\n setDraft('');\n setReplyTo(null);\n onDraftChange?.('');\n haptics?.impact('light');\n onSend(text, quote);\n jumpToLatest();\n }, [draft, staged, replyTo, editing, haptics, onSend, onSendAttachments, onEdit, onDraftChange, jumpToLatest]);\n\n // The menu must be fully closed before the picker opens: iOS silently refuses to present over\n // a modal that is still animating away (same as Share). iOS waits for the sheet's onDismiss;\n // Android has no onDismiss, so it waits out the slide.\n const pendingPick = React.useRef<'library' | 'camera' | null>(null);\n const runPendingPick = React.useCallback(() => {\n const source = pendingPick.current;\n pendingPick.current = null;\n if (!source || !media) return;\n const run =\n source === 'library'\n ? media.pickFromLibrary({ limit: Math.max(1, 10 - staged.length) })\n : media.captureFromCamera();\n run.then((files) => {\n if (files.length) setStaged((prev) => [...prev, ...files].slice(0, 10));\n }).catch((e: unknown) => setComposerError(e instanceof Error ? e.message : 'Could not open photos.'));\n }, [media, staged.length]);\n const pick = React.useCallback(\n (source: 'library' | 'camera') => {\n if (!media) return;\n setComposerError(null);\n pendingPick.current = source;\n setAttachOpen(false);\n if (Platform.OS !== 'ios') setTimeout(runPendingPick, 400);\n },\n [media, runPendingPick],\n );\n /** The composer's camera button: no sheet in between, so it can run at once. */\n const openCamera = React.useCallback(() => {\n if (!media) return;\n setComposerError(null);\n pendingPick.current = 'camera';\n runPendingPick();\n }, [media, runPendingPick]);\n\n const startRecording = React.useCallback(async () => {\n if (!audio) return;\n setComposerError(null);\n try {\n const ok = await audio.startRecording();\n if (!ok) {\n setComposerError('Microphone access is off. Allow it in Settings to send voice messages.');\n return;\n }\n haptics?.impact('medium');\n setRecordingSince(Date.now());\n } catch (e) {\n setComposerError(e instanceof Error ? e.message : 'Could not start recording.');\n }\n }, [audio, haptics]);\n\n const finishRecording = React.useCallback(\n async (send: boolean) => {\n if (!audio) return;\n setRecordingSince(null);\n try {\n if (!send) {\n await audio.cancelRecording();\n return;\n }\n const file = await audio.stopRecording();\n if (file && onSendAttachments) {\n haptics?.impact('light');\n onSendAttachments([file], '', 'audio', replyTo);\n setReplyTo(null);\n }\n } catch (e) {\n setComposerError(e instanceof Error ? e.message : 'Could not send the recording.');\n }\n },\n [audio, haptics, onSendAttachments, replyTo],\n );\n\n // Leaving the thread mid-recording throws the recording away.\n const recordingRef = React.useRef(recordingSince);\n recordingRef.current = recordingSince;\n React.useEffect(\n () => () => {\n if (recordingRef.current) void audio?.cancelRecording();\n },\n [audio],\n );\n\n const headerSubtitle = typingText || subtitle || '';\n\n return (\n <AppKeyboardAvoidingView\n style={[styles.fill, { backgroundColor: theme.threadBg }]}\n behavior={Platform.OS === 'ios' ? 'padding' : undefined}\n keyboardVerticalOffset={0}\n >\n <SafeAreaView edges={['top']} style={{ backgroundColor: theme.headerBg }}>\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n paddingLeft: 4,\n paddingRight: 8,\n paddingVertical: 6,\n minHeight: 52,\n borderBottomWidth: StyleSheet.hairlineWidth,\n borderBottomColor: theme.border,\n backgroundColor: theme.headerBg,\n }}\n >\n <Pressable\n onPress={onBack}\n hitSlop={10}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Back\"\n style={styles.headerIcon}\n testID=\"chat-thread-back\"\n >\n <MaterialCommunityIcons name=\"chevron-left\" size={32} color={theme.accent} />\n </Pressable>\n <Pressable\n onPress={onOpenInfo ?? undefined}\n disabled={!onOpenInfo}\n accessibilityRole=\"button\"\n accessibilityLabel={onOpenInfo ? `${title}, chat info` : title}\n style={{ flex: 1, minWidth: 0 }}\n testID=\"chat-thread-header\"\n >\n <View style={{ flexDirection: 'row', alignItems: 'center', minWidth: 0 }}>\n <Avatar name={title} uri={avatarUrl} theme={theme} size={38} variant=\"initials\" />\n <View style={{ flex: 1, minWidth: 0, marginLeft: 10 }}>\n <View style={{ flexDirection: 'row', alignItems: 'center' }}>\n <Text\n numberOfLines={1}\n style={{ flexShrink: 1, fontSize: 17, fontWeight: '600', color: theme.text }}\n >\n {title}\n </Text>\n {muted ? (\n <MaterialCommunityIcons\n name=\"bell-off\"\n size={14}\n color={theme.textMuted}\n style={{ marginLeft: 5 }}\n accessibilityLabel=\"Muted\"\n />\n ) : null}\n </View>\n {headerSubtitle ? (\n <Text\n numberOfLines={1}\n style={{\n fontSize: 13,\n color: typingText ? theme.accent : theme.textMuted,\n marginTop: 1,\n }}\n testID=\"chat-thread-subtitle\"\n >\n {headerSubtitle}\n </Text>\n ) : null}\n </View>\n </View>\n </Pressable>\n {menuActions.length ? (\n <Pressable\n onPress={() => setMenuOpen(true)}\n hitSlop={8}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Chat menu\"\n style={styles.headerIcon}\n testID=\"chat-thread-menu\"\n >\n <MaterialCommunityIcons name=\"dots-vertical\" size={24} color={theme.textMuted} />\n </Pressable>\n ) : null}\n </View>\n {searchOpen ? (\n <View\n style={[\n styles.searchBar,\n { backgroundColor: theme.headerBg, borderBottomColor: theme.border, flexDirection: 'row' },\n ]}\n >\n <View\n style={[styles.searchField, { backgroundColor: theme.composerField, flexDirection: 'row' }]}\n >\n <MaterialCommunityIcons name=\"magnify\" size={20} color={theme.textMuted} />\n <TextInput\n value={searchQuery}\n onChangeText={setSearchQuery}\n placeholder=\"Search this chat\"\n placeholderTextColor={theme.textMuted}\n autoFocus\n returnKeyType=\"search\"\n style={[styles.searchInput, { color: theme.text }]}\n testID=\"chat-thread-search\"\n />\n {searching ? <ActivityIndicator size=\"small\" color={theme.textMuted} /> : null}\n </View>\n <Pressable\n onPress={closeSearch}\n hitSlop={8}\n accessibilityRole=\"button\"\n style={styles.searchCancel}\n >\n <Text style={{ color: theme.accent, fontSize: 16 }}>Cancel</Text>\n </Pressable>\n </View>\n ) : null}\n </SafeAreaView>\n\n <ConnectionBanner state={connectionState} theme={theme} />\n <InlineBanner message={error} theme={theme} onDismiss={onDismissError} />\n <InlineBanner message={composerError} theme={theme} onDismiss={() => setComposerError(null)} />\n\n {loading && messages.length === 0 ? (\n <View style={[styles.center, { flex: 1 }]}>\n <ActivityIndicator color={theme.accent} />\n </View>\n ) : (\n <View style={styles.fill}>\n <FlatList\n ref={listRef}\n inverted\n data={rendered}\n style={styles.fill}\n keyExtractor={(m) => m.id}\n onScroll={onScroll}\n scrollEventThrottle={100}\n onScrollToIndexFailed={(info) => {\n // Not measured yet (far up the transcript): get close, then settle on it.\n listRef.current?.scrollToOffset({\n offset: info.averageItemLength * info.index,\n animated: true,\n });\n }}\n renderItem={({ item, index }) => {\n const older = rendered[index + 1];\n const label = dayLabel(item.createdAt, now);\n const olderLabel = older ? dayLabel(older.createdAt, now) : null;\n const newDay = olderLabel !== label;\n const sameRun = (a: ChatMessage | null | undefined, b: ChatMessage) =>\n Boolean(a && !a.isDeleted && !b.isDeleted && a.authorId && a.authorId === b.authorId);\n // A day chip or the unread band breaks a run, so the tail comes back after it.\n const startsBand = unreadAnchor?.id === item.id;\n const groupWithPrevious = sameRun(older, item) && !newDay && !startsBand;\n return (\n <View>\n {/* An inverted list flips the list, not each cell: inside a cell the\n first child is on top, so the day chip and the unread band come\n before the bubble they introduce. */}\n {newDay ? <DaySeparator label={label} theme={theme} /> : null}\n {startsBand && unreadAnchor ? (\n <UnreadDivider count={unreadAnchor.count} theme={theme} />\n ) : null}\n <SwipeToReply\n enabled={!item.isDeleted && (!item.sendState || item.sendState === 'sent')}\n theme={theme}\n onReply={() => startReply(item)}\n >\n <MessageBubble\n message={item}\n theme={theme}\n status={\n item.isMine\n ? messageStatus(item, readWatermark ?? 0, deliveredWatermark ?? 0)\n : undefined\n }\n viewerId={viewerId}\n fileBaseUrl={media?.fileBaseUrl}\n audio={audio}\n onOpenImage={setViewerUrl}\n linkPreviews={linkPreviews}\n onOpenLink={onOpenLink}\n showAuthor={Boolean(isGroup) && !groupWithPrevious}\n groupWithPrevious={groupWithPrevious}\n highlighted={highlightId === item.id}\n onPressQuote={jumpToMessage}\n onRetry={() => onRetry(item.id)}\n onLongPress={\n // Only confirmed messages can be reacted to or acted on.\n !item.isDeleted && (!item.sendState || item.sendState === 'sent')\n ? (frame) => {\n haptics?.impact('medium');\n setSelected({ id: item.id, frame });\n }\n : undefined\n }\n />\n </SwipeToReply>\n </View>\n );\n }}\n onEndReached={onLoadMore}\n onEndReachedThreshold={0.4}\n ListHeaderComponent={<View style={styles.listBottomGap} />}\n ListFooterComponent={\n loadingMore ? (\n <ActivityIndicator style={styles.moreSpinner} size=\"small\" color={theme.textMuted} />\n ) : null\n }\n contentContainerStyle={rendered.length === 0 ? styles.listContentEmpty : undefined}\n ListEmptyComponent={\n <View style={styles.emptyInverted}>\n <View style={[styles.emptyChip, { backgroundColor: theme.chipBg }]}>\n <MaterialCommunityIcons name=\"lock-outline\" size={14} color={theme.chipText} />\n <Text style={[styles.emptyChipText, { color: theme.chipText }]}>\n Messages you send appear here. Say hi!\n </Text>\n </View>\n </View>\n }\n keyboardDismissMode=\"interactive\"\n keyboardShouldPersistTaps=\"handled\"\n testID=\"chat-thread\"\n />\n {searchOpen && searchHits ? (\n <View\n style={[StyleSheet.absoluteFill, { backgroundColor: theme.bg }]}\n testID=\"chat-thread-search-results\"\n >\n <FlatList\n data={searchHits}\n keyExtractor={(h) => h.id}\n keyboardShouldPersistTaps=\"handled\"\n ListEmptyComponent={\n <Text style={[styles.searchEmpty, { color: theme.textMuted }]}>\n No messages found\n </Text>\n }\n renderItem={({ item }) => (\n <Pressable\n onPress={() => {\n closeSearch();\n jumpToMessage(item.id);\n }}\n accessibilityRole=\"button\"\n >\n <View style={[styles.searchHit, { borderBottomColor: theme.border }]}>\n <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>\n <Text\n style={[styles.searchHitAuthor, { color: theme.text }]}\n numberOfLines={1}\n >\n {item.authorName}\n </Text>\n <Text style={{ color: theme.textMuted, fontSize: 12 }}>\n {`${dayLabel(item.createdAt, now)} ${timeLabel(item.createdAt)}`}\n </Text>\n </View>\n <Text\n style={{ color: theme.textMuted, fontSize: 15, marginTop: 2 }}\n numberOfLines={2}\n >\n {item.body}\n </Text>\n </View>\n </Pressable>\n )}\n />\n </View>\n ) : null}\n {scrolledUp ? (\n <Pressable\n onPress={jumpToLatest}\n accessibilityRole=\"button\"\n accessibilityLabel={missed ? `${missed} new messages, jump to latest` : 'Jump to latest'}\n style={[styles.jumpButton, { backgroundColor: theme.isDark ? theme.surface : theme.bg }]}\n testID=\"chat-jump-latest\"\n >\n <MaterialCommunityIcons name=\"chevron-double-down\" size={22} color={theme.textMuted} />\n {missed ? (\n <View style={[styles.jumpBadge, { backgroundColor: theme.unread }]}>\n <Text style={styles.jumpBadgeText}>{missed > 99 ? '99+' : missed}</Text>\n </View>\n ) : null}\n </Pressable>\n ) : null}\n </View>\n )}\n\n <StagedAttachments\n files={staged}\n theme={theme}\n onRemove={(index) => setStaged((prev) => prev.filter((_, i) => i !== index))}\n />\n {editing && !recordingSince ? (\n <View\n style={[styles.replyBar, { backgroundColor: theme.composerBar, flexDirection: 'row' }]}\n testID=\"chat-composer-editing\"\n >\n <MaterialCommunityIcons name=\"pencil\" size={18} color={theme.accent} style={styles.editIcon} />\n <View style={{ flex: 1 }}>\n <Text style={{ color: theme.accent, fontSize: 13, fontWeight: '600' }}>Edit message</Text>\n <Text numberOfLines={1} style={{ color: theme.textMuted, fontSize: 14 }}>\n {editing.original}\n </Text>\n </View>\n <Pressable\n onPress={() => {\n if (editing) setDraft(editing.draftBefore);\n setEditing(null);\n }}\n hitSlop={10}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Cancel edit\"\n style={styles.replyClose}\n >\n <MaterialCommunityIcons name=\"close\" size={20} color={theme.textMuted} />\n </Pressable>\n </View>\n ) : null}\n {replyTo && !recordingSince ? (\n <View\n style={[styles.replyBar, { backgroundColor: theme.composerBar, flexDirection: 'row' }]}\n testID=\"chat-composer-reply\"\n >\n <View style={{ flex: 1 }}>\n <ReplyQuote reply={replyTo} theme={theme} viewerId={viewerId} compact />\n </View>\n <Pressable\n onPress={() => setReplyTo(null)}\n hitSlop={10}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Cancel reply\"\n style={styles.replyClose}\n >\n <MaterialCommunityIcons name=\"close\" size={20} color={theme.textMuted} />\n </Pressable>\n </View>\n ) : null}\n {recordingSince ? (\n <RecordingBar\n theme={theme}\n startedAt={recordingSince}\n onCancel={() => void finishRecording(false)}\n onSend={() => void finishRecording(true)}\n />\n ) : (\n <SafeAreaView edges={['bottom']} style={{ backgroundColor: theme.composerBar }}>\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'flex-end',\n paddingHorizontal: 6,\n paddingVertical: 6,\n backgroundColor: theme.composerBar,\n }}\n >\n {canAttach ? (\n <Pressable\n onPress={() => setAttachOpen(true)}\n hitSlop={6}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Attach\"\n style={styles.composerIcon}\n testID=\"chat-composer-attach\"\n >\n <MaterialCommunityIcons name=\"plus\" size={28} color={theme.accent} />\n </Pressable>\n ) : null}\n <View\n style={{\n flex: 1,\n flexDirection: 'row',\n alignItems: 'flex-end',\n backgroundColor: theme.composerField,\n borderRadius: 20,\n borderWidth: theme.isDark ? 0 : StyleSheet.hairlineWidth,\n borderColor: theme.border,\n paddingHorizontal: 14,\n minHeight: 38,\n marginHorizontal: 4,\n }}\n >\n <TextInput\n ref={inputRef}\n value={draft}\n onChangeText={(text) => {\n setDraft(text);\n // An edit in progress is not the chat's draft (nor \"typing\").\n if (!editing) onDraftChange?.(text);\n }}\n placeholder=\"Message\"\n placeholderTextColor={theme.textMuted}\n style={{\n flex: 1,\n color: theme.text,\n fontSize: 17,\n paddingVertical: Platform.OS === 'ios' ? 8 : 6,\n maxHeight: 120,\n }}\n multiline\n blurOnSubmit={false}\n testID=\"chat-composer-input\"\n />\n </View>\n {canSend || !canRecord ? (\n <Pressable\n onPress={canSend ? submit : undefined}\n disabled={!canSend}\n accessibilityRole=\"button\"\n accessibilityLabel={editing ? 'Save edit' : 'Send message'}\n style={[\n styles.composerSend,\n { backgroundColor: canSend ? theme.accent : theme.border },\n ]}\n testID=\"chat-composer-send\"\n >\n <MaterialCommunityIcons\n name={editing ? 'check' : 'send'}\n size={editing ? 22 : 20}\n color={theme.onAccent}\n style={editing ? null : styles.sendGlyph}\n />\n </Pressable>\n ) : (\n <View style={{ flexDirection: 'row', alignItems: 'center' }}>\n {canAttach ? (\n <Pressable\n onPress={openCamera}\n hitSlop={6}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Take a photo\"\n style={styles.composerIcon}\n testID=\"chat-composer-camera\"\n >\n <MaterialCommunityIcons name=\"camera-outline\" size={26} color={theme.accent} />\n </Pressable>\n ) : null}\n <Pressable\n onPress={() => void startRecording()}\n hitSlop={6}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Record voice message\"\n style={styles.composerIcon}\n testID=\"chat-composer-mic\"\n >\n <MaterialCommunityIcons name=\"microphone-outline\" size={26} color={theme.accent} />\n </Pressable>\n </View>\n )}\n </View>\n </SafeAreaView>\n )}\n\n <AttachSheet\n visible={attachOpen}\n theme={theme}\n onClose={() => setAttachOpen(false)}\n onPhotos={() => pick('library')}\n onCamera={() => pick('camera')}\n onDismissed={Platform.OS === 'ios' ? runPendingPick : undefined}\n />\n <ImageViewer url={viewerUrl} onClose={() => setViewerUrl(null)} />\n\n <MessageActionsOverlay\n message={selectedMessage}\n frame={selected?.frame ?? null}\n theme={theme}\n actions={actions}\n onReact={(emoji) => {\n if (selectedMessage && onReact) {\n haptics?.impact('selection');\n onReact(selectedMessage.id, emoji);\n }\n setSelected(null);\n }}\n onClose={closeActions}\n onDismissed={Platform.OS === 'ios' ? flushPendingShare : undefined}\n />\n <ActionSheet\n visible={Boolean(deleteTarget)}\n title=\"Delete message?\"\n actions={deleteActions}\n theme={theme}\n onClose={() => setDeleteTarget(null)}\n testID=\"chat-delete-sheet\"\n />\n <ActionSheet\n visible={menuOpen}\n actions={menuActions}\n theme={theme}\n onClose={() => setMenuOpen(false)}\n testID=\"chat-thread-menu-sheet\"\n />\n </AppKeyboardAvoidingView>\n );\n}\n\nconst styles = StyleSheet.create({\n fill: { flex: 1 },\n center: { flex: 1, alignItems: 'center', justifyContent: 'center' },\n listContentEmpty: { flexGrow: 1, justifyContent: 'center' },\n listBottomGap: { height: 8 },\n moreSpinner: { paddingVertical: 12 },\n emptyInverted: { transform: [{ scaleY: -1 }], paddingVertical: 24, alignItems: 'center', paddingHorizontal: 32 },\n emptyChip: {\n flexDirection: 'row',\n alignItems: 'center',\n borderRadius: 8,\n paddingHorizontal: 12,\n paddingVertical: 8,\n },\n emptyChipText: { fontSize: 13, marginLeft: 6, textAlign: 'center' },\n headerIcon: { width: 40, height: 40, alignItems: 'center', justifyContent: 'center' },\n composerIcon: {\n width: 40,\n height: 38,\n alignItems: 'center',\n justifyContent: 'center',\n },\n composerSend: {\n width: 38,\n height: 38,\n borderRadius: 19,\n alignItems: 'center',\n justifyContent: 'center',\n marginLeft: 2,\n },\n /** The paper plane's optical center sits left of its box. */\n sendGlyph: { marginLeft: 3 },\n replyBar: { alignItems: 'center', paddingLeft: 10, paddingRight: 4, paddingTop: 8 },\n replyClose: { width: 36, height: 36, alignItems: 'center', justifyContent: 'center' },\n editIcon: { marginRight: 10 },\n searchBar: {\n alignItems: 'center',\n paddingHorizontal: 10,\n paddingBottom: 8,\n borderBottomWidth: StyleSheet.hairlineWidth,\n },\n searchField: { flex: 1, alignItems: 'center', height: 36, borderRadius: 10, paddingHorizontal: 10 },\n searchInput: { flex: 1, marginLeft: 6, fontSize: 16, paddingVertical: 0 },\n searchCancel: { marginLeft: 10, paddingVertical: 6 },\n searchEmpty: { textAlign: 'center', marginTop: 40, fontSize: 15 },\n searchHit: { paddingHorizontal: 16, paddingVertical: 10, borderBottomWidth: StyleSheet.hairlineWidth },\n searchHitAuthor: { fontSize: 15, fontWeight: '600', flex: 1, marginRight: 8 },\n jumpButton: {\n position: 'absolute',\n right: 12,\n bottom: 12,\n width: 40,\n height: 40,\n borderRadius: 20,\n alignItems: 'center',\n justifyContent: 'center',\n shadowColor: '#0b141a',\n shadowOpacity: 0.2,\n shadowRadius: 3,\n shadowOffset: { width: 0, height: 1 },\n elevation: 3,\n },\n jumpBadge: {\n position: 'absolute',\n top: -6,\n right: -4,\n minWidth: 20,\n height: 20,\n borderRadius: 10,\n paddingHorizontal: 5,\n alignItems: 'center',\n justifyContent: 'center',\n },\n jumpBadgeText: { color: '#ffffff', fontSize: 11, fontWeight: '700' },\n swipeIcon: { position: 'absolute', left: 8, top: 0, bottom: 0, justifyContent: 'center' },\n swipeIconPlate: { width: 30, height: 30, borderRadius: 15, alignItems: 'center', justifyContent: 'center' },\n});\n"],"names":["_a"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ThreadScreen.js","sources":["../../../src/features/messaging/ThreadScreen.tsx"],"sourcesContent":["/**\n * One conversation, laid out like WhatsApp: a header you tap for chat info, the\n * transcript on a wallpaper, an unread band where the new messages start, a\n * jump-to-latest button, swipe-to-reply, and the `+ | field | camera mic` composer\n * that turns into a send button once there is something to send.\n *\n * The list is INVERTED. That is the standard trick for a chat transcript - it\n * pins to the bottom for free, keeps position when older pages prepend, and\n * makes \"scrolled to newest\" simply `offset === 0`. The data is therefore\n * reversed for rendering while `chatModel` keeps it oldest-first everywhere\n * else, which is the order every merge and comparison reasons about.\n */\nimport * as React from 'react';\nimport {\n ActivityIndicator,\n Animated,\n FlatList,\n PanResponder,\n Platform,\n Pressable,\n StyleSheet,\n Text,\n TextInput,\n View,\n type NativeScrollEvent,\n type NativeSyntheticEvent,\n} from 'react-native';\nimport { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { AppKeyboardAvoidingView } from '../../components/AppKeyboardAvoidingView';\nimport {\n Avatar,\n ConnectionBanner,\n DaySeparator,\n InlineBanner,\n MessageBubble,\n ReplyQuote,\n SystemRow,\n UnreadDivider,\n type ChatTheme,\n} from './ChatComponents';\nimport { ActionSheet, type SheetAction } from './ActionSheet';\nimport { TapRow } from './TapRow';\nimport {\n canDeleteForEveryone,\n canEditMessage,\n dayLabel,\n firstUnreadId,\n messageStatus,\n systemText,\n timeLabel,\n replyRefOf,\n type ChatGroupMember,\n type ChatMessage,\n type ChatReplyRef,\n type ChatAttachmentKind,\n} from './chatModel';\nimport { MessageActionsOverlay, type BubbleFrame, type MessageAction } from './MessageActions';\nimport type { ChatAudioSeam, ChatConnectionState, ChatHapticsSeam, ChatMediaSeam, ChatPickedImage } from './chatHost';\nimport type { LinkPreviewLoader } from './linkPreview';\nimport { AttachSheet, ImageViewer, RecordingBar, StagedAttachments } from './ChatAttachments';\nimport { PollComposer } from './PollComposer';\n\n/** One search result in a chat. */\nexport interface ChatSearchHit {\n id: string;\n body: string;\n createdAt: number;\n authorName: string;\n}\n\n/** How far up (px) the transcript must be scrolled before the jump-to-latest button shows. */\nconst JUMP_BUTTON_OFFSET = 320;\n/** Swipe distance that arms a reply, and the furthest a bubble follows the finger. */\nconst REPLY_SWIPE_TRIGGER = 56;\nconst REPLY_SWIPE_MAX = 80;\n\n/**\n * Swipe a message right to reply to it, as in WhatsApp. RN's own PanResponder and\n * Animated - no gesture library - and it claims the touch only for a clearly\n * horizontal rightward drag, so vertical scrolling and long-press are untouched.\n */\nfunction SwipeToReply({\n enabled,\n theme,\n onReply,\n children,\n}: {\n enabled: boolean;\n theme: ChatTheme;\n onReply: () => void;\n children: React.ReactNode;\n}) {\n const dx = React.useRef(new Animated.Value(0)).current;\n const armed = React.useRef(false);\n const onReplyRef = React.useRef(onReply);\n onReplyRef.current = onReply;\n\n const responder = React.useMemo(\n () =>\n PanResponder.create({\n onMoveShouldSetPanResponder: (_, g) => enabled && g.dx > 12 && Math.abs(g.dx) > Math.abs(g.dy) * 2,\n onPanResponderMove: (_, g) => {\n const x = Math.max(0, Math.min(REPLY_SWIPE_MAX, g.dx));\n dx.setValue(x);\n armed.current = x >= REPLY_SWIPE_TRIGGER;\n },\n onPanResponderRelease: () => {\n if (armed.current) onReplyRef.current();\n armed.current = false;\n Animated.spring(dx, { toValue: 0, useNativeDriver: true, bounciness: 6 }).start();\n },\n onPanResponderTerminate: () => {\n armed.current = false;\n Animated.spring(dx, { toValue: 0, useNativeDriver: true }).start();\n },\n onPanResponderTerminationRequest: () => true,\n }),\n [dx, enabled],\n );\n\n const iconOpacity = dx.interpolate({\n inputRange: [0, REPLY_SWIPE_TRIGGER],\n outputRange: [0, 1],\n extrapolate: 'clamp',\n });\n\n return (\n <View>\n <Animated.View pointerEvents=\"none\" style={[styles.swipeIcon, { opacity: iconOpacity }]}>\n <View style={[styles.swipeIconPlate, { backgroundColor: theme.isDark ? theme.surface : theme.chipBg }]}>\n <MaterialCommunityIcons name=\"reply\" size={18} color={theme.textMuted} />\n </View>\n </Animated.View>\n <Animated.View style={{ transform: [{ translateX: dx }] }} {...responder.panHandlers}>\n {children}\n </Animated.View>\n </View>\n );\n}\n\nexport function ThreadScreen({\n title,\n subtitle,\n avatarUrl,\n isGroup,\n muted,\n viewerId,\n readWatermark,\n deliveredWatermark,\n initialUnreadCount,\n typingText,\n infoLabel,\n onDraftChange,\n onEdit,\n onDeleteForEveryone,\n onDeleteForMe,\n onStar,\n onForward,\n onSearch,\n onLoadUntil,\n initialJumpTo,\n initialDraft,\n onShowInfo,\n messages,\n loading,\n loadingMore,\n error,\n theme,\n connectionState,\n haptics,\n onBack,\n onOpenInfo,\n onSend,\n onLoadMore,\n onRetry,\n onDismissError,\n onReact,\n onCopyText,\n onShareText,\n media,\n audio,\n onSendAttachments,\n linkPreviews,\n onOpenLink,\n memberNameOf,\n mentionCandidates,\n composerLock,\n onVote,\n onViewVotes,\n onCreatePoll,\n onReportMessage,\n onKeep,\n peerBlocked,\n onUnblockPeer,\n}: {\n title: string;\n /** Under the name: a group's members, or \"Muted\" / a hint to tap for info. */\n subtitle?: string;\n avatarUrl?: string | null;\n /** Groups label each sender's run with their name. */\n isGroup?: boolean;\n muted?: boolean;\n viewerId?: string | null;\n /** Everyone else has read up to here (epoch millis); drives the blue ticks. */\n readWatermark?: number;\n /** Everyone else's phones have the messages up to here (epoch millis); two gray ticks. */\n deliveredWatermark?: number;\n /** Unread when the chat was opened; places the unread band. */\n initialUnreadCount?: number;\n /** \"typing…\" / \"Asha is typing…\": replaces the subtitle, in green, while someone types. */\n typingText?: string;\n /** \"Contact info\" or \"Group info\", for the chat menu. */\n infoLabel?: string;\n /** Every composer change (drives the viewer's own \"typing…\"). */\n onDraftChange?: (text: string) => void;\n /** Save an edit to one of the viewer's messages. */\n onEdit?: (messageId: string, body: string) => void;\n onDeleteForEveryone?: (messageId: string) => void;\n onDeleteForMe?: (messageId: string) => void;\n onStar?: (messageId: string, starred: boolean) => void;\n /** Pick chats to forward a message to. */\n onForward?: (message: ChatMessage) => void;\n /** Search this chat; without it the menu has no Search. */\n onSearch?: (query: string) => Promise<ChatSearchHit[]>;\n /** Page back until a message is loaded, so a jump can reach it. */\n onLoadUntil?: (messageId: string) => Promise<boolean>;\n /** Open at this message (from Starred messages) instead of the newest. */\n initialJumpTo?: string | null;\n /** The unsent text the viewer left in this chat, restored into the composer. */\n initialDraft?: string;\n /** Message info for one of the viewer's messages (Read by / Delivered to). */\n onShowInfo?: (message: ChatMessage) => void;\n messages: ChatMessage[];\n loading: boolean;\n loadingMore: boolean;\n error: string | null;\n theme: ChatTheme;\n connectionState: ChatConnectionState;\n haptics?: ChatHapticsSeam;\n onBack: () => void;\n /** Tapping the header opens chat info (mute, notifications). */\n onOpenInfo?: () => void;\n onSend: (body: string, replyTo?: ChatReplyRef | null, mentions?: string[]) => void;\n /** Resolve a member id to a display name, for rendering system lines. */\n memberNameOf?: (id: string | null | undefined) => string;\n /** The group's other members, for the @mention picker (empty in a DM). */\n mentionCandidates?: ChatGroupMember[];\n /** Non-null makes the composer read-only: only admins may send, or the viewer left. */\n composerLock?: 'adminsOnly' | 'notParticipant' | null;\n onLoadMore: () => void;\n onRetry: (id: string) => void;\n onDismissError: () => void;\n /** Pick or remove the viewer's reaction; absent disables long-press reactions. */\n onReact?: (messageId: string, emoji: string) => void;\n /** Present only when the host provides a clipboard. */\n onCopyText?: (text: string) => void;\n onShareText?: (text: string) => void;\n /** Photos / camera; without it (or `onSendAttachments`) the \"+\" and camera buttons are hidden. */\n media?: ChatMediaSeam;\n /** Voice notes; without it the mic button is hidden. */\n audio?: ChatAudioSeam;\n onSendAttachments?: (\n files: ChatPickedImage[],\n caption: string,\n kind: ChatAttachmentKind,\n replyTo?: ChatReplyRef | null,\n ) => void;\n /** A link's card, from the gateway; without it links show no card. */\n linkPreviews?: LinkPreviewLoader;\n /** Opens a tapped link; without it links are not tappable. */\n onOpenLink?: (url: string) => void;\n /** Tap a poll option (id tapped); without it polls are read-only. */\n onVote?: (messageId: string, optionId: string) => void;\n /** Open the \"who voted\" screen for a poll. */\n onViewVotes?: (message: ChatMessage) => void;\n /** Create a poll; without it (or without media) the \"+\" sheet has no Poll row. */\n onCreatePoll?: (question: string, options: string[], multiple: boolean) => Promise<void> | void;\n /** Report a message (adds a Report row to the long-press menu). */\n onReportMessage?: (message: ChatMessage) => void;\n /** Keep / unkeep a disappearing message. Provided only in disappearing chats. */\n onKeep?: (messageId: string, keep: boolean) => void;\n /** DM only: the viewer has blocked the peer, so the composer becomes an \"unblock\" bar. */\n peerBlocked?: boolean;\n /** Unblock the peer from the blocked-composer bar. */\n onUnblockPeer?: () => void;\n}) {\n const [draft, setDraft] = React.useState(initialDraft ?? '');\n // The draft can arrive after the chat opened (the list loads it); take it once, and only\n // while the composer is still empty, so it never overwrites what the person is typing.\n const draftRestored = React.useRef(Boolean(initialDraft));\n React.useEffect(() => {\n if (draftRestored.current || !initialDraft) return;\n draftRestored.current = true;\n setDraft((current) => current || initialDraft);\n }, [initialDraft]);\n const [staged, setStaged] = React.useState<ChatPickedImage[]>([]);\n const [attachOpen, setAttachOpen] = React.useState(false);\n const [pollComposerOpen, setPollComposerOpen] = React.useState(false);\n const [recordingSince, setRecordingSince] = React.useState<number | null>(null);\n const [viewerUrl, setViewerUrl] = React.useState<string | null>(null);\n const [composerError, setComposerError] = React.useState<string | null>(null);\n const [replyTo, setReplyTo] = React.useState<ChatReplyRef | null>(null);\n /** The message being edited in the composer, WhatsApp-style. */\n const [editing, setEditing] = React.useState<{ id: string; original: string; draftBefore: string } | null>(null);\n const [deleteTarget, setDeleteTarget] = React.useState<ChatMessage | null>(null);\n const [menuOpen, setMenuOpen] = React.useState(false);\n const [searchOpen, setSearchOpen] = React.useState(false);\n const [searchQuery, setSearchQuery] = React.useState('');\n const [searchHits, setSearchHits] = React.useState<ChatSearchHit[] | null>(null);\n const [searching, setSearching] = React.useState(false);\n const [highlightId, setHighlightId] = React.useState<string | null>(null);\n const inputRef = React.useRef<TextInput>(null);\n const listRef = React.useRef<FlatList<ChatMessage>>(null);\n const canAttach = Boolean(media && onSendAttachments);\n const canRecord = Boolean(audio && onSendAttachments);\n // The host wraps the whole chat in a bottom-edge SafeAreaView, and the composer below applies\n // its own bottom inset (so the composer bar's colour fills to the home indicator, WhatsApp-style).\n // Cancel the host's inset here so it is not counted twice - otherwise there is a double gap\n // below the composer. The composer's own SafeAreaView is the single source of the bottom inset.\n const insets = useSafeAreaInsets();\n // Resolve a member id to a name for system lines, with a neutral fallback.\n const resolveName = React.useCallback(\n (id: string | null | undefined) => memberNameOf?.(id) ?? 'Someone',\n [memberNameOf],\n );\n // @mention composer state. Each pick records the inserted `@token` and the member id; on send\n // we keep only the ids whose token still appears in the text (the user may have deleted some).\n const insertedMentions = React.useRef<{ token: string; id: string }[]>([]);\n const [mentionQuery, setMentionQuery] = React.useState<string | null>(null);\n const mentionMatches = React.useMemo(() => {\n if (mentionQuery == null || !mentionCandidates?.length) return [];\n const q = mentionQuery.toLowerCase();\n return mentionCandidates\n .filter((m) => !m.isYou)\n .filter(\n (m) =>\n !q ||\n m.name\n .toLowerCase()\n .split(/\\s+/)\n .some((w) => w.startsWith(q)),\n )\n .slice(0, 8);\n }, [mentionQuery, mentionCandidates]);\n const mentionIdsFor = React.useCallback((text: string): string[] => {\n const ids = insertedMentions.current.filter((m) => text.includes(m.token)).map((m) => m.id);\n return Array.from(new Set(ids));\n }, []);\n /** The `@query` immediately before the end of the text, or null. Simple and caret-free. */\n const activeMentionQuery = React.useCallback(\n (text: string): string | null => {\n if (!mentionCandidates?.length) return null;\n const m = /(?:^|\\s)@([\\p{L}\\p{N}._'’-]*)$/u.exec(text);\n return m ? m[1] : null;\n },\n [mentionCandidates],\n );\n const [selected, setSelected] = React.useState<{ id: string; frame: BubbleFrame } | null>(null);\n const selectedMessage = React.useMemo(\n () => (selected ? (messages.find((m) => m.id === selected.id) ?? null) : null),\n [selected, messages],\n );\n const closeActions = React.useCallback(() => setSelected(null), []);\n // Share must open AFTER the overlay's modal is gone: iOS refuses to present the\n // share sheet from a view controller that is still dismissing, and fails silently.\n const pendingShare = React.useRef<string | null>(null);\n const flushPendingShare = React.useCallback(() => {\n const text = pendingShare.current;\n pendingShare.current = null;\n if (text) onShareText?.(text);\n }, [onShareText]);\n\n const startReply = React.useCallback(\n (message: ChatMessage) => {\n haptics?.impact('light');\n setReplyTo(replyRefOf(message));\n inputRef.current?.focus();\n },\n [haptics],\n );\n\n const actions = React.useMemo<MessageAction[]>(() => {\n const body = selectedMessage?.body.trim() ?? '';\n const list: MessageAction[] = [];\n const at = Date.now();\n if (selectedMessage) {\n const target = selectedMessage;\n list.push({\n key: 'reply',\n label: 'Reply',\n icon: 'reply',\n onPress: () => {\n setSelected(null);\n startReply(target);\n },\n });\n if (onForward && body) {\n list.push({\n key: 'forward',\n label: 'Forward',\n icon: 'share',\n onPress: () => {\n setSelected(null);\n onForward(target);\n },\n });\n }\n }\n if (onCopyText && body) {\n list.push({\n key: 'copy',\n label: 'Copy',\n icon: 'content-copy',\n onPress: () => {\n onCopyText(body);\n setSelected(null);\n },\n });\n }\n if (onShareText && body) {\n list.push({\n key: 'share',\n label: 'Share',\n icon: 'export-variant',\n onPress: () => {\n pendingShare.current = body;\n setSelected(null);\n // Android has no Modal onDismiss; its modal is gone after the fade.\n if (Platform.OS !== 'ios') setTimeout(flushPendingShare, 300);\n },\n });\n }\n if (\n selectedMessage &&\n onShowInfo &&\n selectedMessage.isMine &&\n !selectedMessage.isDeleted &&\n (!selectedMessage.sendState || selectedMessage.sendState === 'sent')\n ) {\n const target = selectedMessage;\n list.push({\n key: 'info',\n label: 'Info',\n icon: 'information-outline',\n onPress: () => {\n setSelected(null);\n onShowInfo(target);\n },\n });\n }\n if (selectedMessage && onStar) {\n const target = selectedMessage;\n list.push({\n key: 'star',\n label: target.starred ? 'Unstar' : 'Star',\n icon: target.starred ? 'star-off-outline' : 'star-outline',\n onPress: () => {\n setSelected(null);\n onStar(target.id, !target.starred);\n },\n });\n }\n if (\n selectedMessage &&\n onKeep &&\n !selectedMessage.isDeleted &&\n (!selectedMessage.sendState || selectedMessage.sendState === 'sent')\n ) {\n const target = selectedMessage;\n list.push({\n key: 'keep',\n label: target.kept ? 'Unkeep' : 'Keep',\n icon: target.kept ? 'bookmark-off-outline' : 'bookmark-outline',\n onPress: () => {\n setSelected(null);\n onKeep(target.id, !target.kept);\n },\n });\n }\n if (selectedMessage && onEdit && canEditMessage(selectedMessage, at)) {\n const target = selectedMessage;\n list.push({\n key: 'edit',\n label: 'Edit',\n icon: 'pencil-outline',\n onPress: () => {\n setSelected(null);\n setReplyTo(null);\n // The composer holds the message while editing; the chat's own draft comes back after.\n setEditing({ id: target.id, original: target.body, draftBefore: draft });\n setDraft(target.body);\n inputRef.current?.focus();\n },\n });\n }\n // Report someone else's message (never your own), WhatsApp-style.\n if (selectedMessage && onReportMessage && !selectedMessage.isMine && !selectedMessage.isDeleted) {\n const target = selectedMessage;\n list.push({\n key: 'report',\n label: 'Report',\n icon: 'alert-octagon-outline',\n onPress: () => {\n setSelected(null);\n onReportMessage(target);\n },\n });\n }\n if (selectedMessage && (onDeleteForMe || onDeleteForEveryone)) {\n const target = selectedMessage;\n list.push({\n key: 'delete',\n label: 'Delete',\n icon: 'delete-outline',\n onPress: () => {\n setSelected(null);\n setDeleteTarget(target);\n },\n });\n }\n return list;\n }, [\n selectedMessage,\n onCopyText,\n onShareText,\n flushPendingShare,\n startReply,\n onForward,\n onStar,\n onEdit,\n onKeep,\n onReportMessage,\n onDeleteForMe,\n onDeleteForEveryone,\n onShowInfo,\n draft,\n ]);\n\n const deleteActions = React.useMemo<SheetAction[]>(() => {\n const target = deleteTarget;\n if (!target) return [];\n const list: SheetAction[] = [];\n if (onDeleteForEveryone && canDeleteForEveryone(target, Date.now())) {\n list.push({\n key: 'delete-everyone',\n label: 'Delete for everyone',\n icon: 'delete-outline',\n destructive: true,\n onPress: () => onDeleteForEveryone(target.id),\n });\n }\n if (onDeleteForMe) {\n list.push({\n key: 'delete-me',\n label: 'Delete for me',\n icon: 'delete-outline',\n destructive: true,\n onPress: () => onDeleteForMe(target.id),\n });\n }\n return list;\n }, [deleteTarget, onDeleteForEveryone, onDeleteForMe]);\n\n const [now, setNow] = React.useState(() => Date.now());\n React.useEffect(() => {\n // Day chips roll over at midnight while a chat stays open.\n const t = setInterval(() => setNow(Date.now()), 60_000);\n return () => clearInterval(t);\n }, []);\n const rendered = React.useMemo(() => messages.slice().reverse(), [messages]);\n const canSend = draft.trim().length > 0 || staged.length > 0;\n\n // The unread band is placed ONCE, from the count the chat opened with, and stays put\n // while the chat is open - messages arriving now are being read as they land.\n const [unreadAnchor, setUnreadAnchor] = React.useState<{ id: string; count: number } | null>(null);\n const anchorDecided = React.useRef(false);\n React.useEffect(() => {\n if (anchorDecided.current || loading || !messages.length) return;\n anchorDecided.current = true;\n const id = firstUnreadId(messages, initialUnreadCount ?? 0);\n if (id) setUnreadAnchor({ id, count: initialUnreadCount ?? 0 });\n }, [loading, messages, initialUnreadCount]);\n\n // Jump-to-latest button, with a count of messages that arrived while scrolled up.\n const [scrolledUp, setScrolledUp] = React.useState(false);\n const [missed, setMissed] = React.useState(0);\n const newestId = messages.length ? messages[messages.length - 1].id : null;\n const lastNewest = React.useRef(newestId);\n React.useEffect(() => {\n const previous = lastNewest.current;\n lastNewest.current = newestId;\n if (!previous || previous === newestId || !scrolledUp) return;\n const newest = messages[messages.length - 1];\n if (newest && !newest.isMine) setMissed((n) => n + 1);\n }, [newestId, scrolledUp, messages]);\n const onScroll = React.useCallback((e: NativeSyntheticEvent<NativeScrollEvent>) => {\n const up = e.nativeEvent.contentOffset.y > JUMP_BUTTON_OFFSET;\n setScrolledUp(up);\n if (!up) setMissed(0);\n }, []);\n const jumpToLatest = React.useCallback(() => {\n listRef.current?.scrollToOffset({ offset: 0, animated: true });\n setMissed(0);\n }, []);\n\n const renderedRef = React.useRef(rendered);\n renderedRef.current = rendered;\n const scrollTo = React.useCallback((messageId: string): boolean => {\n const index = renderedRef.current.findIndex((m) => m.id === messageId);\n if (index < 0) return false;\n listRef.current?.scrollToIndex({ index, animated: true, viewPosition: 0.5 });\n setHighlightId(messageId);\n setTimeout(() => setHighlightId((id) => (id === messageId ? null : id)), 1400);\n return true;\n }, []);\n const jumpToMessage = React.useCallback(\n (messageId: string) => {\n if (scrollTo(messageId) || !onLoadUntil) return;\n // Further up than what is loaded: page back to it, then scroll once it has rendered.\n void onLoadUntil(messageId).then((found) => {\n if (found) setTimeout(() => scrollTo(messageId), 120);\n else setComposerError('That message is too far back to show here.');\n });\n },\n [scrollTo, onLoadUntil],\n );\n\n // Opened from Starred messages: go to that message once the transcript is in.\n const jumpedTo = React.useRef<string | null>(null);\n React.useEffect(() => {\n if (!initialJumpTo || loading || jumpedTo.current === initialJumpTo) return;\n jumpedTo.current = initialJumpTo;\n setTimeout(() => jumpToMessage(initialJumpTo), 250);\n }, [initialJumpTo, loading, jumpToMessage]);\n\n const runSearch = React.useCallback(\n async (query: string) => {\n const q = query.trim();\n if (!onSearch || q.length < 2) {\n setSearchHits(null);\n return;\n }\n setSearching(true);\n try {\n setSearchHits(await onSearch(q));\n } catch {\n setSearchHits([]);\n } finally {\n setSearching(false);\n }\n },\n [onSearch],\n );\n React.useEffect(() => {\n if (!searchOpen) return undefined;\n const t = setTimeout(() => void runSearch(searchQuery), 350);\n return () => clearTimeout(t);\n }, [searchOpen, searchQuery, runSearch]);\n const closeSearch = React.useCallback(() => {\n setSearchOpen(false);\n setSearchQuery('');\n setSearchHits(null);\n }, []);\n\n const menuActions = React.useMemo<SheetAction[]>(() => {\n const list: SheetAction[] = [];\n if (onOpenInfo) {\n list.push({\n key: 'info',\n label: infoLabel ?? 'Chat info',\n icon: 'information-outline',\n onPress: onOpenInfo,\n });\n }\n if (onSearch) {\n list.push({ key: 'search', label: 'Search', icon: 'magnify', onPress: () => setSearchOpen(true) });\n }\n return list;\n }, [onOpenInfo, onSearch, infoLabel]);\n\n const submit = React.useCallback(() => {\n const text = draft.trim();\n const quote = replyTo;\n if (editing) {\n if (text && text !== editing.original.trim()) onEdit?.(editing.id, text);\n setEditing(null);\n setDraft(editing.draftBefore);\n return;\n }\n if (staged.length && onSendAttachments) {\n setDraft('');\n setStaged([]);\n setReplyTo(null);\n haptics?.impact('light');\n onSendAttachments(staged, text, 'image', quote);\n jumpToLatest();\n return;\n }\n if (!text) return;\n const mentions = mentionIdsFor(text);\n setDraft('');\n setReplyTo(null);\n setMentionQuery(null);\n insertedMentions.current = [];\n onDraftChange?.('');\n haptics?.impact('light');\n onSend(text, quote, mentions);\n jumpToLatest();\n }, [\n draft,\n staged,\n replyTo,\n editing,\n haptics,\n onSend,\n onSendAttachments,\n onEdit,\n onDraftChange,\n jumpToLatest,\n mentionIdsFor,\n ]);\n\n /** Replace the trailing `@query` with `@FirstName ` and record the picked member. */\n const insertMention = React.useCallback(\n (member: ChatGroupMember) => {\n const handle = member.name.trim().split(/\\s+/)[0] || 'member';\n const token = `@${handle}`;\n setDraft((prev) => {\n const next = prev.replace(/(?:^|\\s)@([\\p{L}\\p{N}._'’-]*)$/u, (whole) => {\n const lead = whole.startsWith('@') ? '' : whole[0];\n return `${lead}${token} `;\n });\n onDraftChange?.(next);\n return next;\n });\n insertedMentions.current = [...insertedMentions.current, { token, id: member.id }];\n setMentionQuery(null);\n inputRef.current?.focus();\n },\n [onDraftChange],\n );\n\n // The menu must be fully closed before the picker opens: iOS silently refuses to present over\n // a modal that is still animating away (same as Share). iOS waits for the sheet's onDismiss;\n // Android has no onDismiss, so it waits out the slide.\n const pendingPick = React.useRef<'library' | 'camera' | null>(null);\n const runPendingPick = React.useCallback(() => {\n const source = pendingPick.current;\n pendingPick.current = null;\n if (!source || !media) return;\n const run =\n source === 'library'\n ? media.pickFromLibrary({ limit: Math.max(1, 10 - staged.length) })\n : media.captureFromCamera();\n run.then((files) => {\n if (files.length) setStaged((prev) => [...prev, ...files].slice(0, 10));\n }).catch((e: unknown) => setComposerError(e instanceof Error ? e.message : 'Could not open photos.'));\n }, [media, staged.length]);\n const pick = React.useCallback(\n (source: 'library' | 'camera') => {\n if (!media) return;\n setComposerError(null);\n pendingPick.current = source;\n setAttachOpen(false);\n if (Platform.OS !== 'ios') setTimeout(runPendingPick, 400);\n },\n [media, runPendingPick],\n );\n /** The composer's camera button: no sheet in between, so it can run at once. */\n const openCamera = React.useCallback(() => {\n if (!media) return;\n setComposerError(null);\n pendingPick.current = 'camera';\n runPendingPick();\n }, [media, runPendingPick]);\n\n // Same iOS modal-timing dance as the picker: the attach sheet must be fully gone before the\n // poll composer (another full-screen modal) can present.\n const pendingPoll = React.useRef(false);\n const runPendingPoll = React.useCallback(() => {\n if (!pendingPoll.current) return;\n pendingPoll.current = false;\n setPollComposerOpen(true);\n }, []);\n const openPoll = React.useCallback(() => {\n pendingPoll.current = true;\n setAttachOpen(false);\n if (Platform.OS !== 'ios') setTimeout(runPendingPoll, 400);\n }, [runPendingPoll]);\n\n const startRecording = React.useCallback(async () => {\n if (!audio) return;\n setComposerError(null);\n try {\n const ok = await audio.startRecording();\n if (!ok) {\n setComposerError('Microphone access is off. Allow it in Settings to send voice messages.');\n return;\n }\n haptics?.impact('medium');\n setRecordingSince(Date.now());\n } catch (e) {\n setComposerError(e instanceof Error ? e.message : 'Could not start recording.');\n }\n }, [audio, haptics]);\n\n const finishRecording = React.useCallback(\n async (send: boolean) => {\n if (!audio) return;\n setRecordingSince(null);\n try {\n if (!send) {\n await audio.cancelRecording();\n return;\n }\n const file = await audio.stopRecording();\n if (file && onSendAttachments) {\n haptics?.impact('light');\n onSendAttachments([file], '', 'audio', replyTo);\n setReplyTo(null);\n }\n } catch (e) {\n setComposerError(e instanceof Error ? e.message : 'Could not send the recording.');\n }\n },\n [audio, haptics, onSendAttachments, replyTo],\n );\n\n // Leaving the thread mid-recording throws the recording away.\n const recordingRef = React.useRef(recordingSince);\n recordingRef.current = recordingSince;\n React.useEffect(\n () => () => {\n if (recordingRef.current) void audio?.cancelRecording();\n },\n [audio],\n );\n\n const headerSubtitle = typingText || subtitle || '';\n\n return (\n <AppKeyboardAvoidingView\n style={[styles.fill, { backgroundColor: theme.threadBg, marginBottom: -insets.bottom }]}\n behavior={Platform.OS === 'ios' ? 'padding' : undefined}\n keyboardVerticalOffset={0}\n >\n <SafeAreaView edges={['top']} style={{ backgroundColor: theme.headerBg }}>\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n paddingLeft: 4,\n paddingRight: 8,\n paddingVertical: 6,\n minHeight: 52,\n borderBottomWidth: StyleSheet.hairlineWidth,\n borderBottomColor: theme.border,\n backgroundColor: theme.headerBg,\n }}\n >\n <Pressable\n onPress={onBack}\n hitSlop={10}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Back\"\n style={styles.headerIcon}\n testID=\"chat-thread-back\"\n >\n <MaterialCommunityIcons name=\"chevron-left\" size={32} color={theme.accent} />\n </Pressable>\n <Pressable\n onPress={onOpenInfo ?? undefined}\n disabled={!onOpenInfo}\n accessibilityRole=\"button\"\n accessibilityLabel={onOpenInfo ? `${title}, chat info` : title}\n style={{ flex: 1, minWidth: 0 }}\n testID=\"chat-thread-header\"\n >\n <View style={{ flexDirection: 'row', alignItems: 'center', minWidth: 0 }}>\n <Avatar name={title} uri={avatarUrl} theme={theme} size={38} variant=\"initials\" />\n <View style={{ flex: 1, minWidth: 0, marginLeft: 10 }}>\n <View style={{ flexDirection: 'row', alignItems: 'center' }}>\n <Text\n numberOfLines={1}\n style={{ flexShrink: 1, fontSize: 17, fontWeight: '600', color: theme.text }}\n >\n {title}\n </Text>\n {muted ? (\n <MaterialCommunityIcons\n name=\"bell-off\"\n size={14}\n color={theme.textMuted}\n style={{ marginLeft: 5 }}\n accessibilityLabel=\"Muted\"\n />\n ) : null}\n </View>\n {headerSubtitle ? (\n <Text\n numberOfLines={1}\n style={{\n fontSize: 13,\n color: typingText ? theme.accent : theme.textMuted,\n marginTop: 1,\n }}\n testID=\"chat-thread-subtitle\"\n >\n {headerSubtitle}\n </Text>\n ) : null}\n </View>\n </View>\n </Pressable>\n {menuActions.length ? (\n <Pressable\n onPress={() => setMenuOpen(true)}\n hitSlop={8}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Chat menu\"\n style={styles.headerIcon}\n testID=\"chat-thread-menu\"\n >\n <MaterialCommunityIcons name=\"dots-vertical\" size={24} color={theme.textMuted} />\n </Pressable>\n ) : null}\n </View>\n {searchOpen ? (\n <View\n style={[\n styles.searchBar,\n { backgroundColor: theme.headerBg, borderBottomColor: theme.border, flexDirection: 'row' },\n ]}\n >\n <View\n style={[styles.searchField, { backgroundColor: theme.composerField, flexDirection: 'row' }]}\n >\n <MaterialCommunityIcons name=\"magnify\" size={20} color={theme.textMuted} />\n <TextInput\n value={searchQuery}\n onChangeText={setSearchQuery}\n placeholder=\"Search this chat\"\n placeholderTextColor={theme.textMuted}\n autoFocus\n returnKeyType=\"search\"\n style={[styles.searchInput, { color: theme.text }]}\n testID=\"chat-thread-search\"\n />\n {searching ? <ActivityIndicator size=\"small\" color={theme.textMuted} /> : null}\n </View>\n <Pressable\n onPress={closeSearch}\n hitSlop={8}\n accessibilityRole=\"button\"\n style={styles.searchCancel}\n >\n <Text style={{ color: theme.accent, fontSize: 16 }}>Cancel</Text>\n </Pressable>\n </View>\n ) : null}\n </SafeAreaView>\n\n <ConnectionBanner state={connectionState} theme={theme} />\n <InlineBanner message={error} theme={theme} onDismiss={onDismissError} />\n <InlineBanner message={composerError} theme={theme} onDismiss={() => setComposerError(null)} />\n\n {loading && messages.length === 0 ? (\n <View style={[styles.center, { flex: 1 }]}>\n <ActivityIndicator color={theme.accent} />\n </View>\n ) : (\n <View style={styles.fill}>\n <FlatList\n ref={listRef}\n inverted\n data={rendered}\n style={styles.fill}\n keyExtractor={(m) => m.id}\n onScroll={onScroll}\n scrollEventThrottle={100}\n onScrollToIndexFailed={(info) => {\n // Not measured yet (far up the transcript): get close, then settle on it.\n listRef.current?.scrollToOffset({\n offset: info.averageItemLength * info.index,\n animated: true,\n });\n }}\n renderItem={({ item, index }) => {\n const older = rendered[index + 1];\n const label = dayLabel(item.createdAt, now);\n const olderLabel = older ? dayLabel(older.createdAt, now) : null;\n const newDay = olderLabel !== label;\n const sameRun = (a: ChatMessage | null | undefined, b: ChatMessage) =>\n Boolean(\n a &&\n !a.isDeleted &&\n !b.isDeleted &&\n !a.system &&\n !b.system &&\n a.authorId &&\n a.authorId === b.authorId,\n );\n // A day chip or the unread band breaks a run, so the tail comes back after it.\n const startsBand = unreadAnchor?.id === item.id;\n const groupWithPrevious = sameRun(older, item) && !newDay && !startsBand;\n return (\n <View>\n {/* An inverted list flips the list, not each cell: inside a cell the\n first child is on top, so the day chip and the unread band come\n before the bubble they introduce. */}\n {newDay ? <DaySeparator label={label} theme={theme} /> : null}\n {startsBand && unreadAnchor ? (\n <UnreadDivider count={unreadAnchor.count} theme={theme} />\n ) : null}\n {item.system ? (\n <SystemRow\n text={systemText(item.system, viewerId ?? '', resolveName)}\n theme={theme}\n />\n ) : (\n <SwipeToReply\n enabled={!item.isDeleted && (!item.sendState || item.sendState === 'sent')}\n theme={theme}\n onReply={() => startReply(item)}\n >\n <MessageBubble\n message={item}\n theme={theme}\n status={\n item.isMine\n ? messageStatus(\n item,\n readWatermark ?? 0,\n deliveredWatermark ?? 0,\n )\n : undefined\n }\n viewerId={viewerId}\n fileBaseUrl={media?.fileBaseUrl}\n audio={audio}\n onOpenImage={setViewerUrl}\n linkPreviews={linkPreviews}\n onOpenLink={onOpenLink}\n onVote={\n item.poll && onVote\n ? (optionId) => onVote(item.id, optionId)\n : undefined\n }\n onViewVotes={\n item.poll && onViewVotes ? () => onViewVotes(item) : undefined\n }\n showAuthor={Boolean(isGroup) && !groupWithPrevious}\n groupWithPrevious={groupWithPrevious}\n highlighted={highlightId === item.id}\n onPressQuote={jumpToMessage}\n onRetry={() => onRetry(item.id)}\n onLongPress={\n // Only confirmed messages can be reacted to or acted on.\n !item.isDeleted && (!item.sendState || item.sendState === 'sent')\n ? (frame) => {\n haptics?.impact('medium');\n setSelected({ id: item.id, frame });\n }\n : undefined\n }\n />\n </SwipeToReply>\n )}\n </View>\n );\n }}\n onEndReached={onLoadMore}\n onEndReachedThreshold={0.4}\n ListHeaderComponent={<View style={styles.listBottomGap} />}\n ListFooterComponent={\n loadingMore ? (\n <ActivityIndicator style={styles.moreSpinner} size=\"small\" color={theme.textMuted} />\n ) : null\n }\n contentContainerStyle={rendered.length === 0 ? styles.listContentEmpty : undefined}\n ListEmptyComponent={\n <View style={styles.emptyInverted}>\n <View style={[styles.emptyChip, { backgroundColor: theme.chipBg }]}>\n <MaterialCommunityIcons name=\"lock-outline\" size={14} color={theme.chipText} />\n <Text style={[styles.emptyChipText, { color: theme.chipText }]}>\n Messages you send appear here. Say hi!\n </Text>\n </View>\n </View>\n }\n keyboardDismissMode=\"interactive\"\n keyboardShouldPersistTaps=\"handled\"\n testID=\"chat-thread\"\n />\n {searchOpen && searchHits ? (\n <View\n style={[StyleSheet.absoluteFill, { backgroundColor: theme.bg }]}\n testID=\"chat-thread-search-results\"\n >\n <FlatList\n data={searchHits}\n keyExtractor={(h) => h.id}\n keyboardShouldPersistTaps=\"handled\"\n ListEmptyComponent={\n <Text style={[styles.searchEmpty, { color: theme.textMuted }]}>\n No messages found\n </Text>\n }\n renderItem={({ item }) => (\n <Pressable\n onPress={() => {\n closeSearch();\n jumpToMessage(item.id);\n }}\n accessibilityRole=\"button\"\n >\n <View style={[styles.searchHit, { borderBottomColor: theme.border }]}>\n <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>\n <Text\n style={[styles.searchHitAuthor, { color: theme.text }]}\n numberOfLines={1}\n >\n {item.authorName}\n </Text>\n <Text style={{ color: theme.textMuted, fontSize: 12 }}>\n {`${dayLabel(item.createdAt, now)} ${timeLabel(item.createdAt)}`}\n </Text>\n </View>\n <Text\n style={{ color: theme.textMuted, fontSize: 15, marginTop: 2 }}\n numberOfLines={2}\n >\n {item.body}\n </Text>\n </View>\n </Pressable>\n )}\n />\n </View>\n ) : null}\n {scrolledUp ? (\n <Pressable\n onPress={jumpToLatest}\n accessibilityRole=\"button\"\n accessibilityLabel={missed ? `${missed} new messages, jump to latest` : 'Jump to latest'}\n style={[styles.jumpButton, { backgroundColor: theme.isDark ? theme.surface : theme.bg }]}\n testID=\"chat-jump-latest\"\n >\n <MaterialCommunityIcons name=\"chevron-double-down\" size={22} color={theme.textMuted} />\n {missed ? (\n <View style={[styles.jumpBadge, { backgroundColor: theme.unread }]}>\n <Text style={styles.jumpBadgeText}>{missed > 99 ? '99+' : missed}</Text>\n </View>\n ) : null}\n </Pressable>\n ) : null}\n </View>\n )}\n\n {!composerLock && !peerBlocked && mentionMatches.length ? (\n <View\n style={[styles.mentionPanel, { backgroundColor: theme.bg, borderTopColor: theme.border }]}\n testID=\"chat-mention-picker\"\n >\n {mentionMatches.map((m) => (\n <TapRow\n key={m.id}\n onPress={() => insertMention(m)}\n accessibilityRole=\"button\"\n accessibilityLabel={`Mention ${m.name}`}\n pressedColor={theme.surface}\n >\n <View\n style={[styles.mentionRow, { borderBottomColor: theme.border, flexDirection: 'row' }]}\n >\n <Avatar name={m.name} uri={m.avatarUrl} size={34} theme={theme} variant=\"initials\" />\n <Text numberOfLines={1} style={[styles.mentionName, { color: theme.text }]}>\n {m.name}\n </Text>\n {m.isAdmin ? (\n <Text style={[styles.mentionAdmin, { color: theme.textMuted }]}>Admin</Text>\n ) : null}\n </View>\n </TapRow>\n ))}\n </View>\n ) : null}\n {composerLock ? (\n <SafeAreaView edges={['bottom']} style={{ backgroundColor: theme.composerBar }}>\n <View style={[styles.composerLock, { borderTopColor: theme.border }]} testID=\"chat-composer-lock\">\n <MaterialCommunityIcons\n name={composerLock === 'adminsOnly' ? 'shield-account' : 'account-off'}\n size={18}\n color={theme.textMuted}\n style={{ marginRight: 8 }}\n />\n <Text style={[styles.composerLockText, { color: theme.textMuted }]}>\n {composerLock === 'adminsOnly'\n ? 'Only admins can send messages'\n : \"You can't send messages to this group because you're no longer a participant\"}\n </Text>\n </View>\n </SafeAreaView>\n ) : null}\n {!composerLock && peerBlocked ? (\n <SafeAreaView edges={['bottom']} style={{ backgroundColor: theme.composerBar }}>\n <Pressable\n onPress={onUnblockPeer}\n disabled={!onUnblockPeer}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Unblock to send a message\"\n style={[styles.composerLock, { borderTopColor: theme.border }]}\n testID=\"chat-composer-blocked\"\n >\n <Text style={[styles.composerLockText, { color: theme.textMuted }]}>\n You blocked this contact.{onUnblockPeer ? ' Tap to unblock.' : ''}\n </Text>\n </Pressable>\n </SafeAreaView>\n ) : null}\n {!composerLock && !peerBlocked ? (\n <StagedAttachments\n files={staged}\n theme={theme}\n onRemove={(index) => setStaged((prev) => prev.filter((_, i) => i !== index))}\n />\n ) : null}\n {!composerLock && !peerBlocked && editing && !recordingSince ? (\n <View\n style={[styles.replyBar, { backgroundColor: theme.composerBar, flexDirection: 'row' }]}\n testID=\"chat-composer-editing\"\n >\n <MaterialCommunityIcons name=\"pencil\" size={18} color={theme.accent} style={styles.editIcon} />\n <View style={{ flex: 1 }}>\n <Text style={{ color: theme.accent, fontSize: 13, fontWeight: '600' }}>Edit message</Text>\n <Text numberOfLines={1} style={{ color: theme.textMuted, fontSize: 14 }}>\n {editing.original}\n </Text>\n </View>\n <Pressable\n onPress={() => {\n if (editing) setDraft(editing.draftBefore);\n setEditing(null);\n }}\n hitSlop={10}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Cancel edit\"\n style={styles.replyClose}\n >\n <MaterialCommunityIcons name=\"close\" size={20} color={theme.textMuted} />\n </Pressable>\n </View>\n ) : null}\n {!composerLock && !peerBlocked && replyTo && !recordingSince ? (\n <View\n style={[styles.replyBar, { backgroundColor: theme.composerBar, flexDirection: 'row' }]}\n testID=\"chat-composer-reply\"\n >\n <View style={{ flex: 1 }}>\n <ReplyQuote reply={replyTo} theme={theme} viewerId={viewerId} compact />\n </View>\n <Pressable\n onPress={() => setReplyTo(null)}\n hitSlop={10}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Cancel reply\"\n style={styles.replyClose}\n >\n <MaterialCommunityIcons name=\"close\" size={20} color={theme.textMuted} />\n </Pressable>\n </View>\n ) : null}\n {composerLock || peerBlocked ? null : recordingSince ? (\n <RecordingBar\n theme={theme}\n startedAt={recordingSince}\n onCancel={() => void finishRecording(false)}\n onSend={() => void finishRecording(true)}\n />\n ) : (\n <SafeAreaView edges={['bottom']} style={{ backgroundColor: theme.composerBar }}>\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'flex-end',\n paddingHorizontal: 6,\n paddingVertical: 6,\n backgroundColor: theme.composerBar,\n }}\n >\n {canAttach ? (\n <Pressable\n onPress={() => setAttachOpen(true)}\n hitSlop={6}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Attach\"\n style={styles.composerIcon}\n testID=\"chat-composer-attach\"\n >\n <MaterialCommunityIcons name=\"plus\" size={28} color={theme.accent} />\n </Pressable>\n ) : null}\n <View\n style={{\n flex: 1,\n flexDirection: 'row',\n alignItems: 'flex-end',\n backgroundColor: theme.composerField,\n borderRadius: 20,\n borderWidth: theme.isDark ? 0 : StyleSheet.hairlineWidth,\n borderColor: theme.border,\n paddingHorizontal: 14,\n minHeight: 38,\n marginHorizontal: 4,\n }}\n >\n <TextInput\n ref={inputRef}\n value={draft}\n onChangeText={(text) => {\n setDraft(text);\n // An edit in progress is not the chat's draft (nor \"typing\").\n if (!editing) onDraftChange?.(text);\n setMentionQuery(editing ? null : activeMentionQuery(text));\n }}\n placeholder=\"Message\"\n placeholderTextColor={theme.textMuted}\n style={{\n flex: 1,\n color: theme.text,\n fontSize: 17,\n paddingVertical: Platform.OS === 'ios' ? 8 : 6,\n maxHeight: 120,\n }}\n multiline\n blurOnSubmit={false}\n testID=\"chat-composer-input\"\n />\n </View>\n {canSend || !canRecord ? (\n <Pressable\n onPress={canSend ? submit : undefined}\n disabled={!canSend}\n accessibilityRole=\"button\"\n accessibilityLabel={editing ? 'Save edit' : 'Send message'}\n style={[\n styles.composerSend,\n { backgroundColor: canSend ? theme.accent : theme.border },\n ]}\n testID=\"chat-composer-send\"\n >\n <MaterialCommunityIcons\n name={editing ? 'check' : 'send'}\n size={editing ? 22 : 20}\n color={theme.onAccent}\n style={editing ? null : styles.sendGlyph}\n />\n </Pressable>\n ) : (\n <View style={{ flexDirection: 'row', alignItems: 'center' }}>\n {canAttach ? (\n <Pressable\n onPress={openCamera}\n hitSlop={6}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Take a photo\"\n style={styles.composerIcon}\n testID=\"chat-composer-camera\"\n >\n <MaterialCommunityIcons name=\"camera-outline\" size={26} color={theme.accent} />\n </Pressable>\n ) : null}\n <Pressable\n onPress={() => void startRecording()}\n hitSlop={6}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Record voice message\"\n style={styles.composerIcon}\n testID=\"chat-composer-mic\"\n >\n <MaterialCommunityIcons name=\"microphone-outline\" size={26} color={theme.accent} />\n </Pressable>\n </View>\n )}\n </View>\n </SafeAreaView>\n )}\n\n <AttachSheet\n visible={attachOpen}\n theme={theme}\n onClose={() => setAttachOpen(false)}\n onPhotos={() => pick('library')}\n onCamera={() => pick('camera')}\n onPoll={onCreatePoll ? openPoll : undefined}\n onDismissed={\n Platform.OS === 'ios'\n ? () => {\n runPendingPick();\n runPendingPoll();\n }\n : undefined\n }\n />\n {onCreatePoll ? (\n <PollComposer\n visible={pollComposerOpen}\n theme={theme}\n onCancel={() => setPollComposerOpen(false)}\n onCreate={async (question, options, multiple) => {\n await onCreatePoll(question, options, multiple);\n setPollComposerOpen(false);\n }}\n />\n ) : null}\n <ImageViewer url={viewerUrl} onClose={() => setViewerUrl(null)} />\n\n <MessageActionsOverlay\n message={selectedMessage}\n frame={selected?.frame ?? null}\n theme={theme}\n actions={actions}\n onReact={(emoji) => {\n if (selectedMessage && onReact) {\n haptics?.impact('selection');\n onReact(selectedMessage.id, emoji);\n }\n setSelected(null);\n }}\n onClose={closeActions}\n onDismissed={Platform.OS === 'ios' ? flushPendingShare : undefined}\n />\n <ActionSheet\n visible={Boolean(deleteTarget)}\n title=\"Delete message?\"\n actions={deleteActions}\n theme={theme}\n onClose={() => setDeleteTarget(null)}\n testID=\"chat-delete-sheet\"\n />\n <ActionSheet\n visible={menuOpen}\n actions={menuActions}\n theme={theme}\n onClose={() => setMenuOpen(false)}\n testID=\"chat-thread-menu-sheet\"\n />\n </AppKeyboardAvoidingView>\n );\n}\n\nconst styles = StyleSheet.create({\n fill: { flex: 1 },\n center: { flex: 1, alignItems: 'center', justifyContent: 'center' },\n listContentEmpty: { flexGrow: 1, justifyContent: 'center' },\n listBottomGap: { height: 8 },\n moreSpinner: { paddingVertical: 12 },\n emptyInverted: { transform: [{ scaleY: -1 }], paddingVertical: 24, alignItems: 'center', paddingHorizontal: 32 },\n emptyChip: {\n flexDirection: 'row',\n alignItems: 'center',\n borderRadius: 8,\n paddingHorizontal: 12,\n paddingVertical: 8,\n },\n emptyChipText: { fontSize: 13, marginLeft: 6, textAlign: 'center' },\n headerIcon: { width: 40, height: 40, alignItems: 'center', justifyContent: 'center' },\n composerIcon: {\n width: 40,\n height: 38,\n alignItems: 'center',\n justifyContent: 'center',\n },\n composerSend: {\n width: 38,\n height: 38,\n borderRadius: 19,\n alignItems: 'center',\n justifyContent: 'center',\n marginLeft: 2,\n },\n /** The paper plane's optical center sits left of its box. */\n sendGlyph: { marginLeft: 3 },\n replyBar: { alignItems: 'center', paddingLeft: 10, paddingRight: 4, paddingTop: 8 },\n mentionPanel: { maxHeight: 220, borderTopWidth: StyleSheet.hairlineWidth },\n mentionRow: {\n alignItems: 'center',\n paddingHorizontal: 14,\n paddingVertical: 8,\n borderBottomWidth: StyleSheet.hairlineWidth,\n },\n mentionName: { flex: 1, fontSize: 16, marginLeft: 12 },\n mentionAdmin: { fontSize: 12, marginLeft: 8 },\n composerLock: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n paddingHorizontal: 24,\n paddingVertical: 14,\n borderTopWidth: StyleSheet.hairlineWidth,\n },\n composerLockText: { fontSize: 13.5, textAlign: 'center', flexShrink: 1 },\n replyClose: { width: 36, height: 36, alignItems: 'center', justifyContent: 'center' },\n editIcon: { marginRight: 10 },\n searchBar: {\n alignItems: 'center',\n paddingHorizontal: 10,\n paddingBottom: 8,\n borderBottomWidth: StyleSheet.hairlineWidth,\n },\n searchField: { flex: 1, alignItems: 'center', height: 36, borderRadius: 10, paddingHorizontal: 10 },\n searchInput: { flex: 1, marginLeft: 6, fontSize: 16, paddingVertical: 0 },\n searchCancel: { marginLeft: 10, paddingVertical: 6 },\n searchEmpty: { textAlign: 'center', marginTop: 40, fontSize: 15 },\n searchHit: { paddingHorizontal: 16, paddingVertical: 10, borderBottomWidth: StyleSheet.hairlineWidth },\n searchHitAuthor: { fontSize: 15, fontWeight: '600', flex: 1, marginRight: 8 },\n jumpButton: {\n position: 'absolute',\n right: 12,\n bottom: 12,\n width: 40,\n height: 40,\n borderRadius: 20,\n alignItems: 'center',\n justifyContent: 'center',\n shadowColor: '#0b141a',\n shadowOpacity: 0.2,\n shadowRadius: 3,\n shadowOffset: { width: 0, height: 1 },\n elevation: 3,\n },\n jumpBadge: {\n position: 'absolute',\n top: -6,\n right: -4,\n minWidth: 20,\n height: 20,\n borderRadius: 10,\n paddingHorizontal: 5,\n alignItems: 'center',\n justifyContent: 'center',\n },\n jumpBadgeText: { color: '#ffffff', fontSize: 11, fontWeight: '700' },\n swipeIcon: { position: 'absolute', left: 8, top: 0, bottom: 0, justifyContent: 'center' },\n swipeIconPlate: { width: 30, height: 30, borderRadius: 15, alignItems: 'center', justifyContent: 'center' },\n});\n"],"names":["_a"],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const MENTION_RE = /(?:^|\s)@[\p{L}\p{N}][\p{L}\p{N}._'’-]*/gu;
|
|
1
2
|
const LINK_RE = /\b(?:https?:\/\/|www\.)[^\s<>"']+/gi;
|
|
2
3
|
const TRAILING_PUNCTUATION = /[.,;:!?'"…]+$/;
|
|
3
4
|
const PAIRS = {
|
|
@@ -45,6 +46,42 @@ function splitLinks(body) {
|
|
|
45
46
|
text: body
|
|
46
47
|
}];
|
|
47
48
|
}
|
|
49
|
+
function splitChatParts(body, highlightMentions) {
|
|
50
|
+
var _a;
|
|
51
|
+
if (!highlightMentions) return splitLinks(body);
|
|
52
|
+
const parts = [];
|
|
53
|
+
for (const part of splitLinks(body)) {
|
|
54
|
+
if (part.kind !== "text") {
|
|
55
|
+
parts.push(part);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
let at = 0;
|
|
59
|
+
for (const match of part.text.matchAll(MENTION_RE)) {
|
|
60
|
+
const start = (_a = match.index) != null ? _a : 0;
|
|
61
|
+
const whole = match[0];
|
|
62
|
+
const atPos = whole.indexOf("@");
|
|
63
|
+
const token = whole.slice(atPos);
|
|
64
|
+
const lead = part.text.slice(at, start) + whole.slice(0, atPos);
|
|
65
|
+
if (lead) parts.push({
|
|
66
|
+
kind: "text",
|
|
67
|
+
text: lead
|
|
68
|
+
});
|
|
69
|
+
parts.push({
|
|
70
|
+
kind: "mention",
|
|
71
|
+
text: token
|
|
72
|
+
});
|
|
73
|
+
at = start + whole.length;
|
|
74
|
+
}
|
|
75
|
+
if (at < part.text.length) parts.push({
|
|
76
|
+
kind: "text",
|
|
77
|
+
text: part.text.slice(at)
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return parts.length ? parts : [{
|
|
81
|
+
kind: "text",
|
|
82
|
+
text: body
|
|
83
|
+
}];
|
|
84
|
+
}
|
|
48
85
|
function firstLink(body) {
|
|
49
86
|
for (const part of splitLinks(body)) if (part.kind === "link") return part.url;
|
|
50
87
|
return null;
|
|
@@ -55,10 +92,10 @@ function isOnlyALink(body) {
|
|
|
55
92
|
}
|
|
56
93
|
function autolinkBareUrls(markdown) {
|
|
57
94
|
return splitLinks(markdown).map((part, i, parts) => {
|
|
58
|
-
if (part.kind
|
|
95
|
+
if (part.kind !== "link") return part.text;
|
|
59
96
|
const before = parts[i - 1];
|
|
60
97
|
const after = parts[i + 1];
|
|
61
98
|
const wrapped = (before == null ? void 0 : before.kind) === "text" && before.text.endsWith("<") && (after == null ? void 0 : after.kind) === "text" && after.text.startsWith(">");
|
|
62
99
|
return wrapped ? part.text : `<${part.url}>`;
|
|
63
100
|
}).join("");
|
|
64
|
-
}export{autolinkBareUrls,firstLink,isOnlyALink,splitLinks};//# sourceMappingURL=chatLinks.js.map
|
|
101
|
+
}export{autolinkBareUrls,firstLink,isOnlyALink,splitChatParts,splitLinks};//# sourceMappingURL=chatLinks.js.map
|