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 },
})