global player nav to musicDetails

This commit is contained in:
2025-10-24 14:56:53 +02:00
parent 0b37c7bc07
commit 47d5b92a57
+104 -55
View File
@@ -8,6 +8,7 @@ import { arrayRemove, arrayUnion, projectsRef } from "../../config/firebase";
import useDataFromRef from "../../hooks/useDataFromRef"; import useDataFromRef from "../../hooks/useDataFromRef";
import { isWeb } from "../../hooks/useLayoutType"; import { isWeb } from "../../hooks/useLayoutType";
import usePlayer from "../../hooks/usePlayer"; import usePlayer from "../../hooks/usePlayer";
import useNavigateToMusicDetails from "../../hooks/useNavigateToMusicDetails";
import { useUser } from "../../providers/UserDataProvider"; import { useUser } from "../../providers/UserDataProvider";
import { gutters, Palette } from "../../styles"; import { gutters, Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts"; import { FONT_FAMILY } from "../../styles/Fonts";
@@ -26,6 +27,7 @@ const GlobalAudioPlayer = () => {
usePlayer(); usePlayer();
const { currentUID } = useUser() || {}; const { currentUID } = useUser() || {};
const [pendingLike, setPendingLike] = useState(null); const [pendingLike, setPendingLike] = useState(null);
const navigateToMusicDetails = useNavigateToMusicDetails();
const projectId = useMemo(() => { const projectId = useMemo(() => {
const metadataProjectId = const metadataProjectId =
@@ -80,7 +82,8 @@ const GlobalAudioPlayer = () => {
} }
}, [pendingLike, likedFromDoc]); }, [pendingLike, likedFromDoc]);
const handleToggleLike = useCallback(async () => { const handleToggleLike = useCallback(async (event) => {
event?.stopPropagation?.();
if (!projectId || !currentUID || isLikeProcessing) return; if (!projectId || !currentUID || isLikeProcessing) return;
const next = !effectiveIsLiked; const next = !effectiveIsLiked;
setPendingLike(next); setPendingLike(next);
@@ -113,13 +116,45 @@ const GlobalAudioPlayer = () => {
return img.placeholder; return img.placeholder;
}, [currentTrack?.artwork, currentTrack?.coverUrl]); }, [currentTrack?.artwork, currentTrack?.coverUrl]);
const handleToggle = async () => { const handleToggle = useCallback(
if (isPlaying) { async (event) => {
await pause(); event?.stopPropagation?.();
} else { if (isPlaying) {
await resume(); await pause();
} else {
await resume();
}
},
[isPlaying, pause, resume]
);
const handleOpenDetails = useCallback(() => {
if (!projectId) return;
let songUrl = null;
if (typeof currentTrack?.source === "string") {
songUrl = currentTrack.source;
} else if (
currentTrack?.source &&
typeof currentTrack.source === "object" &&
typeof currentTrack.source.uri === "string"
) {
songUrl = currentTrack.source.uri;
} else if (typeof currentTrack?.metadata?.songUrl === "string") {
songUrl = currentTrack.metadata.songUrl;
} else if (typeof currentTrack?.metadata?.musicUrl === "string") {
songUrl = currentTrack.metadata.musicUrl;
} }
}; const project =
currentTrack?.metadata?.project &&
typeof currentTrack.metadata.project === "object"
? currentTrack.metadata.project
: null;
navigateToMusicDetails({
projectId,
songUrl,
project,
});
}, [currentTrack, navigateToMusicDetails, projectId]);
const TAB_BAR_HEIGHT = 64; const TAB_BAR_HEIGHT = 64;
const GAP_WITH_TAB = 8; const GAP_WITH_TAB = 8;
@@ -132,57 +167,64 @@ const GlobalAudioPlayer = () => {
pointerEvents="box-none" pointerEvents="box-none"
style={[styles.host, { bottom: bottomOffset }]} style={[styles.host, { bottom: bottomOffset }]}
> >
<BlurView <Pressable
intensity={40} onPress={handleOpenDetails}
// tint="dark" style={({ pressed }) => [
blurReductionFactor={2} styles.pressable,
// tint="dark" pressed && styles.pressablePressed,
style={[
styles.container,
{ paddingVertical: Math.max(4, insets.bottom / 6) },
]} ]}
experimentalBlurMethod="dimezisBlurView" android_ripple={{ color: "rgba(255,255,255,0.08)", borderless: false }}
> >
<Image source={artworkSource} style={styles.cover} /> <BlurView
<View style={styles.details}> intensity={40}
<Text numberOfLines={1} style={styles.title}> blurReductionFactor={2}
{title} style={[
</Text> styles.container,
{!!artist && ( { paddingVertical: Math.max(4, insets.bottom / 6) },
<Text numberOfLines={1} style={styles.artist}> ]}
{artist} experimentalBlurMethod="dimezisBlurView"
>
<Image source={artworkSource} style={styles.cover} />
<View style={styles.details}>
<Text numberOfLines={1} style={styles.title}>
{title}
</Text> </Text>
)} {!!artist && (
</View> <Text numberOfLines={1} style={styles.artist}>
<View style={styles.actions}> {artist}
<Pressable </Text>
onPress={handleToggleLike} )}
hitSlop={12} </View>
disabled={!projectId || !currentUID || isLikeProcessing} <View style={styles.actions}>
style={[ <Pressable
styles.actionButton, onPress={handleToggleLike}
styles.likeButton, hitSlop={12}
(!projectId || !currentUID || isLikeProcessing) && disabled={!projectId || !currentUID || isLikeProcessing}
styles.disabledAction, style={[
]} styles.actionButton,
> styles.likeButton,
<Image (!projectId || !currentUID || isLikeProcessing) &&
source={effectiveIsLiked ? icons.heart : icons.heartOutline} styles.disabledAction,
style={styles.likeIcon} ]}
/> >
</Pressable> <Image
<Pressable source={effectiveIsLiked ? icons.heart : icons.heartOutline}
onPress={handleToggle} style={styles.likeIcon}
hitSlop={12} />
style={[styles.actionButton, styles.toggleButton]} </Pressable>
> <Pressable
<Image onPress={handleToggle}
source={isPlaying ? icons.pause : icons.play} hitSlop={12}
style={styles.toggleIcon} style={[styles.actionButton, styles.toggleButton]}
/> >
</Pressable> <Image
</View> source={isPlaying ? icons.pause : icons.play}
</BlurView> style={styles.toggleIcon}
/>
</Pressable>
</View>
</BlurView>
</Pressable>
</View> </View>
); );
}; };
@@ -283,6 +325,13 @@ const styles = StyleSheet.create({
tintColor: Palette.white, tintColor: Palette.white,
resizeMode: "contain", resizeMode: "contain",
}, },
pressable: {
width: "100%",
borderRadius: 12,
},
pressablePressed: {
opacity: 0.9,
},
}); });
export default GlobalAudioPlayer; export default GlobalAudioPlayer;