empty liked musique

This commit is contained in:
2025-10-24 10:50:42 +02:00
parent 4812e503a4
commit 2839aa3ae8
2 changed files with 149 additions and 12 deletions
+12 -2
View File
@@ -38,7 +38,10 @@ export default ({ children }) => {
});
// Subscribe to user's projects (musics)
const { data: userProjects = [] } = useDataFromRef({
const {
data: userProjects = [],
loading: userProjectsLoading = true,
} = useDataFromRef({
ref: currentUID
? projectsRef
.where("userId", "==", currentUID)
@@ -54,7 +57,10 @@ export default ({ children }) => {
? userProjects.filter((project) => project.playbackUrl)
: [];
// Subscribe to user's liked projects
const { data: userLikedProjects = [] } = useDataFromRef({
const {
data: userLikedProjects = [],
loading: userLikedProjectsLoading = true,
} = useDataFromRef({
ref: currentUID
? projectsRef
.where("likedBy", "array-contains", currentUID)
@@ -394,9 +400,13 @@ export default ({ children }) => {
currentUID,
currentUserData: currentUserDoc,
userProjects,
userProjectsLoading,
userPlaybacks,
userPlaybacksLoading: userProjectsLoading,
userLikedProjects,
userLikedProjectsLoading,
userLikedPlaybacks,
userLikedPlaybacksLoading: userLikedProjectsLoading,
userPlaylists,
selectedProjectId,
selectedProject,
+137 -10
View File
@@ -1,14 +1,16 @@
import { useRoute } from "@react-navigation/native";
import React, { useState } from "react";
import { View } from "react-native";
import React, { useMemo, useState } from "react";
import { ActivityIndicator, Text, View } from "react-native";
import { background } from "../../assets";
import GradientButton from "../../components/GradientButton";
import MoreMenu from "../../components/MoreMenu";
import useNavigateToMusicDetails from "../../hooks/useNavigateToMusicDetails";
import Page from "../../layouts/Page";
import { Routes } from "../../navigation";
import { navigate } from "../../navigation/NavigationService";
import { useUser } from "../../providers/UserDataProvider";
import { gutters } from "../../styles";
import { Palette, Style, gutters } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import MusicCard from "./components/MusicCard";
export default function AllMyList() {
@@ -19,11 +21,17 @@ export default function AllMyList() {
liked = false,
} = route?.params || {};
const { userProjects, userLikedProjects, userPlaybacks, userLikedPlaybacks } =
useUser();
const {
userProjects,
userProjectsLoading,
userLikedProjects,
userLikedProjectsLoading,
userPlaybacks,
userLikedPlaybacks,
} = useUser();
const navigateToMusicDetails = useNavigateToMusicDetails();
const items = (() => {
const items = useMemo(() => {
if (scope === "playback") {
return Array.isArray(liked ? userLikedPlaybacks : userPlaybacks)
? liked
@@ -37,7 +45,101 @@ export default function AllMyList() {
? userLikedProjects
: userProjects
: [];
})();
}, [
liked,
scope,
userLikedPlaybacks,
userPlaybacks,
userLikedProjects,
userProjects,
]);
const sanitizedItems = Array.isArray(items) ? items : [];
const itemsLoading = liked
? userLikedProjectsLoading
: userProjectsLoading;
const emptyStateContent = useMemo(() => {
const variant = liked ? "liked" : "default";
const scopeKey = scope === "playback" ? "playback" : "music";
const content = {
music: {
default: {
title: "Aucune musique pour le moment",
description:
"Créez un nouveau titre ou explorez la bibliothèque pour alimenter votre collection.",
cta: {
label: "Créer une musique",
action: () => navigate(Routes.WritingLyrics),
},
},
liked: {
title: "Aucune musique likée pour le moment",
description:
"Likez les morceaux qui vous inspirent pour les garder à portée de main.",
cta: {
label: "Explorer la bibliothèque",
action: () => navigate(Routes.Research),
},
},
},
playback: {
default: {
title: "Aucun playback pour le moment",
description:
"Enregistrez ou importez un playback pour le retrouver facilement ici.",
cta: {
label: "Créer un playback",
action: () => navigate(Routes.PlaybackOnboarding),
},
},
liked: {
title: "Aucun playback liké pour le moment",
description:
"Ajoutez vos playbacks favoris à vos likes pour les retrouver instantanément.",
cta: {
label: "Voir les playbacks",
action: () => navigate(Routes.Playbacks),
},
},
},
};
return content[scopeKey][variant];
}, [liked, scope]);
const loadingMessage = useMemo(() => {
const target = scope === "playback" ? "playbacks" : "musiques";
return liked
? `Chargement des ${target} likés…`
: `Chargement des ${target}`;
}, [liked, scope]);
const placeholderBaseStyle = {
gap: 16,
paddingVertical: 52,
paddingHorizontal: 32,
backgroundColor: Palette.glass,
borderRadius: 16,
alignSelf: "stretch",
};
const placeholderTitleStyle = {
fontSize: 20,
color: Palette.white,
fontFamily: FONT_FAMILY.InterSemiBold,
textAlign: "center",
};
const placeholderDescriptionStyle = {
fontSize: 14,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
opacity: 0.8,
textAlign: "center",
maxWidth: 420,
};
const [menuPosition, setMenuPosition] = useState(null);
const [showMenu, setShowMenu] = useState(false);
@@ -63,8 +165,13 @@ export default function AllMyList() {
>
<View style={{ flex: 1 }}>
<View style={{ gap: 10 }}>
{Array.isArray(items) &&
items.map((item) => (
{itemsLoading ? (
<View style={[Style.containerCenter, placeholderBaseStyle]}>
<ActivityIndicator size="small" color={Palette.white} />
<Text style={placeholderDescriptionStyle}>{loadingMessage}</Text>
</View>
) : sanitizedItems.length > 0 ? (
sanitizedItems.map((item) => (
<MusicCard
key={item.id}
title={item?.title || "Sans titre"}
@@ -82,7 +189,27 @@ export default function AllMyList() {
);
}}
/>
))}
))
) : (
<View style={[Style.containerCenter, placeholderBaseStyle]}>
<Text style={placeholderTitleStyle}>
{emptyStateContent.title}
</Text>
<Text style={placeholderDescriptionStyle}>
{emptyStateContent.description}
</Text>
{emptyStateContent?.cta ? (
<GradientButton
title={emptyStateContent.cta.label}
onPress={emptyStateContent.cta.action}
containerStyle={{
alignSelf: "center",
minWidth: 200,
}}
/>
) : null}
</View>
)}
<MoreMenu
visible={showMenu}
top={menuPosition?.top ?? 0}