import { BlurView } from "expo-blur"; import { Image as ExpoImage } from "expo-image"; import React, { useEffect, useRef, useState } from "react"; import { Dimensions, Pressable, Image as RNImage, StyleSheet, Text, View, } from "react-native"; import { responsiveWidth } from "react-native-responsive-dimensions"; import { useGlobal } from "reactn"; import { icons, img } from "../../../assets"; import PressableScale from "../../../components/PressableScale"; import { arrayRemove, arrayUnion, projectsRef } from "../../../config/firebase"; import { Palette, Style } from "../../../styles"; import { FONT_FAMILY } from "../../../styles/Fonts"; import { size } from "../../../styles/Style"; const MusicCard = ({ onPress, onPressMore, title = "Sans titre", subtitle = "MusicLand", imageUri = null, projectId = null, likedBy = [], }) => { const [currentUID] = useGlobal("currentUID"); const [selected, setSelected] = useState(false); const [layout, setLayout] = useState(null); const [menuPos, setMenuPos] = useState({ top: 0, right: 0, left: 0, width: 0, height: 0, }); const cardRef = useRef(null); const moreButtonRef = useRef(null); useEffect(() => { if (layout) { const top = (layout?.y || 0) + 45; setMenuPos((prev) => ({ ...prev, top })); } }, [layout]); useEffect(() => { if (Array.isArray(likedBy) && currentUID) { setSelected(likedBy.includes(currentUID)); } }, [JSON.stringify(likedBy), currentUID]); const toggleLike = async () => { if (!projectId || !currentUID) return; const next = !selected; setSelected(next); try { await projectsRef.doc(projectId).update({ likedBy: next ? arrayUnion(currentUID) : arrayRemove(currentUID), }); } catch (e) { // rollback on failure setSelected(!next); } }; const onPressMenu = () => { const computeAnchor = (x = 0, y = 0, width = 0, height = 0) => { const windowWidth = Dimensions.get("window").width || 0; const top = (y || 0) + (height || 0) + 8; const right = Math.max(0, windowWidth - ((x || 0) + (width || 0))); const left = Math.max(0, x || 0); const anchor = { top, right, left, width, height }; setMenuPos(anchor); onPressMore?.(anchor); }; if (moreButtonRef?.current?.measureInWindow) { try { moreButtonRef.current.measureInWindow((x, y, width, height) => { computeAnchor(x, y, width, height); }); return; } catch (e) { // fallback to card measurement below } } // Prefer absolute screen position when available (Portal rendering) if (cardRef?.current?.measureInWindow) { try { cardRef.current.measureInWindow((x, y, width, height) => { computeAnchor(x, y, width, height); }); return; } catch (e) { // fallback to relative layout position } } onPressMore?.(menuPos); }; return ( <> setLayout(e.nativeEvent.layout)} > {imageUri ? ( ) : ( )} {title || "Sans titre"} {subtitle || "MusicLand"} {/* {open && ( )} */} ); }; export default MusicCard; const styles = StyleSheet.create({ blurContainer: { borderRadius: 12, overflow: "hidden", flex: 1, height: "100%", }, title: { fontSize: 16, color: Palette.white, fontFamily: FONT_FAMILY.OwnersRegular, lineHeight: 18, width: responsiveWidth(45), }, subTitle: { fontSize: 12, color: Palette.white, fontFamily: FONT_FAMILY.InterRegular, }, filterContainer: { backgroundColor: Palette.tran, }, });