mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-01-15 23:59:08 +00:00
fix: improve gestures
This commit is contained in:
@@ -111,28 +111,28 @@ export const MiniPlayerBar: React.FC = () => {
|
|||||||
|
|
||||||
// Swipe up - open modal (check position OR velocity)
|
// Swipe up - open modal (check position OR velocity)
|
||||||
if (currentPosition < -16 || velocity < -VELOCITY_THRESHOLD) {
|
if (currentPosition < -16 || velocity < -VELOCITY_THRESHOLD) {
|
||||||
|
// Slow return animation - won't jank with navigation
|
||||||
|
translateY.value = withTiming(0, {
|
||||||
|
duration: 600,
|
||||||
|
easing: Easing.out(Easing.cubic),
|
||||||
|
});
|
||||||
runOnJS(handlePress)();
|
runOnJS(handlePress)();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// Swipe down - stop playback and dismiss (check position OR velocity)
|
// Swipe down - stop playback and dismiss (check position OR velocity)
|
||||||
else if (currentPosition > 16 || velocity > VELOCITY_THRESHOLD) {
|
if (currentPosition > 16 || velocity > VELOCITY_THRESHOLD) {
|
||||||
|
// No need to reset - component will unmount
|
||||||
runOnJS(handleDismiss)();
|
runOnJS(handleDismiss)();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Smooth return to original position (no bounce)
|
// Only animate back if no action was triggered
|
||||||
translateY.value = withTiming(0, {
|
translateY.value = withTiming(0, {
|
||||||
duration: 200,
|
duration: 200,
|
||||||
easing: Easing.out(Easing.cubic),
|
easing: Easing.out(Easing.cubic),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Tap gesture for opening modal (preserves existing behavior)
|
|
||||||
const tapGesture = Gesture.Tap().onEnd(() => {
|
|
||||||
runOnJS(handlePress)();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Combine gestures - pan takes priority over tap
|
|
||||||
const composedGesture = Gesture.Race(panGesture, tapGesture);
|
|
||||||
|
|
||||||
// Animated styles for the container
|
// Animated styles for the container
|
||||||
const animatedContainerStyle = useAnimatedStyle(() => ({
|
const animatedContainerStyle = useAnimatedStyle(() => ({
|
||||||
transform: [{ translateY: translateY.value }],
|
transform: [{ translateY: translateY.value }],
|
||||||
@@ -158,31 +158,38 @@ export const MiniPlayerBar: React.FC = () => {
|
|||||||
|
|
||||||
const content = (
|
const content = (
|
||||||
<>
|
<>
|
||||||
{/* Album art */}
|
{/* Tappable area: Album art + Track info */}
|
||||||
<View style={styles.albumArt}>
|
<TouchableOpacity
|
||||||
{imageUrl ? (
|
onPress={handlePress}
|
||||||
<Image
|
activeOpacity={0.7}
|
||||||
source={{ uri: imageUrl }}
|
style={styles.tappableArea}
|
||||||
style={styles.albumImage}
|
>
|
||||||
contentFit='cover'
|
{/* Album art */}
|
||||||
cachePolicy='memory-disk'
|
<View style={styles.albumArt}>
|
||||||
/>
|
{imageUrl ? (
|
||||||
) : (
|
<Image
|
||||||
<View style={styles.albumPlaceholder}>
|
source={{ uri: imageUrl }}
|
||||||
<Ionicons name='musical-note' size={20} color='#888' />
|
style={styles.albumImage}
|
||||||
</View>
|
contentFit='cover'
|
||||||
)}
|
cachePolicy='memory-disk'
|
||||||
</View>
|
/>
|
||||||
|
) : (
|
||||||
|
<View style={styles.albumPlaceholder}>
|
||||||
|
<Ionicons name='musical-note' size={20} color='#888' />
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
|
||||||
{/* Track info */}
|
{/* Track info */}
|
||||||
<View style={styles.trackInfo}>
|
<View style={styles.trackInfo}>
|
||||||
<Text numberOfLines={1} style={styles.trackTitle}>
|
<Text numberOfLines={1} style={styles.trackTitle}>
|
||||||
{currentTrack.Name}
|
{currentTrack.Name}
|
||||||
</Text>
|
</Text>
|
||||||
<Text numberOfLines={1} style={styles.artistName}>
|
<Text numberOfLines={1} style={styles.artistName}>
|
||||||
{currentTrack.Artists?.join(", ") || currentTrack.AlbumArtist}
|
{currentTrack.Artists?.join(", ") || currentTrack.AlbumArtist}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
{/* Controls */}
|
{/* Controls */}
|
||||||
<View style={styles.controls}>
|
<View style={styles.controls}>
|
||||||
@@ -222,7 +229,7 @@ export const MiniPlayerBar: React.FC = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GestureDetector gesture={composedGesture}>
|
<GestureDetector gesture={panGesture}>
|
||||||
<Animated.View
|
<Animated.View
|
||||||
style={[
|
style={[
|
||||||
styles.container,
|
styles.container,
|
||||||
@@ -288,6 +295,11 @@ const styles = StyleSheet.create({
|
|||||||
borderWidth: 0.5,
|
borderWidth: 0.5,
|
||||||
borderColor: "rgba(255, 255, 255, 0.1)",
|
borderColor: "rgba(255, 255, 255, 0.1)",
|
||||||
},
|
},
|
||||||
|
tappableArea: {
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
albumArt: {
|
albumArt: {
|
||||||
width: 32,
|
width: 32,
|
||||||
height: 32,
|
height: 32,
|
||||||
|
|||||||
Reference in New Issue
Block a user