import {
View,
Text,
Image as NativeImage,
ScrollView,
TouchableOpacity,
Dimensions,
} from "react-native";
import React, { useState, useEffect, useRef } from "react";
import { useTailwind } from "tailwind-rn";
import {
useSafeAreaInsets,
SafeAreaProvider,
} from "react-native-safe-area-context";
import {
SearchBar,
ListItem,
Icon,
CheckBox,
BottomSheet,
} from "@rneui/themed";
import { Image } from "expo-image";
import Empty from "../../components/Empty";
import Toast from "react-native-toast-message";
import baseRequest from "../../utils/baseRequest";
import { generateSignature } from "../../utils/crypto";
import MyDivider from "../../components/MyDivider/index";
import MySlider from "../../components/MySlider";
import Picker from "../../components/Picker";
import { get } from "../../utils/storeInfo";
export default function Search({ navigation, route }) {
const tailwind = useTailwind();
const insets = useSafeAreaInsets();
const searchRef = useRef(null);
const screenDimensions = Dimensions.get("screen");
const [search, setSearch] = useState("");
const [isMember, setIsMember] = useState(0);
const [streamers, setStreamers] = useState([]);
const [recommList, setRecommList] = useState([]);
const [zones, setZones] = useState([]);
const [isloading, setIsloading] = useState(false);
const [isFilterVisible, setIsFilterVisible] = useState({
comprehensive: false,
zone_admission_price: false,
});
const filters = [
{
name: "年龄",
upper_bound: 60,
lower_bound: 18,
default: 19,
step: 1,
type: "slider",
unit: "岁",
key: "age",
stepValues: Array(61)
.fill(null)
.map((_, index) => index),
},
{
name: "全网粉丝",
upper_bound: 200,
lower_bound: 1,
default: 24,
step: 200 / 10,
type: "slider",
unit: "万",
key: "fans",
stepValues: [1, 3, 5, 10, 20, 50, 75, 100, 150, 200, 1000],
},
{
name: "身高",
upper_bound: 200,
lower_bound: 140,
default: 160,
step: 1,
type: "slider",
unit: "CM",
key: "height",
stepValues: Array(201)
.fill(null)
.map((_, index) => index),
},
{
name: "体重",
upper_bound: 100,
lower_bound: 35,
default: 50,
step: 1,
type: "slider",
unit: "KG",
key: "weight",
stepValues: Array(101)
.fill(null)
.map((_, index) => index),
},
{
name: "所在地",
upper_bound: 1000,
lower_bound: 10,
default: 24,
step: 1,
type: "select",
items: [
"北京市",
"天津市",
"河北省",
"山西省",
"内蒙古自治区",
"辽宁省",
"吉林省",
"黑龙江省",
"上海市",
"江苏省",
"浙江省",
"安徽省",
"福建省",
"江西省",
"山东省",
"河南省",
"湖北省",
"湖南省",
"广东省",
"广西壮族自治区",
"海南省",
"重庆市",
"四川省",
"贵州省",
"云南省",
"西藏自治区",
"陕西省",
"甘肃省",
"青海省",
"宁夏回族自治区",
"新疆维吾尔自治区",
"台湾省",
"香港特别行政区",
"澳门特别行政区",
],
key: "city",
},
{
name: "星座",
upper_bound: 1000,
lower_bound: 10,
default: 24,
step: 1,
type: "select",
key: "constellation",
items: [
"白羊座",
"金牛座",
"双子座",
"巨蟹座",
"狮子座",
"处女座",
"天秤座",
"天蝎座",
"射手座",
"摩羯座",
"水瓶座",
"双鱼座",
],
},
{
name: "最近7日内空间有更新",
upper_bound: 1000,
lower_bound: 10,
default: 24,
step: 1,
type: "checkbox",
key: "is_active_within_a_week",
},
];
const priceFilters = [
{
name: "空间价格",
upper_bound: 200,
lower_bound: 0,
default: 24,
step: 200 / 7,
type: "slider",
unit: "¥",
key: "zone",
stepValues: [0, 1, 10, 50, 100, 150, 200, 4000],
},
{
name: "微信价格",
upper_bound: 200,
lower_bound: 0,
default: 24,
step: 200 / 8,
type: "slider",
unit: "金币",
key: "wechat",
stepValues: [0, 10, 100, 200, 500, 1000, 5000, 10000, 100000],
},
];
const [filtersValue, setFiltersValue] = useState({
age: { lower_bound: 18, upper_bound: 60 },
fans: { lower_bound: 1, upper_bound: 1000 },
height: { lower_bound: 140, upper_bound: 200 },
weight: { lower_bound: 35, upper_bound: 100 },
city: "",
constellation: "",
is_active_within_a_week: 0,
zone_admission_price: { lower_bound: 0, upper_bound: 4000 },
wechat_coin_price: { lower_bound: 0, upper_bound: 100000 },
priceUsed: { show: false, used: false },
comprehensiveUsed: { show: false, used: false },
});
const updateSearch = (search) => {
setSearch(search);
if (!search) return;
setIsloading(true);
};
//进入页面默认focus
useEffect(() => {
searchRef.current.focus();
getIsMember();
}, []);
//搜索框文本变化时进行搜索
useEffect(() => {
if (!search) {
setStreamers([]);
setZones([]);
return;
}
const isNumeric = (str) => {
return /^\d+$/.test(str);
};
const getResult = async () => {
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
const isSearchInt = isNumeric(search);
let api;
let querryParams;
if (isSearchInt) {
api = "/api/streamer/list_ext_fuzzily_by_user_id";
querryParams = { user_id: parseInt(search, 10) };
} else {
api = "/api/streamer/list_ext_fuzzily_by_name";
querryParams = { name: search };
}
try {
const base = await baseRequest();
const signature = await generateSignature({
...base,
...querryParams,
offset: 0,
limit: 20,
});
const response = await fetch(`${apiUrl}${api}?signature=${signature}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
...base,
...querryParams,
offset: 0,
limit: 20,
}),
});
const data = await response.json();
if (data.ret === -1) {
Toast.show({
type: "error",
text1: data.msg,
topOffset: 60,
});
return;
}
if (!ignore) {
const zonesData = data.data.list.filter(
(item) => item.zones.length > 0
);
setStreamers(data.data.list);
setZones(zonesData);
}
setIsloading(false);
} catch (error) {
console.error(error);
}
};
let ignore = false;
getResult();
return () => {
ignore = true;
};
}, [search]);
const getFiltersResult = async () => {
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
let api;
let querryParams;
api = "/api/streamer/filter";
let currentFilterValue = { ...filtersValue };
delete currentFilterValue.comprehensiveUsed;
delete currentFilterValue.priceUsed;
querryParams = currentFilterValue;
try {
const base = await baseRequest();
const signature = await generateSignature({
...base,
...querryParams,
offset: 0,
limit: 20,
});
const response = await fetch(`${apiUrl}${api}?signature=${signature}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
...base,
...querryParams,
offset: 0,
limit: 20,
}),
});
const data = await response.json();
if (data.ret === -1) {
Toast.show({
type: "error",
text1: data.msg,
topOffset: 60,
});
return;
}
const zonesData = data.data.streamer_list.filter(
(item) => item.zones.length > 0
);
setStreamers(data.data.streamer_list);
setZones(zonesData);
setRecommList(data.data.recomm_list);
setIsloading(false);
} catch (error) {
console.error(error);
}
};
const getIsMember = async () => {
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
let api;
api = "/api/account/list_by_mid";
const account = await get("account");
try {
const base = await baseRequest();
const signature = await generateSignature({
...base,
mid: account.mid,
});
const response = await fetch(`${apiUrl}${api}?signature=${signature}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
...base,
mid: account.mid,
}),
});
const data = await response.json();
setIsMember(data.data.account.is_a_member);
} catch (error) {
console.error(error);
}
};
//重置筛选值
const handleResetFiltersValue = (type) => {
let obj = {};
if (type == "comprehensive") {
obj = {
...filtersValue,
age: { lower_bound: 18, upper_bound: 60 },
fans: { lower_bound: 1, upper_bound: 1000 },
weight: { lower_bound: 35, upper_bound: 100 },
height: { lower_bound: 140, upper_bound: 200 },
city: "",
constellation: "",
is_active_within_a_week: 0,
comprehensiveUsed: { show: false, used: false },
};
} else {
obj = {
...filtersValue,
zone_admission_price: { lower_bound: 0, upper_bound: 4000 },
wechat_coin_price: { lower_bound: 0, upper_bound: 100000 },
priceUsed: { show: false, used: false },
};
}
setFiltersValue((old) => ({
...old,
...obj,
}));
if (!obj.comprehensiveUsed.used && !obj.priceUsed.used) {
setRecommList([]);
setStreamers([]);
setZones([]);
}
};
//空间组件
const ZoneItem = ({ item }) => {
return (
navigation.navigate("SpaceIntroduce", { mid: item?.mid })
}
containerStyle={tailwind("p-0 bg-[#07050A]")}
>
{item?.name}
{item?.user_id}
{item.zones[0].profile}
{zones.length === 1 && (
Ta的动态·
{item.zones[0].zone_moment_count > 99
? "99+"
: item.zones[0].zone_moment_count}
{item.zones[0].image_count > 0 &&
` | 图片·${
item.zones[0].image_count > 99
? "99+"
: item.zones[0].image_count
}`}
{item.zones[0].video_count > 0 &&
` | 视频·${
item.zones[0].video_count > 99
? "99+"
: item.zones[0].video_count
}`}
{item.album.images.map((_item, index) => {
if (index > 1) return;
return (
);
})}
)}
);
};
//主播组件
const StreamerItem = ({ item }) => {
return (
navigation.navigate("StreamerProfile", {
mid: item.mid,
})
}
containerStyle={tailwind("p-0 bg-[#07050A]")}
>
{item?.name}
{item?.user_id}
{item.bio}
);
};
return (
navigation.goBack()}
/>
<>>}
searchIcon={() => <>>}
showLoading={isloading}
onChangeText={updateSearch}
value={search}
disabled={
filtersValue.comprehensiveUsed.used || filtersValue.priceUsed.used
}
/>
{
setIsFilterVisible({
...isFilterVisible,
comprehensive: !isFilterVisible.comprehensive,
});
}}
style={{
...tailwind("px-2 rounded-xl flex-row items-center"),
borderColor: "#ff75c8",
borderWidth: filtersValue.comprehensiveUsed.used ? 1 : 0,
boxSizing: "border-box",
width: 110,
}}
>
综合筛选
{filtersValue.comprehensiveUsed.used && (
handleResetFiltersValue("comprehensive")}
style={{ width: 24 }}
>
)}
{
setIsFilterVisible({
...isFilterVisible,
zone_admission_price: !isFilterVisible.zone_admission_price,
});
}}
style={{
...tailwind("px-2 rounded-xl flex-row items-center"),
borderColor: "#ff75c8",
borderWidth: filtersValue.priceUsed.used ? 1 : 0,
boxSizing: "border-box",
width: 110,
}}
>
价格筛选
{filtersValue.priceUsed.used && (
handleResetFiltersValue("zone_admission_price")}
style={{ width: 24 }}
>
)}
{
const { y } = event.nativeEvent.contentOffset;
if (y < -50) {
setIsFilterVisible({
zone_admission_price: false,
comprehensive: false,
});
}
},
}}
isVisible={isFilterVisible.comprehensive}
style={{
paddingTop: 110,
}}
>
{filters.map((item, index) => (
{item.name}
{item.type == "slider" ? (
{
if (item.key == "age") {
setFiltersValue((old) => ({ ...old, age: value }));
} else if (item.key == "fans") {
setFiltersValue((old) => ({ ...old, fans: value }));
} else if (item.key == "height") {
setFiltersValue((old) => ({ ...old, height: value }));
} else if (item.key == "weight") {
setFiltersValue((old) => ({ ...old, weight: value }));
}
}}
maximumTrackTintColor="#ff75c81a"
minimumTrackTintColor="#ff75c8"
processHeight={5}
unit={item.unit}
thumbImage={require("../../assets/icon/32DP/edit.png")}
/>
) : item.type == "checkbox" ? (
setFiltersValue((old) => ({
...old,
is_active_within_a_week: old.is_active_within_a_week
? 0
: 1,
}))
}
iconType="material-community"
checkedIcon="checkbox-marked"
uncheckedIcon="checkbox-blank-outline"
checkedColor="#FF669E"
containerStyle={tailwind("p-0 m-0 bg-transparent")}
size={24}
/>
) : (
({
label: it,
value: it,
}))}
value={
item.key == "constellation"
? filtersValue.constellation
: filtersValue.city
}
onChange={(value) =>
setFiltersValue((old) => {
let newValue = { ...old };
if (item.key == "constellation") {
newValue.constellation = value;
} else {
newValue.city = value;
}
return newValue;
})
}
/>
)}
))}
{isMember == 1 && (
handleResetFiltersValue("comprehensive")}
>
重置
)}
{
setIsFilterVisible({
zone_admission_price: false,
comprehensive: false,
});
if (!isMember) {
navigation.navigate("WebWithoutHeader", {
uri: process.env.EXPO_PUBLIC_WEB_URL + "/vip",
});
return;
}
setFiltersValue((old) => ({
...old,
comprehensiveUsed: { show: false, used: true },
}));
getFiltersResult();
}}
style={{
...tailwind("text-white px-4 py-2 rounded-xl"),
marginVertical: 6,
backgroundColor: "#ff75c8",
minWidth: 120,
}}
>
{!isMember ? "开通VIP后即可筛选" : "确定"}
{
const { y } = event.nativeEvent.contentOffset;
if (y < -50) {
setIsFilterVisible({
zone_admission_price: false,
comprehensive: false,
});
}
},
}}
isVisible={isFilterVisible.zone_admission_price}
style={{
paddingTop: 110,
}}
>
{priceFilters.map((item) => (
{item.name}
{
if (item.key == "zone") {
setFiltersValue((old) => ({
...old,
zone_admission_price: value,
}));
} else if (item.key == "wechat") {
setFiltersValue((old) => ({
...old,
wechat_coin_price: value,
}));
}
}}
maximumTrackTintColor="#ff75c81a"
minimumTrackTintColor="#ff75c8"
processHeight={5}
unit={item.unit}
thumbImage={require("../../assets/icon/32DP/edit.png")}
/>
))}
{isMember == 1 && (
handleResetFiltersValue("zone_admission_price")
}
>
重置
)}
{
setIsFilterVisible({
zone_admission_price: false,
comprehensive: false,
});
if (!isMember) {
navigation.navigate("WebWithoutHeader", {
uri: process.env.EXPO_PUBLIC_WEB_URL + "/vip",
});
return;
}
setFiltersValue((old) => ({
...old,
priceUsed: { show: false, used: true },
}));
getFiltersResult();
}}
style={{
...tailwind("text-white px-4 py-2 rounded-xl"),
marginVertical: 6,
backgroundColor: "#ff75c8",
minWidth: 120,
}}
>
{!isMember ? "开通VIP后即可筛选" : "确定"}
{zones.length > 0 && (
空间
)}
{zones?.map((item, index) => (
))}
{zones.length > 0 && }
{streamers.length > 0 && (
用户
)}
{streamers?.map((item, index) => (
))}
{recommList.length > 0 && }
{recommList.length > 0 && (
猜你喜欢
)}
{recommList?.map((item, index) => (
))}
{streamers.length === 0 && recommList.length === 0 && (
)}
);
}