feat: tickets
This commit is contained in:
@@ -165,7 +165,7 @@ const GlobalAudioPlayer = () => {
|
|||||||
}
|
}
|
||||||
const project =
|
const project =
|
||||||
currentTrack?.metadata?.project &&
|
currentTrack?.metadata?.project &&
|
||||||
typeof currentTrack.metadata.project === "object"
|
typeof currentTrack.metadata.project === "object"
|
||||||
? currentTrack.metadata.project
|
? currentTrack.metadata.project
|
||||||
: null;
|
: null;
|
||||||
navigateToMusicDetails({
|
navigateToMusicDetails({
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ const HIDDEN_ROUTE_NAMES = new Set([
|
|||||||
Routes.PlaybackExample,
|
Routes.PlaybackExample,
|
||||||
Routes.PlaybackOnboarding,
|
Routes.PlaybackOnboarding,
|
||||||
Routes.Playback,
|
Routes.Playback,
|
||||||
|
Routes.PlaybackGuide,
|
||||||
Routes.RecordPlayback,
|
Routes.RecordPlayback,
|
||||||
Routes.RecordedPlayback,
|
Routes.RecordedPlayback,
|
||||||
Routes.ChooseDecor,
|
Routes.ChooseDecor,
|
||||||
|
|||||||
+288
-272
@@ -1,6 +1,12 @@
|
|||||||
import { BlurView } from "expo-blur";
|
import { BlurView } from "expo-blur";
|
||||||
import { Image as ExpoImage } from "expo-image";
|
import { Image as ExpoImage } from "expo-image";
|
||||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import React, {
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from "react";
|
||||||
import {
|
import {
|
||||||
ActivityIndicator,
|
ActivityIndicator,
|
||||||
Image,
|
Image,
|
||||||
@@ -9,6 +15,8 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
TextInput,
|
TextInput,
|
||||||
View,
|
View,
|
||||||
|
KeyboardAvoidingView,
|
||||||
|
Platform,
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
import { background, icons } from "../../assets";
|
import { background, icons } from "../../assets";
|
||||||
import alert from "../../components/Alert";
|
import alert from "../../components/Alert";
|
||||||
@@ -220,10 +228,7 @@ const PouchReady = () => {
|
|||||||
const start = coverProgressStartRef.current;
|
const start = coverProgressStartRef.current;
|
||||||
if (!start) return;
|
if (!start) return;
|
||||||
const elapsed = Date.now() - start.getTime();
|
const elapsed = Date.now() - start.getTime();
|
||||||
const ratio = Math.max(
|
const ratio = Math.max(0, Math.min(1, elapsed / COVER_FAKE_DURATION_MS));
|
||||||
0,
|
|
||||||
Math.min(1, elapsed / COVER_FAKE_DURATION_MS),
|
|
||||||
);
|
|
||||||
const next = COVER_PROGRESS_MAX * ratio;
|
const next = COVER_PROGRESS_MAX * ratio;
|
||||||
setCoverProgress((prev) => {
|
setCoverProgress((prev) => {
|
||||||
if (prev >= COVER_PROGRESS_MAX) return COVER_PROGRESS_MAX;
|
if (prev >= COVER_PROGRESS_MAX) return COVER_PROGRESS_MAX;
|
||||||
@@ -310,45 +315,82 @@ const PouchReady = () => {
|
|||||||
return (
|
return (
|
||||||
<Page backgroundImg={background.studioBG2} headerType="NONE">
|
<Page backgroundImg={background.studioBG2} headerType="NONE">
|
||||||
<MusicLandHeader onPressBack={goBack} progress={72} />
|
<MusicLandHeader onPressBack={goBack} progress={72} />
|
||||||
<View style={{ flex: 1, marginTop: 0 }}>
|
<KeyboardAvoidingView
|
||||||
<CreateLyricsHeader
|
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
||||||
title={
|
style={{ flex: 1 }}
|
||||||
selectedProject?.cover?.backgroundGenerated
|
>
|
||||||
? "Ta pochette est prête!"
|
<View style={{ flex: 1, marginTop: 0 }}>
|
||||||
: "Génération de la pochette"
|
<CreateLyricsHeader
|
||||||
}
|
title={
|
||||||
/>
|
selectedProject?.cover?.backgroundGenerated
|
||||||
<View style={{ flex: 1, ...Style.containerCenter }}>
|
? "Ta pochette est prête!"
|
||||||
<View style={{ width: isWeb ? "80%" : "100%", gap: 24 }}>
|
: "Génération de la pochette"
|
||||||
<View
|
}
|
||||||
style={{
|
/>
|
||||||
width: "100%",
|
<View style={{ flex: 1, ...Style.containerCenter }}>
|
||||||
flexDirection: isWeb ? "row" : "column",
|
<View style={{ width: isWeb ? "80%" : "80%", gap: 24 }}>
|
||||||
gap: 16,
|
<View
|
||||||
justifyContent: "center",
|
style={{
|
||||||
flexWrap: "wrap",
|
width: "100%",
|
||||||
}}
|
flexDirection: isWeb ? "row" : "column",
|
||||||
>
|
gap: 16,
|
||||||
{displayOptions.length > 0 ? (
|
justifyContent: "center",
|
||||||
displayOptions.map((option, index) => {
|
flexWrap: "wrap",
|
||||||
const optionUri =
|
}}
|
||||||
option?.finalUrl || option?.generatedUrl || "";
|
>
|
||||||
if (!optionUri) return null;
|
{displayOptions.length > 0 ? (
|
||||||
if (hasGeneratedOptions) {
|
displayOptions.map((option, index) => {
|
||||||
const isSelected = option?.id === selectedOption?.id;
|
const optionUri =
|
||||||
const cardWidthStyle = isWeb
|
option?.finalUrl || option?.generatedUrl || "";
|
||||||
? styles.coverOptionCardWeb
|
if (!optionUri) return null;
|
||||||
: styles.coverOptionCardMobile;
|
if (hasGeneratedOptions) {
|
||||||
|
const isSelected = option?.id === selectedOption?.id;
|
||||||
|
const cardWidthStyle = isWeb
|
||||||
|
? styles.coverOptionCardWeb
|
||||||
|
: styles.coverOptionCardMobile;
|
||||||
|
return (
|
||||||
|
<Pressable
|
||||||
|
key={option?.id || index}
|
||||||
|
onPress={() => handleSelectOption(option)}
|
||||||
|
disabled={isSelecting}
|
||||||
|
style={[
|
||||||
|
styles.coverOptionCard,
|
||||||
|
cardWidthStyle,
|
||||||
|
isSelected ? styles.coverOptionCardSelected : null,
|
||||||
|
isSelecting ? styles.coverOptionCardDisabled : null,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<ExpoImage
|
||||||
|
source={{ uri: optionUri }}
|
||||||
|
cachePolicy="memory-disk"
|
||||||
|
priority="high"
|
||||||
|
contentFit="cover"
|
||||||
|
transition={120}
|
||||||
|
style={styles.coverOptionImage}
|
||||||
|
/>
|
||||||
|
<View style={styles.coverOptionBadge}>
|
||||||
|
<Text style={styles.coverOptionBadgeLabel}>
|
||||||
|
{`Option ${index + 1}`}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
{isSelected && (
|
||||||
|
<View style={styles.coverOptionSelectedBadge}>
|
||||||
|
<Text style={styles.coverOptionSelectedLabel}>
|
||||||
|
Sélectionnée
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</Pressable>
|
||||||
|
);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<Pressable
|
<View
|
||||||
key={option?.id || index}
|
key={option?.id || index}
|
||||||
onPress={() => handleSelectOption(option)}
|
|
||||||
disabled={isSelecting}
|
|
||||||
style={[
|
style={[
|
||||||
styles.coverOptionCard,
|
styles.coverPreviewCard,
|
||||||
cardWidthStyle,
|
isWeb
|
||||||
isSelected ? styles.coverOptionCardSelected : null,
|
? styles.coverPreviewCardWeb
|
||||||
isSelecting ? styles.coverOptionCardDisabled : null,
|
: styles.coverPreviewCardMobile,
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<ExpoImage
|
<ExpoImage
|
||||||
@@ -357,62 +399,41 @@ const PouchReady = () => {
|
|||||||
priority="high"
|
priority="high"
|
||||||
contentFit="cover"
|
contentFit="cover"
|
||||||
transition={120}
|
transition={120}
|
||||||
style={styles.coverOptionImage}
|
style={styles.coverPreviewImage}
|
||||||
/>
|
/>
|
||||||
<View style={styles.coverOptionBadge}>
|
</View>
|
||||||
<Text style={styles.coverOptionBadgeLabel}>
|
|
||||||
{`Option ${index + 1}`}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
{isSelected && (
|
|
||||||
<View style={styles.coverOptionSelectedBadge}>
|
|
||||||
<Text style={styles.coverOptionSelectedLabel}>
|
|
||||||
Sélectionnée
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
</Pressable>
|
|
||||||
);
|
);
|
||||||
}
|
})
|
||||||
return (
|
) : (
|
||||||
<View
|
<>
|
||||||
key={option?.id || index}
|
{isGenerating && (
|
||||||
style={[
|
<View
|
||||||
styles.coverPreviewCard,
|
style={{
|
||||||
isWeb
|
alignItems: "center",
|
||||||
? styles.coverPreviewCardWeb
|
gap: 8,
|
||||||
: styles.coverPreviewCardMobile,
|
width: isWeb ? 300 : "100%",
|
||||||
]}
|
height: 300,
|
||||||
>
|
borderRadius: 20,
|
||||||
<ExpoImage
|
backgroundColor: "#00000040",
|
||||||
source={{ uri: optionUri }}
|
alignSelf: "center",
|
||||||
cachePolicy="memory-disk"
|
...Style.containerCenter,
|
||||||
priority="high"
|
}}
|
||||||
contentFit="cover"
|
>
|
||||||
transition={120}
|
<ActivityIndicator color={Palette.white} />
|
||||||
style={styles.coverPreviewImage}
|
{isWeb ? (
|
||||||
/>
|
coverBackgroundMessage ? (
|
||||||
</View>
|
<Text
|
||||||
);
|
style={{
|
||||||
})
|
color: Palette.white,
|
||||||
) : (
|
marginTop: 6,
|
||||||
<>
|
textAlign: "center",
|
||||||
{isGenerating && (
|
opacity: 0.9,
|
||||||
<View
|
}}
|
||||||
style={{
|
>
|
||||||
alignItems: "center",
|
{coverBackgroundMessage}
|
||||||
gap: 8,
|
</Text>
|
||||||
width: isWeb ? 300 : "100%",
|
) : null
|
||||||
height: 300,
|
) : (
|
||||||
borderRadius: 20,
|
|
||||||
backgroundColor: "#00000040",
|
|
||||||
alignSelf: "center",
|
|
||||||
...Style.containerCenter,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ActivityIndicator color={Palette.white} />
|
|
||||||
{isWeb ? (
|
|
||||||
coverBackgroundMessage ? (
|
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
color: Palette.white,
|
color: Palette.white,
|
||||||
@@ -421,201 +442,196 @@ const PouchReady = () => {
|
|||||||
opacity: 0.9,
|
opacity: 0.9,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{coverBackgroundMessage}
|
Génération en cours.
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
<View style={{ alignItems: "center", gap: 10 }}>
|
||||||
|
<ProgressBar gradient progress={coverProgressValue} />
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: Palette.white,
|
||||||
|
fontFamily: FONT_FAMILY.InterRegular,
|
||||||
|
fontSize: 13,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{coverProgressValue}%
|
||||||
</Text>
|
</Text>
|
||||||
) : null
|
|
||||||
) : (
|
|
||||||
<Text
|
|
||||||
style={{
|
|
||||||
color: Palette.white,
|
|
||||||
marginTop: 6,
|
|
||||||
textAlign: "center",
|
|
||||||
opacity: 0.9,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Génération en cours.
|
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
<View style={{ alignItems: "center", gap: 10 }}>
|
|
||||||
<ProgressBar gradient progress={coverProgressValue} />
|
|
||||||
<Text
|
|
||||||
style={{
|
|
||||||
color: Palette.white,
|
|
||||||
fontFamily: FONT_FAMILY.InterRegular,
|
|
||||||
fontSize: 13,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{coverProgressValue}%
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
// </View>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
{shouldShowStylePanel && (
|
|
||||||
<BlurView
|
|
||||||
tint="dark"
|
|
||||||
intensity={isWeb ? 40 : 30}
|
|
||||||
style={[styles.stylePanel, isWeb && styles.stylePanelWeb]}
|
|
||||||
>
|
|
||||||
<View style={styles.stylePanelHeader}>
|
|
||||||
<Text style={styles.panelTitle}>Style de la pochette</Text>
|
|
||||||
<Text style={styles.panelSubtitle}>
|
|
||||||
Choisis une ambiance ou écris ton propre brief créatif.
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
<View style={styles.modeContainer}>
|
|
||||||
<View
|
|
||||||
style={[
|
|
||||||
styles.modeCard,
|
|
||||||
styleMode === "preset" ? styles.modeCardActive : null,
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<AppCheckbox
|
|
||||||
label="Choisir un style prédéfini"
|
|
||||||
selected={styleMode === "preset"}
|
|
||||||
onPress={() => {
|
|
||||||
setStyleMode("preset");
|
|
||||||
setIsPresetDropdownOpen(false);
|
|
||||||
if (!selectedPresetStyle) {
|
|
||||||
setSelectedPresetStyle(COVER_STYLE_PRESETS[0]);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
{styleMode === "preset" && (
|
|
||||||
<View style={styles.dropdownArea}>
|
|
||||||
<Pressable
|
|
||||||
style={styles.dropdownTrigger}
|
|
||||||
onPress={() => setIsPresetDropdownOpen((prev) => !prev)}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
style={styles.dropdownTriggerLabel}
|
|
||||||
numberOfLines={2}
|
|
||||||
>
|
|
||||||
{selectedPresetStyle}
|
|
||||||
</Text>
|
|
||||||
<Image
|
|
||||||
source={icons.chevronDown}
|
|
||||||
style={[
|
|
||||||
styles.dropdownArrow,
|
|
||||||
isPresetDropdownOpen
|
|
||||||
? styles.dropdownArrowOpen
|
|
||||||
: null,
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
</Pressable>
|
|
||||||
{isPresetDropdownOpen && (
|
|
||||||
<View style={styles.dropdownList}>
|
|
||||||
{COVER_STYLE_PRESETS.map((styleOption, index) => {
|
|
||||||
const isActive =
|
|
||||||
selectedPresetStyle === styleOption;
|
|
||||||
const isLast =
|
|
||||||
index === COVER_STYLE_PRESETS.length - 1;
|
|
||||||
return (
|
|
||||||
<Pressable
|
|
||||||
key={styleOption}
|
|
||||||
style={[
|
|
||||||
styles.dropdownOption,
|
|
||||||
!isLast ? styles.dropdownOptionDivider : null,
|
|
||||||
isActive ? styles.dropdownOptionActive : null,
|
|
||||||
]}
|
|
||||||
onPress={() => {
|
|
||||||
setSelectedPresetStyle(styleOption);
|
|
||||||
setIsPresetDropdownOpen(false);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
style={[
|
|
||||||
styles.dropdownOptionLabel,
|
|
||||||
isActive
|
|
||||||
? styles.dropdownOptionLabelActive
|
|
||||||
: null,
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
{styleOption}
|
|
||||||
</Text>
|
|
||||||
{isActive && (
|
|
||||||
<Image
|
|
||||||
source={icons.check}
|
|
||||||
style={styles.dropdownOptionIcon}
|
|
||||||
resizeMode="contain"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Pressable>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</View>
|
</View>
|
||||||
)}
|
</View>
|
||||||
</View>
|
)}
|
||||||
)}
|
</>
|
||||||
<View style={styles.modeColumn}>
|
// </View>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
{shouldShowStylePanel && (
|
||||||
|
<BlurView
|
||||||
|
tint="dark"
|
||||||
|
intensity={isWeb ? 40 : 30}
|
||||||
|
style={[styles.stylePanel, isWeb && styles.stylePanelWeb]}
|
||||||
|
>
|
||||||
|
<View style={styles.stylePanelHeader}>
|
||||||
|
<Text style={styles.panelTitle}>Style de la pochette</Text>
|
||||||
|
<Text style={styles.panelSubtitle}>
|
||||||
|
Choisis une ambiance ou écris ton propre brief créatif.
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.modeContainer}>
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
styles.modeCard,
|
styles.modeCard,
|
||||||
styleMode === "custom" ? styles.modeCardActive : null,
|
styleMode === "preset" ? styles.modeCardActive : null,
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<AppCheckbox
|
<AppCheckbox
|
||||||
label="Style personnalisé"
|
label="Choisir un style prédéfini"
|
||||||
selected={styleMode === "custom"}
|
selected={styleMode === "preset"}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
setStyleMode("custom");
|
setStyleMode("preset");
|
||||||
setIsPresetDropdownOpen(false);
|
setIsPresetDropdownOpen(false);
|
||||||
|
if (!selectedPresetStyle) {
|
||||||
|
setSelectedPresetStyle(COVER_STYLE_PRESETS[0]);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
{styleMode === "custom" && (
|
{styleMode === "preset" && (
|
||||||
<View style={styles.customInputWrapper}>
|
<View style={styles.dropdownArea}>
|
||||||
<TextInput
|
<Pressable
|
||||||
placeholder="Exemple : Collage rétro futuriste lumineux"
|
style={styles.dropdownTrigger}
|
||||||
placeholderTextColor={Palette.grayMid}
|
onPress={() =>
|
||||||
value={customStyle}
|
setIsPresetDropdownOpen((prev) => !prev)
|
||||||
onChangeText={setCustomStyle}
|
}
|
||||||
style={styles.customInput}
|
>
|
||||||
multiline={false}
|
<Text
|
||||||
maxLength={120}
|
style={styles.dropdownTriggerLabel}
|
||||||
textAlignVertical="center"
|
numberOfLines={2}
|
||||||
autoCapitalize="sentences"
|
>
|
||||||
autoCorrect
|
{selectedPresetStyle}
|
||||||
selectionColor={Palette.primary}
|
</Text>
|
||||||
/>
|
<Image
|
||||||
|
source={icons.chevronDown}
|
||||||
|
style={[
|
||||||
|
styles.dropdownArrow,
|
||||||
|
isPresetDropdownOpen
|
||||||
|
? styles.dropdownArrowOpen
|
||||||
|
: null,
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Pressable>
|
||||||
|
{isPresetDropdownOpen && (
|
||||||
|
<View style={styles.dropdownList}>
|
||||||
|
{COVER_STYLE_PRESETS.map((styleOption, index) => {
|
||||||
|
const isActive =
|
||||||
|
selectedPresetStyle === styleOption;
|
||||||
|
const isLast =
|
||||||
|
index === COVER_STYLE_PRESETS.length - 1;
|
||||||
|
return (
|
||||||
|
<Pressable
|
||||||
|
key={styleOption}
|
||||||
|
style={[
|
||||||
|
styles.dropdownOption,
|
||||||
|
!isLast
|
||||||
|
? styles.dropdownOptionDivider
|
||||||
|
: null,
|
||||||
|
isActive
|
||||||
|
? styles.dropdownOptionActive
|
||||||
|
: null,
|
||||||
|
]}
|
||||||
|
onPress={() => {
|
||||||
|
setSelectedPresetStyle(styleOption);
|
||||||
|
setIsPresetDropdownOpen(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.dropdownOptionLabel,
|
||||||
|
isActive
|
||||||
|
? styles.dropdownOptionLabelActive
|
||||||
|
: null,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{styleOption}
|
||||||
|
</Text>
|
||||||
|
{isActive && (
|
||||||
|
<Image
|
||||||
|
source={icons.check}
|
||||||
|
style={styles.dropdownOptionIcon}
|
||||||
|
resizeMode="contain"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Pressable>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
<View style={styles.modeColumn}>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
styles.modeCard,
|
||||||
|
styleMode === "custom" ? styles.modeCardActive : null,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<AppCheckbox
|
||||||
|
label="Style personnalisé"
|
||||||
|
selected={styleMode === "custom"}
|
||||||
|
onPress={() => {
|
||||||
|
setStyleMode("custom");
|
||||||
|
setIsPresetDropdownOpen(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
{styleMode === "custom" && (
|
||||||
|
<View style={styles.customInputWrapper}>
|
||||||
|
<TextInput
|
||||||
|
placeholder="Exemple : Collage rétro futuriste lumineux"
|
||||||
|
placeholderTextColor={Palette.grayMid}
|
||||||
|
value={customStyle}
|
||||||
|
onChangeText={setCustomStyle}
|
||||||
|
style={styles.customInput}
|
||||||
|
multiline={false}
|
||||||
|
maxLength={120}
|
||||||
|
textAlignVertical="center"
|
||||||
|
autoCapitalize="sentences"
|
||||||
|
autoCorrect
|
||||||
|
selectionColor={Palette.primary}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</BlurView>
|
||||||
</BlurView>
|
)}
|
||||||
)}
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
<View
|
||||||
<View
|
style={{
|
||||||
style={{
|
paddingBottom: gutters * 2,
|
||||||
paddingBottom: gutters * 2,
|
width: isWeb ? "80%" : "100%",
|
||||||
width: isWeb ? "80%" : "100%",
|
alignSelf: "center",
|
||||||
alignSelf: "center",
|
gap: 12,
|
||||||
gap: 12,
|
}}
|
||||||
}}
|
>
|
||||||
>
|
{!hasGeneratedOptions && (
|
||||||
{!hasGeneratedOptions && (
|
<BorderGradientButton
|
||||||
<BorderGradientButton
|
title={
|
||||||
title={
|
isGenerating ? "Génération en cours..." : "Générer la pochette"
|
||||||
isGenerating ? "Génération en cours..." : "Générer la pochette"
|
}
|
||||||
}
|
icon={icons.stars}
|
||||||
icon={icons.stars}
|
onPress={requestCoverGeneration}
|
||||||
onPress={requestCoverGeneration}
|
disabled={isGenerating}
|
||||||
disabled={isGenerating}
|
/>
|
||||||
/>
|
)}
|
||||||
)}
|
{hasGeneratedOptions && (
|
||||||
{hasGeneratedOptions && (
|
<GradientButton
|
||||||
<GradientButton
|
title={"Valider la pochette"}
|
||||||
title={"Valider la pochette"}
|
onPress={onValidatePicture}
|
||||||
onPress={onValidatePicture}
|
/>
|
||||||
/>
|
)}
|
||||||
)}
|
</View>
|
||||||
</View>
|
</KeyboardAvoidingView>
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user