import { View, Text, FlatList, ScrollView, TouchableOpacity, Image as NativeImage, } from "react-native"; import React, { useState, useEffect, useRef } from "react"; import { useTailwind } from "tailwind-rn"; import Toast from "react-native-toast-message"; import Empty from "../../../components/Empty"; import { ListItem, Icon, SearchBar } from "@rneui/themed"; import { Image } from "expo-image"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import baseRequest from "../../../utils/baseRequest"; import { generateSignature } from "../../../utils/crypto"; import formatTimestamp from "../../../utils/formatTimestamp"; export default function SpaceSearch({ navigation }) { const blurhash = "LcKUTa%gOYWBYRt6xuoJo~s8V@fk"; const tailwind = useTailwind(); const insets = useSafeAreaInsets(); const [data, setData] = useState([]); const [search, setSearch] = useState(""); const [isloading, setIsloading] = useState(false); const searchRef = useRef(null); const getData = async (searchValue) => { // if (searchValue?.length != 6) { // return; // } if (/[^0-9]/.test(searchValue)) { Toast.show({ type: "error", text1: "请输入正确的用户ID", topOffset: 60, }); return; } const apiUrl = process.env.EXPO_PUBLIC_API_URL; try { setIsloading(true); const base = await baseRequest(); const body = { member_user_id: Number(searchValue), ...base, }; console.log("vvvvvv", JSON.stringify(body)); const signature = await generateSignature(body); const _response = await fetch( `${apiUrl}/api/zone/search_zone_member?signature=${signature}`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(body), } ); const _data = await _response.json(); if (_data.ret === -1) { setIsloading(false); Toast.show({ type: "error", text1: _data.msg, topOffset: 60, }); return; } setData(_data.data.list); } catch (error) { console.error(error); } setIsloading(false); }; //进入页面默认focus useEffect(() => { searchRef.current.focus(); }, []); //搜索框文本变化时进行搜索 // useEffect(() => { // if (!search) { // setData([]); // return; // } // let ignore = false; // // getData(search); // return () => { // ignore = true; // }; // }, [search]); const updateSearch = (search) => { setSearch(search); if (!search) return; }; //单个成员组件 const RenderItem = ({ item }) => { return ( <ListItem bottomDivider containerStyle={tailwind("p-0 bg-transparent")}> <View style={tailwind("flex-1")}> <View style={tailwind("flex flex-row items-center py-3")}> <Image style={tailwind("w-12 h-12 rounded-full")} source={item?.account?.avatar?.images[0]?.urls[0]} placeholder={blurhash} contentFit="cover" transition={1000} cachePolicy="disk" /> <View style={tailwind("ml-2 justify-around flex-1")}> <View style={tailwind("flex flex-row w-full mb-2")}> <Text style={tailwind("text-base text-white font-medium")} numberOfLines={1} ellipsizeMode="tail" > {item?.account?.name} </Text> <View style={tailwind("flex flex-row ml-2")}> {item?.is_ironfan == 1 && ( <View style={{ ...tailwind( "flex flex-row items-center mr-2 rounded-full px-2" ), borderRadius: 50, backgroundColor: "#301024", }} numberOfLines={1} ellipsizeMode="tail" > <Text style={{ ...tailwind("text-xs text-white"), borderRadius: 50, color: "#FF669E", }} > 铁粉 </Text> </View> )} {item?.is_superfan == 1 && ( <View style={{ ...tailwind( "flex flex-row items-center mr-2 rounded-full px-2" ), backgroundColor: "#331F0B", borderRadius: 50, }} numberOfLines={1} ellipsizeMode="tail" > <Text style={{ ...tailwind("text-xs"), color: "#FFD685", borderRadius: 50, }} > 超粉 </Text> </View> )} </View> </View> <View style={tailwind("flex-row flex-wrap")}> <View style={tailwind( "flex-row items-center py-0.5 px-2 mr-2 bg-[#FFFFFF1A] rounded-full" )} > <NativeImage source={require("../../../assets/icon/12DP/ID.png")} /> <Text style={tailwind("text-white text-xs font-medium ml-0.5")} > {item?.account?.user_id} </Text> </View> <View style={tailwind( "flex-row items-center py-0.5 px-2 mr-2 bg-[#FFFFFF1A] rounded-full" )} > <Icon type="ionicon" name="calendar-outline" size={12} color="white" /> <Text style={tailwind("text-white text-xs font-medium ml-0.5")} > {formatTimestamp(item?.join_ct)} </Text> </View> </View> </View> </View> </View> </ListItem> ); }; return ( <View style={{ paddingTop: insets.top, paddingBottom: insets.bottom, paddingLeft: insets.left, paddingRight: insets.right, ...tailwind("flex-1"), }} > <View style={tailwind("flex-row px-2 items-center")}> <Icon type="ionicon" name="chevron-back" size={32} color="white" onPress={() => navigation.goBack()} /> <View style={tailwind("flex-1 flex flex-row items-center")}> <SearchBar ref={searchRef} containerStyle={{ ...tailwind("bg-[#07050A]"), width: "80%", }} inputContainerStyle={tailwind("h-10 bg-[#FFFFFF1A]")} inputStyle={tailwind("text-white")} inputMode="numeric" placeholder="请输入完整用户ID" platform="ios" // cancelButtonProps={tailwind("text-[#FF669E]")} cancelButtonTitle="" clearIcon={() => <></>} showCancel={false} searchIcon={() => <></>} showLoading={isloading} onChangeText={updateSearch} value={search} /> <TouchableOpacity style={{ ...tailwind( "bg-[#FF669E] text-center rounded-lg px-2 py-1 flex-1 h-10 items-center justify-center" ), }} onPress={() => getData(search)} > <Text style={{ ...tailwind("text-center text-white text-base font-bold"), width: 48, }} > 搜索 </Text> </TouchableOpacity> </View> </View> <ScrollView style={tailwind("flex-1")}> <View style={tailwind("flex-1 px-4")}> {data?.map((item, index) => ( <RenderItem key={index} item={item} /> ))} {data.length === 0 && <Empty type={search ? "search" : "nodata"} />} </View> </ScrollView> </View> ); }