437 lines
14 KiB
JavaScript
437 lines
14 KiB
JavaScript
import {
|
||
View,
|
||
Text,
|
||
TextInput,
|
||
ScrollView,
|
||
Modal,
|
||
TouchableOpacity,
|
||
KeyboardAvoidingView,
|
||
ActivityIndicator,
|
||
} from "react-native";
|
||
import React, { useState, useEffect } from "react";
|
||
import { useTailwind } from "tailwind-rn";
|
||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||
import MediaPicker from "../../components/MediaPicker";
|
||
import { Button, Switch } from "@rneui/themed";
|
||
import Toast from "react-native-toast-message";
|
||
import { multiUpload } from "../../utils/upload";
|
||
import baseRequest from "../../utils/baseRequest";
|
||
import { generateSignature } from "../../utils/crypto";
|
||
import MyModal from "../../components/MyModal";
|
||
|
||
export default function CreateVideoPost({ navigation, route }) {
|
||
const tailwind = useTailwind();
|
||
const insets = useSafeAreaInsets();
|
||
|
||
//文案
|
||
const [content, setContent] = useState();
|
||
|
||
//视频
|
||
const [videoAssets, setVideoAssets] = useState([]);
|
||
|
||
//付费设置弹窗是否展示
|
||
const [isModalVisible, setIsModalVisible] = useState(false);
|
||
|
||
//价格
|
||
const [price, setPrice] = useState();
|
||
|
||
//可预览文案行数
|
||
const [textVisibleRange, setTextVisibleRange] = useState("999");
|
||
|
||
//是否模糊封面
|
||
const [blurCover, setBlurCover] = useState(true);
|
||
|
||
//是否铁粉免费查看
|
||
const [isFreeForIronfan, setIsFreeForIronfan] = useState(false);
|
||
|
||
//正在提交
|
||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||
|
||
//保存付费设置
|
||
const handleSavePaymentSetting = () => {
|
||
if (parseFloat(price) < 0) {
|
||
Toast.show({
|
||
type: "error",
|
||
text1: "请输入正确区间的价格",
|
||
topOffset: 60,
|
||
});
|
||
return;
|
||
}
|
||
if (parseFloat(price) > 0 && parseInt(parseFloat(price) * 100, 10) < 100) {
|
||
Toast.show({
|
||
type: "error",
|
||
text1: "请输入正确区间的价格",
|
||
topOffset: 60,
|
||
});
|
||
return;
|
||
}
|
||
if (parseInt(parseFloat(price) * 100, 10) > 300000) {
|
||
Toast.show({
|
||
type: "error",
|
||
text1: "请输入正确区间的价格",
|
||
topOffset: 60,
|
||
});
|
||
return;
|
||
}
|
||
if (parseInt(textVisibleRange, 10) < 1) {
|
||
Toast.show({
|
||
type: "error",
|
||
text1: "请输入正确区间的可预览文案行数",
|
||
topOffset: 60,
|
||
});
|
||
return;
|
||
}
|
||
setIsModalVisible(false);
|
||
};
|
||
|
||
//发布内容
|
||
const handleSubmit = async () => {
|
||
if (!content) {
|
||
Toast.show({
|
||
type: "error",
|
||
text1: "动态内容不能为空",
|
||
topOffset: 60,
|
||
});
|
||
return;
|
||
}
|
||
if (videoAssets.length === 0) {
|
||
Toast.show({
|
||
type: "error",
|
||
text1: "请选择视频",
|
||
topOffset: 60,
|
||
});
|
||
return;
|
||
}
|
||
//提交数据
|
||
if (isSubmitting) return;
|
||
setIsSubmitting(true);
|
||
const media = await multiUpload(videoAssets);
|
||
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
|
||
try {
|
||
const base = await baseRequest();
|
||
const body = {
|
||
...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,
|
||
};
|
||
const signature = await generateSignature(body);
|
||
const response = await fetch(
|
||
`${apiUrl}/api/zone_moment/create?signature=${signature}`,
|
||
{
|
||
method: "POST",
|
||
headers: {
|
||
"Content-Type": "application/json",
|
||
},
|
||
body: JSON.stringify(body),
|
||
}
|
||
);
|
||
const data = await response.json();
|
||
if (data.ret === -1) {
|
||
Toast.show({
|
||
type: "error",
|
||
text1: data.msg,
|
||
topOffset: 60,
|
||
});
|
||
return;
|
||
}
|
||
//提交成功后显示Toast并返回上一页
|
||
Toast.show({
|
||
type: "success",
|
||
text1: "发布成功",
|
||
topOffset: 60,
|
||
});
|
||
navigation.goBack();
|
||
} catch (error) {
|
||
console.error(error);
|
||
} finally {
|
||
setIsSubmitting(false);
|
||
}
|
||
};
|
||
|
||
//发布按钮
|
||
useEffect(() => {
|
||
navigation.setOptions({
|
||
headerRight: () => (
|
||
<Text
|
||
onPress={handleSubmit}
|
||
style={tailwind("text-[#FF669E] text-base font-medium")}
|
||
>
|
||
{isSubmitting ? "" : "发布"}
|
||
{isSubmitting && <ActivityIndicator size="small" color="white" />}
|
||
</Text>
|
||
),
|
||
});
|
||
}, [navigation, handleSubmit, isSubmitting]);
|
||
|
||
//查询已发布空间内免费帖数量、付费帖数量、发布付费帖剩余额度、审核未通过帖数量
|
||
const [postCount, setPostCount] = useState();
|
||
const [isBlockModalVisible, setIsBlockModalVisible] = useState(false);
|
||
useEffect(() => {
|
||
const getPostCountData = async () => {
|
||
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
|
||
try {
|
||
const base = await baseRequest();
|
||
const body = {
|
||
...base,
|
||
};
|
||
const signature = await generateSignature(body);
|
||
const _response = await fetch(
|
||
`${apiUrl}/api/zone_moment/list_statistics_by_creater_mid?signature=${signature}`,
|
||
{
|
||
method: "POST",
|
||
headers: {
|
||
"Content-Type": "application/json",
|
||
},
|
||
body: JSON.stringify(body),
|
||
}
|
||
);
|
||
const _data = await _response.json();
|
||
if (_data.ret === -1) {
|
||
Toast.show({
|
||
type: "error",
|
||
text1: _data.msg,
|
||
topOffset: 60,
|
||
});
|
||
return;
|
||
}
|
||
setPostCount(_data.data);
|
||
if (_data.data.rejected_count >= 5) setIsBlockModalVisible(true);
|
||
} catch (error) {
|
||
console.error(error);
|
||
}
|
||
};
|
||
getPostCountData();
|
||
}, []);
|
||
|
||
return (
|
||
<ScrollView
|
||
style={{
|
||
paddingBottom: insets.bottom,
|
||
paddingLeft: insets.left,
|
||
paddingRight: insets.right,
|
||
...tailwind("flex-1"),
|
||
}}
|
||
>
|
||
<MyModal
|
||
visible={isBlockModalVisible}
|
||
setVisible={setIsBlockModalVisible}
|
||
title="当前无法发帖"
|
||
content="您当前审核未通过动态过多,请修改后再试"
|
||
custom={() => {
|
||
setIsBlockModalVisible(false);
|
||
setTimeout(
|
||
() => navigation.replace("VisibleToOneselfSpacePosts"),
|
||
500
|
||
);
|
||
}}
|
||
customText="去修改"
|
||
/>
|
||
<View style={tailwind("p-4")}>
|
||
<View style={tailwind("mb-4")}>
|
||
<Text style={tailwind("text-sm font-medium text-[#27F5B7] mb-2")}>
|
||
为了空间良性发展,请保持免费/付费比例为1/1
|
||
</Text>
|
||
<View
|
||
style={tailwind(
|
||
"flex flex-row flex-wrap justify-between p-4 rounded-2xl bg-[#FFFFFF1A]"
|
||
)}
|
||
>
|
||
<Text style={tailwind("text-xs font-medium text-white basis-1/2")}>
|
||
已发布免费动态:{postCount?.free_count}条
|
||
</Text>
|
||
<Text style={tailwind("text-xs font-medium text-white basis-1/2")}>
|
||
已发布付费动态:{postCount?.paid_count}条
|
||
</Text>
|
||
<Text style={tailwind("text-xs font-medium text-white basis-1/2")}>
|
||
<Text style={tailwind("text-[#27F5B7]")}>可发布付费动态:</Text>
|
||
{postCount?.paid_limit}条
|
||
</Text>
|
||
<Text style={tailwind("text-xs font-medium text-white basis-1/2")}>
|
||
<Text style={tailwind("text-[#F53030]")}>审核未通过动态:</Text>
|
||
{postCount?.rejected_count}条
|
||
</Text>
|
||
</View>
|
||
</View>
|
||
<Text style={tailwind("text-base font-medium text-white")}>
|
||
动态内容
|
||
</Text>
|
||
<TextInput
|
||
placeholder="请遵守平台准则,严禁发布违规内容"
|
||
placeholderTextColor="#FFFFFF80"
|
||
underlineColorAndroid="transparent"
|
||
multiline
|
||
textAlignVertical="top"
|
||
onChangeText={(value) => setContent(value)}
|
||
value={content}
|
||
style={tailwind(
|
||
"h-32 bg-[#FFFFFF1A] text-white rounded-2xl mt-2 mb-4 p-2"
|
||
)}
|
||
/>
|
||
<MediaPicker maxCount={1} type="video" setAssets={setVideoAssets} />
|
||
<Button
|
||
color="#FF669E"
|
||
radius="999"
|
||
size="md"
|
||
onPress={() => setIsModalVisible(!isModalVisible)}
|
||
titleStyle={tailwind("text-base")}
|
||
containerStyle={tailwind("mt-4 w-28")}
|
||
>
|
||
付费设置
|
||
</Button>
|
||
<Modal
|
||
visible={isModalVisible}
|
||
transparent={true}
|
||
statusBarTranslucent
|
||
animationType="slide"
|
||
>
|
||
<TouchableOpacity
|
||
activeOpacity={1}
|
||
style={{
|
||
paddingBottom: insets.bottom,
|
||
paddingLeft: insets.left,
|
||
paddingRight: insets.right,
|
||
...tailwind("flex flex-1 bg-[#00000080] px-4"),
|
||
}}
|
||
onPress={handleSavePaymentSetting}
|
||
>
|
||
<KeyboardAvoidingView style={tailwind("flex-1")} behavior="padding">
|
||
<TouchableOpacity
|
||
activeOpacity={1}
|
||
style={{
|
||
gap: 8,
|
||
...tailwind(
|
||
"flex flex-col mt-auto mb-2 bg-[#17161A] rounded-3xl"
|
||
),
|
||
}}
|
||
>
|
||
<View
|
||
style={{
|
||
gap: 8,
|
||
...tailwind("flex flex-col px-6 pt-6 pb-2"),
|
||
}}
|
||
>
|
||
<View style={tailwind("flex flex-row items-center")}>
|
||
<Text style={tailwind("text-white text-base font-medium")}>
|
||
价格:
|
||
</Text>
|
||
<TextInput
|
||
placeholder="¥1~3000"
|
||
placeholderTextColor="#FFFFFF80"
|
||
keyboardType="numeric"
|
||
underlineColorAndroid="transparent"
|
||
onChangeText={(value) => setPrice(value)}
|
||
value={price}
|
||
style={tailwind(
|
||
"flex-1 bg-[#FFFFFF1A] text-white rounded-2xl px-4 h-8 mx-2"
|
||
)}
|
||
/>
|
||
<Text
|
||
onPress={() => setPrice("0")}
|
||
style={tailwind("text-[#FF669E] text-base font-medium")}
|
||
>
|
||
免费
|
||
</Text>
|
||
</View>
|
||
{parseFloat(price) > 0 && (
|
||
<>
|
||
<View style={tailwind("flex flex-row items-center")}>
|
||
<Text
|
||
style={tailwind(
|
||
"text-white text-base font-medium mr-2"
|
||
)}
|
||
>
|
||
可预览文案:
|
||
</Text>
|
||
<Text
|
||
style={tailwind("text-white text-base font-medium")}
|
||
>
|
||
前
|
||
</Text>
|
||
<TextInput
|
||
placeholder="1~10"
|
||
placeholderTextColor="#FFFFFF80"
|
||
keyboardType="numeric"
|
||
underlineColorAndroid="transparent"
|
||
onChangeText={(value) => setTextVisibleRange(value)}
|
||
value={textVisibleRange}
|
||
style={tailwind(
|
||
"bg-[#FFFFFF1A] text-white rounded-2xl px-4 mx-2 h-8"
|
||
)}
|
||
/>
|
||
<Text
|
||
style={tailwind("text-white text-base font-medium")}
|
||
>
|
||
行
|
||
</Text>
|
||
<Text
|
||
onPress={() => setTextVisibleRange("999")}
|
||
style={tailwind(
|
||
"text-[#FF669E] text-base font-medium ml-auto"
|
||
)}
|
||
>
|
||
全部可见
|
||
</Text>
|
||
</View>
|
||
<View style={tailwind("flex flex-row items-center")}>
|
||
<Text
|
||
style={tailwind(
|
||
"text-white text-base font-medium mr-2"
|
||
)}
|
||
>
|
||
封面模糊:
|
||
</Text>
|
||
<Switch
|
||
value={blurCover}
|
||
onValueChange={(value) => setBlurCover(value)}
|
||
thumbColor="#ffffff"
|
||
trackColor={{ true: "#FF669E", false: "#FFFFFF1A" }}
|
||
/>
|
||
</View>
|
||
<View style={tailwind("flex flex-row items-center")}>
|
||
<Text
|
||
style={tailwind(
|
||
"text-white text-base font-medium mr-2"
|
||
)}
|
||
>
|
||
铁粉免费查看:
|
||
</Text>
|
||
<Switch
|
||
value={isFreeForIronfan}
|
||
onValueChange={(value) => setIsFreeForIronfan(value)}
|
||
thumbColor="#ffffff"
|
||
trackColor={{ true: "#FF669E", false: "#FFFFFF1A" }}
|
||
/>
|
||
</View>
|
||
</>
|
||
)}
|
||
</View>
|
||
<TouchableOpacity
|
||
onPress={handleSavePaymentSetting}
|
||
style={{
|
||
height: 52,
|
||
...tailwind(
|
||
"flex justify-center items-center border-t border-[#FFFFFF14]"
|
||
),
|
||
}}
|
||
>
|
||
<Text style={tailwind("text-white text-base font-medium")}>
|
||
保存
|
||
</Text>
|
||
</TouchableOpacity>
|
||
</TouchableOpacity>
|
||
</KeyboardAvoidingView>
|
||
</TouchableOpacity>
|
||
</Modal>
|
||
</View>
|
||
</ScrollView>
|
||
);
|
||
}
|