tiefen_space_app/screeens/EditSpacePost/index.jsx

758 lines
26 KiB
React
Raw Normal View History

2024-04-18 22:58:59 +08:00
import {
View,
Text,
TextInput,
ScrollView,
ActivityIndicator,
Modal,
KeyboardAvoidingView,
TouchableOpacity,
Platform,
2024-04-18 22:58:59 +08:00
} from "react-native";
import React, { useState, useEffect } from "react";
2024-04-18 22:58:59 +08:00
import { useTailwind } from "tailwind-rn";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import MediaPicker from "../../components/MediaPicker";
import Toast from "react-native-toast-message";
import { multiUpload } from "../../utils/upload";
import baseRequest from "../../utils/baseRequest";
import { generateSignature } from "../../utils/crypto";
import { Button, Switch } from "@rneui/themed";
import MediaGrid from "../../components/MediaGrid";
import requireAPI from "../../utils/requireAPI";
2024-04-18 22:58:59 +08:00
export default function EditSpacePost({ navigation, route }) {
// const initalData = route.params.data;
2024-04-18 22:58:59 +08:00
const tailwind = useTailwind();
const insets = useSafeAreaInsets();
const [content, setContent] = useState(null);
2024-04-18 22:58:59 +08:00
const [isSubmitting, setIsSubmitting] = useState(false);
//付费设置弹窗是否展示
const [isModalVisible, setIsModalVisible] = useState(false);
//价格
const [price, setPrice] = useState(0);
//可预览文案行数
const [textVisibleRange, setTextVisibleRange] = useState(null);
//可预览图片张数
const [imageVisibleRange, setImageVisibleRange] = useState();
//是否模糊封面
const [blurCover, setBlurCover] = useState(true);
//是否铁粉免费查看
const [isFreeForIronfan, setIsFreeForIronfan] = useState();
//是否添加付费文案
const [isCreatingPaidText, setIsCreatingPaidText] = useState(false);
//付费文案内容
const [paidText, setPaidText] = useState();
//保存新添加的媒体
const [newMeidaAssets, setNewMediaAssets] = useState([]);
//展示旧媒体组件
const [oldMediaAssets, setOldMediaAssets] = useState([]);
const [initalData, setInitalData] = useState({});
useEffect(() => {
getData();
}, []);
const getData = async () => {
const ids = [parseInt(route.params.id, 10)];
try {
const body = {
ids,
};
const _data = await requireAPI(
"POST",
"/api/zone_moment/list_by_ids_from_creater",
{
body,
},
true
);
if (_data.ret === -1) {
Toast.show({
type: "error",
text1: _data.msg,
topOffset: 60,
});
return;
}
const {
text,
paid_text,
price,
media_visible_range,
text_visible_range,
is_creating_paid_text,
is_ironfan_visible,
is_blurring_cover,
m_type,
media_component,
} = _data.data.list[0];
setContent(
is_creating_paid_text
? text.slice(0, text.length - paid_text.length)
: text
);
setPrice((price ? price / 100 : 0).toString());
2025-02-18 19:10:44 +08:00
setTextVisibleRange(text_visible_range?.toString());
setImageVisibleRange(media_visible_range?.toString());
setBlurCover(is_blurring_cover === 1);
setIsFreeForIronfan(is_ironfan_visible === 1);
setPaidText(paid_text ? paid_text.substring(1) : "");
setIsCreatingPaidText(is_creating_paid_text === 1);
setOldMediaAssets(
m_type === 1 ? media_component.images : media_component.videos
);
setInitalData(_data.data.list[0]);
} catch (error) {
console.error(error);
} finally {
setIsSubmitting(false);
}
};
//保存付费设置
const handleSavePaymentSetting = () => {
if (parseFloat(price) === 0) {
Toast.show({
type: "error",
text1: "不可改为免费动态",
topOffset: 60,
});
return;
}
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;
}
if (
parseInt(imageVisibleRange, 10) < 0 ||
parseInt(imageVisibleRange, 10) > 3
) {
Toast.show({
type: "error",
text1: "请输入正确区间的可预览图片张数",
topOffset: 60,
});
return;
}
setIsModalVisible(false);
};
2024-04-18 22:58:59 +08:00
//发布更新内容
const handleSubmit = async () => {
if (!content) {
Toast.show({
type: "error",
text1: "动态内容不能为空",
topOffset: 60,
});
return;
}
if (oldMediaAssets.length === 0 && newMeidaAssets.length === 0) {
Toast.show({
type: "error",
text1: "请选择要上传的图片或视频",
topOffset: 60,
});
return;
}
if (
initalData.m_type === 1 &&
2024-04-18 22:58:59 +08:00
oldMediaAssets.length + newMeidaAssets.length > 30
) {
Toast.show({
type: "error",
text1: "最多只能上传30张照片哦",
topOffset: 60,
});
return;
}
if (
initalData.m_type === 2 &&
2024-04-18 22:58:59 +08:00
oldMediaAssets.length + newMeidaAssets.length > 1
) {
Toast.show({
type: "error",
text1: "最多只能上传1个视频哦",
topOffset: 60,
});
return;
}
if (
initalData.c_type === 1 &&
initalData.m_type === 1 &&
oldMediaAssets.length + newMeidaAssets.length <= imageVisibleRange
2024-04-18 22:58:59 +08:00
) {
Toast.show({
type: "error",
text1: "预览图片数不得大于等于上传图片数",
topOffset: 60,
});
return;
}
2024-05-22 12:15:24 +08:00
if (isCreatingPaidText && price > 0 && !paidText) {
Toast.show({
type: "error",
text1: "请填写付费文案",
topOffset: 60,
});
return;
}
2024-04-18 22:58:59 +08:00
//提交数据
if (isSubmitting) return;
setIsSubmitting(true);
const newMediaIds = await multiUpload(newMeidaAssets);
const oldMediaIds = oldMediaAssets.map((item) => item.id);
const media = {
image_ids:
initalData.m_type === 1
? [...oldMediaIds, ...newMediaIds?.image_ids]
: [],
2024-04-18 22:58:59 +08:00
video_ids:
initalData.m_type === 2
? [...oldMediaIds, ...newMediaIds?.video_ids]
: [],
2024-04-18 22:58:59 +08:00
};
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
try {
const base = await baseRequest();
const body = {
...base,
id: initalData.id,
c_type: initalData.c_type,
m_type: initalData.m_type,
2024-04-18 22:58:59 +08:00
text: content,
media_component: media,
text_visible_range: textVisibleRange
? parseInt(textVisibleRange, 10)
: 999,
media_visible_range: imageVisibleRange
? parseInt(imageVisibleRange, 10)
: 1,
is_blurring_cover: blurCover ? 1 : 0,
is_ironfan_visible: isFreeForIronfan ? 1 : 0,
2024-05-01 00:51:16 +08:00
price: parseFloat(price) ? parseInt(parseFloat(price) * 100, 10) : null,
2024-05-22 12:15:24 +08:00
is_creating_paid_text: isCreatingPaidText && price > 0 ? 1 : 0,
paid_text: isCreatingPaidText && price > 0 ? paidText : null,
2024-04-18 22:58:59 +08:00
};
const signature = await generateSignature(body);
const _response = await fetch(
`${apiUrl}/api/zone_moment/update?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: "info",
text1: "提交成功,等耐心等待审核",
2024-04-18 22:58:59 +08:00
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>
),
});
}, [isSubmitting, handleSubmit]);
//是否正在拖动图片用于禁用ScrollView的滚动
const [dragging, setDragging] = useState(false);
2024-04-18 22:58:59 +08:00
return (
<KeyboardAvoidingView
behavior={Platform.OS == "ios" ? "padding" : "height"}
keyboardVerticalOffset={insets.bottom + 60}
2024-04-18 22:58:59 +08:00
style={{
paddingLeft: insets.left,
paddingRight: insets.right,
...tailwind("flex-1"),
}}
>
<ScrollView scrollEnabled={!dragging}>
<View style={tailwind("p-4")}>
{initalData?.status === 3 && (
<View style={tailwind("mb-4")}>
<Text
style={tailwind("text-base font-medium text-[#F53030] mb-2")}
>
违规详情
</Text>
<View style={tailwind("p-4 rounded-2xl bg-[#FFFFFF1A]")}>
{initalData.text_audit_opinion && (
<Text style={tailwind("text-sm font-medium text-white")}>
<Text style={tailwind("text-[#F53030]")}>
文案违规原因
</Text>
{initalData.text_audit_opinion}
</Text>
)}
{initalData.image_audit_opinion && (
<Text style={tailwind("text-sm font-medium text-white")}>
<Text style={tailwind("text-[#F53030]")}>
图片/视频违规原因
</Text>
{initalData.image_audit_opinion}
</Text>
)}
{initalData.manually_review_opinion && (
<Text style={tailwind("text-sm font-medium text-white")}>
<Text style={tailwind("text-[#F53030]")}>运营追加</Text>
{initalData.manually_review_opinion}
</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"
)}
/>
2024-05-22 12:15:24 +08:00
{isCreatingPaidText && price > 0 && (
<>
<Text style={tailwind("text-base font-medium text-white")}>
付费文案
</Text>
<TextInput
placeholder="仅在用户解锁后展示,请勿发布违规内容"
placeholderTextColor="#FFFFFF80"
underlineColorAndroid="transparent"
multiline
textAlignVertical="top"
onChangeText={(value) => setPaidText(value)}
value={paidText}
style={tailwind(
"h-32 bg-[#FFFFFF1A] text-white rounded-2xl mt-2 mb-4 p-2"
)}
/>
</>
)}
{oldMediaAssets.length > 0 && (
<MediaGrid
setDragging={setDragging}
assets={oldMediaAssets}
setAssets={setOldMediaAssets}
/>
)}
<MediaPicker
setDragging={setDragging}
maxCount={
initalData.m_type === 1
? 30 - oldMediaAssets.length
: 1 - oldMediaAssets.length
}
type={initalData.m_type === 1 ? "image" : "video"}
setAssets={setNewMediaAssets}
/>
{initalData.c_type === 1 && (
<Button
color="#FF669E"
radius="999"
size="md"
onPress={() => setIsModalVisible(!isModalVisible)}
titleStyle={tailwind("text-base")}
containerStyle={tailwind("mt-4 w-28")}
>
付费设置
</Button>
2024-04-18 22:58:59 +08:00
)}
{initalData.m_type === 1 && (
<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="¥13000"
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="0~3"
placeholderTextColor="#FFFFFF80"
keyboardType="numeric"
underlineColorAndroid="transparent"
onChangeText={(value) =>
setImageVisibleRange(value)
}
value={imageVisibleRange}
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={() => setImageVisibleRange("0")}
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={isCreatingPaidText}
onValueChange={(value) =>
setIsCreatingPaidText(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>
<Toast />
</Modal>
)}
{initalData.m_type === 2 && (
<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="¥13000"
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>
<Switch
value={isCreatingPaidText}
onValueChange={(value) =>
setIsCreatingPaidText(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={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>
</KeyboardAvoidingView>
2024-04-18 22:58:59 +08:00
);
}