update 17 files

master
Reza_ashrafi 2 years ago
parent 9ccfb80304
commit c10d14f827
  1. 4
      src/redux/actions/config.js
  2. 1
      src/redux/proxy.js
  3. 11
      src/redux/reducers/config.js
  4. 2
      src/redux/reducers/file.js
  5. 554
      src/screens/Product/components/Book.js
  6. 6
      src/screens/Product/index.js
  7. 4
      src/screens/Profile/components/User.js
  8. 5
      src/screens/Splash/index.js
  9. 27
      src/screens/Video/components/Season.js
  10. 45
      src/screens/Video/index.js
  11. 1
      src/screens/VideoDisplay/components/Season/index.js
  12. 20
      src/screens/VideoDisplay/index.js
  13. 24
      src/screens/Videos/components/MostViewedVideo.js
  14. 2
      src/screens/Videos/components/NewestVideo.js
  15. 1
      src/screens/Videos/index.js

@ -9,6 +9,10 @@ const config = {
(data = {}) => (data = {}) =>
async (dispatch) => async (dispatch) =>
await proxy.get("config/filters", data, { dispatch }), await proxy.get("config/filters", data, { dispatch }),
getAvailableForSell:
(data = {}) =>
async (dispatch) =>
await proxy.get("config/availableForSell", data, { dispatch }),
}; };
export default config; export default config;

@ -60,6 +60,7 @@ class Proxy {
dispatch = dispatch || (() => {}); dispatch = dispatch || (() => {});
dispatch({ type: url.split("/")[0] + "/" + "loading" }); dispatch({ type: url.split("/")[0] + "/" + "loading" });
let response = await fetch(); let response = await fetch();
// console.log(response);
switch (response.status) { switch (response.status) {
case 200: case 200:
dispatch({ type: url, data: response.data.data, params }); dispatch({ type: url, data: response.data.data, params });

@ -2,6 +2,7 @@ const initialState = {
loading: false, loading: false,
error: null, error: null,
bottomNavigation: null, bottomNavigation: null,
availableForSell: [],
}; };
export default function config(state = initialState, action) { export default function config(state = initialState, action) {
@ -14,6 +15,14 @@ export default function config(state = initialState, action) {
bottomNavigation: data.bottomNavigationList, bottomNavigation: data.bottomNavigationList,
error: null, error: null,
}; };
case "config/availableForSell":
console.log(data);
return {
...state,
loading: false,
availableForSell: data.productTypes,
error: null,
};
case "config/loading": case "config/loading":
return { ...state, loading: true }; return { ...state, loading: true };
case "config/error": case "config/error":
@ -21,4 +30,4 @@ export default function config(state = initialState, action) {
default: default:
return state; return state;
} }
} }

