tiefen_space_app/screeens/EditStreamerMedia/index.jsx

402 lines
14 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
View,
Text,
ScrollView,
TouchableOpacity,
KeyboardAvoidingView,
Platform,
ActivityIndicator,
} from "react-native";
import React, { useState, useEffect } from "react";
import { useTailwind } from "tailwind-rn";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { Divider, Icon, Button } from "@rneui/themed";
import { Image } from "expo-image";
import { Formik } from "formik";
import MediaPickerModal from "../../components/MediaPickerModal";
import MediaPicker from "../../components/MediaPicker";
import Toast from "react-native-toast-message";
import { get } from "../../utils/storeInfo";
import { multiUpload } from "../../utils/upload";
import baseRequest from "../../utils/baseRequest";
import { generateSignature } from "../../utils/crypto";
const blurhash = "LcKUTa%gOYWBYRt6xuoJo~s8V@fk";
export default function EditStreamerMedia({ navigation, route }) {
const tailwind = useTailwind();
const insets = useSafeAreaInsets();
//保存封面图以及控制上传封面图Modal出现
const [displayImagePickerModalVisible, setDisplayImagePickerModalVisible] =
useState(false);
const [displayImage, setDisplayImage] = useState([]);
//保存展示视频以及控制上传展示视频Modal出现
const [displayVideoPickerModalVisible, setDisplayVideoPickerModalVisible] =
useState(false);
const [displayVideo, setDisplayVideo] = useState([]);
//保存新添加的相册图片
const [photos, setPhotos] = useState([]);
//展示旧相册图片组件
const [oldPhotos, setOldPhotos] = useState([]);
const DisplayOldPhotos = ({ url, index }) => {
const handleDelete = () => {
const updatedAssets = [...oldPhotos];
updatedAssets.splice(index, 1);
setOldPhotos(updatedAssets);
};
return (
<View
style={{
aspectRatio: 1,
...tailwind("w-1/4 p-1"),
}}
>
<Image
style={tailwind("w-full h-full rounded-lg")}
source={url}
contentFit="cover"
cachePolicy="disk"
/>
<View style={tailwind("absolute top-2 right-2")}>
<Icon
type="ionicon"
name="close"
color="white"
size={18}
onPress={handleDelete}
style={tailwind("bg-black rounded-full opacity-70")}
/>
</View>
</View>
);
};
//正在加载数据
const [isLoading, setIsloading] = useState(true);
useEffect(() => {
const getData = async () => {
const account = await get("account");
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
const base = await baseRequest();
const signature = await generateSignature({
mid: account?.mid,
...base,
});
try {
//获取主播数据
const streamerResponse = await fetch(
`${apiUrl}/api/streamer/list_by_mid?signature=${signature}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
mid: account?.mid,
...base,
}),
}
);
const streamerData = await streamerResponse.json();
if (streamerData.ret === -1) {
Toast.show({
type: "error",
text1: streamerData.msg,
topOffset: 60,
});
return;
}
setDisplayImage([
{
notChanged: true,
id: { image_ids: streamerData.data.streamer.cover.image_ids },
uri: streamerData.data.streamer.cover.images[0].urls[0],
},
]);
setDisplayVideo([
{
notChanged: true,
id: { video_ids: streamerData.data.streamer.shorts.video_ids },
old_uri:
streamerData?.data?.streamer?.shorts?.videos[0]?.cover_urls[0],
},
]);
setOldPhotos(streamerData.data.streamer.album.images);
setIsloading(false);
} catch (error) {
console.error(error);
}
};
getData();
}, []);
//正在提交状态
const [isSubmitting, setIsSubmitting] = useState(false);
//loading时展示加载中
if (isLoading) {
return (
<ActivityIndicator style={tailwind("mt-32")} size="large" color="white" />
);
}
return (
<KeyboardAvoidingView
behavior={Platform.OS == "ios" ? "padding" : "height"}
keyboardVerticalOffset={insets.bottom + 60}
style={{
paddingLeft: insets.left,
paddingRight: insets.right,
...tailwind("flex-1"),
}}
>
<ScrollView style={tailwind("px-4 py-4")}>
<Formik
initialValues={{}}
enableReinitialize
onSubmit={async () => {
//相册不得低于2张
if (oldPhotos.length + photos.length < 2) {
Toast.show({
type: "error",
text1: "相册至少需要上传2张照片哦",
topOffset: 60,
});
return;
}
//相册不得超过9张
if (oldPhotos.length + photos.length > 9) {
Toast.show({
type: "error",
text1: "相册最多只能上传9张照片哦",
topOffset: 60,
});
return;
}
setIsSubmitting(true);
const account = await get("account");
const cover = displayImage[0].notChanged
? displayImage[0].id
: await multiUpload(displayImage);
const shorts = displayVideo[0].notChanged
? displayVideo[0].id
: await multiUpload(displayVideo);
const newPhotosIds = await multiUpload(photos);
const oldPhotosIds = oldPhotos.map((item) => item.id);
const album = {
image_ids: [...oldPhotosIds, ...newPhotosIds?.image_ids],
};
if (
!cover.image_ids.length ||
!shorts.video_ids.length ||
!album.image_ids.length
) {
Toast.show({
type: "error",
text1: "上传失败,请联系客服进行上传",
topOffset: 60,
});
setIsSubmitting(false);
return;
}
//获取环境变量
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
//上传表单
const base = await baseRequest();
const signature = await generateSignature({
mid: account?.mid,
cover: cover,
shorts: shorts,
album: album,
...base,
});
try {
const response = await fetch(
`${apiUrl}/api/streamer/update?signature=${signature}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
mid: account?.mid,
cover: cover,
shorts: shorts,
album: album,
...base,
}),
}
);
const streamerData = await response.json();
if (streamerData.ret === -1) {
Toast.show({
type: "error",
text1: streamerData.msg,
topOffset: 60,
});
return;
}
//提交成功后弹窗提示并返回上级
Toast.show({
type: "success",
text1: "更改成功",
topOffset: 60,
});
navigation.goBack();
} catch (error) {
console.error(error);
} finally {
setIsSubmitting(false);
}
}}
>
{({ handleSubmit }) => (
<>
<Text style={tailwind("text-sm text-[#F53030] font-medium")}>
将展示在推荐主页空间请认真完善
</Text>
<View style={tailwind("my-2 bg-[#FFFFFF1A] p-2 rounded-2xl")}>
<View style={tailwind("flex-row justify-between items-center")}>
<Text style={tailwind("text-base text-white font-medium")}>
<Text style={tailwind("text-[#F53030]")}>*</Text>
封面图
</Text>
<TouchableOpacity
onPress={() => setDisplayImagePickerModalVisible(true)}
style={tailwind("flex-row items-center")}
>
{displayImage.length !== 0 ? (
<Image
style={tailwind("w-12 h-12 rounded-lg")}
source={displayImage[0].uri}
placeholder={blurhash}
contentFit="cover"
transition={1000}
cachePolicy="disk"
/>
) : (
<Text
style={tailwind("text-xs text-[#FFFFFF80] font-medium")}
>
请尽量选择横屏照片
</Text>
)}
<Icon
name="chevron-forward-outline"
type="ionicon"
color="white"
/>
</TouchableOpacity>
<MediaPickerModal
visible={displayImagePickerModalVisible}
setVisible={setDisplayImagePickerModalVisible}
type="image"
maxCount={1}
setAssets={setDisplayImage}
/>
</View>
<Divider style={tailwind("my-2")} />
<View style={tailwind("flex-row justify-between items-center")}>
<Text style={tailwind("text-base text-white font-medium")}>
<Text style={tailwind("text-[#F53030]")}>*</Text>
展示视频
</Text>
<TouchableOpacity
onPress={() => setDisplayVideoPickerModalVisible(true)}
style={tailwind("flex-row items-center")}
>
{displayVideo.length !== 0 ? (
<Image
style={tailwind("w-12 h-16 rounded-lg")}
source={displayVideo[0].old_uri}
placeholder={blurhash}
contentFit="cover"
transition={1000}
cachePolicy="disk"
/>
) : (
<Text
style={tailwind("text-xs text-[#FFFFFF80] font-medium")}
>
请选择60秒内短视频
</Text>
)}
<Icon
name="chevron-forward-outline"
type="ionicon"
color="white"
/>
</TouchableOpacity>
<MediaPickerModal
visible={displayVideoPickerModalVisible}
setVisible={setDisplayVideoPickerModalVisible}
type="video"
maxCount={1}
setAssets={setDisplayVideo}
/>
</View>
<Divider style={tailwind("my-2")} />
<View>
<View
style={tailwind("flex-row justify-between items-center")}
>
<Text style={tailwind("text-base text-white font-medium")}>
<Text style={tailwind("text-[#F53030]")}>*</Text>
相册
</Text>
<Text
style={tailwind("text-xs text-[#FFFFFF80] font-medium")}
>
请上传29张照片
</Text>
</View>
<View style={tailwind("flex-row flex-wrap")}>
{oldPhotos.map((item, index) => (
<DisplayOldPhotos
key={index}
url={item?.urls[0]}
index={index}
/>
))}
</View>
<MediaPicker
maxCount={9}
type="image"
setAssets={setPhotos}
/>
</View>
</View>
<Button
color="#FF669E"
radius="999"
size="md"
disabled={isSubmitting}
disabledStyle={tailwind("bg-[#FFFFFF80]")}
disabledTitleStyle={tailwind("text-white")}
onPress={(e) => {
handleSubmit(e);
}}
titleStyle={tailwind("text-base")}
containerStyle={{
marginBottom: insets.bottom + 60,
...tailwind("mt-4"),
}}
>
{isSubmitting && (
<ActivityIndicator size="small" color="white" />
)}
{isSubmitting ? "正在提交..." : "确认修改"}
</Button>
</>
)}
</Formik>
</ScrollView>
</KeyboardAvoidingView>
);
}