import React, { useCallback, useState } from 'react' import { View, Text, FlatList, StyleSheet, TouchableOpacity, SafeAreaView, ActivityIndicator, Alert, } from 'react-native' import { useFocusEffect } from '@react-navigation/native' import { ImSDK, type FriendRequest } from '@xuqm/rn-sdk' import type { UserProfile } from '../../api/demo' import { toDemoUserProfile } from '../../utils/userProfiles' function RequestRow({ request, profile, onAccept, onReject, }: { request: FriendRequest profile?: UserProfile onAccept(): void onReject(): void }) { const name = profile?.nickname || request.fromUserId return ( {name} 申请人:@{request.fromUserId} {!!request.remark && 附言:{request.remark}} 状态:{request.status} 接受 拒绝 ) } export default function FriendRequestsScreen() { const [requests, setRequests] = useState([]) const [loading, setLoading] = useState(true) const [profiles, setProfiles] = useState>({}) const load = useCallback(async () => { setLoading(true) try { const list = await ImSDK.listFriendRequests('incoming') setRequests(list) const nextProfiles: Record = {} await Promise.all(list.map(async (req) => { try { const result = await ImSDK.searchUsers(req.fromUserId) const match = result.find(u => u.userId === req.fromUserId) if (match) nextProfiles[req.fromUserId] = toDemoUserProfile(match) } catch { /* ignore */ } })) setProfiles(nextProfiles) } catch { setRequests([]) setProfiles({}) } finally { setLoading(false) } }, []) useFocusEffect(useCallback(() => { load() }, [load])) const handleAccept = async (request: FriendRequest) => { try { await ImSDK.acceptFriendRequest(request.id) await load() } catch (e: any) { Alert.alert('处理失败', e?.message ?? '请稍后重试') } } const handleReject = async (request: FriendRequest) => { try { await ImSDK.rejectFriendRequest(request.id) await load() } catch (e: any) { Alert.alert('处理失败', e?.message ?? '请稍后重试') } } return ( {loading ? ( ) : ( item.id} renderItem={({ item }) => ( handleAccept(item)} onReject={() => handleReject(item)} /> )} ItemSeparatorComponent={() => } ListEmptyComponent={暂无好友申请} contentContainerStyle={requests.length === 0 ? styles.emptyContainer : undefined} /> )} ) } const styles = StyleSheet.create({ root: { flex: 1, backgroundColor: '#f5f5f5' }, row: { flexDirection: 'row', padding: 12, backgroundColor: '#fff', alignItems: 'center' }, body: { flex: 1, paddingRight: 8 }, name: { fontSize: 16, fontWeight: '600', color: '#111' }, uid: { fontSize: 13, color: '#888', marginTop: 2 }, remark: { fontSize: 13, color: '#555', marginTop: 4 }, time: { fontSize: 12, color: '#999', marginTop: 4 }, actions: { gap: 8 }, actionBtn: { paddingHorizontal: 12, paddingVertical: 6, borderRadius: 6 }, acceptBtn: { backgroundColor: '#07C160' }, rejectBtn: { backgroundColor: '#ff3b30' }, actionText: { color: '#fff', fontSize: 13, fontWeight: '600' }, sep: { height: StyleSheet.hairlineWidth, backgroundColor: '#e0e0e0', marginLeft: 12 }, emptyContainer: { flexGrow: 1 }, empty: { flex: 1, alignItems: 'center', justifyContent: 'center' }, emptyText: { color: '#bbb', fontSize: 15 }, })