import React, { useEffect, useState } from 'react'; import { ActivityIndicator, SectionList, StyleSheet, Text, TouchableOpacity, View, } from 'react-native'; import dayjs from 'dayjs'; import Svg, { Defs, LinearGradient, Rect, Stop } from 'react-native-svg'; import { Avatar, CheckSend, Close, useTheme, vw } from 'stream-chat-react-native'; import { useUserSearchContext } from '../../context/UserSearchContext'; import type { UserResponse } from 'stream-chat'; import type { LocalUserType } from '../../types'; import { Search } from '../../icons/Search'; const styles = StyleSheet.create({ absolute: { position: 'absolute' }, emptyResultIndicator: { alignItems: 'center', justifyContent: 'center', paddingTop: 28, }, emptyResultIndicatorText: { alignItems: 'center', justifyContent: 'center', paddingTop: 28, }, flex: { flex: 1 }, gradient: { height: 24, paddingHorizontal: 8, paddingVertical: 5, }, matches: { fontSize: 12 }, searchResultContainer: { alignItems: 'center', borderBottomWidth: 1, flexDirection: 'row', paddingLeft: 8, paddingRight: 16, paddingVertical: 12, }, searchResultUserDetails: { flex: 1, paddingLeft: 8, }, searchResultUserLastOnline: { fontSize: 12 }, searchResultUserName: { fontSize: 14, fontWeight: '700' }, sectionHeader: { fontSize: 14.5, fontWeight: '700', paddingHorizontal: 8, paddingVertical: 6, }, }); type UserSearchResultsProps = { groupedAlphabetically?: boolean; removeOnPressOnly?: boolean; results?: UserResponse[]; showOnlineStatus?: boolean; toggleSelectedUser?: (user: UserResponse) => void; }; export const UserSearchResults: React.FC = ({ groupedAlphabetically = true, removeOnPressOnly = false, results: resultsProp, showOnlineStatus = true, toggleSelectedUser, }) => { const { loading, loadMore, results: resultsContext, searchText, selectedUserIds, toggleUser, } = useUserSearchContext(); const [sections, setSections] = useState< Array<{ data: UserResponse[]; title: string; }> >([]); const { theme: { colors: { accent_blue, bg_gradient_end, bg_gradient_start, black, border, grey, grey_gainsboro, white_smoke, white_snow, }, }, } = useTheme(); const results = resultsProp || resultsContext; const resultsLength = results.length; useEffect(() => { const newSections: { [key: string]: { data: UserResponse[]; title: string; }; } = {}; results.forEach((user) => { const initial = user.name?.slice(0, 1).toUpperCase(); if (!initial) return; if (!newSections[initial]) { newSections[initial] = { data: [user], title: initial, }; } else { newSections[initial].data.push(user); } }); setSections(Object.values(newSections)); }, [resultsLength]); return ( {groupedAlphabetically && sections.length > 0 && ( {searchText ? `Matches for "${searchText}"` : 'On the platform'} )} {loading && (!results || results.length === 0) && searchText === '' ? ( ) : ( ( {loading ? 'Loading...' : 'No user matches these keywords...'} )} onEndReached={loadMore} renderItem={({ item }) => ( { if (toggleSelectedUser) { toggleSelectedUser(item); } else { toggleUser(item); } }} style={[ styles.searchResultContainer, { backgroundColor: white_snow, borderBottomColor: border, }, ]} > {item.name} {showOnlineStatus && ( Last online {dayjs(item.last_active).calendar()} )} {selectedUserIds.indexOf(item.id) > -1 && ( <> {removeOnPressOnly ? ( ) : ( )} )} )} renderSectionHeader={({ section: { title } }) => { if (searchText || !groupedAlphabetically) { return null; } return ( {title} ); }} sections={sections} stickySectionHeadersEnabled /> )} ); };