feat: fixes and formatter
This commit is contained in:
+126
-141
@@ -1,25 +1,25 @@
|
||||
/* eslint-disable react/display-name */
|
||||
import { Image, Pressable, Text, View, StyleSheet } from "react-native";
|
||||
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
import React from "reactn";
|
||||
import { responsiveHeight } from "../actions/responsiveSizes.js";
|
||||
import { subBadges } from "../assets";
|
||||
import BaseHeader from "../components/BaseHeader";
|
||||
import CreditAmount from "../components/CreditAmount";
|
||||
import ConnectBtn from "../components/ConnectBtn.js";
|
||||
import GradientButton from "../components/GradientButton";
|
||||
import CoinPackModal from "../components/modal/CoinPackModal";
|
||||
import NavigateHeader from "../components/NavigateHeader";
|
||||
import ShareBtn from "../components/ShareBtn/ShareBtn";
|
||||
import { isWeb } from "../hooks/useLayoutType.js";
|
||||
import { useUserData } from "../providers/UserDataProvider";
|
||||
import { Routes } from "../navigation";
|
||||
import { navigate } from "../navigation/NavigationService";
|
||||
import { gutters, Palette } from "../styles";
|
||||
import { FONT_FAMILY } from "../styles/Fonts";
|
||||
import { subscribeCoinPackModal } from "../utils/coinPackModal";
|
||||
import { BlurView } from "expo-blur";
|
||||
import { Image, Pressable, Text, View, StyleSheet } from 'react-native'
|
||||
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'
|
||||
import { SafeAreaView } from 'react-native-safe-area-context'
|
||||
import React from 'reactn'
|
||||
import { responsiveHeight } from '../actions/responsiveSizes.js'
|
||||
import { subBadges } from '../assets'
|
||||
import BaseHeader from '../components/BaseHeader'
|
||||
import CreditAmount from '../components/CreditAmount'
|
||||
import ConnectBtn from '../components/ConnectBtn.js'
|
||||
import GradientButton from '../components/GradientButton'
|
||||
import CoinPackModal from '../components/modal/CoinPackModal'
|
||||
import NavigateHeader from '../components/NavigateHeader'
|
||||
import ShareBtn from '../components/ShareBtn/ShareBtn'
|
||||
import { isWeb } from '../hooks/useLayoutType.js'
|
||||
import { useUserData } from '../providers/UserDataProvider'
|
||||
import { Routes } from '../navigation'
|
||||
import { navigate } from '../navigation/NavigationService'
|
||||
import { gutters, Palette } from '../styles'
|
||||
import { FONT_FAMILY } from '../styles/Fonts'
|
||||
import { subscribeCoinPackModal } from '../utils/coinPackModal'
|
||||
import { BlurView } from 'expo-blur'
|
||||
|
||||
export default ({
|
||||
children,
|
||||
@@ -27,11 +27,11 @@ export default ({
|
||||
topStickyContent = null,
|
||||
bottomStickyContent = null,
|
||||
|
||||
title = "",
|
||||
title = '',
|
||||
rightComponent = null,
|
||||
|
||||
containerType = "SAFE_AREA_VIEW",
|
||||
headerType = "BASE",
|
||||
containerType = 'SAFE_AREA_VIEW',
|
||||
headerType = 'BASE',
|
||||
|
||||
containerStyle = {},
|
||||
headerStyle = {},
|
||||
@@ -48,159 +48,149 @@ export default ({
|
||||
shareBtn = false,
|
||||
connect = false,
|
||||
blurIntensity = 0,
|
||||
backgroundColor = "#000",
|
||||
backgroundColor = '#000',
|
||||
showCoin = true,
|
||||
showReturnHome = false,
|
||||
onReturnHome = null,
|
||||
}) => {
|
||||
const { currentUID = null, currentUserData = null } = useUserData?.() || {};
|
||||
const { currentUID = null, currentUserData = null } = useUserData?.() || {}
|
||||
|
||||
const coinBalance = React.useMemo(() => {
|
||||
const value = currentUserData?.coins;
|
||||
if (typeof value === "number" && Number.isFinite(value)) {
|
||||
return value;
|
||||
const value = currentUserData?.coins
|
||||
if (typeof value === 'number' && Number.isFinite(value)) {
|
||||
return value
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
const parsed = Number(value);
|
||||
if (typeof value === 'string') {
|
||||
const parsed = Number(value)
|
||||
if (Number.isFinite(parsed)) {
|
||||
return parsed;
|
||||
return parsed
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}, [currentUserData?.coins]);
|
||||
return 0
|
||||
}, [currentUserData?.coins])
|
||||
|
||||
const showCoinBadge = isWeb && !!currentUID && showCoin;
|
||||
const showReturnHomeButton = isWeb && showReturnHome;
|
||||
const coinBadgeContainerVisible = showCoinBadge || showReturnHomeButton;
|
||||
const [isCoinModalVisible, setCoinModalVisible] = React.useState(false);
|
||||
const showCoinBadge = isWeb && !!currentUID && showCoin
|
||||
const showReturnHomeButton = isWeb && showReturnHome
|
||||
const coinBadgeContainerVisible = showCoinBadge || showReturnHomeButton
|
||||
const [isCoinModalVisible, setCoinModalVisible] = React.useState(false)
|
||||
|
||||
const subscriptionBadgeSource = React.useMemo(() => {
|
||||
const allowedLevels = new Set(["starter", "pro", "premium"]);
|
||||
const allowedLevels = new Set(['starter', 'pro', 'premium'])
|
||||
const pickLevel = (value) => {
|
||||
if (typeof value !== "string") {
|
||||
return null;
|
||||
if (typeof value !== 'string') {
|
||||
return null
|
||||
}
|
||||
const normalized = value.trim().toLowerCase();
|
||||
return normalized && allowedLevels.has(normalized) ? normalized : null;
|
||||
};
|
||||
const normalized = value.trim().toLowerCase()
|
||||
return normalized && allowedLevels.has(normalized) ? normalized : null
|
||||
}
|
||||
|
||||
const nestedSubscription =
|
||||
currentUserData?.subscription &&
|
||||
typeof currentUserData.subscription === "object"
|
||||
currentUserData?.subscription && typeof currentUserData.subscription === 'object'
|
||||
? currentUserData.subscription
|
||||
: null;
|
||||
: null
|
||||
|
||||
const stripeMetadata =
|
||||
currentUserData?.stripeSubscription &&
|
||||
typeof currentUserData.stripeSubscription === "object" &&
|
||||
typeof currentUserData.stripeSubscription.metadata === "object"
|
||||
typeof currentUserData.stripeSubscription === 'object' &&
|
||||
typeof currentUserData.stripeSubscription.metadata === 'object'
|
||||
? currentUserData.stripeSubscription.metadata
|
||||
: null;
|
||||
: null
|
||||
|
||||
const directCandidates = [
|
||||
pickLevel(currentUserData?.premiumLevel),
|
||||
pickLevel(currentUserData?.subscriptionLevel),
|
||||
pickLevel(currentUserData?.subscriptionPlan),
|
||||
pickLevel(currentUserData?.subscriptionPack),
|
||||
];
|
||||
]
|
||||
|
||||
const nestedCandidates = nestedSubscription
|
||||
? ["level", "plan", "pack", "type"].map((key) =>
|
||||
pickLevel(nestedSubscription?.[key])
|
||||
)
|
||||
: [];
|
||||
? ['level', 'plan', 'pack', 'type'].map((key) => pickLevel(nestedSubscription?.[key]))
|
||||
: []
|
||||
|
||||
const metadataCandidates = stripeMetadata
|
||||
? [
|
||||
"level",
|
||||
"subscriptionLevel",
|
||||
"subscription_level",
|
||||
"pack",
|
||||
"Pack",
|
||||
].map((key) => pickLevel(stripeMetadata?.[key]))
|
||||
: [];
|
||||
? ['level', 'subscriptionLevel', 'subscription_level', 'pack', 'Pack'].map((key) =>
|
||||
pickLevel(stripeMetadata?.[key])
|
||||
)
|
||||
: []
|
||||
|
||||
const resolvedLevel = [
|
||||
...directCandidates,
|
||||
...nestedCandidates,
|
||||
...metadataCandidates,
|
||||
].find(Boolean);
|
||||
const resolvedLevel = [...directCandidates, ...nestedCandidates, ...metadataCandidates].find(
|
||||
Boolean
|
||||
)
|
||||
|
||||
return resolvedLevel ? subBadges[resolvedLevel] || null : null;
|
||||
}, [currentUserData]);
|
||||
return resolvedLevel ? subBadges[resolvedLevel] || null : null
|
||||
}, [currentUserData])
|
||||
|
||||
const handleCoinPress = React.useCallback(() => {
|
||||
if (!showCoinBadge) return;
|
||||
setCoinModalVisible(true);
|
||||
}, [showCoinBadge]);
|
||||
if (!showCoinBadge) return
|
||||
setCoinModalVisible(true)
|
||||
}, [showCoinBadge])
|
||||
|
||||
const handleCloseCoinModal = React.useCallback(() => {
|
||||
setCoinModalVisible(false);
|
||||
}, []);
|
||||
setCoinModalVisible(false)
|
||||
}, [])
|
||||
|
||||
const handleReturnHomePress = React.useCallback(() => {
|
||||
if (typeof onReturnHome === "function") {
|
||||
onReturnHome();
|
||||
return;
|
||||
if (typeof onReturnHome === 'function') {
|
||||
onReturnHome()
|
||||
return
|
||||
}
|
||||
navigate(Routes.LandingPage);
|
||||
}, [onReturnHome]);
|
||||
navigate(Routes.LandingPage)
|
||||
}, [onReturnHome])
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!showCoinBadge && isCoinModalVisible) {
|
||||
setCoinModalVisible(false);
|
||||
setCoinModalVisible(false)
|
||||
}
|
||||
}, [showCoinBadge, isCoinModalVisible]);
|
||||
}, [showCoinBadge, isCoinModalVisible])
|
||||
|
||||
React.useEffect(() => {
|
||||
const unsubscribe = subscribeCoinPackModal(() => {
|
||||
if (!showCoinBadge) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
setCoinModalVisible(true);
|
||||
});
|
||||
return unsubscribe;
|
||||
}, [showCoinBadge]);
|
||||
setCoinModalVisible(true)
|
||||
})
|
||||
return unsubscribe
|
||||
}, [showCoinBadge])
|
||||
|
||||
const PageContainer =
|
||||
containerType === "SAFE_AREA_VIEW" ? SafeAreaView : View;
|
||||
const PageContainer = containerType === 'SAFE_AREA_VIEW' ? SafeAreaView : View
|
||||
|
||||
const ContentContainer = scrollEnabled ? KeyboardAwareScrollView : View;
|
||||
const ContentContainer = scrollEnabled ? KeyboardAwareScrollView : View
|
||||
|
||||
const computedWidth = width ?? (isWeb ? "60%" : "100%");
|
||||
const computedWidth = width ?? (isWeb ? '60%' : '100%')
|
||||
|
||||
const shareButtonElement = (() => {
|
||||
if (!shareBtn) return null;
|
||||
if (typeof React?.isValidElement === "function") {
|
||||
if (!shareBtn) return null
|
||||
if (typeof React?.isValidElement === 'function') {
|
||||
if (React.isValidElement(shareBtn)) {
|
||||
return shareBtn;
|
||||
return shareBtn
|
||||
}
|
||||
}
|
||||
if (typeof shareBtn === "object" && !Array.isArray(shareBtn)) {
|
||||
return <ShareBtn {...shareBtn} />;
|
||||
if (typeof shareBtn === 'object' && !Array.isArray(shareBtn)) {
|
||||
return <ShareBtn {...shareBtn} />
|
||||
}
|
||||
return <ShareBtn />;
|
||||
})();
|
||||
return <ShareBtn />
|
||||
})()
|
||||
|
||||
const resolvedContainerStyle = React.useMemo(
|
||||
() => StyleSheet.flatten(containerStyle) || {},
|
||||
[containerStyle]
|
||||
);
|
||||
)
|
||||
const resolvedHeaderStyle = React.useMemo(
|
||||
() => StyleSheet.flatten(headerStyle) || {},
|
||||
[headerStyle]
|
||||
);
|
||||
)
|
||||
const resolvedContentContainerStyle = React.useMemo(
|
||||
() => StyleSheet.flatten(contentContainerStyle) || {},
|
||||
[contentContainerStyle]
|
||||
);
|
||||
)
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
minHeight: isWeb ? "100svh" : "100%",
|
||||
position: "relative",
|
||||
minHeight: isWeb ? '100svh' : '100%',
|
||||
position: 'relative',
|
||||
backgroundColor: backgroundColor,
|
||||
}}
|
||||
>
|
||||
@@ -210,14 +200,12 @@ export default ({
|
||||
resizeMode="cover"
|
||||
blurIntensity={blurIntensity}
|
||||
style={{
|
||||
position: "absolute",
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
...(isWeb && blurIntensity
|
||||
? { filter: `blur(${blurIntensity}px)` }
|
||||
: {}),
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
...(isWeb && blurIntensity ? { filter: `blur(${blurIntensity}px)` } : {}),
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
@@ -234,7 +222,7 @@ export default ({
|
||||
value={coinBalance}
|
||||
iconSize={22}
|
||||
textStyle={{
|
||||
color: "#ffffff",
|
||||
color: '#ffffff',
|
||||
fontFamily: FONT_FAMILY.InterSemiBold,
|
||||
fontSize: 14,
|
||||
}}
|
||||
@@ -248,7 +236,7 @@ export default ({
|
||||
>
|
||||
<Image
|
||||
source={subscriptionBadgeSource}
|
||||
style={{ height: 50, width: 50, resizeMode: "contain" }}
|
||||
style={{ height: 50, width: 50, resizeMode: 'contain' }}
|
||||
/>
|
||||
</Pressable>
|
||||
) : null}
|
||||
@@ -268,10 +256,10 @@ export default ({
|
||||
paddingHorizontal: 10,
|
||||
paddingVertical: 8,
|
||||
borderRadius: 12,
|
||||
overflow: "hidden",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
overflow: 'hidden',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
@@ -290,21 +278,21 @@ export default ({
|
||||
</View>
|
||||
) : null}
|
||||
<PageContainer
|
||||
{...(containerType === "SAFE_AREA_VIEW" ? { edges: ["top"] } : {})}
|
||||
{...(containerType === 'SAFE_AREA_VIEW' ? { edges: ['top'] } : {})}
|
||||
style={{
|
||||
height: "100%",
|
||||
height: '100%',
|
||||
paddingTop: isWeb ? gutters / 2 : 0,
|
||||
padding: gutters,
|
||||
paddingBottom: 0,
|
||||
...(isWeb ? { maxHeight: "100svh" } : {}),
|
||||
...(isWeb ? { maxHeight: '100svh' } : {}),
|
||||
width: computedWidth,
|
||||
maxWidth: maxWidth ? maxWidth : null,
|
||||
alignSelf: isWeb ? "center" : "auto",
|
||||
alignSelf: isWeb ? 'center' : 'auto',
|
||||
...resolvedContainerStyle,
|
||||
}}
|
||||
>
|
||||
{headerType !== "NONE" ? (
|
||||
headerType === "BASE" ? (
|
||||
{headerType !== 'NONE' ? (
|
||||
headerType === 'BASE' ? (
|
||||
<BaseHeader containerStyle={{ ...resolvedHeaderStyle }} />
|
||||
) : (
|
||||
<NavigateHeader
|
||||
@@ -327,7 +315,7 @@ export default ({
|
||||
scrollEventThrottle: 80,
|
||||
showsVerticalScrollIndicator: false,
|
||||
contentContainerStyle: { paddingBottom: responsiveHeight(55) },
|
||||
keyboardDismissMode: "on-drag",
|
||||
keyboardDismissMode: 'on-drag',
|
||||
}
|
||||
: {})}
|
||||
>
|
||||
@@ -339,11 +327,11 @@ export default ({
|
||||
{(shareButtonElement || connect) && isWeb && (
|
||||
<View
|
||||
style={{
|
||||
position: "absolute",
|
||||
position: 'absolute',
|
||||
top: 20,
|
||||
right: 20,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 12, // ou marginLeft sur chaque bouton si gap non supporté
|
||||
}}
|
||||
>
|
||||
@@ -352,37 +340,34 @@ export default ({
|
||||
</View>
|
||||
)}
|
||||
|
||||
<CoinPackModal
|
||||
visible={isCoinModalVisible}
|
||||
onClose={handleCloseCoinModal}
|
||||
/>
|
||||
<CoinPackModal visible={isCoinModalVisible} onClose={handleCloseCoinModal} />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
coinBadgeContainer: {
|
||||
position: "absolute",
|
||||
position: 'absolute',
|
||||
top: gutters,
|
||||
left: gutters,
|
||||
alignItems: "flex-start",
|
||||
alignItems: 'flex-start',
|
||||
gap: 10,
|
||||
zIndex: 20,
|
||||
},
|
||||
coinRow: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 6,
|
||||
},
|
||||
coinButton: {
|
||||
paddingHorizontal: 14,
|
||||
paddingVertical: 8,
|
||||
borderRadius: 20,
|
||||
backgroundColor: "rgba(12, 14, 18, 0.72)",
|
||||
backgroundColor: 'rgba(12, 14, 18, 0.72)',
|
||||
borderWidth: 1,
|
||||
borderColor: "rgba(255, 255, 255, 0.1)",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
borderColor: 'rgba(255, 255, 255, 0.1)',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 8,
|
||||
},
|
||||
subscriptionBadge: {
|
||||
@@ -390,6 +375,6 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
returnHomeButton: {
|
||||
width: 220,
|
||||
alignSelf: "flex-start",
|
||||
alignSelf: 'flex-start',
|
||||
},
|
||||
});
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user