271 lines
7.4 KiB
JavaScript
271 lines
7.4 KiB
JavaScript
import { Routes } from '../navigation/Routes'
|
|
|
|
export const CREATION_STAGE_KEYS = ['songwriter', 'beatmaker', 'director']
|
|
|
|
const getSectionLyrics = (section) => {
|
|
if (typeof section === 'string') {
|
|
return section.trim()
|
|
}
|
|
if (section && typeof section === 'object') {
|
|
const value = typeof section.lyrics === 'string' ? section.lyrics.trim() : ''
|
|
return value
|
|
}
|
|
return ''
|
|
}
|
|
|
|
const getLyricsCount = (project) => {
|
|
if (!project) return 0
|
|
const { lyrics } = project
|
|
if (Array.isArray(lyrics)) {
|
|
return lyrics.reduce((count, section) => (getSectionLyrics(section) ? count + 1 : count), 0)
|
|
}
|
|
if (lyrics && typeof lyrics === 'object') {
|
|
return Object.values(lyrics).reduce(
|
|
(count, value) => (getSectionLyrics(value) ? count + 1 : count),
|
|
0
|
|
)
|
|
}
|
|
return getSectionLyrics(lyrics) ? 1 : 0
|
|
}
|
|
|
|
const getStageMetadata = (project) => {
|
|
const lyricsCount = getLyricsCount(project)
|
|
const hasLyrics = !!(project?.hasLyrics || lyricsCount > 0)
|
|
const hasSongUrl = !!project?.songUrl
|
|
const cover = project?.cover || {}
|
|
const hasCoverUrl = !!project?.coverUrl
|
|
const hasPlaybackAsset = !!project?.playbackUrl
|
|
const hasPlayback = hasPlaybackAsset || hasSongUrl
|
|
const musicUrls = Array.isArray(project?.musicUrls) ? project.musicUrls.filter(Boolean) : []
|
|
const musicStatus = project?.musicStatus || null
|
|
const coverStatus = project?.coverStatus || null
|
|
const playbackStatus = project?.playbackStatus || null
|
|
const isPlaybackGenerating =
|
|
project?.playbackGenerating === true ||
|
|
project?.isPlaybackGenerating === true ||
|
|
playbackStatus === 'GENERATING'
|
|
const isPlaybackDraftReady = playbackStatus === 'DRAFT_READY'
|
|
|
|
return {
|
|
lyricsCount,
|
|
hasLyrics,
|
|
hasSongUrl,
|
|
hasCover: hasCoverUrl,
|
|
hasPlayback,
|
|
hasPlaybackAsset,
|
|
hasMusicDraft: musicUrls.length > 0,
|
|
musicStatus,
|
|
coverStatus,
|
|
playbackStatus,
|
|
isPlaybackDraftReady,
|
|
isMusicGenerating: musicStatus === 'GENERATING',
|
|
isCoverGenerating: coverStatus === 'GENERATING',
|
|
isPlaybackGenerating,
|
|
}
|
|
}
|
|
|
|
const getStageLockState = (key, metadata) => {
|
|
switch (key) {
|
|
case 'songwriter':
|
|
return metadata.hasSongUrl
|
|
case 'beatmaker':
|
|
if (metadata.hasCover) {
|
|
return true
|
|
}
|
|
return metadata.lyricsCount <= 0
|
|
case 'director':
|
|
return !metadata.hasCover
|
|
default:
|
|
return true
|
|
}
|
|
}
|
|
|
|
const getStageDescription = (key, metadata) => {
|
|
const {
|
|
hasLyrics,
|
|
hasSongUrl,
|
|
hasCover,
|
|
hasPlaybackAsset,
|
|
hasMusicDraft,
|
|
isMusicGenerating,
|
|
isPlaybackGenerating,
|
|
isPlaybackDraftReady,
|
|
} = metadata
|
|
|
|
switch (key) {
|
|
case 'songwriter':
|
|
if (!hasLyrics) {
|
|
return 'Commencer à créer des paroles pour votre chanson'
|
|
}
|
|
if (!hasSongUrl) {
|
|
return 'Continuer la création de paroles'
|
|
}
|
|
return 'Modifier les paroles créées'
|
|
case 'beatmaker':
|
|
if (metadata.hasCover) {
|
|
return 'Impossible de modifier la cover ou la production musicale'
|
|
}
|
|
if (!hasLyrics) {
|
|
return 'Écrivez vos paroles pour débloquer la musique'
|
|
}
|
|
if (isMusicGenerating) {
|
|
return 'Votre morceau est en cours de création'
|
|
}
|
|
if (hasSongUrl) {
|
|
if (!hasCover) {
|
|
return 'Créer ou modifier la cover de votre morceau'
|
|
}
|
|
return 'Modifier la cover ou la production musicale'
|
|
}
|
|
if (hasMusicDraft) {
|
|
return 'Modifier la production musicale'
|
|
}
|
|
return 'Commencer la création de votre morceau'
|
|
case 'director':
|
|
if (!hasCover) {
|
|
return 'Validez votre pochette pour débloquer le playback'
|
|
}
|
|
if (isPlaybackGenerating) {
|
|
return 'Votre playback est en cours de préparation'
|
|
}
|
|
if (isPlaybackDraftReady) {
|
|
return 'Votre playback IA est prêt à être validé'
|
|
}
|
|
if (hasPlaybackAsset) {
|
|
return 'Télécharger ou publier votre playback'
|
|
}
|
|
return 'Commencer la création de votre playback'
|
|
default:
|
|
return ''
|
|
}
|
|
}
|
|
|
|
const getStageLockedDescription = (key, metadata) => {
|
|
switch (key) {
|
|
case 'songwriter':
|
|
return metadata.hasSongUrl ? 'Impossible de modifier les paroles' : undefined
|
|
case 'beatmaker':
|
|
if (metadata.hasCover) {
|
|
return 'Impossible de modifier la cover ou la production musicale'
|
|
}
|
|
return metadata.lyricsCount > 0 ? undefined : 'Créez vos paroles pour débloquer le studio'
|
|
case 'director':
|
|
return undefined
|
|
default:
|
|
return undefined
|
|
}
|
|
}
|
|
|
|
const getStageCompletionState = (key, metadata) => {
|
|
switch (key) {
|
|
case 'songwriter':
|
|
return metadata.hasLyrics
|
|
case 'beatmaker':
|
|
return metadata.hasSongUrl || metadata.musicStatus === 'GENERATED'
|
|
case 'director':
|
|
return metadata.hasPlaybackAsset
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
export const getCreationStageStates = (project) => {
|
|
const metadata = getStageMetadata(project)
|
|
return CREATION_STAGE_KEYS.map((key, index) => {
|
|
const isLocked = getStageLockState(key, metadata)
|
|
const description = getStageDescription(key, metadata)
|
|
const lockedDescription = getStageLockedDescription(key, metadata)
|
|
|
|
return {
|
|
key,
|
|
index,
|
|
isLocked,
|
|
isCompleted: getStageCompletionState(key, metadata),
|
|
description: isLocked && lockedDescription ? lockedDescription : description,
|
|
lockedDescription,
|
|
}
|
|
})
|
|
}
|
|
|
|
export const getStageAction = (key, project) => {
|
|
switch (key) {
|
|
case 'songwriter':
|
|
return {
|
|
route: getLyricsCount(project) > 0 ? Routes.Lyrics : Routes.CreateLyricsWithAi,
|
|
}
|
|
case 'beatmaker': {
|
|
if (!project) {
|
|
return { route: Routes.ComposeSong }
|
|
}
|
|
|
|
const musicStatus = project?.musicStatus || null
|
|
const songUrl = project?.songUrl || null
|
|
const coverStatus = project?.coverStatus || null
|
|
const cover = project?.cover || {}
|
|
const hasCoverResult = !!cover?.result
|
|
const hasFinalCover = !!project?.coverUrl
|
|
|
|
if (musicStatus === 'GENERATING') {
|
|
return { route: Routes.GeneratingSong }
|
|
}
|
|
|
|
if (!songUrl) {
|
|
if (musicStatus === 'GENERATED') {
|
|
return { route: Routes.SongReady }
|
|
}
|
|
return { route: Routes.ComposeSong }
|
|
}
|
|
|
|
if (coverStatus === 'GENERATING') {
|
|
return { route: Routes.PouchReady }
|
|
}
|
|
|
|
if (!hasCoverResult) {
|
|
return { route: Routes.ChooseCoverType }
|
|
}
|
|
|
|
return { route: hasFinalCover ? Routes.ChooseCoverType : Routes.PouchReady }
|
|
}
|
|
case 'director':
|
|
if (project?.playbackUrl) {
|
|
return {
|
|
route: Routes.PlaybackDownload,
|
|
params: {
|
|
action: 'playback',
|
|
project,
|
|
},
|
|
}
|
|
}
|
|
return {
|
|
route: Routes.Playback,
|
|
params: project ? { project } : undefined,
|
|
}
|
|
default:
|
|
return {}
|
|
}
|
|
}
|
|
|
|
export const findFirstUnlockedStageIndex = (project) => {
|
|
const stages = getCreationStageStates(project)
|
|
if (!stages.length) {
|
|
return 0
|
|
}
|
|
|
|
const actionableIndex = stages.findIndex((stage) => !stage.isCompleted && !stage.isLocked)
|
|
if (actionableIndex !== -1) {
|
|
return actionableIndex
|
|
}
|
|
|
|
const firstIncomplete = stages.findIndex((stage) => !stage.isCompleted)
|
|
if (firstIncomplete !== -1) {
|
|
return firstIncomplete
|
|
}
|
|
|
|
const firstUnlocked = stages.findIndex((stage) => !stage.isLocked)
|
|
if (firstUnlocked !== -1) {
|
|
return firstUnlocked
|
|
}
|
|
|
|
return stages.length - 1
|
|
}
|