filter on lyrics for bloking unwanted content, tickets fix
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { View, ScrollView, Alert } from "react-native";
|
||||
import React, { useMemo, useState, useCallback, useEffect, useRef } from "react";
|
||||
import React, { useMemo, useState, useCallback, useEffect } from "react";
|
||||
import Page from "../../layouts/Page";
|
||||
import MusicLandHeader from "../../components/MusicLandHeader";
|
||||
import { navigate } from "../../navigation/NavigationService";
|
||||
@@ -61,37 +61,6 @@ const Lyrics = ({ navigation }) => {
|
||||
}, [projectTitle, projectLyrics, projectConfig]);
|
||||
|
||||
const [titleValue, setTitleValue] = useState(initial.title || "");
|
||||
const titleSaveTimer = useRef(null);
|
||||
|
||||
// Auto-save du titre lorsqu'il est modifié (si non vide)
|
||||
useEffect(() => {
|
||||
const newTitle = (titleValue || "").trim();
|
||||
// Annuler tout timer précédent
|
||||
if (titleSaveTimer.current) clearTimeout(titleSaveTimer.current);
|
||||
// Ne rien faire si inchangé vs projet courant
|
||||
const currentTitle = (selectedProject?.title || "").trim();
|
||||
if (!newTitle || newTitle === currentTitle) return;
|
||||
|
||||
titleSaveTimer.current = setTimeout(async () => {
|
||||
try {
|
||||
await projectsRef.doc(selectedProjectId).set(
|
||||
{
|
||||
title: newTitle,
|
||||
titleLower: newTitle.toLowerCase(),
|
||||
updatedAt: firebase.firestore.FieldValue.serverTimestamp(),
|
||||
},
|
||||
{ merge: true },
|
||||
);
|
||||
} catch (e) {
|
||||
// silencieux: l'utilisateur pourra tjs valider plus tard
|
||||
console.log("Auto-save titre échoué", e?.message);
|
||||
}
|
||||
}, 500);
|
||||
|
||||
return () => {
|
||||
if (titleSaveTimer.current) clearTimeout(titleSaveTimer.current);
|
||||
};
|
||||
}, [titleValue, selectedProjectId, selectedProject]);
|
||||
const [sections, setSections] = useState(initial.sections || []);
|
||||
const setSectionAt = (index, value) => {
|
||||
setSections((prev) => {
|
||||
@@ -158,6 +127,79 @@ const Lyrics = ({ navigation }) => {
|
||||
s.lyrics === normalizedNewLyrics[i]?.lyrics,
|
||||
);
|
||||
|
||||
// 1) Appel de la Cloud Function de modération avant tout enregistrement
|
||||
try {
|
||||
const callable = firebase
|
||||
.functions()
|
||||
.httpsCallable("lyrics-analyseLyricsToxicity");
|
||||
const { data } = await callable({
|
||||
title: titleTrimmed,
|
||||
lyrics: normalizedNewLyrics,
|
||||
});
|
||||
|
||||
if (!data?.success) {
|
||||
// Blocage dur: afficher le message et ne pas sauvegarder
|
||||
if (data?.errorCode === "TOXIC_CONTENT_BLOCKED") {
|
||||
const quotes = Array.isArray(data?.result?.excerpts)
|
||||
? data.result.excerpts
|
||||
.slice(0, 3)
|
||||
.map((e) => `• ${e.quote}`)
|
||||
.join("\n")
|
||||
: null;
|
||||
Alert.alert(
|
||||
"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") {
|
||||
Alert.alert(
|
||||
"Analyse indisponible",
|
||||
"Impossible de vérifier la toxicité pour le moment. Réessayez plus tard.",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Cas signalé mais non bloquant: demander confirmation
|
||||
if (data?.errorCode === "TOXIC_CONTENT_FLAGGED") {
|
||||
const quotes = Array.isArray(data?.result?.excerpts)
|
||||
? data.result.excerpts
|
||||
.slice(0, 3)
|
||||
.map((e) => `• ${e.quote}`)
|
||||
.join("\n")
|
||||
: null;
|
||||
const msg = [data?.message, quotes].filter(Boolean).join("\n\n");
|
||||
|
||||
const proceed = await new Promise((resolve) => {
|
||||
Alert.alert("Contenu potentiellement sensible", msg, [
|
||||
{
|
||||
text: "Annuler",
|
||||
style: "cancel",
|
||||
onPress: () => resolve(false),
|
||||
},
|
||||
{
|
||||
text: "Continuer",
|
||||
style: "destructive",
|
||||
onPress: () => resolve(true),
|
||||
},
|
||||
]);
|
||||
});
|
||||
if (!proceed) return;
|
||||
}
|
||||
} catch (moderationError) {
|
||||
console.log(
|
||||
"Moderation call failed",
|
||||
moderationError?.message || moderationError,
|
||||
);
|
||||
Alert.alert(
|
||||
"Analyse indisponible",
|
||||
"Impossible de vérifier la toxicité pour le moment. Réessayez plus tard.",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const baseData = {
|
||||
title: titleTrimmed,
|
||||
titleLower: titleTrimmed.toLowerCase(),
|
||||
|
||||
Reference in New Issue
Block a user