diff --git a/src/screens/Writing/Lyrics.js b/src/screens/Writing/Lyrics.js
index 986dbb2..e77f12f 100644
--- a/src/screens/Writing/Lyrics.js
+++ b/src/screens/Writing/Lyrics.js
@@ -1,6 +1,5 @@
import React, { useCallback, useMemo, useRef, useState } from 'react'
import { ScrollView, StyleSheet, Text, View } from 'react-native'
-import useMinuit from 'react-native-minuit/src/hooks/useMinuit.js'
import { background, icons } from '../../assets'
import alert from '../../components/Alert'
import AppCheckbox from '../../components/AppCheckbox'
@@ -15,6 +14,7 @@ import { isWeb } from '../../hooks/useLayoutType'
import Page from '../../layouts/Page'
import { Routes } from '../../navigation'
import { navigate } from '../../navigation/NavigationService'
+import { LoaderIndicator } from '../../providers/LoadingProvider'
import { useUser } from '../../providers/UserDataProvider'
import { Palette, gutters } from '../../styles'
import { FONT_FAMILY } from '../../styles/Fonts'
@@ -35,7 +35,6 @@ const RESPONSIBILITY_CHECKBOX_LABEL =
const Lyrics = ({ navigation }) => {
const scrollRef = useRef(null)
const [containerLayout, setContainerLayout] = useState(null)
- const { setIsLoading } = useMinuit()
const { selectedProjectId, selectedProject } = useUser()
const hasExistingMusicDraft = useMemo(() => {
if (!Array.isArray(selectedProject?.musicUrls)) return false
@@ -43,6 +42,9 @@ const Lyrics = ({ navigation }) => {
}, [selectedProject?.musicUrls])
const [isFocus, setIsFocus] = useState(null)
const [itemsContainerLayout, setItemsContainerLayout] = useState([])
+ const [isSubmitting, setIsSubmitting] = useState(false)
+ const [isBlockingUI, setIsBlockingUI] = useState(false)
+ const isSubmittingRef = useRef(false)
const [sensitiveContentModal, setSensitiveContentModal] = useState({
visible: false,
title: '',
@@ -194,10 +196,14 @@ const Lyrics = ({ navigation }) => {
}, [closeSensitiveContentModal, isSensitiveContentAcknowledged])
const onValidate = useCallback(async () => {
+ if (isSubmittingRef.current) return
+ isSubmittingRef.current = true
+ setIsSubmitting(true)
+ setIsBlockingUI(true)
try {
- await setIsLoading(true)
const titleTrimmed = (titleValue || '').trim()
if (!titleTrimmed) {
+ setIsBlockingUI(false)
alertMessage('Titre manquant', 'Veuillez renseigner un titre.')
return
}
@@ -207,6 +213,7 @@ const Lyrics = ({ navigation }) => {
return !(s?.lyrics || '').trim()
})
if (invalid) {
+ setIsBlockingUI(false)
alertMessage('Champs incomplets', 'Chaque section doit contenir du texte.')
return
}
@@ -247,11 +254,13 @@ const Lyrics = ({ navigation }) => {
.map((e) => `• ${e.quote}`)
.join('\n')
: null
+ setIsBlockingUI(false)
alertMessage('Contenu interdit', [data?.message, quotes].filter(Boolean).join('\n\n'))
return // stop here
}
// Erreur d'analyse: informer et arrêter
if (data?.errorCode === 'ANALYSE_FAILED') {
+ setIsBlockingUI(false)
alertMessage(
'Analyse indisponible',
'Impossible de vérifier la toxicité pour le moment. Réessayez plus tard.'
@@ -270,11 +279,14 @@ const Lyrics = ({ navigation }) => {
: null
const msg = [data?.message, quotes].filter(Boolean).join('\n\n')
+ setIsBlockingUI(false)
const proceed = await confirmSensitiveContent('Contenu potentiellement sensible', msg)
if (!proceed) return
+ setIsBlockingUI(true)
}
} catch (moderationError) {
console.log('Moderation call failed', moderationError?.message || moderationError)
+ setIsBlockingUI(false)
alertMessage(
'Analyse indisponible',
'Impossible de vérifier la toxicité pour le moment. Réessayez plus tard.'
@@ -310,7 +322,7 @@ const Lyrics = ({ navigation }) => {
projectForStage.musicStatus = undefined
}
const beatmakerStage = getStageAction('beatmaker', projectForStage)
- await setIsLoading(false)
+ setIsBlockingUI(false)
if (hasExistingMusicDraft) {
navigate(Routes.ComposeSong, { isRegeneration: true })
return
@@ -343,9 +355,12 @@ const Lyrics = ({ navigation }) => {
return
} catch (e) {
console.log(e)
+ setIsBlockingUI(false)
alertMessage('Erreur', "Échec de l'enregistrement dans le projet.")
} finally {
- await setIsLoading(false)
+ isSubmittingRef.current = false
+ setIsSubmitting(false)
+ setIsBlockingUI(false)
}
}, [
titleValue,
@@ -355,7 +370,6 @@ const Lyrics = ({ navigation }) => {
alertMessage,
confirmSensitiveContent,
sanitize,
- setIsLoading,
selectedProjectId,
projectHasLyrics,
projectLyrics,
@@ -461,10 +475,22 @@ const Lyrics = ({ navigation }) => {
}}
>
{!projectHasLyrics && (
-
+
)}
-
+
+ {isBlockingUI ? (
+
+
+
+ ) : null}
{
@@ -578,4 +604,11 @@ const styles = StyleSheet.create({
flexDirection: 'row',
gap: 12,
},
+ loadingOverlay: {
+ ...StyleSheet.absoluteFillObject,
+ zIndex: 10000,
+ backgroundColor: Palette.transparentBlack,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
})