feat(ui): refine club, packs, and download flows

This commit is contained in:
Jacques TIROT
2026-03-11 11:54:10 +01:00
parent af8a8bafa4
commit fd299e8543
12 changed files with 565 additions and 598 deletions
+49 -54
View File
@@ -112,27 +112,37 @@ const SongDownload = ({ route }) => {
const canDownloadDirectly = hasActiveSubscription || hasPaidDownload || hasPurchased
const downloadLabel = canDownloadDirectly
? 'Télécharger mon morceau'
: 'Acheter ce morceau pour 1,99€'
const showSubscriptionCta = !hasActiveSubscription
: 'Télécharger ce morceau pour 1,99€'
const shouldShowDownloadPage = adventureChoice === 'stop'
const reopenAdventureChoice = useCallback(() => {
reopenAdventureModalOnFocusRef.current = false
setShowIntro(null)
setAdventureChoice('pending')
setShowAdventureModal(true)
}, [])
const handleBackPress = useCallback(() => {
if (shouldShowDownloadPage) {
reopenAdventureChoice()
return true
}
if (backRoute) {
navigate(backRoute)
return true
}
goBack()
return true
}, [backRoute])
}, [backRoute, reopenAdventureChoice, shouldShowDownloadPage])
useFocusEffect(
useCallback(() => {
if (Platform.OS !== 'android' || !backRoute) {
if (Platform.OS !== 'android' || (!backRoute && !shouldShowDownloadPage)) {
return undefined
}
const subscription = BackHandler.addEventListener('hardwareBackPress', handleBackPress)
return () => subscription.remove()
}, [backRoute, handleBackPress])
}, [backRoute, handleBackPress, shouldShowDownloadPage])
)
useFocusEffect(
@@ -512,8 +522,8 @@ const SongDownload = ({ route }) => {
}
if (promptPurchaseConfirm) {
Alert.alert(
'Acheter ce morceau',
'Voulez-vous acheter ce morceau pour 1,99€ ?',
'Télécharger ce morceau',
'Voulez-vous télécharger ce morceau pour 1,99€ ?',
[
{ text: 'Annuler', style: 'cancel' },
{ text: 'Acheter', onPress: () => startSongDownloadCheckout() },
@@ -569,38 +579,39 @@ const SongDownload = ({ route }) => {
showsVerticalScrollIndicator={false}
>
<CreateLyricsHeader title="Ta pochette est validée" />
<View style={styles.coverRow}>
{coverUrl ? (
<ExpoImage source={{ uri: coverUrl }} style={styles.coverImage} contentFit="cover" />
) : (
<View style={[styles.coverImage, styles.coverPlaceholder]}>
<Text style={styles.placeholderText}>Aucune pochette</Text>
<ClubAdvantagesCard
style={styles.clubCardSpacing}
topContent={
<View style={styles.coverRow}>
{coverUrl ? (
<ExpoImage source={{ uri: coverUrl }} style={styles.coverImage} contentFit="cover" />
) : (
<View style={[styles.coverImage, styles.coverPlaceholder]}>
<Text style={styles.placeholderText}>Aucune pochette</Text>
</View>
)}
<View style={styles.downloadColumn}>
<Pressable
style={[
styles.downloadTile,
(isDownloading || isCheckoutLaunching) && { opacity: 0.6 },
]}
onPress={handleDownloadPress}
disabled={isDownloading || isCheckoutLaunching}
>
<MaterialCommunityIcons name="download" size={22} color={Palette.white} />
<Text style={styles.downloadText}>{downloadLabel}</Text>
</Pressable>
{!canDownloadDirectly && downloadPaymentPending ? (
<Text style={styles.downloadPendingText}>
Paiement en attente de confirmation...
</Text>
) : null}
</View>
</View>
)}
<View style={styles.downloadColumn}>
<Pressable
style={[
styles.downloadTile,
(isDownloading || isCheckoutLaunching) && { opacity: 0.6 },
]}
onPress={handleDownloadPress}
disabled={isDownloading || isCheckoutLaunching}
>
<MaterialCommunityIcons name="download" size={22} color={Palette.white} />
<Text style={styles.downloadText}>{downloadLabel}</Text>
</Pressable>
{!canDownloadDirectly && downloadPaymentPending ? (
<Text style={styles.downloadPendingText}>
Paiement en attente de confirmation...
</Text>
) : null}
</View>
</View>
<ClubAdvantagesCard style={styles.clubCardSpacing} />
}
/>
<GradientButton
title="Revenir à l'accueil"
onPress={handleGoHome}
@@ -695,22 +706,6 @@ const styles = StyleSheet.create({
color: Palette.white,
opacity: 0.8,
},
subscriptionCta: {
alignItems: 'center',
gap: gutters * 0.6,
marginTop: gutters * 0.4,
},
subscriptionNote: {
fontFamily: FONT_FAMILY.InterRegular,
fontSize: 13,
color: Palette.white,
opacity: 0.8,
textAlign: 'center',
},
subscriptionButton: {
width: '100%',
maxWidth: 280,
},
adventureGatePlaceholder: {
flex: 1,
},