fix queue panel dragging

This commit is contained in:
Boof2015
2026-07-25 20:25:35 -04:00
parent 629be4d9ef
commit 54966b255d
3 changed files with 108 additions and 23 deletions
+34
View File
@@ -0,0 +1,34 @@
import type { ReactNode } from 'react';
import { View, type StyleProp, type ViewStyle } from 'react-native';
import {
BottomSheetHandle,
type BottomSheetHandleProps,
} from '@gorhom/bottom-sheet';
interface QueueSheetHandleProps extends BottomSheetHandleProps {
children: ReactNode;
style?: StyleProp<ViewStyle>;
indicatorStyle?: StyleProp<ViewStyle>;
}
/**
* Keeps the library's visual/accessibility handle while extending its gesture
* surface across the fixed queue header rendered below it.
*/
export function QueueSheetHandle({
children,
style,
indicatorStyle,
...handleProps
}: QueueSheetHandleProps) {
return (
<View>
<BottomSheetHandle
{...handleProps}
style={style}
indicatorStyle={indicatorStyle}
/>
{children}
</View>
);
}
+33 -3
View File
@@ -18,6 +18,7 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
import BottomSheet, {
BottomSheetBackdrop,
type BottomSheetBackdropProps,
type BottomSheetHandleProps,
useBottomSheetScrollableCreator
} from '@gorhom/bottom-sheet';
import { FlashList, type ListRenderItemInfo } from '@shopify/flash-list';
@@ -72,6 +73,7 @@ import {
QUEUE_ROW_HEIGHT,
queuePreviewRowCount,
} from './queuePerformance';
import { QueueSheetHandle } from './QueueSheetHandle';
const ART = 42;
const EMPTY_KEY_SET = new Set<string>();
@@ -805,7 +807,7 @@ export const QueueTray = memo(function QueueTray({ onClose, embedded = false }:
const selectedCount = visibleSelectedKeys.size;
const canEdit = queueReady && entries.length > 0;
const body = (
const topSection = useMemo(() => (
<>
<View style={styles.headerRow}>
<View style={styles.headerText}>
@@ -853,7 +855,20 @@ export const QueueTray = memo(function QueueTray({ onClose, embedded = false }:
<Text variant="caption" style={[styles.sectionLabel, styles.upcomingLabel]}>
Up next
</Text>
</>
), [
canEdit,
colors.accent,
currentTrack,
editMode,
exitEdit,
ripple.bounded,
styles,
upcomingTotal,
]);
const content = (
<>
<View style={listAreaStyle}>
{listReady ? (
<FlashList
@@ -922,8 +937,22 @@ export const QueueTray = memo(function QueueTray({ onClose, embedded = false }:
</>
);
const renderSheetHandle = useCallback(
(props: BottomSheetHandleProps) => (
<QueueSheetHandle {...props}>
{topSection}
</QueueSheetHandle>
),
[topSection]
);
if (embedded) {
return <View style={styles.embeddedRoot}>{body}</View>;
return (
<View style={styles.embeddedRoot}>
{topSection}
{content}
</View>
);
}
return (
@@ -938,9 +967,10 @@ export const QueueTray = memo(function QueueTray({ onClose, embedded = false }:
onClose={onClose}
backdropComponent={renderBackdrop}
backgroundStyle={styles.sheetBg}
handleComponent={renderSheetHandle}
handleIndicatorStyle={styles.handle}
>
{body}
{content}
</BottomSheet>
);
});
+41 -20
View File
@@ -11,6 +11,7 @@ import { Ionicons } from '@expo/vector-icons';
import BottomSheet, {
BottomSheetBackdrop,
type BottomSheetBackdropProps,
type BottomSheetHandleProps,
useBottomSheetScrollableCreator,
} from '@gorhom/bottom-sheet';
import { FlashList, type ListRenderItemInfo } from '@shopify/flash-list';
@@ -21,6 +22,7 @@ import { SCROLL_PRESS_DELAY, useRipple } from '@/theme/ripple';
import { formatDuration } from '@/lib/format';
import { useDesktopRemoteStore } from '@/stores/desktopRemoteStore';
import type { DesktopRemoteQueueItem } from '@/types/desktopRemote';
import { QueueSheetHandle } from './QueueSheetHandle';
interface RemoteQueueSheetProps {
onClose: () => void;
@@ -102,34 +104,52 @@ export function RemoteQueueSheet({ onClose, embedded = false }: RemoteQueueSheet
[playItem, colors, styles, ripple]
);
const body = (
<>
const topSection = useMemo(
() => (
<View style={styles.headerRow}>
<Text variant="heading">Desktop queue</Text>
<Text variant="label" color={colors.textTertiary}>
{upcomingCount === 1 ? '1 song up next' : `${upcomingCount} songs up next`}
</Text>
</View>
<FlashList
data={items}
keyExtractor={(item) => item.queueId}
renderScrollComponent={embedded ? undefined : renderFlashListScrollComponent}
renderItem={renderItem}
contentContainerStyle={styles.listContent}
showsVerticalScrollIndicator={false}
ListEmptyComponent={
<View style={styles.empty}>
<Text variant="body" color={colors.textSecondary}>
The desktop queue is empty.
</Text>
</View>
}
/>
</>
),
[colors.textTertiary, styles.headerRow, upcomingCount]
);
const content = (
<FlashList
data={items}
keyExtractor={(item) => item.queueId}
renderScrollComponent={embedded ? undefined : renderFlashListScrollComponent}
renderItem={renderItem}
contentContainerStyle={styles.listContent}
showsVerticalScrollIndicator={false}
ListEmptyComponent={
<View style={styles.empty}>
<Text variant="body" color={colors.textSecondary}>
The desktop queue is empty.
</Text>
</View>
}
/>
);
const renderSheetHandle = useCallback(
(props: BottomSheetHandleProps) => (
<QueueSheetHandle {...props}>
{topSection}
</QueueSheetHandle>
),
[topSection]
);
if (embedded) {
return <View style={styles.embeddedRoot}>{body}</View>;
return (
<View style={styles.embeddedRoot}>
{topSection}
{content}
</View>
);
}
return (
@@ -141,9 +161,10 @@ export function RemoteQueueSheet({ onClose, embedded = false }: RemoteQueueSheet
onClose={onClose}
backdropComponent={renderBackdrop}
backgroundStyle={styles.sheetBg}
handleComponent={renderSheetHandle}
handleIndicatorStyle={styles.handle}
>
{body}
{content}
</BottomSheet>
);
}