184 lines
6.5 KiB
JavaScript
184 lines
6.5 KiB
JavaScript
import { Image as ExpoImage } from 'expo-image'
|
|
import React, { useEffect, useRef, useState } from 'react'
|
|
import { ActivityIndicator, Text, View } from 'react-native'
|
|
import { background } from '../../assets'
|
|
import GradientButton from '../../components/GradientButton'
|
|
import MusicLandHeader from '../../components/MusicLandHeader'
|
|
import loaderMessages from '../../config/loaderMessages'
|
|
import { isWeb } from '../../hooks/useLayoutType'
|
|
import Page from '../../layouts/Page'
|
|
import { Routes } from '../../navigation'
|
|
import { goBack, navigate } from '../../navigation/NavigationService'
|
|
import { useUserData } from '../../providers/UserDataProvider'
|
|
import { gutters, Palette, Style } from '../../styles'
|
|
import { FONT_FAMILY } from '../../styles/Fonts'
|
|
import CreateLyricsHeader from '../Writing/components/CreateLyricsHeader'
|
|
import ProgressBar from '../../components/ProgressBar'
|
|
const COVER_PROGRESS_MAX = 98
|
|
const COVER_PROGRESS_INTERVAL_MS = 500
|
|
const COVER_FAKE_DURATION_MS = 2 * 60 * 1000
|
|
|
|
const PhotoCover = () => {
|
|
const [coverProgress, setCoverProgress] = useState(0)
|
|
const progressIntervalRef = useRef(null)
|
|
const progressStartRef = useRef(null)
|
|
const { selectedProject } = useUserData()
|
|
const isGenerating = selectedProject?.coverStatus === 'GENERATING'
|
|
const coverGenerationMessage = isWeb ? loaderMessages.photoCoverGenerationWeb : ''
|
|
|
|
const coverOptions = Array.isArray(selectedProject?.cover?.options)
|
|
? selectedProject.cover.options
|
|
: []
|
|
const coverUrl =
|
|
selectedProject?.cover?.result ||
|
|
selectedProject?.cover?.generatedBackground ||
|
|
coverOptions?.[0]?.finalUrl ||
|
|
coverOptions?.[0]?.generatedUrl ||
|
|
null
|
|
const coverProgressValue = Math.max(0, Math.min(100, Math.round(coverProgress)))
|
|
|
|
useEffect(() => {
|
|
const clearProgressInterval = () => {
|
|
if (progressIntervalRef.current) {
|
|
global.clearInterval(progressIntervalRef.current)
|
|
progressIntervalRef.current = null
|
|
}
|
|
}
|
|
|
|
if (!isGenerating || coverUrl) {
|
|
clearProgressInterval()
|
|
progressStartRef.current = null
|
|
setCoverProgress(coverUrl ? 100 : 0)
|
|
return clearProgressInterval
|
|
}
|
|
|
|
progressStartRef.current = new Date()
|
|
setCoverProgress(0)
|
|
clearProgressInterval()
|
|
progressIntervalRef.current = global.setInterval(() => {
|
|
const start = progressStartRef.current
|
|
if (!start) return
|
|
const elapsed = Date.now() - start.getTime()
|
|
const ratio = Math.max(0, Math.min(1, elapsed / COVER_FAKE_DURATION_MS))
|
|
const next = COVER_PROGRESS_MAX * ratio
|
|
setCoverProgress((prev) => {
|
|
if (prev >= COVER_PROGRESS_MAX) return COVER_PROGRESS_MAX
|
|
return next >= COVER_PROGRESS_MAX ? COVER_PROGRESS_MAX : next
|
|
})
|
|
}, COVER_PROGRESS_INTERVAL_MS)
|
|
|
|
return clearProgressInterval
|
|
}, [coverUrl, isGenerating])
|
|
|
|
return (
|
|
<Page backgroundImg={background.studioBG2} headerType="NONE">
|
|
<MusicLandHeader onPressBack={goBack} progress={81} />
|
|
<View style={{ flex: 1, marginTop: 16 }}>
|
|
<CreateLyricsHeader
|
|
title="Ta pochette MusicLand Production"
|
|
subTitle="Le logo est automatiquement ajouté en bas à droite."
|
|
/>
|
|
<View style={{ flex: 1, ...Style.containerCenter }}>
|
|
<View style={{ width: '80%', position: 'relative' }}>
|
|
{coverUrl && !isGenerating ? (
|
|
<ExpoImage
|
|
source={{ uri: coverUrl }}
|
|
cachePolicy="memory-disk"
|
|
priority="high"
|
|
contentFit="cover"
|
|
transition={120}
|
|
style={{
|
|
width: isWeb ? 300 : '100%',
|
|
height: 300,
|
|
borderRadius: 20,
|
|
alignSelf: 'center',
|
|
}}
|
|
/>
|
|
) : (
|
|
<View
|
|
style={{
|
|
width: '100%',
|
|
height: 300,
|
|
borderRadius: 20,
|
|
backgroundColor: '#00000040',
|
|
...Style.containerCenter,
|
|
}}
|
|
>
|
|
<View style={{ alignItems: 'center', gap: 8 }}>
|
|
{isGenerating ? (
|
|
<>
|
|
<ActivityIndicator color={Palette.white} />
|
|
{isWeb && coverGenerationMessage ? (
|
|
<Text
|
|
style={{
|
|
color: Palette.white,
|
|
marginTop: 6,
|
|
textAlign: 'center',
|
|
opacity: 0.9,
|
|
}}
|
|
>
|
|
{coverGenerationMessage}
|
|
</Text>
|
|
) : (
|
|
<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>
|
|
</>
|
|
) : (
|
|
<Text
|
|
style={{
|
|
color: Palette.white,
|
|
marginTop: 6,
|
|
textAlign: 'center',
|
|
opacity: 0.9,
|
|
}}
|
|
>
|
|
La pochette sera disponible une fois la génération terminée.
|
|
</Text>
|
|
)}
|
|
</View>
|
|
</View>
|
|
)}
|
|
</View>
|
|
</View>
|
|
</View>
|
|
<View
|
|
style={{
|
|
paddingBottom: gutters * 2,
|
|
width: '80%',
|
|
alignSelf: 'center',
|
|
gap: 12,
|
|
}}
|
|
>
|
|
<GradientButton
|
|
title="Valider la pochette"
|
|
onPress={() => navigate(Routes.ValidateCover)}
|
|
disabled={isGenerating || !coverUrl}
|
|
/>
|
|
</View>
|
|
</Page>
|
|
)
|
|
}
|
|
|
|
export default PhotoCover
|