more menu

This commit is contained in:
2025-10-01 11:16:03 +02:00
parent 75375942b7
commit 08e02a752a
9 changed files with 117 additions and 42 deletions
+34 -7
View File
@@ -6,6 +6,7 @@ import {
Text,
View,
Image as RNImage,
Dimensions,
} from "react-native";
import { Image as ExpoImage } from "expo-image";
import { useGlobal } from "reactn";
@@ -28,13 +29,20 @@ const MusicCard = ({
const [currentUID] = useGlobal("currentUID");
const [selected, setSelected] = useState(false);
const [layout, setLayout] = useState(null);
const [menuPos, setMenuPos] = useState(0);
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 + 45;
setMenuPos(top);
const top = (layout?.y || 0) + 45;
setMenuPos((prev) => ({ ...prev, top }));
}
}, [layout]);
@@ -59,13 +67,32 @@ const MusicCard = ({
};
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) => {
const top = (y || 0) + 45;
setMenuPos(top);
onPressMore?.(top);
computeAnchor(x, y, width, height);
});
return;
} catch (e) {
@@ -132,7 +159,7 @@ const MusicCard = ({
resizeMode="contain"
/>
</Pressable>
<Pressable onPress={onPressMenu}>
<Pressable ref={moreButtonRef} onPress={onPressMenu}>
<RNImage source={icons.more} style={size({ size: 24 })} />
</Pressable>
</View>