@ -7,7 +7,7 @@ export default function file(state = initialState, action) {
let { type, data, params } = action; let { type, data, params } = action;
switch (type) { switch (type) {
case "file/upload": case "file/upload":
console.log(data, params); console.log(data);
return { return {
...state, ...state,
loading: false, loading: false,

@ -18,7 +18,6 @@ import separate from "../../../utils/separate";
//components //components
import LinkBox from "./LinkBox"; import LinkBox from "./LinkBox";
import Comments from "./Comments"; import Comments from "./Comments";
import ImageSlider from "../../../components/ImageSlider";
import Rates from "./Rates"; import Rates from "./Rates";
//style //style
@ -39,20 +38,23 @@ function Book({
userProducts, userProducts,
theme, theme,
orientation, orientation,
availableForSell,
}) { }) {
const [width, setWidth] = React.useState(Dimensions.get("window").width); const [width, setWidth] = React.useState(Dimensions.get("window").width);
const navigation = useNavigation(); const navigation = useNavigation();
const [type, setType] = useState(1);
const [whichTypeAdded, setWhichTypeAdded] = React.useState(null); const [whichTypeAdded, setWhichTypeAdded] = React.useState(null);
const [pageLoading, setPageLoading] = useState(false);
const [imageSlider, setImageSlider] = useState(false);
useEffect(() => { const physicalAvailableForSell = React.useMemo(() => {
setPageLoading(true); return availableForSell?.filter((product) => product === 2)?.length;
setTimeout(() => { }, [availableForSell]);
setPageLoading(false);
}, 500); const digitalAvailableForSell = React.useMemo(() => {
}, [type]); return availableForSell?.filter((product) => product === 1)?.length;
}, [availableForSell]);
const videoAvailableForSell = React.useMemo(() => {
return availableForSell?.filter((product) => product === 4)?.length;
}, [availableForSell]);
const physicalProduct = React.useMemo(() => { const physicalProduct = React.useMemo(() => {
return book?.product?.filter((product) => product?.productType === 2)[0]; return book?.product?.filter((product) => product?.productType === 2)[0];
@ -134,6 +136,144 @@ function Book({
} }
}, [userProducts]); }, [userProducts]);
const ProductButton = ({
availableInCart,
availableForSell,
product,
type,
onLoad,
title,
sample,
sampleAction,
}) => {
return product ? (
<View style={tw("w-full flex flex-row-reverse justify-between")}>
<TouchableHighlight
underlayColor={Colors.theme1.greenFF + "22"}
style={[
tw("flex flex-row-reverse justify-between px-2 py-3 mb-4"),
{
borderWidth: 1,
borderColor: Colors.theme1.greenCF,
backgroundColor:
theme === "light" ? Colors.theme1.greenFF + "0a" : null,
width: width - 32 - 8 - (fontSize.sm * 6 + 18),
},
]}
onPress={() =>
availableInCart
? asyncAwesomeAlert(
"",
"این محصول قبلا به سبد خرید شما اضافه شده است.",
{
showCancelButton: true,
onConfirm: () =>
navigation.navigate("Root", {
screen: "ShoppingCartTab",
}),
confirmText: "مشاهده سبد خرید",
cancelText: "باشه",
}
)
: availableForSell
? addToCart(
pushToCart({
productId: product?.id,
userId: userId,
count: 1,
}),
type
)
: null
}
>
<>
{onLoad ? (
<ActivityIndicator
color={
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF
}
size={fontSize.sm}
/>
) : (
<Text
style={{
fontFamily: "bold",
fontSize: fontSize.sm,
color:
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF,
paddingVertical: 4,
}}
>
{title}
</Text>
)}
<View style={tw("flex flex-row-reverse items-center")}>
<View style={tw("w-px h-full bg-green-300")}></View>
<View style={tw("flex")}>
<Text
style={[
tw("py-1 pr-2"),
{
fontFamily: "bold",
color:
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF,
fontSize: fontSize.sm,
},
]}
>
{availableForSell
? (separate(product?.price) || " ") + " " + "تومان"
: "ناموجود"}
</Text>
</View>
</View>
</>
</TouchableHighlight>
{sample ? (
<TouchableHighlight
underlayColor={Colors.theme1.greenFF + "22"}
style={[
tw("flex flex-row-reverse justify-center px-2 py-3 mb-4"),
{
borderWidth: 1,
borderColor: Colors.theme1.greenCF,
backgroundColor:
theme === "light" ? Colors.theme1.greenFF + "0a" : null,
width: fontSize.sm * 6 + 18,
},
]}
onPress={() => sampleAction()}
>
<Text
style={{
fontFamily: "bold",
fontSize: fontSize.xs,
color:
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF,
paddingVertical: 4,
}}
>
مشاهده نمونه
</Text>
</TouchableHighlight>
) : null}
</View>
) : null;
};
return ( return (
<View <View
style={[tw("flex flex-1 relative")]} style={[tw("flex flex-1 relative")]}
@ -263,360 +403,61 @@ function Book({
}} }}
> >
{" "} {" "}
{4.8 + "\n" + "امتیاز"} {book?.rate || 4 + "\n" + "امتیاز"}
</Text> </Text>
</View> </View>
</View> </View>
{book?.product?.length > 1 ? ( {book?.product?.length > 1 ? (
<View style={"flex mt-8"}> <Text
<Text style={[
style={[ tw("w-full text-right"),
tw("w-full text-right"), {
{ color:
color: theme === "light" ? Colors.theme1.green79 : Colors.theme1.white,
theme === "light"
? Colors.theme1.green79
: Colors.theme1.white,
fontSize: mobile ? fontSize.tiny : fontSize.base, fontSize: mobile ? fontSize.tiny : fontSize.base,
fontFamily: "demi", fontFamily: "demi",
}, },
]} ]}
> >
نسخه محصول را انتخاب کنید نسخه محصول را انتخاب کنید
</Text> </Text>
<View style={tw("flex justify-between")}></View>
</View>
) : null} ) : null}
<View style={tw("flex flex-row-reverse justify-between flex-wrap py-3")}> <View style={tw("mt-4")}>
{physicalProduct ? ( <ProductButton
<TouchableHighlight product={physicalProduct}
underlayColor={Colors.theme1.greenFF + "22"} availableForSell={physicalAvailableForSell}
style={[ availableInCart={physicalAvailabileInCart}
tw("flex flex-row-reverse justify-between px-2 py-3 mb-4"), type="physical"
{ onLoad={whichTypeAdded === "physical" && userProductsLoading}
borderWidth: 1, title="خرید نسخه فیزیکی کتاب"
borderColor: Colors.theme1.greenCF, sample={true}
backgroundColor: sampleAction={() =>
theme === "light" ? Colors.theme1.greenFF + "0a" : null, navigation.push("Sample", { id: book?.sampleFileId })
width: width - 32 - 8 - (fontSize.sm * 6 + 18), }
}, />
]}
onPress={() =>
physicalAvailabileInCart
? asyncAwesomeAlert(
"",
"این محصول قبلا به سبد خرید شما اضافه شده است.",
{
showCancelButton: true,
onConfirm: () =>
navigation.navigate("Root", {
screen: "ShoppingCartTab",
}),
confirmText: "مشاهده سبد خرید",
cancelText: "باشه",
}
)
: addToCart(
pushToCart({
productId: physicalProduct?.id,
userId: userId,
count: 1,
}),
"physical"
)
}
>
<>
{whichTypeAdded === "physical" && userProductsLoading ? (
<ActivityIndicator
color={
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF
}
size={fontSize.sm}
/>
) : (
<Text
style={{
fontFamily: "bold",
fontSize: fontSize.sm,
color:
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF,
paddingVertical: 4,
}}
>
خرید نسخه فیزیکی کتاب
</Text>
)}
<View style={tw("flex flex-row-reverse items-center")}>
<View style={tw("w-px h-full bg-green-300")}></View>
<View style={tw("flex")}>
<Text
style={[
tw("py-1 pr-2"),
{
fontFamily: "bold",
color:
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF,
fontSize: fontSize.sm,
},
]}
>
{(separate(physicalProduct?.price) || " ") + " " + "تومان"}
</Text>
</View>
</View>
</>
</TouchableHighlight>
) : null}
{physicalProduct ? (
<TouchableHighlight
underlayColor={Colors.theme1.greenFF + "22"}
style={[
tw("flex flex-row-reverse justify-center px-2 py-3 mb-4"),
{
borderWidth: 1,
borderColor: Colors.theme1.greenCF,
backgroundColor:
theme === "light" ? Colors.theme1.greenFF + "0a" : null,
width: fontSize.sm * 6 + 18,
},
]}
onPress={() =>
navigation.push("Sample", { id: book?.sampleFileId })
}
>
<Text
style={{
fontFamily: "bold",
fontSize: fontSize.xs,
color:
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF,
paddingVertical: 4,
}}
>
مشاهده نمونه
</Text>
</TouchableHighlight>
) : null}
{digitalProduct ? (
<TouchableHighlight
underlayColor={Colors.theme1.greenFF + "22"}
style={[
tw("flex flex-row-reverse justify-between px-2 py-3 mb-4"),
{
borderWidth: 1,
borderColor: Colors.theme1.greenCF,
backgroundColor:
theme === "light" ? Colors.theme1.greenFF + "0a" : null,
width: width - 32 - 8 - (fontSize.sm * 6 + 18),
},
]}
onPress={() =>
digitalAvailabileInCart
? asyncAwesomeAlert(
"",
"این محصول قبلا به سبد خرید شما اضافه شده است.",
{
showCancelButton: true,
onConfirm: () =>
navigation.navigate("Root", {
screen: "ShoppingCartTab",
}),
confirmText: "مشاهده سبد خرید",
cancelText: "باشه",
}
)
: addToCart(
pushToCart({
productId: digitalProduct?.id,
userId: userId,
count: 1,
}),
"digital"
)
}
>
<>
{whichTypeAdded === "digital" && userProductsLoading ? (
<ActivityIndicator
color={
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF
}
size={fontSize.sm}
/>
) : (
<Text
style={{
fontFamily: "bold",
fontSize: fontSize.sm,
color:
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF,
paddingVertical: 4,
}}
>
خرید نسخه دیجیتال کتاب
</Text>
)}
<View style={tw("flex")}>
<Text
style={[
tw("py-1 pr-2"),
{
borderRightWidth: 1,
borderColor: Colors.theme1.greenCF,
fontFamily: "bold",
color:
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF,
fontSize: fontSize.sm,
},
]}
>
{(separate(digitalProduct?.price) || " ") + " " + "تومان"}
</Text>
</View>
</>
</TouchableHighlight>
) : null}
{digitalProduct ? (
<TouchableHighlight
underlayColor={Colors.theme1.greenFF + "22"}
style={[
tw("flex flex-row-reverse justify-center px-2 py-3 mb-4"),
{
borderWidth: 1,
borderColor: Colors.theme1.greenCF,
backgroundColor:
theme === "light" ? Colors.theme1.greenFF + "0a" : null,
width: fontSize.sm * 6 + 18,
},
]}
onPress={() => navigation.navigate("Video", { id: book?.id })}
>
<Text
style={{
fontFamily: "bold",
fontSize: fontSize.xs,
color:
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF,
paddingVertical: 4,
}}
>
پیش نمایش
</Text>
</TouchableHighlight>
) : null}
{videoProduct ? (
<TouchableHighlight
underlayColor={Colors.theme1.greenFF + "22"}
style={[
tw("flex flex-row-reverse justify-between px-2 py-3 mb-4"),
{
borderWidth: 1,
borderColor: Colors.theme1.greenCF,
backgroundColor:
theme === "light" ? Colors.theme1.greenFF + "0a" : null,
width: width - 32 - 8 - (fontSize.sm * 6 + 18),
},
]}
onPress={() =>
videoAvailabileInCart
? asyncAwesomeAlert(
"",
"این محصول قبلا به سبد خرید شما اضافه شده است.",
{
showCancelButton: true,
onConfirm: () =>
navigation.navigate("Root", {
screen: "ShoppingCartTab",
}),
confirmText: "مشاهده سبد خرید",
cancelText: "باشه",
}
)
: addToCart(
pushToCart({
productId: videoProduct?.id,
userId: userId,
count: 1,
}),
"video"
)
}
>
<>
{whichTypeAdded === "video" && userProductsLoading ? (
<ActivityIndicator
color={
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF
}
size={fontSize.sm}
/>
) : (
<Text
style={{
fontFamily: "bold",
fontSize: fontSize.sm,
color:
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF,
paddingVertical: 4, <ProductButton
}} product={videoProduct}
> availableInCart={videoAvailabileInCart}
خرید دوره ویدئویی کتاب availableForSell={videoAvailableForSell}
</Text> type="video"
)} onLoad={whichTypeAdded === "video" && userProductsLoading}
<View style={tw("flex flex-row-reverse")}> title="خرید نسخه ویدئویی کتاب"
<View style={tw("w-px h-full bg-green-500")}></View> sample={true}
<Text sampleAction={() => navigation.navigate("Video", { id: book?.id })}
style={[ />
tw("py-1 pr-2"),
{
fontFamily: "bold",
color:
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF,
fontSize: fontSize.sm, <ProductButton
}, product={digitalProduct}
]} availableInCart={digitalAvailabileInCart}
> availableForSell={digitalAvailableForSell}
{(separate(videoProduct?.price) || " ") + " " + "تومان"} type="digital"
</Text> onLoad={whichTypeAdded === "digital" && userProductsLoading}
</View> title="خرید نسخه دیجیتال کتاب"
</> sample={false}
</TouchableHighlight> sampleAction={() => {}}
) : null} />
</View> </View>
{book?.text ? ( {book?.text ? (
<LinkBox <LinkBox
@ -699,6 +540,7 @@ const mapStateToProps = (state) => ({
mobile: state.publicApi.mobile, mobile: state.publicApi.mobile,
orientation: state.publicApi.orientation, orientation: state.publicApi.orientation,
theme: state.publicApi.theme, theme: state.publicApi.theme,
availableForSell: state.config.availableForSell,
}); });
const mapDispatchToProps = { const mapDispatchToProps = {

@ -9,14 +9,15 @@ import {
KeyboardAvoidingView, KeyboardAvoidingView,
} from "react-native"; } from "react-native";
import Book from "./components/Book"; import Book from "./components/Book";
import { book } from "../../redux/actions"; import { book, config } from "../../redux/actions";
import { connect } from "react-redux"; import { connect } from "react-redux";
import Navbar from "../../components/Navbar"; import Navbar from "../../components/Navbar";
const { height, width } = Dimensions.get("window"); const { height, width } = Dimensions.get("window");
function Product({ route, book, getBook, grades }) { function Product({ route, book, getBook, grades, getAvailableForSell }) {
useEffect(() => { useEffect(() => {
getAvailableForSell();
getBook({ id: route.params.id, vod: true }); getBook({ id: route.params.id, vod: true });
}, []); }, []);
@ -69,6 +70,7 @@ const mapStateToProps = (state) => ({
const mapDispatchToProps = { const mapDispatchToProps = {
getBook: book.info, getBook: book.info,
getAvailableForSell: config.getAvailableForSell
}; };
export default connect(mapStateToProps, mapDispatchToProps)(Product); export default connect(mapStateToProps, mapDispatchToProps)(Product);

@ -31,9 +31,7 @@ const User = ({ user, mobile, theme, upload }) => {
quality: 1, quality: 1,
}); });
console.log(result); upload({file : result, name : 'file'});
upload(result);
if (!result.cancelled) { if (!result.cancelled) {
setImage(result.uri); setImage(result.uri);

@ -4,7 +4,6 @@ import {
Image, Image,
ActivityIndicator, ActivityIndicator,
Dimensions, Dimensions,
BackHandler,
StatusBar, StatusBar,
} from "react-native"; } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage"; import AsyncStorage from "@react-native-async-storage/async-storage";
@ -16,7 +15,6 @@ import {
publicApi, publicApi,
config, config,
} from "../../redux/actions"; } from "../../redux/actions";
import { useIsFocused } from "@react-navigation/native";
import Logo from "../../assets/images/logo.png"; import Logo from "../../assets/images/logo.png";
@ -87,6 +85,7 @@ function Splash({
alignItems: "center", alignItems: "center",
flex: 1, flex: 1,
display: "flex", display: "flex",
backgroundColor : 'white'
}} }}
> >
<View style={{ height: (width * 0.7 * 2) / 3 }}> <View style={{ height: (width * 0.7 * 2) / 3 }}>
@ -101,7 +100,7 @@ function Splash({
</View> </View>
<ActivityIndicator <ActivityIndicator
size={"large"} size={"large"}
color={theme === "light" ? Colors.theme1.dark : Colors.theme1.white} color={Colors.theme1.dark}
style={{ marginTop: 20 }} style={{ marginTop: 20 }}
/> />
</View> </View>

@ -1,6 +1,7 @@
import React from "react"; import React from "react";
import { View, Text, Pressable, Appearance } from "react-native"; import { View, Text, Pressable, Appearance } from "react-native";
import { SimpleLineIcons } from "@expo/vector-icons"; import { SimpleLineIcons } from "@expo/vector-icons";
import { asyncAwesomeAlert } from "../../../utils/AsyncWrappers";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { publicApi } from "../../../redux/actions"; import { publicApi } from "../../../redux/actions";
import { useNavigation } from "@react-navigation/native"; import { useNavigation } from "@react-navigation/native";
@ -24,6 +25,7 @@ const duration = (value) => {
const Season = ({ const Season = ({
season, season,
videoBuyed,
toggle, toggle,
activeSeason, activeSeason,
realSeasons, realSeasons,
@ -89,7 +91,11 @@ const Season = ({
Number(index) === 0 Number(index) === 0
? Colors.theme1.greenCF ? Colors.theme1.greenCF
: theme === "light" : theme === "light"
? Colors.theme1.gray2077 ? videoBuyed
? Colors.theme1.greenCF
: Colors.theme1.gray2077
: videoBuyed
? Colors.theme1.greenCF
: Colors.theme1.white + "66", : Colors.theme1.white + "66",
}, },
]} ]}
@ -99,8 +105,19 @@ const Season = ({
season: season, season: season,
unit: unit, unit: unit,
name: seasonName, name: seasonName,
videoBuyed: videoBuyed,
})
: videoBuyed
? navigation.navigate("VideoDisplay", {
season: season,
unit: unit,
name: seasonName,
videoBuyed: videoBuyed,
})
: asyncAwesomeAlert("خطا", "ابتدا دوره را خریداری کنید", {
showCancelButton: false,
confirmText: "باشه",
}) })
: {}
} }
> >
<Text <Text
@ -113,7 +130,11 @@ const Season = ({
Number(index) === 0 Number(index) === 0
? Colors.theme1.greenCF ? Colors.theme1.greenCF
: theme === "light" : theme === "light"
? Colors.theme1.gray2077 ? videoBuyed
? Colors.theme1.greenCF
: Colors.theme1.gray2077
: videoBuyed
? Colors.theme1.greenCF
: Colors.theme1.white + "66", : Colors.theme1.white + "66",
}} }}
> >

@ -13,7 +13,7 @@ import {
} from "react-native"; } from "react-native";
import { useNavigation } from "@react-navigation/native"; import { useNavigation } from "@react-navigation/native";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { publicApi, userProduct } from "../../redux/actions"; import { publicApi, userProduct, config } from "../../redux/actions";
import separate from "../../utils/separate"; import separate from "../../utils/separate";
import { asyncAwesomeAlert } from "../../utils/AsyncWrappers"; import { asyncAwesomeAlert } from "../../utils/AsyncWrappers";
@ -44,11 +44,15 @@ function Product({
mobile, mobile,
theme, theme,
userProducts, userProducts,
getAvailableForSell,
availableForSell,
}) { }) {
const [position, setPosition] = useState("100%"); const [position, setPosition] = useState("100%");
const navigation = useNavigation(); const navigation = useNavigation();
const [addedFlag, setAddedFlag] = React.useState(false); const [addedFlag, setAddedFlag] = React.useState(false);
useEffect(() => { useEffect(() => {
getAvailableForSell();
getBook({ bookId: route.params.id }, { id: route.params.id, vod: true }); getBook({ bookId: route.params.id }, { id: route.params.id, vod: true });
}, []); }, []);
@ -57,12 +61,29 @@ function Product({
setPosition(position === "100%" ? "0%" : "100%"); setPosition(position === "100%" ? "0%" : "100%");
}; };
const videoProduct = React.useMemo(() => {
return book?.product?.filter((product) => product?.productType === 4)[0];
}, [book]);
const videoAvailabileInCart = React.useMemo(() => { const videoAvailabileInCart = React.useMemo(() => {
return userProducts?.filter( return userProducts?.filter(
(product) => product?.productId === book?.product[2]?.id (product) =>
)[0]; product?.productId === videoProduct?.id && product?.condition < 2
)?.length;
}, [userProducts, book]);
const videoBuyed = React.useMemo(() => {
return userProducts?.filter(
(product) =>
product?.productId === videoProduct?.id && product?.condition >= 2
)?.length;
}, [userProducts, book]); }, [userProducts, book]);
const videoAvailableForSell = React.useMemo(() => {
return availableForSell?.filter((product) => product === 4)?.length;
}, [availableForSell]);
const addToCart = React.useCallback( const addToCart = React.useCallback(
async (action) => { async (action) => {
setAddedFlag(true); setAddedFlag(true);
@ -170,9 +191,13 @@ function Product({
<Divider type={"vertical"} /> <Divider type={"vertical"} />
</View> </View>
<CustomPressable <CustomPressable
title={`خرید با قیمت ${separate( title={
book?.product[2]?.price || " " videoAvailableForSell
)} تومان`} ? `خرید با قیمت ${separate(
book?.product[2]?.price || " "
)} تومان`
: "ناموجود"
}
backgroundColor={Colors.theme1.greenCF} backgroundColor={Colors.theme1.greenCF}
color={"white"} color={"white"}
border={{ color: "#196EC0", width: 0 }} border={{ color: "#196EC0", width: 0 }}
@ -193,13 +218,15 @@ function Product({
cancelText: "ادامه خرید", cancelText: "ادامه خرید",
} }
) )
: addToCart( : videoAvailableForSell
? addToCart(
pushToCart({ pushToCart({
productId: book?.product[2]?.id, productId: book?.product[2]?.id,
userId: userId, userId: userId,
count: 1, count: 1,
}) })
) )
: null
} }
/> />
</View> </View>
@ -207,7 +234,7 @@ function Product({
{seasons {seasons
?.sort((a, b) => a[0]?.categoryId - b[0]?.categoryId) ?.sort((a, b) => a[0]?.categoryId - b[0]?.categoryId)
?.map((season, index) => ( ?.map((season, index) => (
<Season season={season} key={index} id={book?.id} index={index} /> <Season season={season} key={index} id={book?.id} index={index} videoBuyed={videoBuyed} />
))} ))}
</View> </View>
</ScrollView> </ScrollView>
@ -235,10 +262,12 @@ const mapStateToProps = (state) => ({
loading: state.userProduct.loading, loading: state.userProduct.loading,
mobile: state.publicApi.mobile, mobile: state.publicApi.mobile,
theme: state.publicApi.theme, theme: state.publicApi.theme,
availableForSell: state.config.availableForSell,
}); });
const mapDispatchToProps = { const mapDispatchToProps = {
getBook: publicApi.bookInfo, getBook: publicApi.bookInfo,
pushToCart: userProduct.add, pushToCart: userProduct.add,
getAvailableForSell: config.getAvailableForSell,
}; };
export default connect(mapStateToProps, mapDispatchToProps)(Product); export default connect(mapStateToProps, mapDispatchToProps)(Product);

@ -30,6 +30,7 @@ const Season = ({
setVideoActive, setVideoActive,
mobile, mobile,
theme, theme,
videoBuyed,
}) => { }) => {
const navigation = useNavigation(); const navigation = useNavigation();

@ -28,7 +28,6 @@ import Colors from "../../constants/Colors";
const ios = Platform.OS === "ios"; const ios = Platform.OS === "ios";
function VideoDisplay({ route, mobile, theme }) { function VideoDisplay({ route, mobile, theme }) {
const video = React.useRef(null); const video = React.useRef(null);
const [width, setWidth] = useState(Dimensions.get("window").width); const [width, setWidth] = useState(Dimensions.get("window").width);
@ -42,7 +41,9 @@ function VideoDisplay({ route, mobile, theme }) {
const onFullscreenUpdate = async ({ fullscreenUpdate }) => { const onFullscreenUpdate = async ({ fullscreenUpdate }) => {
if (fullscreenUpdate === Video.FULLSCREEN_UPDATE_PLAYER_DID_PRESENT) { if (fullscreenUpdate === Video.FULLSCREEN_UPDATE_PLAYER_DID_PRESENT) {
await ScreenOrientation.unlockAsync(); await ScreenOrientation.unlockAsync();
} else if (fullscreenUpdate === Video.FULLSCREEN_UPDATE_PLAYER_WILL_DISMISS) { } else if (
fullscreenUpdate === Video.FULLSCREEN_UPDATE_PLAYER_WILL_DISMISS
) {
await ScreenOrientation.lockAsync( await ScreenOrientation.lockAsync(
ScreenOrientation.OrientationLock.PORTRAIT ScreenOrientation.OrientationLock.PORTRAIT
); );
@ -95,7 +96,7 @@ function VideoDisplay({ route, mobile, theme }) {
style={{ style={{
fontSize: fontSize.xl, fontSize: fontSize.xl,
fontFamily: "bold", fontFamily: "bold",
marginTop: mobile ? 8 : 12, marginTop: mobile ? 20 : 12,
color: color:
theme === "light" ? Colors.theme1.gray20 : Colors.theme1.white, theme === "light" ? Colors.theme1.gray20 : Colors.theme1.white,
textAlign: "right", textAlign: "right",
@ -113,11 +114,14 @@ function VideoDisplay({ route, mobile, theme }) {
> >
<Divider type={"vertical"} /> <Divider type={"vertical"} />
</View> </View>
<Season {route?.params?.videoBuyed ? (
season={route.params.season} <Season
activeUnit={route.params.unit} season={route.params.season}
name={route.params.name} videoBuyed={route.params.videoBuyed}
/> activeUnit={route.params.unit}
name={route.params.name}
/>
) : null}
</View> </View>
</ScrollView> </ScrollView>
</SafeAreaView> </SafeAreaView>

@ -52,9 +52,7 @@ function MostViewedVideo({ videos, grades, mobile, theme }) {
source={{ uri: `https://dnvn.ir/api/v1/file/${video.fileIds}` }} source={{ uri: `https://dnvn.ir/api/v1/file/${video.fileIds}` }}
resizeMode="contain" resizeMode="contain"
style={[ style={[
tw( tw(`rounded-sm h-full absolute left-2`),
`rounded-sm h-full absolute left-2`
),
{ {
width: mobile ? 70 : 105, width: mobile ? 70 : 105,
height: mobile ? 110 : 150, height: mobile ? 110 : 150,
@ -110,7 +108,11 @@ function MostViewedVideo({ videos, grades, mobile, theme }) {
}, },
]} ]}
> >
{separate(video?.product?.filter((product) => product?.productType === 4)[0]?.price)} {separate(
video?.product?.filter(
(product) => product?.productType === 4
)[0]?.price
)}
</Text> </Text>
</View> </View>
@ -136,16 +138,18 @@ function MostViewedVideo({ videos, grades, mobile, theme }) {
return ( return (
<View style={tw("w-full flex w-full mt-3")}> <View style={tw("w-full flex w-full mt-3")}>
<Header <View style={tw('pl-4 pr-4')}>
title="پربازدیدترین" <Header
route={"Products"} title="پربازدیدترین"
state={{ productType: "دوره ویدئویی" }} route={"Products"}
/> state={{ productType: "دوره ویدئویی" }}
/>
</View>
<FlatList <FlatList
showsHorizontalScrollIndicator={false} showsHorizontalScrollIndicator={false}
horizontal={true} horizontal={true}
inverted={true} inverted={true}
style={tw("pb-1.5 mt-3 flex flex-row w-full")} style={tw("pb-1.5 px-4 mt-3 flex flex-row w-full")}
data={videos.slice(0, 7)} data={videos.slice(0, 7)}
renderItem={({ item }) => <Video video={item} />} renderItem={({ item }) => <Video video={item} />}
keyExtractor={(item) => item.id} keyExtractor={(item) => item.id}

@ -70,7 +70,7 @@ const NewestVideo = ({ videos, grades, mobile, theme }) => {
); );
}; };
return ( return (
<View style={tw("w-full flex w-full")}> <View style={tw("w-full flex w-full px-4")}>
<Header title="جدیدترین دورهها" route="" /> <Header title="جدیدترین دورهها" route="" />
<View <View
style={tw( style={tw(

@ -93,7 +93,6 @@ const styles = StyleSheet.create({
container: { container: {
flexDirection: "column", flexDirection: "column",
paddingVertical: 0, paddingVertical: 0,
paddingHorizontal: 16,
}, },
}); });

Loading…
Cancel
Save