mirror of
https://github.com/Boof2015/astra-mobile.git
synced 2026-08-12 05:10:52 +02:00
fix queue panel dragging
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user