完善空间功能

This commit is contained in:
yezian 2024-04-22 22:04:58 +08:00
parent 21a187c341
commit f18c1c0234
10 changed files with 181 additions and 104 deletions

View File

@ -132,7 +132,7 @@ export default function CreateImagePost({ navigation, route }) {
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
try {
const base = await baseRequest();
const signature = await generateSignature({
const body = {
...base,
c_type: parseFloat(price) ? 1 : 0,
is_ironfan_visible: isFreeForIronfan ? 1 : 0,
@ -146,7 +146,8 @@ export default function CreateImagePost({ navigation, route }) {
? parseInt(imageVisibleRange, 10)
: 1,
price: parseFloat(price) ? parseInt(parseFloat(price) * 100, 10) : null,
});
};
const signature = await generateSignature(body);
const response = await fetch(
`${apiUrl}/api/zone_moment/create?signature=${signature}`,
{
@ -154,23 +155,7 @@ export default function CreateImagePost({ navigation, route }) {
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
...base,
c_type: parseFloat(price) ? 1 : 0,
is_ironfan_visible: isFreeForIronfan ? 1 : 0,
m_type: 1,
text: content,
media_component: media,
text_visible_range: textVisibleRange
? parseInt(textVisibleRange, 10)
: 999,
media_visible_range: imageVisibleRange
? parseInt(imageVisibleRange, 10)
: 0,
price: parseFloat(price)
? parseInt(parseFloat(price) * 100, 10)
: null,
}),
body: JSON.stringify(body),
}
);
const data = await response.json();

View File

@ -110,7 +110,7 @@ export default function CreateVideoPost({ navigation, route }) {
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
try {
const base = await baseRequest();
const signature = await generateSignature({
const body = {
...base,
c_type: parseFloat(price) ? 1 : 0,
is_ironfan_visible: isFreeForIronfan ? 1 : 0,
@ -122,7 +122,8 @@ export default function CreateVideoPost({ navigation, route }) {
: 999,
is_blurring_cover: blurCover ? 1 : 0,
price: parseFloat(price) ? parseInt(parseFloat(price) * 100, 10) : null,
});
};
const signature = await generateSignature(body);
const response = await fetch(
`${apiUrl}/api/zone_moment/create?signature=${signature}`,
{
@ -130,21 +131,7 @@ export default function CreateVideoPost({ navigation, route }) {
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
...base,
c_type: parseFloat(price) ? 1 : 0,
is_ironfan_visible: isFreeForIronfan ? 1 : 0,
m_type: 2,
text: content,
media_component: media,
text_visible_range: textVisibleRange
? parseInt(textVisibleRange, 10)
: 999,
is_blurring_cover: blurCover ? 1 : 0,
price: parseFloat(price)
? parseInt(parseFloat(price) * 100, 10)
: null,
}),
body: JSON.stringify(body),
}
);
const data = await response.json();

View File

@ -7,7 +7,6 @@ import MyDivider from "../../components/MyDivider";
import { Icon } from "@rneui/themed";
import * as Clipboard from "expo-clipboard";
//todo:
export default function ShareSpace({ navigation, route }) {
const tailwind = useTailwind();
const insets = useSafeAreaInsets();

View File

@ -1,5 +1,5 @@
import { View, Text, RefreshControl, TouchableOpacity } from "react-native";
import React, { useState, useEffect, useCallback } from "react";
import React, { useState, useCallback } from "react";
import { useTailwind } from "tailwind-rn";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import Toast from "react-native-toast-message";
@ -9,6 +9,7 @@ import { useNavigation } from "@react-navigation/native";
import SpaceCard from "../../../components/SpaceCard";
import baseRequest from "../../../utils/baseRequest";
import { generateSignature } from "../../../utils/crypto";
import { useFocusEffect } from "@react-navigation/native";
export default function SpaceList() {
const tailwind = useTailwind();
@ -17,6 +18,7 @@ export default function SpaceList() {
const navigation = useNavigation();
const [data, setData] = useState([]);
const getData = async () => {
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
@ -57,6 +59,12 @@ export default function SpaceList() {
console.error(error);
}
};
//focus
useFocusEffect(
useCallback(() => {
getData();
}, [])
);
const renderItem = ({ item }) => <SpaceCard data={item} />;
@ -108,7 +116,6 @@ export default function SpaceList() {
return (
<View
style={{
paddingBottom: insets.bottom,
paddingLeft: insets.left,
paddingRight: insets.right,
...tailwind("flex-1"),
@ -130,7 +137,6 @@ export default function SpaceList() {
onRefresh={() => handleRefresh()}
/>
}
onEndReached={getData}
ListEmptyComponent={EmptyComponent}
/>
</View>

View File

@ -19,6 +19,7 @@ import VideoModal from "../../components/VideoModal";
import SpaceIntroduceSkeleton from "./skeleton";
import { usePreventScreenCapture } from "expo-screen-capture";
import { useFocusEffect } from "@react-navigation/native";
import ImageViewer from "../../components/ImageViewer";
export default function SpaceIntroduce({ navigation, route }) {
usePreventScreenCapture();
@ -78,6 +79,16 @@ export default function SpaceIntroduce({ navigation, route }) {
}, [])
);
//modal
const [imagesVisible, setImagesVisible] = useState(false);
//modal
const [imageIndex, setImageIndex] = useState("");
const images = data?.streamer_ext?.album?.images?.map((image, index) => {
if (index > 4) return;
return image?.urls[0];
});
const imagesForImageViewer = images?.map((url) => ({ url }));
//0
const handleJoinFreeSpace = async () => {
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
@ -263,7 +274,15 @@ export default function SpaceIntroduce({ navigation, route }) {
{data?.streamer_ext?.album?.images?.map((item, index) => {
if (index > 4) return;
return (
<View key={index} style={tailwind("basis-1/3 p-0.5")}>
<TouchableOpacity
activeOpacity={1}
onPress={() => {
setImageIndex(index);
setImagesVisible(true);
}}
key={index}
style={tailwind("basis-1/3 p-0.5")}
>
<Image
style={{
aspectRatio: "1/1",
@ -274,7 +293,7 @@ export default function SpaceIntroduce({ navigation, route }) {
transition={500}
cachePolicy="disk"
/>
</View>
</TouchableOpacity>
);
})}
</View>
@ -330,13 +349,15 @@ export default function SpaceIntroduce({ navigation, route }) {
"flex flex-row items-center justify-center h-12 rounded-full px-10 bg-[#FF669E]"
)}
>
{data?.admission_price !== 0 && (
<NativeImage
style={tailwind("ml-2")}
source={require("../../assets/icon/others/money_pink.png")}
/>
)}
<Text style={tailwind("text-base text-white font-medium ml-2")}>
{data?.admission_price === 0
? "立即加入"
? "免费加入"
: `${data?.admission_price / 100}元立即加入`}
</Text>
<NativeImage source={require("../../assets/icon/32DP/link.png")} />
@ -363,6 +384,13 @@ export default function SpaceIntroduce({ navigation, route }) {
setVisible={setShowVideo}
url={data?.streamer_ext?.shorts?.videos[0]?.urls[0]}
/>
{/* 展示图片的modal */}
<ImageViewer
isVisible={imagesVisible}
setIsVisible={setImagesVisible}
imageUrls={imagesForImageViewer}
index={imageIndex}
/>
</View>
);
}

View File

@ -200,7 +200,7 @@ export default function AgencySetting({ navigation, route }) {
const generateItems = useCallback((min, max) => {
const items = [];
for (let i = min; i <= max; i++) {
items.push({ label: i.toString(), value: i.toString() });
items.push({ label: `${i.toString()}%`, value: i.toString() });
}
return items;
}, []);

View File

@ -7,6 +7,7 @@ import {
KeyboardAvoidingView,
TouchableOpacity,
Image as NativeImage,
ActivityIndicator,
} from "react-native";
import React, { useState, useEffect, useCallback, useMemo } from "react";
import { useTailwind } from "tailwind-rn";
@ -30,10 +31,13 @@ export default function CollaboratorSetting({ navigation, route }) {
//
const [data, setData] = useState();
useEffect(() => {
const [selfMid, setSelfMid] = useState();
const [isFetching, setIsFetching] = useState(true);
const getData = async () => {
setIsFetching(true);
try {
const base = await baseRequest();
setSelfMid(base.b_mid);
const body = {
zid: route.params.data.id,
visitor_role: route.params.data.visitor_role,
@ -60,11 +64,14 @@ export default function CollaboratorSetting({ navigation, route }) {
});
return;
}
setData(_data.data.list);
setData(_data.data);
} catch (error) {
console.error(error);
} finally {
setIsFetching(false);
}
};
useEffect(() => {
getData();
}, []);
@ -125,15 +132,28 @@ export default function CollaboratorSetting({ navigation, route }) {
//
const [rate, setRate] = useState();
//
const remainingRate = useMemo(() => {
if (!data) return;
const totalRate = data?.list?.reduce(
(acc, cur) => acc + cur.sharing_ratio,
0
);
return (data?.zone_third_partner?.sharing_ratio - totalRate).toFixed(2);
}, [data]);
//
const generateItems = useCallback((min, max) => {
const items = [];
for (let i = min; i <= max; i++) {
items.push({ label: i.toString(), value: i.toString() });
items.push({ label: `${i.toString()}%`, value: i.toString() });
}
return items;
}, []);
const rates = useMemo(() => generateItems(1, 50), []);
const rates = useMemo(
() => generateItems(1, parseInt(remainingRate * 100)),
[remainingRate]
);
//
const handleSubmit = async () => {
@ -188,6 +208,8 @@ export default function CollaboratorSetting({ navigation, route }) {
text1: "添加合伙人成功",
topOffset: 60,
});
getData();
handleCancel();
} catch (error) {
console.error(error);
}
@ -237,13 +259,15 @@ export default function CollaboratorSetting({ navigation, route }) {
text1: "移除合伙人成功",
topOffset: 60,
});
getData();
handleCancel();
} catch (error) {
console.error(error);
}
};
//
const CollaboratorItem = ({ item }) => {
const CollaboratorItem = useCallback(({ item }) => {
return (
<ListItem bottomDivider containerStyle={tailwind("p-0 bg-transparent")}>
<View style={tailwind("flex-1")}>
@ -298,7 +322,7 @@ export default function CollaboratorSetting({ navigation, route }) {
</View>
</View>
</View>
{route.params.data.visitor_role === 1 && (
{!item?.isDeleteBtnInvisible && (
<View style={tailwind("ml-2 justify-around items-center")}>
<Button
titleStyle={tailwind("text-sm font-medium px-2")}
@ -315,7 +339,41 @@ export default function CollaboratorSetting({ navigation, route }) {
</View>
</ListItem>
);
};
}, []);
if (isFetching) {
return (
<View style={tailwind("flex flex-1 justify-center items-center")}>
<ActivityIndicator size="large" />
</View>
);
}
if (route.params.data.visitor_role === 2) {
const selfData = data?.list?.filter(
(item) => item.collaborator_mid === selfMid
);
return (
<View
style={{
gap: 8,
...tailwind(
"flex flex-col border border-2 border-[#2c2b2f] rounded-2xl p-4 w-full mt-6"
),
}}
>
<Text style={tailwind("text-white text-base font-medium")}>
合伙人昵称{selfData.collaborator_account.name}
</Text>
<Text style={tailwind("text-white text-base font-medium")}>
ID{selfData.collaborator_account.user_id}
</Text>
<Text style={tailwind("text-white text-base font-medium")}>
分成比例{data.sharing_ratio * 100}%
</Text>
</View>
);
}
return (
<ScrollView
@ -332,14 +390,26 @@ export default function CollaboratorSetting({ navigation, route }) {
总分成比例
</Text>
<Text style={tailwind("text-[#F53030] text-3xl font-medium my-2")}>
35%
{data?.zone_third_partner?.sharing_ratio * 100}%
</Text>
<Text style={tailwind("text-[#FFFFFF80] text-sm")}>
修改比例请联系平台客服
</Text>
</View>
<MyDivider style={tailwind("my-4")} />
{route.params.data.visitor_role === 1 && (
<MyDivider style={tailwind("mt-4")} />
<View style={tailwind("flex flex-col w-full")}>
<CollaboratorItem
item={{
collaborator_account:
data?.zone_third_partner?.third_partner_account,
sharing_ratio: remainingRate,
isDeleteBtnInvisible: true,
}}
/>
{data?.list?.map((item, index) => (
<CollaboratorItem key={index} item={item} />
))}
</View>
<Icon
onPress={() => setIsAddCollaboratorModalVisible(true)}
type="ionicon"
@ -347,15 +417,9 @@ export default function CollaboratorSetting({ navigation, route }) {
size={40}
color="white"
containerStyle={tailwind(
"border border-white rounded-full w-[4.6rem] h-[4.6rem] flex items-center justify-center"
"border border-white rounded-full w-[4.6rem] h-[4.6rem] flex items-center justify-center mt-4"
)}
/>
)}
<View style={tailwind("flex flex-col w-full mt-4")}>
{data?.map((item, index) => (
<CollaboratorItem key={index} item={item} />
))}
</View>
<View style={tailwind("mt-8")}>
<Text style={tailwind("text-[#FFFFFF80] text-base font-medium")}>
注意事项

View File

@ -56,6 +56,7 @@ export default function SpaceRefund({ navigation, route }) {
if (isSubmitting) return;
setIsSubmitting(true);
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
const base = await baseRequest();
try {
const body = {
zid: route.params.data.id,
@ -76,7 +77,6 @@ export default function SpaceRefund({ navigation, route }) {
}
);
const _data = await _response.json();
console.log(_data);
if (_data.ret === -1) {
Toast.show({
type: "error",

View File

@ -145,12 +145,21 @@ export default function StreamerSpace({ navigation, route }) {
//tab
const layout = useWindowDimensions();
const [index, setIndex] = useState(0);
const [routes] = useState([
const [routes, setRoutes] = useState([
{ key: "all", title: "全部" },
{ key: "ironFan", title: "铁粉专享" },
{ key: "superFan", title: "超粉专享" },
]);
//tab
useEffect(() => {
if (data?.is_superfanship_enabled === 0)
setRoutes([
{ key: "all", title: "全部" },
{ key: "ironFan", title: "铁粉专享" },
]);
}, [data]);
const renderScene = useCallback(
SceneMap({
all: () => <AllSpacePosts zid={data?.id} />,

View File

@ -19,7 +19,6 @@ import Toast from "react-native-toast-message";
import * as Clipboard from "expo-clipboard";
import { generateSignature } from "../../../utils/crypto";
//todo:线
export default function AlreadyAddWechat({}) {
const blurhash = "LcKUTa%gOYWBYRt6xuoJo~s8V@fk";