animation, dots, dropdown, popover and design fixes
This commit is contained in:
+109
-20
@@ -1,15 +1,22 @@
|
||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { Platform, StyleSheet, View } from "react-native";
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { Alert, Platform, StyleSheet, View } from "react-native";
|
||||
import { background } from "../../assets";
|
||||
import BorderGradientButton from "../../components/BorderGradientButton";
|
||||
import FeatureCarousel from "../../components/FeatureCarousel/FeatureCarousel";
|
||||
import GradientButton from "../../components/GradientButton";
|
||||
import MoreMenu from "../../components/MoreMenu";
|
||||
import ProjectDropDown from "../../components/ProjectDropDown/ProjectDropDown";
|
||||
import ShareBtn from "../../components/ShareBtn/ShareBtn";
|
||||
import { isWeb } from "../../hooks/useLayoutType.js";
|
||||
import Page from "../../layouts/Page";
|
||||
import { Routes } from "../../navigation";
|
||||
import { navigate } from "../../navigation/NavigationService";
|
||||
import { projectsRef } from "../../config/firebase";
|
||||
import { useUser } from "../../providers/UserDataProvider";
|
||||
import { gutters, Palette } from "../../styles";
|
||||
import {
|
||||
@@ -17,6 +24,7 @@ import {
|
||||
getCreationStageStates,
|
||||
getStageAction,
|
||||
} from "../../utils/projectStages";
|
||||
import useMinuit from "react-native-minuit/src/hooks/useMinuit.js";
|
||||
|
||||
const Home = () => {
|
||||
const {
|
||||
@@ -26,10 +34,11 @@ const Home = () => {
|
||||
selectedProject,
|
||||
selectedProjectId,
|
||||
} = useUser();
|
||||
const { setTooltip } = useMinuit();
|
||||
|
||||
const projects = useMemo(
|
||||
() => (Array.isArray(userProjects) ? userProjects : []),
|
||||
[userProjects]
|
||||
[userProjects],
|
||||
);
|
||||
|
||||
const currentProject = useMemo(() => {
|
||||
@@ -60,22 +69,9 @@ const Home = () => {
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleSelectProject = (project) => {
|
||||
if (!project?.id) return;
|
||||
selectProject(project.id);
|
||||
setActiveStageIndex(findFirstUnlockedStageIndex(project));
|
||||
};
|
||||
|
||||
const handleModifyProject = (project) => {
|
||||
if (!project?.id) return;
|
||||
selectProject(project.id);
|
||||
setActiveStageIndex(findFirstUnlockedStageIndex(project));
|
||||
navigate(Routes.Home);
|
||||
};
|
||||
|
||||
const stageStates = useMemo(
|
||||
() => getCreationStageStates(currentProject),
|
||||
[currentProject]
|
||||
[currentProject],
|
||||
);
|
||||
|
||||
const firstUnlockedIndex = useMemo(() => {
|
||||
@@ -84,6 +80,10 @@ const Home = () => {
|
||||
}, [stageStates]);
|
||||
|
||||
const [activeStageIndex, setActiveStageIndex] = useState(firstUnlockedIndex);
|
||||
const [menuVisible, setMenuVisible] = useState(false);
|
||||
const [menuAnchor, setMenuAnchor] = useState(null);
|
||||
const [menuProject, setMenuProject] = useState(null);
|
||||
const menuAnchorRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
setActiveStageIndex((prev) => {
|
||||
@@ -99,6 +99,86 @@ const Home = () => {
|
||||
});
|
||||
}, [stageStates, firstUnlockedIndex]);
|
||||
|
||||
const handleSelectProject = useCallback(
|
||||
(project) => {
|
||||
if (!project?.id) return;
|
||||
selectProject(project.id);
|
||||
setActiveStageIndex(findFirstUnlockedStageIndex(project));
|
||||
},
|
||||
[selectProject],
|
||||
);
|
||||
|
||||
const handleCloseMenu = useCallback(() => {
|
||||
setMenuVisible(false);
|
||||
setMenuAnchor(null);
|
||||
setMenuProject(null);
|
||||
menuAnchorRef.current = null;
|
||||
}, []);
|
||||
|
||||
const handleDeleteProject = useCallback(async () => {
|
||||
if (!menuProject?.id) return;
|
||||
try {
|
||||
await projectsRef.doc(menuProject.id).delete();
|
||||
setTooltip?.({ type: "success", text: "Projet supprimé" });
|
||||
} catch (error) {
|
||||
setTooltip?.({
|
||||
type: "error",
|
||||
text: error?.message || "Suppression impossible",
|
||||
});
|
||||
} finally {
|
||||
handleCloseMenu();
|
||||
}
|
||||
}, [handleCloseMenu, menuProject?.id, setTooltip]);
|
||||
|
||||
const handleModifyProject = useCallback((project, anchor) => {
|
||||
if (!project?.id) return;
|
||||
|
||||
const prevAnchor = menuAnchorRef.current;
|
||||
const normalizedAnchor =
|
||||
typeof anchor === "number"
|
||||
? { top: anchor }
|
||||
: anchor && typeof anchor === "object"
|
||||
? anchor
|
||||
: {};
|
||||
|
||||
setMenuProject(project);
|
||||
setMenuAnchor(normalizedAnchor);
|
||||
setMenuVisible((prev) => {
|
||||
if (!prev) return true;
|
||||
const prevTop =
|
||||
typeof prevAnchor?.top === "number" ? prevAnchor.top : null;
|
||||
const nextTop =
|
||||
typeof normalizedAnchor?.top === "number" ? normalizedAnchor.top : null;
|
||||
return prevTop !== nextTop;
|
||||
});
|
||||
menuAnchorRef.current = normalizedAnchor;
|
||||
}, []);
|
||||
|
||||
const moreMenuItems = useMemo(() => {
|
||||
if (!menuProject?.id) return [];
|
||||
return [
|
||||
{
|
||||
label: "Supprimer",
|
||||
onPress: () =>
|
||||
Alert.alert(
|
||||
"Confirmer la suppression",
|
||||
"Cette action supprimera définitivement ce projet.",
|
||||
[
|
||||
{ text: "Annuler", style: "cancel" },
|
||||
{
|
||||
text: "Supprimer",
|
||||
style: "destructive",
|
||||
onPress: () => {
|
||||
handleDeleteProject();
|
||||
},
|
||||
},
|
||||
],
|
||||
{ cancelable: true },
|
||||
),
|
||||
},
|
||||
];
|
||||
}, [handleDeleteProject, menuProject?.id]);
|
||||
|
||||
const activeStage =
|
||||
stageStates[activeStageIndex] || stageStates[firstUnlockedIndex];
|
||||
const stageAction = useMemo(() => {
|
||||
@@ -139,7 +219,7 @@ const Home = () => {
|
||||
|
||||
const songwriterAction = useMemo(
|
||||
() => getStageAction("songwriter", null),
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
const handleStartNew = useCallback(() => {
|
||||
@@ -149,7 +229,7 @@ const Home = () => {
|
||||
console.log(
|
||||
"navigating to",
|
||||
songwriterAction.route,
|
||||
songwriterAction.params
|
||||
songwriterAction.params,
|
||||
);
|
||||
navigate(songwriterAction.route, songwriterAction.params);
|
||||
}
|
||||
@@ -185,6 +265,15 @@ const Home = () => {
|
||||
/>
|
||||
{!isWeb && <ShareBtn />}
|
||||
</View>
|
||||
<MoreMenu
|
||||
visible={menuVisible}
|
||||
top={menuAnchor?.top ?? 0}
|
||||
position={menuAnchor}
|
||||
onClose={handleCloseMenu}
|
||||
inPlaylist={false}
|
||||
projectId={menuProject?.id || null}
|
||||
extraItems={moreMenuItems}
|
||||
/>
|
||||
<View style={styles.carouselSection}>
|
||||
<FeatureCarousel
|
||||
selectedProject={currentProject}
|
||||
|
||||
Reference in New Issue
Block a user