@adminide-stack/yantra-mobile 12.0.105 → 12.0.106

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/lib/features/messaging/BlockedContactsScreen.js +127 -0
  2. package/lib/features/messaging/BlockedContactsScreen.js.map +1 -0
  3. package/lib/features/messaging/ChatAttachments.js +4 -2
  4. package/lib/features/messaging/ChatAttachments.js.map +1 -1
  5. package/lib/features/messaging/ChatComponents.js +194 -10
  6. package/lib/features/messaging/ChatComponents.js.map +1 -1
  7. package/lib/features/messaging/ChatInfoScreen.js +173 -17
  8. package/lib/features/messaging/ChatInfoScreen.js.map +1 -1
  9. package/lib/features/messaging/ConversationListScreen.js +17 -1
  10. package/lib/features/messaging/ConversationListScreen.js.map +1 -1
  11. package/lib/features/messaging/MediaGalleryScreen.js +264 -0
  12. package/lib/features/messaging/MediaGalleryScreen.js.map +1 -0
  13. package/lib/features/messaging/NativeChatExperience.js +137 -18
  14. package/lib/features/messaging/NativeChatExperience.js.map +1 -1
  15. package/lib/features/messaging/NewGroupScreen.js +191 -0
  16. package/lib/features/messaging/NewGroupScreen.js.map +1 -0
  17. package/lib/features/messaging/PollComposer.js +137 -0
  18. package/lib/features/messaging/PollComposer.js.map +1 -0
  19. package/lib/features/messaging/PollVotesScreen.js +122 -0
  20. package/lib/features/messaging/PollVotesScreen.js.map +1 -0
  21. package/lib/features/messaging/ThreadScreen.js +180 -13
  22. package/lib/features/messaging/ThreadScreen.js.map +1 -1
  23. package/lib/features/messaging/chatLinks.js +39 -2
  24. package/lib/features/messaging/chatLinks.js.map +1 -1
  25. package/lib/features/messaging/chatModel.js +186 -19
  26. package/lib/features/messaging/chatModel.js.map +1 -1
  27. package/lib/features/messaging/chatOperations.js +111 -2
  28. package/lib/features/messaging/chatOperations.js.map +1 -1
  29. package/lib/features/messaging/nativeChatChannelQuery.js +7 -2
  30. package/lib/features/messaging/nativeChatChannelQuery.js.map +1 -1
  31. package/lib/features/messaging/useChatData.js +248 -10
  32. package/lib/features/messaging/useChatData.js.map +1 -1
  33. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"ConversationListScreen.js","sources":["../../../src/features/messaging/ConversationListScreen.tsx"],"sourcesContent":["/**\n * The conversation list, WhatsApp-style: a large \"Chats\" title, search, the\n * All / Unread / Groups filter chips, and rows with ticks, mute and a green\n * unread badge.\n */\nimport * as React from 'react';\nimport {\n ActivityIndicator,\n FlatList,\n Pressable,\n RefreshControl,\n StyleSheet,\n Text,\n TextInput,\n View,\n} from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { ConnectionBanner, ConversationRow, EmptyState, InlineBanner, type ChatTheme } from './ChatComponents';\nimport {\n conversationListKey,\n dedupeConversationList,\n emptyListCopy,\n filterConversations,\n type ChatConversation,\n type ChatListFilter,\n} from './chatModel';\nimport { usePressed } from './usePressed';\nimport { ActionSheet, type SheetAction } from './ActionSheet';\nimport type { ChatConnectionState, ChatPushSeam } from './chatHost';\n\nconst FILTERS: ReadonlyArray<{ key: ChatListFilter; label: string }> = [\n { key: 'all', label: 'All' },\n { key: 'unread', label: 'Unread' },\n { key: 'groups', label: 'Groups' },\n];\n\nfunction FilterChip({\n label,\n active,\n theme,\n onPress,\n}: {\n label: string;\n active: boolean;\n theme: ChatTheme;\n onPress: () => void;\n}) {\n const [pressed, pressHandlers] = usePressed();\n const activeBg = theme.isDark ? 'rgba(0, 168, 132, 0.25)' : '#d8fdd2';\n const activeText = theme.isDark ? '#d8fdd2' : '#0b5c44';\n return (\n <Pressable\n onPress={onPress}\n {...pressHandlers}\n accessibilityRole=\"tab\"\n accessibilityState={{ selected: active }}\n style={[styles.chip, { backgroundColor: active ? activeBg : theme.surface, opacity: pressed ? 0.7 : 1 }]}\n testID={`chat-filter-${label.toLowerCase()}`}\n >\n <Text style={[styles.chipText, { color: active ? activeText : theme.textMuted }]}>{label}</Text>\n </Pressable>\n );\n}\n\nexport function ConversationListScreen({\n conversations,\n loading,\n refreshing,\n error,\n theme,\n connectionState,\n canInvite,\n onRefresh,\n onRetry,\n onOpen,\n onNewChat,\n onOpenNotifications,\n pushStatus,\n onEnablePush,\n onDismissError,\n notice = null,\n onDismissNotice,\n loadingMore = false,\n onLoadMore,\n mode = 'chats',\n archivedCount = 0,\n onOpenArchived,\n onOpenStarred,\n onBack,\n onSetListState,\n}: {\n conversations: ChatConversation[];\n loading: boolean;\n refreshing: boolean;\n loadingMore?: boolean;\n onLoadMore?: () => void;\n error: string | null;\n theme: ChatTheme;\n connectionState: ChatConnectionState;\n canInvite: boolean;\n onRefresh: () => void;\n onRetry: () => void;\n onOpen: (id: string) => void;\n onNewChat: () => void;\n /** Opens the chat notification settings; absent hides the bell. */\n onOpenNotifications?: () => void;\n /** This phone's push permission; anything but granted shows the \"Turn on notifications\" row. */\n pushStatus?: ChatPushSeam['status'];\n onEnablePush?: () => void;\n onDismissError: () => void;\n /** A one-off message that is not a load failure (e.g. an invite that could not be opened). */\n notice?: string | null;\n onDismissNotice?: () => void;\n /** The main list, or the chats the viewer archived. */\n mode?: 'chats' | 'archived';\n /** Archived chats, for the \"Archived\" row at the top of the main list. */\n archivedCount?: number;\n onOpenArchived?: () => void;\n onOpenStarred?: () => void;\n /** Archived mode's back button. */\n onBack?: () => void;\n /** Pin / archive from a row's long-press options; absent disables them. */\n onSetListState?: (channelId: string, state: { pinned?: boolean; archived?: boolean }) => void;\n}) {\n const archived = mode === 'archived';\n const [rowTarget, setRowTarget] = React.useState<ChatConversation | null>(null);\n const [menuOpen, setMenuOpen] = React.useState(false);\n const rowActions = React.useMemo<SheetAction[]>(() => {\n const target = rowTarget;\n if (!target || !onSetListState) return [];\n const list: SheetAction[] = [];\n if (!archived) {\n list.push({\n key: target.pinnedAt > 0 ? 'unpin' : 'pin',\n label: target.pinnedAt > 0 ? 'Unpin chat' : 'Pin chat',\n icon: target.pinnedAt > 0 ? 'pin-off-outline' : 'pin-outline',\n onPress: () => onSetListState(target.id, { pinned: !(target.pinnedAt > 0) }),\n });\n }\n list.push({\n key: archived ? 'unarchive' : 'archive',\n label: archived ? 'Unarchive chat' : 'Archive chat',\n icon: archived ? 'archive-arrow-up-outline' : 'archive-arrow-down-outline',\n onPress: () => onSetListState(target.id, { archived: !archived }),\n });\n return list;\n }, [rowTarget, onSetListState, archived]);\n const menuActions = React.useMemo<SheetAction[]>(() => {\n const list: SheetAction[] = [];\n if (onOpenStarred)\n list.push({ key: 'starred', label: 'Starred messages', icon: 'star-outline', onPress: onOpenStarred });\n if (onOpenArchived) {\n list.push({ key: 'archived', label: 'Archived chats', icon: 'archive-outline', onPress: onOpenArchived });\n }\n if (onOpenNotifications) {\n list.push({\n key: 'notifications',\n label: 'Notifications',\n icon: 'bell-outline',\n onPress: onOpenNotifications,\n });\n }\n return list;\n }, [onOpenStarred, onOpenArchived, onOpenNotifications]);\n const [now, setNow] = React.useState(() => Date.now());\n const [query, setQuery] = React.useState('');\n const [filter, setFilter] = React.useState<ChatListFilter>('all');\n React.useEffect(() => {\n const t = setInterval(() => setNow(Date.now()), 60_000);\n return () => clearInterval(t);\n }, []);\n\n const visible = React.useMemo(() => {\n const inMode = conversations.filter((c) => (archived ? c.archivedAt > 0 : !(c.archivedAt > 0)));\n const deduped = filterConversations(dedupeConversationList(inMode), filter);\n const q = query.trim().toLowerCase();\n if (!q) return deduped;\n return deduped.filter((c) => c.title.toLowerCase().includes(q) || c.subtitle.toLowerCase().includes(q));\n }, [conversations, query, filter, archived]);\n const narrowed = Boolean(query.trim()) || filter !== 'all';\n const empty = emptyListCopy({ searching: Boolean(query.trim()), filter, canInvite });\n let emptyAction: { label: string; onPress: () => void } | undefined;\n if (empty.action === 'all') emptyAction = { label: 'Show all chats', onPress: () => setFilter('all') };\n else if (empty.action === 'new') emptyAction = { label: 'New chat', onPress: onNewChat };\n\n const Separator = React.useCallback(\n () => <View style={[styles.separator, { backgroundColor: theme.border }]} />,\n [theme.border],\n );\n\n const listHeader = archived ? (\n // The host hides its header off the main list, so this one owns the top inset.\n <SafeAreaView edges={['top']} style={{ backgroundColor: theme.headerBg }}>\n <View style={[styles.archivedHeader, { borderBottomColor: theme.border, flexDirection: 'row' }]}>\n <Pressable\n onPress={onBack}\n hitSlop={10}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Back\"\n style={styles.headerCompose}\n testID=\"chat-archived-back\"\n >\n <MaterialCommunityIcons name=\"chevron-left\" size={32} color={theme.accent} />\n </Pressable>\n <Text style={[styles.archivedTitle, { color: theme.text }]}>Archived</Text>\n <View style={styles.headerComposeSpacer} />\n </View>\n </SafeAreaView>\n ) : (\n <View style={[styles.listHeader, { flexDirection: 'row', alignItems: 'center' }]}>\n <Text style={[styles.listTitle, { color: theme.text }]}>Chats</Text>\n <View style={{ flexDirection: 'row', alignItems: 'center' }}>\n {menuActions.length ? (\n <Pressable\n onPress={() => setMenuOpen(true)}\n accessibilityRole=\"button\"\n accessibilityLabel=\"More\"\n style={styles.headerCompose}\n testID=\"chat-list-menu\"\n >\n <MaterialCommunityIcons name=\"dots-horizontal-circle-outline\" size={26} color={theme.accent} />\n </Pressable>\n ) : null}\n {canInvite ? (\n <Pressable\n onPress={onNewChat}\n accessibilityRole=\"button\"\n accessibilityLabel=\"New chat\"\n style={styles.headerCompose}\n testID=\"chat-new\"\n >\n <View style={[styles.composeDot, { backgroundColor: theme.accent }]}>\n <MaterialCommunityIcons name=\"plus\" size={20} color={theme.onAccent} />\n </View>\n </Pressable>\n ) : (\n <View style={styles.headerComposeSpacer} />\n )}\n </View>\n </View>\n );\n\n return (\n <View style={[styles.fill, { backgroundColor: theme.bg }]}>\n {listHeader}\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\"\n placeholderTextColor={theme.textMuted}\n style={[styles.searchInput, { color: theme.text }]}\n testID=\"chat-search\"\n />\n </View>\n {archived ? (\n <Text style={[styles.archivedNote, { color: theme.textMuted }]}>\n Archived chats stay here when new messages arrive. Unarchive one to put it back in Chats.\n </Text>\n ) : null}\n <View style={[styles.chips, { flexDirection: 'row' }, archived && styles.hidden]}>\n {FILTERS.map((f) => (\n <FilterChip\n key={f.key}\n label={f.label}\n active={filter === f.key}\n theme={theme}\n onPress={() => setFilter(f.key)}\n />\n ))}\n </View>\n\n {!archived && onEnablePush && (pushStatus === 'undetermined' || pushStatus === 'denied') ? (\n <Pressable\n onPress={pushStatus === 'denied' && onOpenNotifications ? onOpenNotifications : onEnablePush}\n accessibilityRole=\"button\"\n style={[styles.pushRow, { backgroundColor: theme.isDark ? '#103629' : '#e7fce3' }]}\n testID=\"chat-push-banner\"\n >\n <View style={{ flexDirection: 'row', alignItems: 'center' }}>\n <MaterialCommunityIcons name=\"bell-ring-outline\" size={22} color={theme.accent} />\n <View style={{ flex: 1, marginLeft: 12 }}>\n <Text style={[styles.pushTitle, { color: theme.text }]}>Turn on notifications</Text>\n <Text style={[styles.pushDetail, { color: theme.textMuted }]}>\n Get notified about new messages.\n </Text>\n </View>\n <MaterialCommunityIcons name=\"chevron-right\" size={22} color={theme.textMuted} />\n </View>\n </Pressable>\n ) : null}\n <ConnectionBanner state={connectionState} theme={theme} />\n <InlineBanner message={error} theme={theme} onDismiss={onDismissError} />\n <InlineBanner message={notice} theme={theme} onDismiss={() => onDismissNotice?.()} />\n {error ? (\n <Pressable\n onPress={onRetry}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Retry loading chats\"\n style={[styles.retryBanner, { backgroundColor: theme.surface }]}\n >\n <Text style={[styles.retryBannerText, { color: theme.accent }]}>Retry loading chats</Text>\n </Pressable>\n ) : null}\n\n {loading && conversations.length === 0 ? (\n <View style={styles.center}>\n <ActivityIndicator color={theme.accent} />\n </View>\n ) : (\n <FlatList\n data={visible}\n keyExtractor={(c) => conversationListKey(c)}\n ItemSeparatorComponent={Separator}\n ListHeaderComponent={\n !archived && archivedCount > 0 && onOpenArchived ? (\n <Pressable\n onPress={onOpenArchived}\n accessibilityRole=\"button\"\n accessibilityLabel={`Archived, ${archivedCount} chats`}\n testID=\"chat-archived-row\"\n >\n <View style={[styles.archivedRow, { flexDirection: 'row' }]}>\n <View style={styles.archivedIcon}>\n <MaterialCommunityIcons\n name=\"archive-outline\"\n size={22}\n color={theme.textMuted}\n />\n </View>\n <Text style={[styles.archivedLabel, { color: theme.text }]}>Archived</Text>\n <Text style={{ color: theme.accent, fontSize: 14 }}>{archivedCount}</Text>\n </View>\n </Pressable>\n ) : null\n }\n renderItem={({ item }) => (\n <ConversationRow\n conversation={item}\n theme={theme}\n now={now}\n onPress={() => onOpen(item.id)}\n onLongPress={onSetListState ? () => setRowTarget(item) : undefined}\n />\n )}\n refreshControl={\n <RefreshControl refreshing={refreshing} onRefresh={onRefresh} tintColor={theme.textMuted} />\n }\n // Paging would skip rows while a search or a filter chip is hiding most of them.\n onEndReached={narrowed ? undefined : onLoadMore}\n onEndReachedThreshold={0.5}\n ListFooterComponent={\n loadingMore ? <ActivityIndicator style={styles.moreSpinner} color={theme.accent} /> : null\n }\n contentContainerStyle={visible.length === 0 ? styles.fill : undefined}\n ListEmptyComponent={\n <EmptyState\n icon=\"message-text-outline\"\n title={empty.title}\n detail={empty.detail}\n theme={theme}\n action={emptyAction}\n />\n }\n testID=\"chat-conversation-list\"\n />\n )}\n <ActionSheet\n visible={Boolean(rowTarget)}\n title={rowTarget?.title}\n actions={rowActions}\n theme={theme}\n onClose={() => setRowTarget(null)}\n testID=\"chat-row-sheet\"\n />\n <ActionSheet\n visible={menuOpen}\n actions={menuActions}\n theme={theme}\n onClose={() => setMenuOpen(false)}\n testID=\"chat-list-menu-sheet\"\n />\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n fill: { flex: 1 },\n center: { flex: 1, alignItems: 'center', justifyContent: 'center' },\n moreSpinner: { paddingVertical: 16 },\n listHeader: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingHorizontal: 16,\n paddingTop: 4,\n paddingBottom: 4,\n },\n listTitle: { fontSize: 34, fontWeight: '700', letterSpacing: 0.35 },\n headerCompose: {\n width: 44,\n height: 44,\n alignItems: 'center',\n justifyContent: 'center',\n },\n headerComposeSpacer: { width: 44 },\n archivedHeader: {\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingHorizontal: 4,\n minHeight: 52,\n borderBottomWidth: StyleSheet.hairlineWidth,\n marginBottom: 8,\n },\n archivedTitle: { fontSize: 17, fontWeight: '600' },\n archivedNote: { fontSize: 13, lineHeight: 18, textAlign: 'center', marginHorizontal: 32, marginBottom: 8 },\n hidden: { display: 'none' },\n archivedRow: { alignItems: 'center', paddingHorizontal: 16, minHeight: 48 },\n archivedIcon: { width: 52, alignItems: 'center' },\n archivedLabel: { flex: 1, fontSize: 16, fontWeight: '600', marginLeft: 14 },\n pushRow: { marginHorizontal: 16, marginBottom: 8, borderRadius: 12, paddingHorizontal: 14, paddingVertical: 12 },\n pushTitle: { fontSize: 15, fontWeight: '600' },\n pushDetail: { fontSize: 13, marginTop: 1 },\n composeDot: { width: 28, height: 28, borderRadius: 14, alignItems: 'center', justifyContent: 'center' },\n chips: { paddingHorizontal: 16, paddingBottom: 8, paddingTop: 2 },\n chip: { paddingHorizontal: 14, height: 32, borderRadius: 16, justifyContent: 'center', marginRight: 8 },\n chipText: { fontSize: 14, fontWeight: '500' },\n searchWrap: {\n flexDirection: 'row',\n alignItems: 'center',\n marginHorizontal: 16,\n marginBottom: 6,\n borderRadius: 10,\n paddingHorizontal: 10,\n height: 36,\n },\n searchInput: { flex: 1, marginLeft: 8, fontSize: 16, paddingVertical: 0 },\n separator: { height: StyleSheet.hairlineWidth, marginLeft: 82 },\n retryBanner: { alignItems: 'center', paddingVertical: 10 },\n retryBannerText: { fontSize: 14, fontWeight: '600' },\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ConversationListScreen.js","sources":["../../../src/features/messaging/ConversationListScreen.tsx"],"sourcesContent":["/**\n * The conversation list, WhatsApp-style: a large \"Chats\" title, search, the\n * All / Unread / Groups filter chips, and rows with ticks, mute and a green\n * unread badge.\n */\nimport * as React from 'react';\nimport {\n ActivityIndicator,\n FlatList,\n Pressable,\n RefreshControl,\n StyleSheet,\n Text,\n TextInput,\n View,\n} from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { ConnectionBanner, ConversationRow, EmptyState, InlineBanner, type ChatTheme } from './ChatComponents';\nimport {\n conversationListKey,\n dedupeConversationList,\n emptyListCopy,\n filterConversations,\n type ChatConversation,\n type ChatListFilter,\n} from './chatModel';\nimport { usePressed } from './usePressed';\nimport { ActionSheet, type SheetAction } from './ActionSheet';\nimport type { ChatConnectionState, ChatPushSeam } from './chatHost';\n\nconst FILTERS: ReadonlyArray<{ key: ChatListFilter; label: string }> = [\n { key: 'all', label: 'All' },\n { key: 'unread', label: 'Unread' },\n { key: 'groups', label: 'Groups' },\n];\n\nfunction FilterChip({\n label,\n active,\n theme,\n onPress,\n}: {\n label: string;\n active: boolean;\n theme: ChatTheme;\n onPress: () => void;\n}) {\n const [pressed, pressHandlers] = usePressed();\n const activeBg = theme.isDark ? 'rgba(0, 168, 132, 0.25)' : '#d8fdd2';\n const activeText = theme.isDark ? '#d8fdd2' : '#0b5c44';\n return (\n <Pressable\n onPress={onPress}\n {...pressHandlers}\n accessibilityRole=\"tab\"\n accessibilityState={{ selected: active }}\n style={[styles.chip, { backgroundColor: active ? activeBg : theme.surface, opacity: pressed ? 0.7 : 1 }]}\n testID={`chat-filter-${label.toLowerCase()}`}\n >\n <Text style={[styles.chipText, { color: active ? activeText : theme.textMuted }]}>{label}</Text>\n </Pressable>\n );\n}\n\nexport function ConversationListScreen({\n conversations,\n loading,\n refreshing,\n error,\n theme,\n connectionState,\n canInvite,\n onRefresh,\n onRetry,\n onOpen,\n onNewChat,\n onNewGroup,\n onOpenNotifications,\n pushStatus,\n onEnablePush,\n onDismissError,\n notice = null,\n onDismissNotice,\n loadingMore = false,\n onLoadMore,\n mode = 'chats',\n archivedCount = 0,\n onOpenArchived,\n onOpenStarred,\n onOpenBlocked,\n onBack,\n onSetListState,\n}: {\n conversations: ChatConversation[];\n loading: boolean;\n refreshing: boolean;\n loadingMore?: boolean;\n onLoadMore?: () => void;\n error: string | null;\n theme: ChatTheme;\n connectionState: ChatConnectionState;\n canInvite: boolean;\n onRefresh: () => void;\n onRetry: () => void;\n onOpen: (id: string) => void;\n onNewChat: () => void;\n /** Open the New group flow (from the list menu). */\n onNewGroup?: () => void;\n /** Opens the chat notification settings; absent hides the bell. */\n onOpenNotifications?: () => void;\n /** This phone's push permission; anything but granted shows the \"Turn on notifications\" row. */\n pushStatus?: ChatPushSeam['status'];\n onEnablePush?: () => void;\n onDismissError: () => void;\n /** A one-off message that is not a load failure (e.g. an invite that could not be opened). */\n notice?: string | null;\n onDismissNotice?: () => void;\n /** The main list, or the chats the viewer archived. */\n mode?: 'chats' | 'archived';\n /** Archived chats, for the \"Archived\" row at the top of the main list. */\n archivedCount?: number;\n onOpenArchived?: () => void;\n onOpenStarred?: () => void;\n /** Open the blocked-contacts privacy list from the overflow menu. */\n onOpenBlocked?: () => void;\n /** Archived mode's back button. */\n onBack?: () => void;\n /** Pin / archive from a row's long-press options; absent disables them. */\n onSetListState?: (channelId: string, state: { pinned?: boolean; archived?: boolean }) => void;\n}) {\n const archived = mode === 'archived';\n const [rowTarget, setRowTarget] = React.useState<ChatConversation | null>(null);\n const [menuOpen, setMenuOpen] = React.useState(false);\n const rowActions = React.useMemo<SheetAction[]>(() => {\n const target = rowTarget;\n if (!target || !onSetListState) return [];\n const list: SheetAction[] = [];\n if (!archived) {\n list.push({\n key: target.pinnedAt > 0 ? 'unpin' : 'pin',\n label: target.pinnedAt > 0 ? 'Unpin chat' : 'Pin chat',\n icon: target.pinnedAt > 0 ? 'pin-off-outline' : 'pin-outline',\n onPress: () => onSetListState(target.id, { pinned: !(target.pinnedAt > 0) }),\n });\n }\n list.push({\n key: archived ? 'unarchive' : 'archive',\n label: archived ? 'Unarchive chat' : 'Archive chat',\n icon: archived ? 'archive-arrow-up-outline' : 'archive-arrow-down-outline',\n onPress: () => onSetListState(target.id, { archived: !archived }),\n });\n return list;\n }, [rowTarget, onSetListState, archived]);\n const menuActions = React.useMemo<SheetAction[]>(() => {\n const list: SheetAction[] = [];\n if (onNewGroup)\n list.push({ key: 'new-group', label: 'New group', icon: 'account-group-outline', onPress: onNewGroup });\n if (onOpenStarred)\n list.push({ key: 'starred', label: 'Starred messages', icon: 'star-outline', onPress: onOpenStarred });\n if (onOpenArchived) {\n list.push({ key: 'archived', label: 'Archived chats', icon: 'archive-outline', onPress: onOpenArchived });\n }\n if (onOpenBlocked) {\n list.push({\n key: 'blocked',\n label: 'Blocked contacts',\n icon: 'account-cancel-outline',\n onPress: onOpenBlocked,\n });\n }\n if (onOpenNotifications) {\n list.push({\n key: 'notifications',\n label: 'Notifications',\n icon: 'bell-outline',\n onPress: onOpenNotifications,\n });\n }\n return list;\n }, [onNewGroup, onOpenStarred, onOpenArchived, onOpenBlocked, onOpenNotifications]);\n const [now, setNow] = React.useState(() => Date.now());\n const [query, setQuery] = React.useState('');\n const [filter, setFilter] = React.useState<ChatListFilter>('all');\n React.useEffect(() => {\n const t = setInterval(() => setNow(Date.now()), 60_000);\n return () => clearInterval(t);\n }, []);\n\n const visible = React.useMemo(() => {\n const inMode = conversations.filter((c) => (archived ? c.archivedAt > 0 : !(c.archivedAt > 0)));\n const deduped = filterConversations(dedupeConversationList(inMode), filter);\n const q = query.trim().toLowerCase();\n if (!q) return deduped;\n return deduped.filter((c) => c.title.toLowerCase().includes(q) || c.subtitle.toLowerCase().includes(q));\n }, [conversations, query, filter, archived]);\n const narrowed = Boolean(query.trim()) || filter !== 'all';\n const empty = emptyListCopy({ searching: Boolean(query.trim()), filter, canInvite });\n let emptyAction: { label: string; onPress: () => void } | undefined;\n if (empty.action === 'all') emptyAction = { label: 'Show all chats', onPress: () => setFilter('all') };\n else if (empty.action === 'new') emptyAction = { label: 'New chat', onPress: onNewChat };\n\n const Separator = React.useCallback(\n () => <View style={[styles.separator, { backgroundColor: theme.border }]} />,\n [theme.border],\n );\n\n const listHeader = archived ? (\n // The host hides its header off the main list, so this one owns the top inset.\n <SafeAreaView edges={['top']} style={{ backgroundColor: theme.headerBg }}>\n <View style={[styles.archivedHeader, { borderBottomColor: theme.border, flexDirection: 'row' }]}>\n <Pressable\n onPress={onBack}\n hitSlop={10}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Back\"\n style={styles.headerCompose}\n testID=\"chat-archived-back\"\n >\n <MaterialCommunityIcons name=\"chevron-left\" size={32} color={theme.accent} />\n </Pressable>\n <Text style={[styles.archivedTitle, { color: theme.text }]}>Archived</Text>\n <View style={styles.headerComposeSpacer} />\n </View>\n </SafeAreaView>\n ) : (\n <View style={[styles.listHeader, { flexDirection: 'row', alignItems: 'center' }]}>\n <Text style={[styles.listTitle, { color: theme.text }]}>Chats</Text>\n <View style={{ flexDirection: 'row', alignItems: 'center' }}>\n {menuActions.length ? (\n <Pressable\n onPress={() => setMenuOpen(true)}\n accessibilityRole=\"button\"\n accessibilityLabel=\"More\"\n style={styles.headerCompose}\n testID=\"chat-list-menu\"\n >\n <MaterialCommunityIcons name=\"dots-horizontal-circle-outline\" size={26} color={theme.accent} />\n </Pressable>\n ) : null}\n {canInvite ? (\n <Pressable\n onPress={onNewChat}\n accessibilityRole=\"button\"\n accessibilityLabel=\"New chat\"\n style={styles.headerCompose}\n testID=\"chat-new\"\n >\n <View style={[styles.composeDot, { backgroundColor: theme.accent }]}>\n <MaterialCommunityIcons name=\"plus\" size={20} color={theme.onAccent} />\n </View>\n </Pressable>\n ) : (\n <View style={styles.headerComposeSpacer} />\n )}\n </View>\n </View>\n );\n\n return (\n <View style={[styles.fill, { backgroundColor: theme.bg }]}>\n {listHeader}\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\"\n placeholderTextColor={theme.textMuted}\n style={[styles.searchInput, { color: theme.text }]}\n testID=\"chat-search\"\n />\n </View>\n {archived ? (\n <Text style={[styles.archivedNote, { color: theme.textMuted }]}>\n Archived chats stay here when new messages arrive. Unarchive one to put it back in Chats.\n </Text>\n ) : null}\n <View style={[styles.chips, { flexDirection: 'row' }, archived && styles.hidden]}>\n {FILTERS.map((f) => (\n <FilterChip\n key={f.key}\n label={f.label}\n active={filter === f.key}\n theme={theme}\n onPress={() => setFilter(f.key)}\n />\n ))}\n </View>\n\n {!archived && onEnablePush && (pushStatus === 'undetermined' || pushStatus === 'denied') ? (\n <Pressable\n onPress={pushStatus === 'denied' && onOpenNotifications ? onOpenNotifications : onEnablePush}\n accessibilityRole=\"button\"\n style={[styles.pushRow, { backgroundColor: theme.isDark ? '#103629' : '#e7fce3' }]}\n testID=\"chat-push-banner\"\n >\n <View style={{ flexDirection: 'row', alignItems: 'center' }}>\n <MaterialCommunityIcons name=\"bell-ring-outline\" size={22} color={theme.accent} />\n <View style={{ flex: 1, marginLeft: 12 }}>\n <Text style={[styles.pushTitle, { color: theme.text }]}>Turn on notifications</Text>\n <Text style={[styles.pushDetail, { color: theme.textMuted }]}>\n Get notified about new messages.\n </Text>\n </View>\n <MaterialCommunityIcons name=\"chevron-right\" size={22} color={theme.textMuted} />\n </View>\n </Pressable>\n ) : null}\n <ConnectionBanner state={connectionState} theme={theme} />\n <InlineBanner message={error} theme={theme} onDismiss={onDismissError} />\n <InlineBanner message={notice} theme={theme} onDismiss={() => onDismissNotice?.()} />\n {error ? (\n <Pressable\n onPress={onRetry}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Retry loading chats\"\n style={[styles.retryBanner, { backgroundColor: theme.surface }]}\n >\n <Text style={[styles.retryBannerText, { color: theme.accent }]}>Retry loading chats</Text>\n </Pressable>\n ) : null}\n\n {loading && conversations.length === 0 ? (\n <View style={styles.center}>\n <ActivityIndicator color={theme.accent} />\n </View>\n ) : (\n <FlatList\n data={visible}\n keyExtractor={(c) => conversationListKey(c)}\n ItemSeparatorComponent={Separator}\n ListHeaderComponent={\n !archived && archivedCount > 0 && onOpenArchived ? (\n <Pressable\n onPress={onOpenArchived}\n accessibilityRole=\"button\"\n accessibilityLabel={`Archived, ${archivedCount} chats`}\n testID=\"chat-archived-row\"\n >\n <View style={[styles.archivedRow, { flexDirection: 'row' }]}>\n <View style={styles.archivedIcon}>\n <MaterialCommunityIcons\n name=\"archive-outline\"\n size={22}\n color={theme.textMuted}\n />\n </View>\n <Text style={[styles.archivedLabel, { color: theme.text }]}>Archived</Text>\n <Text style={{ color: theme.accent, fontSize: 14 }}>{archivedCount}</Text>\n </View>\n </Pressable>\n ) : null\n }\n renderItem={({ item }) => (\n <ConversationRow\n conversation={item}\n theme={theme}\n now={now}\n onPress={() => onOpen(item.id)}\n onLongPress={onSetListState ? () => setRowTarget(item) : undefined}\n />\n )}\n refreshControl={\n <RefreshControl refreshing={refreshing} onRefresh={onRefresh} tintColor={theme.textMuted} />\n }\n // Paging would skip rows while a search or a filter chip is hiding most of them.\n onEndReached={narrowed ? undefined : onLoadMore}\n onEndReachedThreshold={0.5}\n ListFooterComponent={\n loadingMore ? <ActivityIndicator style={styles.moreSpinner} color={theme.accent} /> : null\n }\n contentContainerStyle={visible.length === 0 ? styles.fill : undefined}\n ListEmptyComponent={\n <EmptyState\n icon=\"message-text-outline\"\n title={empty.title}\n detail={empty.detail}\n theme={theme}\n action={emptyAction}\n />\n }\n testID=\"chat-conversation-list\"\n />\n )}\n <ActionSheet\n visible={Boolean(rowTarget)}\n title={rowTarget?.title}\n actions={rowActions}\n theme={theme}\n onClose={() => setRowTarget(null)}\n testID=\"chat-row-sheet\"\n />\n <ActionSheet\n visible={menuOpen}\n actions={menuActions}\n theme={theme}\n onClose={() => setMenuOpen(false)}\n testID=\"chat-list-menu-sheet\"\n />\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n fill: { flex: 1 },\n center: { flex: 1, alignItems: 'center', justifyContent: 'center' },\n moreSpinner: { paddingVertical: 16 },\n listHeader: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingHorizontal: 16,\n paddingTop: 4,\n paddingBottom: 4,\n },\n listTitle: { fontSize: 34, fontWeight: '700', letterSpacing: 0.35 },\n headerCompose: {\n width: 44,\n height: 44,\n alignItems: 'center',\n justifyContent: 'center',\n },\n headerComposeSpacer: { width: 44 },\n archivedHeader: {\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingHorizontal: 4,\n minHeight: 52,\n borderBottomWidth: StyleSheet.hairlineWidth,\n marginBottom: 8,\n },\n archivedTitle: { fontSize: 17, fontWeight: '600' },\n archivedNote: { fontSize: 13, lineHeight: 18, textAlign: 'center', marginHorizontal: 32, marginBottom: 8 },\n hidden: { display: 'none' },\n archivedRow: { alignItems: 'center', paddingHorizontal: 16, minHeight: 48 },\n archivedIcon: { width: 52, alignItems: 'center' },\n archivedLabel: { flex: 1, fontSize: 16, fontWeight: '600', marginLeft: 14 },\n pushRow: { marginHorizontal: 16, marginBottom: 8, borderRadius: 12, paddingHorizontal: 14, paddingVertical: 12 },\n pushTitle: { fontSize: 15, fontWeight: '600' },\n pushDetail: { fontSize: 13, marginTop: 1 },\n composeDot: { width: 28, height: 28, borderRadius: 14, alignItems: 'center', justifyContent: 'center' },\n chips: { paddingHorizontal: 16, paddingBottom: 8, paddingTop: 2 },\n chip: { paddingHorizontal: 14, height: 32, borderRadius: 16, justifyContent: 'center', marginRight: 8 },\n chipText: { fontSize: 14, fontWeight: '500' },\n searchWrap: {\n flexDirection: 'row',\n alignItems: 'center',\n marginHorizontal: 16,\n marginBottom: 6,\n borderRadius: 10,\n paddingHorizontal: 10,\n height: 36,\n },\n searchInput: { flex: 1, marginLeft: 8, fontSize: 16, paddingVertical: 0 },\n separator: { height: StyleSheet.hairlineWidth, marginLeft: 82 },\n retryBanner: { alignItems: 'center', paddingVertical: 10 },\n retryBannerText: { fontSize: 14, fontWeight: '600' },\n});\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,264 @@
1
+ import {jsxs,jsx}from'react/jsx-runtime';import*as React from'react';import {StyleSheet,Dimensions,View,Pressable,Text,ActivityIndicator,FlatList}from'react-native';import {SafeAreaView}from'react-native-safe-area-context';import {Image}from'expo-image';import {MaterialCommunityIcons}from'@expo/vector-icons';import {InlineBanner,EmptyState}from'./ChatComponents.js';import {useLinkPreview,LinkPreviewCard}from'./LinkPreviewCard.js';import {toChatMessage,toChatAttachments,attachmentUrl}from'./chatModel.js';import {firstLink}from'./chatLinks.js';import {MEDIA_MESSAGES_QUERY}from'./chatOperations.js';const TABS = [{
2
+ key: "media",
3
+ label: "Media"
4
+ }, {
5
+ key: "links",
6
+ label: "Links"
7
+ }, {
8
+ key: "docs",
9
+ label: "Docs"
10
+ }];
11
+ const GRID_COLS = 3;
12
+ const GRID_GAP = 2;
13
+ function LinkRow({
14
+ url,
15
+ theme,
16
+ loader,
17
+ onOpen
18
+ }) {
19
+ const preview = useLinkPreview(url, loader);
20
+ if (preview) {
21
+ return /* @__PURE__ */ jsx(View, { style: styles.linkRow, children: /* @__PURE__ */ jsx(LinkPreviewCard, { preview, theme, onOpen }) });
22
+ }
23
+ return /* @__PURE__ */ jsxs(Pressable, { onPress: onOpen ? () => onOpen(url) : void 0, style: [styles.linkFallback, {
24
+ borderColor: theme.border
25
+ }], accessibilityRole: "link", children: [
26
+ /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "link-variant", size: 18, color: theme.accent }),
27
+ /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: [styles.linkFallbackText, {
28
+ color: theme.accent
29
+ }], children: url })
30
+ ] });
31
+ }
32
+ function MediaGalleryScreen({
33
+ gql,
34
+ channelId,
35
+ viewerId,
36
+ theme,
37
+ fileBaseUrl,
38
+ linkPreviews,
39
+ onOpenLink,
40
+ onOpenImage,
41
+ onBack
42
+ }) {
43
+ const [tab, setTab] = React.useState("media");
44
+ const [error, setError] = React.useState(null);
45
+ const [media, setMedia] = React.useState(null);
46
+ const [links, setLinks] = React.useState(null);
47
+ const [docs, setDocs] = React.useState(null);
48
+ const cellSize = Math.floor((Dimensions.get("window").width - GRID_GAP * (GRID_COLS - 1)) / GRID_COLS);
49
+ const load = React.useCallback(async (which) => {
50
+ var _a, _b, _c, _d, _e, _f, _g;
51
+ const res = await gql.query(MEDIA_MESSAGES_QUERY, {
52
+ channelId,
53
+ kind: which,
54
+ limit: 100,
55
+ skip: 0
56
+ }, {
57
+ fetchPolicy: "network-only"
58
+ }).catch(() => null);
59
+ if ((_a = res == null ? void 0 : res.errors) == null ? void 0 : _a.length) setError("Couldn\u2019t load this gallery.");
60
+ const posts = ((_d = (_c = (_b = res == null ? void 0 : res.data) == null ? void 0 : _b.mediaMessages) == null ? void 0 : _c.data) != null ? _d : []).filter((p) => Boolean(p == null ? void 0 : p.id));
61
+ if (which === "links") {
62
+ setLinks(posts.map((p) => {
63
+ var _a2, _b2, _c2;
64
+ const message = toChatMessage(p, viewerId);
65
+ const url = firstLink(message.body);
66
+ return url ? {
67
+ messageId: message.id,
68
+ channelId: String((_c2 = (_b2 = (_a2 = p.channel) == null ? void 0 : _a2.id) != null ? _b2 : channelId) != null ? _c2 : ""),
69
+ url
70
+ } : null;
71
+ }).filter((x) => Boolean(x)));
72
+ return;
73
+ }
74
+ const items = [];
75
+ for (const p of posts) {
76
+ const cid = String((_g = (_f = (_e = p.channel) == null ? void 0 : _e.id) != null ? _f : channelId) != null ? _g : "");
77
+ for (const attachment of toChatAttachments(p)) {
78
+ if (which === "media" && attachment.kind === "image") items.push({
79
+ messageId: p.id,
80
+ channelId: cid,
81
+ attachment
82
+ });
83
+ if (which === "docs" && attachment.kind === "file") items.push({
84
+ messageId: p.id,
85
+ channelId: cid,
86
+ attachment
87
+ });
88
+ }
89
+ }
90
+ if (which === "media") setMedia(items);
91
+ else setDocs(items);
92
+ }, [gql, channelId, viewerId]);
93
+ React.useEffect(() => {
94
+ if (tab === "media" && media === null) void load("media");
95
+ if (tab === "links" && links === null) void load("links");
96
+ if (tab === "docs" && docs === null) void load("docs");
97
+ }, [tab, media, links, docs, load]);
98
+ const loaded = () => {
99
+ if (tab === "media") return media;
100
+ if (tab === "docs") return docs;
101
+ return links;
102
+ };
103
+ const renderMediaList = () => {
104
+ var _a;
105
+ return /* @__PURE__ */ jsx(FlatList, { data: media != null ? media : [], numColumns: GRID_COLS, keyExtractor: (m) => m.attachment.id, contentContainerStyle: ((_a = media == null ? void 0 : media.length) != null ? _a : 0) ? void 0 : styles.fill, ListEmptyComponent: /* @__PURE__ */ jsx(EmptyState, { icon: "image-off-outline", title: "No media", detail: "Photos and videos in this chat show here.", theme }), renderItem: ({
106
+ item,
107
+ index
108
+ }) => /* @__PURE__ */ jsx(Pressable, { onPress: () => onOpenImage == null ? void 0 : onOpenImage(attachmentUrl(item.attachment, fileBaseUrl)), style: {
109
+ width: cellSize,
110
+ height: cellSize,
111
+ marginRight: (index + 1) % GRID_COLS === 0 ? 0 : GRID_GAP,
112
+ marginBottom: GRID_GAP
113
+ }, accessibilityRole: "imagebutton", accessibilityLabel: "Open photo", children: /* @__PURE__ */ jsx(Image, { source: {
114
+ uri: item.attachment.url
115
+ }, style: {
116
+ width: cellSize,
117
+ height: cellSize,
118
+ backgroundColor: theme.surface
119
+ }, contentFit: "cover", transition: 120 }) }) }, "media");
120
+ };
121
+ const renderDocsList = () => {
122
+ var _a;
123
+ return /* @__PURE__ */ jsx(FlatList, { data: docs != null ? docs : [], keyExtractor: (m) => m.attachment.id, contentContainerStyle: ((_a = docs == null ? void 0 : docs.length) != null ? _a : 0) ? void 0 : styles.fill, ListEmptyComponent: /* @__PURE__ */ jsx(EmptyState, { icon: "file-outline", title: "No docs", detail: "Documents shared in this chat show here.", theme }), renderItem: ({
124
+ item
125
+ }) => /* @__PURE__ */ jsxs(Pressable, { onPress: () => onOpenLink == null ? void 0 : onOpenLink(attachmentUrl(item.attachment, fileBaseUrl)), style: [styles.docRow, {
126
+ borderBottomColor: theme.border,
127
+ flexDirection: "row"
128
+ }], accessibilityRole: "button", accessibilityLabel: `Open ${item.attachment.name}`, children: [
129
+ /* @__PURE__ */ jsx(View, { style: [styles.docIcon, {
130
+ backgroundColor: theme.surface
131
+ }], children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "file-document-outline", size: 22, color: theme.accent }) }),
132
+ /* @__PURE__ */ jsx(View, { style: {
133
+ flex: 1
134
+ }, children: /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: [styles.docName, {
135
+ color: theme.text
136
+ }], children: item.attachment.name }) })
137
+ ] }) }, "docs");
138
+ };
139
+ const renderLinksList = () => {
140
+ var _a;
141
+ return /* @__PURE__ */ jsx(FlatList, { data: links != null ? links : [], keyExtractor: (l, i) => `${l.messageId}-${i}`, contentContainerStyle: ((_a = links == null ? void 0 : links.length) != null ? _a : 0) ? styles.linkList : styles.fill, ListEmptyComponent: /* @__PURE__ */ jsx(EmptyState, { icon: "link-off", title: "No links", detail: "Links shared in this chat show here.", theme }), renderItem: ({
142
+ item
143
+ }) => /* @__PURE__ */ jsx(LinkRow, { url: item.url, theme, loader: linkPreviews, onOpen: onOpenLink }) }, "links");
144
+ };
145
+ const renderBody = () => {
146
+ if (loaded() === null) {
147
+ return /* @__PURE__ */ jsx(View, { style: styles.center, children: /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.accent }) });
148
+ }
149
+ if (tab === "media") return renderMediaList();
150
+ if (tab === "docs") return renderDocsList();
151
+ return renderLinksList();
152
+ };
153
+ return /* @__PURE__ */ jsxs(View, { style: [styles.fill, {
154
+ backgroundColor: theme.bg
155
+ }], testID: "chat-media-gallery", children: [
156
+ /* @__PURE__ */ jsxs(SafeAreaView, { edges: ["top"], style: {
157
+ backgroundColor: theme.headerBg
158
+ }, children: [
159
+ /* @__PURE__ */ jsxs(View, { style: [styles.header, {
160
+ borderBottomColor: theme.border,
161
+ flexDirection: "row"
162
+ }], children: [
163
+ /* @__PURE__ */ jsx(Pressable, { onPress: onBack, hitSlop: 10, accessibilityRole: "button", accessibilityLabel: "Back", style: styles.headerIcon, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "chevron-left", size: 32, color: theme.accent }) }),
164
+ /* @__PURE__ */ jsx(Text, { style: [styles.title, {
165
+ color: theme.text
166
+ }], children: "Media, links and docs" }),
167
+ /* @__PURE__ */ jsx(View, { style: styles.headerIcon })
168
+ ] }),
169
+ /* @__PURE__ */ jsx(View, { style: [styles.tabs, {
170
+ flexDirection: "row"
171
+ }], children: TABS.map((t) => {
172
+ const active = t.key === tab;
173
+ return /* @__PURE__ */ jsx(Pressable, { onPress: () => setTab(t.key), style: [styles.tab, active && {
174
+ borderBottomColor: theme.accent
175
+ }], accessibilityRole: "tab", accessibilityState: {
176
+ selected: active
177
+ }, children: /* @__PURE__ */ jsx(Text, { style: [styles.tabText, {
178
+ color: active ? theme.accent : theme.textMuted
179
+ }], children: t.label }) }, t.key);
180
+ }) })
181
+ ] }),
182
+ /* @__PURE__ */ jsx(InlineBanner, { message: error, theme, onDismiss: () => setError(null) }),
183
+ renderBody()
184
+ ] });
185
+ }
186
+ const styles = StyleSheet.create({
187
+ fill: {
188
+ flex: 1
189
+ },
190
+ center: {
191
+ flex: 1,
192
+ alignItems: "center",
193
+ justifyContent: "center"
194
+ },
195
+ header: {
196
+ alignItems: "center",
197
+ justifyContent: "space-between",
198
+ paddingHorizontal: 4,
199
+ minHeight: 52,
200
+ borderBottomWidth: StyleSheet.hairlineWidth
201
+ },
202
+ headerIcon: {
203
+ width: 44,
204
+ height: 44,
205
+ alignItems: "center",
206
+ justifyContent: "center"
207
+ },
208
+ title: {
209
+ fontSize: 17,
210
+ fontWeight: "600"
211
+ },
212
+ tabs: {
213
+ alignItems: "stretch"
214
+ },
215
+ tab: {
216
+ flex: 1,
217
+ alignItems: "center",
218
+ paddingVertical: 12,
219
+ borderBottomWidth: 2,
220
+ borderBottomColor: "transparent"
221
+ },
222
+ tabText: {
223
+ fontSize: 14,
224
+ fontWeight: "600"
225
+ },
226
+ docRow: {
227
+ alignItems: "center",
228
+ paddingHorizontal: 16,
229
+ paddingVertical: 10,
230
+ borderBottomWidth: StyleSheet.hairlineWidth
231
+ },
232
+ docIcon: {
233
+ width: 40,
234
+ height: 40,
235
+ borderRadius: 8,
236
+ alignItems: "center",
237
+ justifyContent: "center",
238
+ marginRight: 12
239
+ },
240
+ docName: {
241
+ fontSize: 15,
242
+ fontWeight: "500"
243
+ },
244
+ linkList: {
245
+ padding: 12
246
+ },
247
+ linkRow: {
248
+ marginBottom: 10
249
+ },
250
+ linkFallback: {
251
+ flexDirection: "row",
252
+ alignItems: "center",
253
+ borderWidth: StyleSheet.hairlineWidth,
254
+ borderRadius: 10,
255
+ paddingHorizontal: 12,
256
+ paddingVertical: 12,
257
+ marginBottom: 10
258
+ },
259
+ linkFallbackText: {
260
+ fontSize: 14,
261
+ marginLeft: 8,
262
+ flex: 1
263
+ }
264
+ });export{MediaGalleryScreen};//# sourceMappingURL=MediaGalleryScreen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MediaGalleryScreen.js","sources":["../../../src/features/messaging/MediaGalleryScreen.tsx"],"sourcesContent":["/**\n * \"Media, links and docs\" - WhatsApp's per-chat gallery, with a cross-chat (\"all chats\") mode\n * when no channelId is given. Three tabs:\n * Media - a 3-column grid of photo/video thumbnails; tap opens the full image.\n * Links - each message carrying a URL, as a link-preview card.\n * Docs - document attachments as rows; tap opens the file.\n * Each tab loads lazily on first view via mediaMessages(kind).\n */\nimport * as React from 'react';\nimport { ActivityIndicator, Dimensions, FlatList, Pressable, StyleSheet, Text, View } from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport { Image } from 'expo-image';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { EmptyState, InlineBanner, type ChatTheme } from './ChatComponents';\nimport { LinkPreviewCard, useLinkPreview } from './LinkPreviewCard';\nimport { attachmentUrl, toChatAttachments, toChatMessage, type ChatAttachment, type WirePost } from './chatModel';\nimport { firstLink } from './chatLinks';\nimport type { ChatGraphQLSeam } from './chatHost';\nimport type { LinkPreviewLoader } from './linkPreview';\nimport { MEDIA_MESSAGES_QUERY } from './chatOperations';\n\ntype Tab = 'media' | 'links' | 'docs';\nconst TABS: { key: Tab; label: string }[] = [\n { key: 'media', label: 'Media' },\n { key: 'links', label: 'Links' },\n { key: 'docs', label: 'Docs' },\n];\n\ninterface MediaItem {\n messageId: string;\n channelId: string;\n attachment: ChatAttachment;\n}\ninterface LinkItem {\n messageId: string;\n channelId: string;\n url: string;\n}\n\nconst GRID_COLS = 3;\nconst GRID_GAP = 2;\n\n/** One Links row: resolves the preview itself (useLinkPreview is a hook, so it needs its own component). */\nfunction LinkRow({\n url,\n theme,\n loader,\n onOpen,\n}: {\n url: string;\n theme: ChatTheme;\n loader?: LinkPreviewLoader;\n onOpen?: (url: string) => void;\n}) {\n const preview = useLinkPreview(url, loader);\n if (preview) {\n return (\n <View style={styles.linkRow}>\n <LinkPreviewCard preview={preview} theme={theme} onOpen={onOpen} />\n </View>\n );\n }\n // No card yet (or none available): a plain tappable URL, so the row is never empty.\n return (\n <Pressable\n onPress={onOpen ? () => onOpen(url) : undefined}\n style={[styles.linkFallback, { borderColor: theme.border }]}\n accessibilityRole=\"link\"\n >\n <MaterialCommunityIcons name=\"link-variant\" size={18} color={theme.accent} />\n <Text numberOfLines={1} style={[styles.linkFallbackText, { color: theme.accent }]}>\n {url}\n </Text>\n </Pressable>\n );\n}\n\nexport function MediaGalleryScreen({\n gql,\n channelId,\n viewerId,\n theme,\n fileBaseUrl,\n linkPreviews,\n onOpenLink,\n onOpenImage,\n onBack,\n}: {\n gql: ChatGraphQLSeam;\n /** A single chat, or null for the cross-chat \"all chats\" gallery. */\n channelId: string | null;\n viewerId: string;\n theme: ChatTheme;\n fileBaseUrl?: string | null;\n linkPreviews?: LinkPreviewLoader;\n onOpenLink?: (url: string) => void;\n /** Open a full-size image in the shared viewer. */\n onOpenImage?: (url: string) => void;\n onBack: () => void;\n}) {\n const [tab, setTab] = React.useState<Tab>('media');\n const [error, setError] = React.useState<string | null>(null);\n // Per-tab cache so switching back is instant; null = not loaded yet.\n const [media, setMedia] = React.useState<MediaItem[] | null>(null);\n const [links, setLinks] = React.useState<LinkItem[] | null>(null);\n const [docs, setDocs] = React.useState<MediaItem[] | null>(null);\n\n const cellSize = Math.floor((Dimensions.get('window').width - GRID_GAP * (GRID_COLS - 1)) / GRID_COLS);\n\n const load = React.useCallback(\n async (which: Tab) => {\n const res = await gql\n .query<{\n mediaMessages?: { data?: (WirePost | null)[] | null } | null;\n }>(\n MEDIA_MESSAGES_QUERY,\n { channelId, kind: which, limit: 100, skip: 0 },\n { fetchPolicy: 'network-only' },\n )\n .catch(() => null);\n if (res?.errors?.length) setError('Couldn’t load this gallery.');\n const posts = (res?.data?.mediaMessages?.data ?? []).filter((p): p is WirePost => Boolean(p?.id));\n if (which === 'links') {\n setLinks(\n posts\n .map((p) => {\n const message = toChatMessage(p, viewerId);\n const url = firstLink(message.body);\n return url\n ? { messageId: message.id, channelId: String(p.channel?.id ?? channelId ?? ''), url }\n : null;\n })\n .filter((x): x is LinkItem => Boolean(x)),\n );\n return;\n }\n // media + docs both come from attachments; split by kind.\n const items: MediaItem[] = [];\n for (const p of posts) {\n const cid = String(p.channel?.id ?? channelId ?? '');\n for (const attachment of toChatAttachments(p)) {\n if (which === 'media' && attachment.kind === 'image')\n items.push({ messageId: p.id, channelId: cid, attachment });\n if (which === 'docs' && attachment.kind === 'file')\n items.push({ messageId: p.id, channelId: cid, attachment });\n }\n }\n if (which === 'media') setMedia(items);\n else setDocs(items);\n },\n [gql, channelId, viewerId],\n );\n\n // Load the active tab the first time it is shown.\n React.useEffect(() => {\n if (tab === 'media' && media === null) void load('media');\n if (tab === 'links' && links === null) void load('links');\n if (tab === 'docs' && docs === null) void load('docs');\n }, [tab, media, links, docs, load]);\n\n const loaded = (): unknown[] | null => {\n if (tab === 'media') return media;\n if (tab === 'docs') return docs;\n return links;\n };\n\n const renderMediaList = () => (\n <FlatList\n key=\"media\"\n data={media ?? []}\n numColumns={GRID_COLS}\n keyExtractor={(m) => m.attachment.id}\n contentContainerStyle={(media?.length ?? 0) ? undefined : styles.fill}\n ListEmptyComponent={\n <EmptyState\n icon=\"image-off-outline\"\n title=\"No media\"\n detail=\"Photos and videos in this chat show here.\"\n theme={theme}\n />\n }\n renderItem={({ item, index }) => (\n <Pressable\n onPress={() => onOpenImage?.(attachmentUrl(item.attachment, fileBaseUrl))}\n style={{\n width: cellSize,\n height: cellSize,\n marginRight: (index + 1) % GRID_COLS === 0 ? 0 : GRID_GAP,\n marginBottom: GRID_GAP,\n }}\n accessibilityRole=\"imagebutton\"\n accessibilityLabel=\"Open photo\"\n >\n <Image\n source={{ uri: item.attachment.url }}\n style={{ width: cellSize, height: cellSize, backgroundColor: theme.surface }}\n contentFit=\"cover\"\n transition={120}\n />\n </Pressable>\n )}\n />\n );\n\n const renderDocsList = () => (\n <FlatList\n key=\"docs\"\n data={docs ?? []}\n keyExtractor={(m) => m.attachment.id}\n contentContainerStyle={(docs?.length ?? 0) ? undefined : styles.fill}\n ListEmptyComponent={\n <EmptyState\n icon=\"file-outline\"\n title=\"No docs\"\n detail=\"Documents shared in this chat show here.\"\n theme={theme}\n />\n }\n renderItem={({ item }) => (\n <Pressable\n onPress={() => onOpenLink?.(attachmentUrl(item.attachment, fileBaseUrl))}\n style={[styles.docRow, { borderBottomColor: theme.border, flexDirection: 'row' }]}\n accessibilityRole=\"button\"\n accessibilityLabel={`Open ${item.attachment.name}`}\n >\n <View style={[styles.docIcon, { backgroundColor: theme.surface }]}>\n <MaterialCommunityIcons name=\"file-document-outline\" size={22} color={theme.accent} />\n </View>\n <View style={{ flex: 1 }}>\n <Text numberOfLines={1} style={[styles.docName, { color: theme.text }]}>\n {item.attachment.name}\n </Text>\n </View>\n </Pressable>\n )}\n />\n );\n\n const renderLinksList = () => (\n <FlatList\n key=\"links\"\n data={links ?? []}\n keyExtractor={(l, i) => `${l.messageId}-${i}`}\n contentContainerStyle={(links?.length ?? 0) ? styles.linkList : styles.fill}\n ListEmptyComponent={\n <EmptyState\n icon=\"link-off\"\n title=\"No links\"\n detail=\"Links shared in this chat show here.\"\n theme={theme}\n />\n }\n renderItem={({ item }) => (\n <LinkRow url={item.url} theme={theme} loader={linkPreviews} onOpen={onOpenLink} />\n )}\n />\n );\n\n const renderBody = () => {\n if (loaded() === null) {\n return (\n <View style={styles.center}>\n <ActivityIndicator color={theme.accent} />\n </View>\n );\n }\n if (tab === 'media') return renderMediaList();\n if (tab === 'docs') return renderDocsList();\n return renderLinksList();\n };\n\n return (\n <View style={[styles.fill, { backgroundColor: theme.bg }]} testID=\"chat-media-gallery\">\n <SafeAreaView edges={['top']} style={{ backgroundColor: theme.headerBg }}>\n <View style={[styles.header, { borderBottomColor: theme.border, flexDirection: 'row' }]}>\n <Pressable\n onPress={onBack}\n hitSlop={10}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Back\"\n style={styles.headerIcon}\n >\n <MaterialCommunityIcons name=\"chevron-left\" size={32} color={theme.accent} />\n </Pressable>\n <Text style={[styles.title, { color: theme.text }]}>Media, links and docs</Text>\n <View style={styles.headerIcon} />\n </View>\n <View style={[styles.tabs, { flexDirection: 'row' }]}>\n {TABS.map((t) => {\n const active = t.key === tab;\n return (\n <Pressable\n key={t.key}\n onPress={() => setTab(t.key)}\n style={[styles.tab, active && { borderBottomColor: theme.accent }]}\n accessibilityRole=\"tab\"\n accessibilityState={{ selected: active }}\n >\n <Text style={[styles.tabText, { color: active ? theme.accent : theme.textMuted }]}>\n {t.label}\n </Text>\n </Pressable>\n );\n })}\n </View>\n </SafeAreaView>\n <InlineBanner message={error} theme={theme} onDismiss={() => setError(null)} />\n\n {renderBody()}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n fill: { flex: 1 },\n center: { flex: 1, alignItems: 'center', justifyContent: 'center' },\n header: {\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingHorizontal: 4,\n minHeight: 52,\n borderBottomWidth: StyleSheet.hairlineWidth,\n },\n headerIcon: { width: 44, height: 44, alignItems: 'center', justifyContent: 'center' },\n title: { fontSize: 17, fontWeight: '600' },\n tabs: { alignItems: 'stretch' },\n tab: { flex: 1, alignItems: 'center', paddingVertical: 12, borderBottomWidth: 2, borderBottomColor: 'transparent' },\n tabText: { fontSize: 14, fontWeight: '600' },\n docRow: {\n alignItems: 'center',\n paddingHorizontal: 16,\n paddingVertical: 10,\n borderBottomWidth: StyleSheet.hairlineWidth,\n },\n docIcon: {\n width: 40,\n height: 40,\n borderRadius: 8,\n alignItems: 'center',\n justifyContent: 'center',\n marginRight: 12,\n },\n docName: { fontSize: 15, fontWeight: '500' },\n linkList: { padding: 12 },\n linkRow: { marginBottom: 10 },\n linkFallback: {\n flexDirection: 'row',\n alignItems: 'center',\n borderWidth: StyleSheet.hairlineWidth,\n borderRadius: 10,\n paddingHorizontal: 12,\n paddingVertical: 12,\n marginBottom: 10,\n },\n linkFallbackText: { fontSize: 14, marginLeft: 8, flex: 1 },\n});\n"],"names":["_a","_b","_c"],"mappings":"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"}