This commit is contained in:
Philip Cesar Garay
2025-09-09 17:17:11 +08:00
parent a3dc4f89b7
commit 69977aba2b
5 changed files with 84 additions and 17 deletions
+10 -1
View File
@@ -3,13 +3,17 @@ import React from "react";
import BorderGradient from "../BorderGradient/BorderGradient";
import { BlurView } from "expo-blur";
import { responsiveHeight } from "react-native-responsive-dimensions";
import { useKeyboard } from "@react-native-community/hooks";
const ItemContainer = ({
height = responsiveHeight(40),
children,
gradientProps,
style,
disableKeyboardHeight = false,
}) => {
const { keyboardShown } = useKeyboard();
return (
<BorderGradient
gradientProps={{
@@ -20,7 +24,12 @@ const ItemContainer = ({
}}
style={{
...styles.borderGradientStyle,
height,
height: !disableKeyboardHeight
? keyboardShown
? responsiveHeight(30)
: height
: height,
...style,
}}
>
+8 -3
View File
@@ -1,4 +1,4 @@
import { View, Dimensions } from "react-native";
import { View, Dimensions, Platform } from "react-native";
import React, { useMemo, useRef, useState } from "react";
import Page from "../../layouts/Page";
import MusicLandHeader from "../../components/MusicLandHeader";
@@ -73,7 +73,8 @@ const CreateLyricsWithAi = () => {
setStyle(sel.style);
if (!otherStyle && typeof sel.otherStyle === "string")
setOtherStyle(sel.otherStyle);
if (!audience && typeof sel.audience === "string") setAudience(sel.audience);
if (!audience && typeof sel.audience === "string")
setAudience(sel.audience);
// Structure choisie (string) si déjà enregistrée dans selections
if (structure == null && typeof sel.structure === "string" && sel.structure)
@@ -216,7 +217,11 @@ const CreateLyricsWithAi = () => {
}, [selectedIndex, parentLayout?.height]);
return (
<Page headerType="NONE">
<Page
headerType="NONE"
behavior={Platform.OS === "ios" ? "padding" : "height"}
keyboardVerticalOffset={Platform.OS === "ios" ? 64 : 100}
>
<MusicLandHeader onPressBack={onPressBack} progress={progress} />
<View
style={{
+17 -2
View File
@@ -1,4 +1,12 @@
import { View, Text, FlatList, StyleSheet, Pressable } from "react-native";
import {
View,
Text,
FlatList,
StyleSheet,
Pressable,
KeyboardAvoidingView,
Platform,
} from "react-native";
import React, { useState } from "react";
import CreateLyricsHeader from "./components/CreateLyricsHeader";
import { Palette, Style } from "../../styles";
@@ -6,8 +14,15 @@ import { GOALS } from "../../data/data";
import { FONT_FAMILY } from "../../styles/Fonts";
import CustomInput from "./components/CustomInput";
import ItemContainer from "../../components/ItemContainer/ItemContainer";
import { useKeyboard } from "@react-native-community/hooks";
import { responsiveHeight } from "react-native-responsive-dimensions";
const Goals = ({ selected: selectedProp, setSelected: setSelectedProp, otherObjective, setOtherObjective }) => {
const Goals = ({
selected: selectedProp,
setSelected: setSelectedProp,
otherObjective,
setOtherObjective,
}) => {
const [internalSelected, setInternalSelected] = useState(null);
const selected = selectedProp ?? internalSelected;
+41 -8
View File
@@ -1,5 +1,11 @@
import { View, ScrollView, Alert } from "react-native";
import React, { useMemo, useState, useCallback, useEffect } from "react";
import React, {
useMemo,
useState,
useCallback,
useEffect,
useRef,
} from "react";
import Page from "../../layouts/Page";
import MusicLandHeader from "../../components/MusicLandHeader";
import { navigate } from "../../navigation/NavigationService";
@@ -14,9 +20,12 @@ import useMinuit from "react-native-minuit/src/hooks/useMinuit.js";
import { useUser } from "../../providers/UserDataProvider";
const Lyrics = ({ navigation }) => {
const scrollRef = useRef(null);
const [containerLayout, setContainerLayout] = useState(null);
const { setIsLoading } = useMinuit();
const { selectedProjectId, selectedProject } = useUser();
const [isFocus, setIsFocus] = useState(null);
const [itemsContainerLayout, setItemsContainerLayout] = useState([]);
// Effective sources from provider only
const projectTitle = selectedProject?.title || "";
@@ -103,7 +112,7 @@ const Lyrics = ({ navigation }) => {
if (invalid) {
Alert.alert(
"Champs incomplets",
"Chaque couplet et refrain doit contenir du texte.",
"Chaque couplet et refrain doit contenir du texte."
);
return;
}
@@ -124,7 +133,7 @@ const Lyrics = ({ navigation }) => {
normalizedOldLyrics.every(
(s, i) =>
s.type === normalizedNewLyrics[i]?.type &&
s.lyrics === normalizedNewLyrics[i]?.lyrics,
s.lyrics === normalizedNewLyrics[i]?.lyrics
);
// 1) Appel de la Cloud Function de modération avant tout enregistrement
@@ -148,7 +157,7 @@ const Lyrics = ({ navigation }) => {
: null;
Alert.alert(
"Contenu interdit",
[data?.message, quotes].filter(Boolean).join("\n\n"),
[data?.message, quotes].filter(Boolean).join("\n\n")
);
return; // stop here
}
@@ -156,7 +165,7 @@ const Lyrics = ({ navigation }) => {
if (data?.errorCode === "ANALYSE_FAILED") {
Alert.alert(
"Analyse indisponible",
"Impossible de vérifier la toxicité pour le moment. Réessayez plus tard.",
"Impossible de vérifier la toxicité pour le moment. Réessayez plus tard."
);
return;
}
@@ -191,11 +200,11 @@ const Lyrics = ({ navigation }) => {
} catch (moderationError) {
console.log(
"Moderation call failed",
moderationError?.message || moderationError,
moderationError?.message || moderationError
);
Alert.alert(
"Analyse indisponible",
"Impossible de vérifier la toxicité pour le moment. Réessayez plus tard.",
"Impossible de vérifier la toxicité pour le moment. Réessayez plus tard."
);
return;
}
@@ -250,8 +259,12 @@ const Lyrics = ({ navigation }) => {
}}
onLayout={(e) => setContainerLayout(e.nativeEvent.layout)}
>
<ItemContainer height={containerLayout?.height}>
<ItemContainer
height={containerLayout?.height}
disableKeyboardHeight={isFocus !== sections.length - 1 || !isFocus}
>
<ScrollView
ref={scrollRef}
contentContainerStyle={{
paddingHorizontal: 14,
paddingVertical: 10,
@@ -267,6 +280,13 @@ const Lyrics = ({ navigation }) => {
setValue={setTitleValue}
multiline={false}
maxLength={60}
onLayout={(e) => {
e.persist();
setItemsContainerLayout((prev) => [
...prev,
e?.nativeEvent?.layout,
]);
}}
/>
{sections.map((s, idx) => {
// Calculer l'index humain par type
@@ -284,6 +304,19 @@ const Lyrics = ({ navigation }) => {
height={type === "refrain" ? 170 : 225}
value={s?.lyrics || ""}
setValue={(val) => setSectionAt(idx, val)}
onFocus={() => {
setIsFocus(idx);
scrollRef?.current?.scrollTo({
y: itemsContainerLayout[idx + 1]?.y,
});
}}
onLayout={(e) => {
e.persist();
setItemsContainerLayout((prev) => [
...prev,
e?.nativeEvent?.layout,
]);
}}
/>
);
})}
@@ -11,9 +11,12 @@ const CustomInput = ({
height = 65,
multiline = true,
maxLength,
onFocus,
onBlur,
onLayout,
}) => {
return (
<View style={{ gap: 8 }}>
<View style={{ gap: 8 }} onLayout={onLayout}>
{label && (
<Text
style={{
@@ -48,6 +51,8 @@ const CustomInput = ({
numberOfLines={multiline ? undefined : 1}
maxLength={maxLength}
textAlignVertical={multiline ? "top" : "center"}
onFocus={onFocus}
onBlur={onBlur}
/>
</View>
</View>