Change main page and modify flows
This commit is contained in:
@@ -1,84 +1,93 @@
|
||||
import { View, Text, StyleSheet, ScrollView } from "react-native";
|
||||
import React, { useMemo, useState } from "react";
|
||||
import CreateLyricsHeader from "./components/CreateLyricsHeader";
|
||||
import { View, StyleSheet, Image, Platform, Text } from "react-native";
|
||||
import React, { useMemo, useState, useCallback, useEffect } from "react";
|
||||
import { BlurView } from "expo-blur";
|
||||
import { Palette } from "../../styles";
|
||||
import CreateLyricsHeader from "./components/CreateLyricsHeader";
|
||||
import { Palette, Style } from "../../styles";
|
||||
import { FONT_FAMILY } from "../../styles/Fonts";
|
||||
import ItemContainer from "../../components/ItemContainer/ItemContainer";
|
||||
import { CUSTOM_SONG_STRUCTURE } from "../../data/data";
|
||||
import SongStructureDragDrop from "../../components/SongStructureDragDrop";
|
||||
import Sortable from "react-native-sortables";
|
||||
import { icons } from "../../assets";
|
||||
|
||||
// baseStructure: array like ['couplet','refrain',...]
|
||||
// onChange: callback that receives array like ['couplet','refrain',...]
|
||||
const CustomizeSongStructure = ({ baseStructure = [], onChange }) => {
|
||||
const [containerLayout, setContainerLayout] = useState(null);
|
||||
|
||||
const sourceItems = useMemo(() => {
|
||||
// create unique ids for duplicates
|
||||
// Build stable keyed data like { 'couplet-1': { label, value }, ... }
|
||||
const data = useMemo(() => {
|
||||
const counters = { couplet: 0, refrain: 0 };
|
||||
return (baseStructure || []).map((type) => {
|
||||
const key = (type || '').toLowerCase();
|
||||
const out = {};
|
||||
(baseStructure || []).forEach((type) => {
|
||||
const key = (type || "").toLowerCase();
|
||||
counters[key] = (counters[key] || 0) + 1;
|
||||
const idx = counters[key];
|
||||
return {
|
||||
id: `${key}-${idx}`,
|
||||
label: `${type} ${idx}`,
|
||||
const id = `${key}-${idx}`;
|
||||
out[id] = {
|
||||
id,
|
||||
label: `${key === "couplet" ? "Couplet" : "Refrain"} ${idx}`,
|
||||
value: key,
|
||||
};
|
||||
});
|
||||
return out;
|
||||
}, [baseStructure]);
|
||||
|
||||
const items = useMemo(() => Object.values(data), [data]);
|
||||
|
||||
// Initialize parent with current order (so it's saved even without drag)
|
||||
useEffect(() => {
|
||||
const initialValues = (items || []).map((it) => it?.value).filter(Boolean);
|
||||
onChange?.(initialValues);
|
||||
// We only want to run when baseStructure-derived items change
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [items.length]);
|
||||
|
||||
const Row = ({ item: rowData }) => (
|
||||
<View style={styles.itemContainer}>
|
||||
<BlurView
|
||||
intensity={30}
|
||||
style={styles.rowBlur}
|
||||
experimentalBlurMethod={Platform.OS !== "ios" ? "dimezisBlurView" : "none"}
|
||||
>
|
||||
<View style={{ ...Style.containerSpaceBetween, alignItems: "center" }}>
|
||||
<View>
|
||||
<View>
|
||||
<View>
|
||||
<View />
|
||||
</View>
|
||||
</View>
|
||||
<View>
|
||||
<View />
|
||||
</View>
|
||||
</View>
|
||||
<View style={{ flex: 1, justifyContent: "center" }}>
|
||||
<View>
|
||||
<Text style={styles.rowText}>{rowData?.label || ""}</Text>
|
||||
</View>
|
||||
</View>
|
||||
<Sortable.Handle>
|
||||
<Image source={icons.dragDots} style={styles.handleIcon} />
|
||||
</Sortable.Handle>
|
||||
</View>
|
||||
</BlurView>
|
||||
</View>
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={{ flex: 1, gap: 10, marginTop: 16 }}>
|
||||
<CreateLyricsHeader
|
||||
title="Personnalise la structure de ta chanson"
|
||||
subTitle="Intègre en Drag and drop"
|
||||
subTitle="Réorganise par glisser-déposer"
|
||||
/>
|
||||
{/* <View style={{ flex: 1, gap: 10 }}>
|
||||
<View
|
||||
style={{ flex: 1 }}
|
||||
onLayout={(e) => {
|
||||
setContainerLayout(e.nativeEvent.layout);
|
||||
<View style={{ flex: 1 }} onLayout={(e) => setContainerLayout(e.nativeEvent.layout)}>
|
||||
<Sortable.Grid
|
||||
columns={1}
|
||||
rowGap={12}
|
||||
data={items}
|
||||
renderItem={({ item }) => <Row item={item} />}
|
||||
customHandle
|
||||
onDragEnd={({ data: newData }) => {
|
||||
const values = (newData || []).map((it) => it?.value).filter(Boolean);
|
||||
onChange?.(values);
|
||||
}}
|
||||
>
|
||||
<ItemContainer height={containerLayout?.height}>
|
||||
<ScrollView contentContainerStyle={{ gap: 10, paddingBottom: 20 }}>
|
||||
{["Couplet", "Refrain", "Couplet", "Refrain"].map(
|
||||
(item, index) => (
|
||||
<View key={index} style={styles.dropzoneContainer}>
|
||||
<Text style={styles.dropzone}>{item}</Text>
|
||||
</View>
|
||||
)
|
||||
)}
|
||||
</ScrollView>
|
||||
</ItemContainer>
|
||||
</View>
|
||||
<View style={{ flex: 1 }}>
|
||||
<ItemContainer height={containerLayout?.height}>
|
||||
<ScrollView contentContainerStyle={{ gap: 10, paddingBottom: 20 }}>
|
||||
{CUSTOM_SONG_STRUCTURE.map((item, index) => (
|
||||
<View key={index} style={styles.itemContainer}>
|
||||
<BlurView
|
||||
intensity={30}
|
||||
style={{
|
||||
flex: 1,
|
||||
backgroundColor: Palette.glass,
|
||||
justifyContent: "center",
|
||||
paddingHorizontal: 12,
|
||||
}}
|
||||
>
|
||||
<Text style={styles.dropzone}>{item}</Text>
|
||||
</BlurView>
|
||||
</View>
|
||||
))}
|
||||
</ScrollView>
|
||||
</ItemContainer>
|
||||
</View>
|
||||
</View> */}
|
||||
<View style={{ flex: 1 }}>
|
||||
<SongStructureDragDrop
|
||||
sourceItems={sourceItems}
|
||||
onChange={(arr) => onChange?.(arr)}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
@@ -88,17 +97,6 @@ const CustomizeSongStructure = ({ baseStructure = [], onChange }) => {
|
||||
export default CustomizeSongStructure;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
dropzoneContainer: {
|
||||
paddingVertical: 14,
|
||||
paddingHorizontal: 12,
|
||||
backgroundColor: "#00000080",
|
||||
borderRadius: 14,
|
||||
},
|
||||
dropzone: {
|
||||
fontSize: 16,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
},
|
||||
itemContainer: {
|
||||
height: 54,
|
||||
backgroundColor: Palette.glass,
|
||||
@@ -113,4 +111,21 @@ const styles = StyleSheet.create({
|
||||
shadowRadius: 3.84,
|
||||
elevation: 5,
|
||||
},
|
||||
rowBlur: {
|
||||
flex: 1,
|
||||
backgroundColor: Palette.glass,
|
||||
justifyContent: "center",
|
||||
paddingHorizontal: 12,
|
||||
height: "100%",
|
||||
},
|
||||
rowText: {
|
||||
fontSize: 16,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
},
|
||||
handleIcon: {
|
||||
width: 22,
|
||||
height: 22,
|
||||
tintColor: Palette.white,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user