mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 09:33:46 +00:00
fix: disable Telegram vertical swipes during drag operations
- Add useTelegramDnd hook for @dnd-kit integration - Update Sheet components to disable swipes when open - Update AdminPaymentMethods to use the new hook - Prevents conflict between app drag gestures and Telegram swipe-to-close
This commit is contained in:
@@ -7,10 +7,12 @@ import {
|
||||
useContext,
|
||||
useState,
|
||||
useCallback,
|
||||
useEffect,
|
||||
} from 'react';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { usePlatform } from '@/platform';
|
||||
import { useBackButton } from '@/platform';
|
||||
import { useTelegramSDK } from '@/hooks/useTelegramSDK';
|
||||
import {
|
||||
backdrop,
|
||||
backdropTransition,
|
||||
@@ -138,10 +140,26 @@ export const SheetContent = forwardRef<HTMLDivElement, SheetContentProps>(
|
||||
const { open, onClose } = useContext(SheetContext);
|
||||
const { haptic } = usePlatform();
|
||||
const dragControls = useDragControls();
|
||||
const { disableVerticalSwipes, enableVerticalSwipes, isTelegramWebApp } = useTelegramSDK();
|
||||
|
||||
// Back button integration
|
||||
useBackButton(open ? onClose : null);
|
||||
|
||||
// Disable Telegram vertical swipes when sheet is open (prevents conflict with drag gestures)
|
||||
useEffect(() => {
|
||||
if (!isTelegramWebApp) return;
|
||||
|
||||
if (open) {
|
||||
disableVerticalSwipes();
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (open) {
|
||||
enableVerticalSwipes();
|
||||
}
|
||||
};
|
||||
}, [open, isTelegramWebApp, disableVerticalSwipes, enableVerticalSwipes]);
|
||||
|
||||
const handleDragEnd = useCallback(
|
||||
(_: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => {
|
||||
const velocity = info.velocity.y;
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useEffect, useRef, useCallback, useState, type ReactNode } from 'react'
|
||||
import { createPortal } from 'react-dom';
|
||||
import { useBackButton } from '@/platform';
|
||||
import { useHaptic } from '@/platform';
|
||||
import { useTelegramSDK } from '@/hooks/useTelegramSDK';
|
||||
|
||||
export interface SheetProps {
|
||||
isOpen: boolean;
|
||||
@@ -104,10 +105,26 @@ export function Sheet({
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
|
||||
const haptic = useHaptic();
|
||||
const { disableVerticalSwipes, enableVerticalSwipes, isTelegramWebApp } = useTelegramSDK();
|
||||
|
||||
// BackButton integration
|
||||
useBackButton(isOpen ? onClose : null);
|
||||
|
||||
// Disable Telegram vertical swipes when sheet is open (prevents conflict with drag gestures)
|
||||
useEffect(() => {
|
||||
if (!isTelegramWebApp) return;
|
||||
|
||||
if (isOpen) {
|
||||
disableVerticalSwipes();
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (isOpen) {
|
||||
enableVerticalSwipes();
|
||||
}
|
||||
};
|
||||
}, [isOpen, isTelegramWebApp, disableVerticalSwipes, enableVerticalSwipes]);
|
||||
|
||||
// Calculate current height based on snap point
|
||||
const currentHeight = `${snapPoints[currentSnapIndex] * 100}vh`;
|
||||
|
||||
|
||||
55
src/hooks/useTelegramDnd.ts
Normal file
55
src/hooks/useTelegramDnd.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { useCallback, useRef } from 'react';
|
||||
import { useTelegramSDK } from './useTelegramSDK';
|
||||
|
||||
/**
|
||||
* Hook to manage Telegram vertical swipes during drag-and-drop operations.
|
||||
* Disables Telegram's swipe-to-close gesture while dragging to prevent conflicts.
|
||||
*
|
||||
* Usage with @dnd-kit:
|
||||
* ```tsx
|
||||
* const { onDragStart, onDragEnd } = useTelegramDnd();
|
||||
*
|
||||
* <DndContext
|
||||
* onDragStart={(e) => {
|
||||
* onDragStart();
|
||||
* // your drag start logic
|
||||
* }}
|
||||
* onDragEnd={(e) => {
|
||||
* onDragEnd();
|
||||
* // your drag end logic
|
||||
* }}
|
||||
* >
|
||||
* ```
|
||||
*/
|
||||
export function useTelegramDnd() {
|
||||
const { disableVerticalSwipes, enableVerticalSwipes, isTelegramWebApp } = useTelegramSDK();
|
||||
const isDraggingRef = useRef(false);
|
||||
|
||||
const onDragStart = useCallback(() => {
|
||||
if (isTelegramWebApp && !isDraggingRef.current) {
|
||||
isDraggingRef.current = true;
|
||||
disableVerticalSwipes();
|
||||
}
|
||||
}, [isTelegramWebApp, disableVerticalSwipes]);
|
||||
|
||||
const onDragEnd = useCallback(() => {
|
||||
if (isTelegramWebApp && isDraggingRef.current) {
|
||||
isDraggingRef.current = false;
|
||||
enableVerticalSwipes();
|
||||
}
|
||||
}, [isTelegramWebApp, enableVerticalSwipes]);
|
||||
|
||||
const onDragCancel = useCallback(() => {
|
||||
if (isTelegramWebApp && isDraggingRef.current) {
|
||||
isDraggingRef.current = false;
|
||||
enableVerticalSwipes();
|
||||
}
|
||||
}, [isTelegramWebApp, enableVerticalSwipes]);
|
||||
|
||||
return {
|
||||
onDragStart,
|
||||
onDragEnd,
|
||||
onDragCancel,
|
||||
isTelegramWebApp,
|
||||
};
|
||||
}
|
||||
@@ -8,7 +8,9 @@ import {
|
||||
useSensor,
|
||||
useSensors,
|
||||
type DragEndEvent,
|
||||
type DragStartEvent,
|
||||
} from '@dnd-kit/core';
|
||||
import { useTelegramDnd } from '../hooks/useTelegramDnd';
|
||||
import {
|
||||
arrayMove,
|
||||
SortableContext,
|
||||
@@ -674,18 +676,40 @@ export default function AdminPaymentMethods() {
|
||||
useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),
|
||||
);
|
||||
|
||||
const handleDragEnd = useCallback((event: DragEndEvent) => {
|
||||
const { active, over } = event;
|
||||
if (over && active.id !== over.id) {
|
||||
setMethods((prev) => {
|
||||
const oldIndex = prev.findIndex((m) => m.method_id === active.id);
|
||||
const newIndex = prev.findIndex((m) => m.method_id === over.id);
|
||||
if (oldIndex === -1 || newIndex === -1) return prev;
|
||||
return arrayMove(prev, oldIndex, newIndex);
|
||||
});
|
||||
setOrderChanged(true);
|
||||
}
|
||||
}, []);
|
||||
// Telegram swipe behavior for drag-and-drop
|
||||
const {
|
||||
onDragStart: onTelegramDragStart,
|
||||
onDragEnd: onTelegramDragEnd,
|
||||
onDragCancel: onTelegramDragCancel,
|
||||
} = useTelegramDnd();
|
||||
|
||||
const handleDragStart = useCallback(
|
||||
(_event: DragStartEvent) => {
|
||||
onTelegramDragStart();
|
||||
},
|
||||
[onTelegramDragStart],
|
||||
);
|
||||
|
||||
const handleDragEnd = useCallback(
|
||||
(event: DragEndEvent) => {
|
||||
onTelegramDragEnd();
|
||||
const { active, over } = event;
|
||||
if (over && active.id !== over.id) {
|
||||
setMethods((prev) => {
|
||||
const oldIndex = prev.findIndex((m) => m.method_id === active.id);
|
||||
const newIndex = prev.findIndex((m) => m.method_id === over.id);
|
||||
if (oldIndex === -1 || newIndex === -1) return prev;
|
||||
return arrayMove(prev, oldIndex, newIndex);
|
||||
});
|
||||
setOrderChanged(true);
|
||||
}
|
||||
},
|
||||
[onTelegramDragEnd],
|
||||
);
|
||||
|
||||
const handleDragCancel = useCallback(() => {
|
||||
onTelegramDragCancel();
|
||||
}, [onTelegramDragCancel]);
|
||||
|
||||
const handleSaveOrder = () => {
|
||||
saveOrderMutation.mutate(methods.map((m) => m.method_id));
|
||||
@@ -737,7 +761,12 @@ export default function AdminPaymentMethods() {
|
||||
<div className="h-8 w-8 animate-spin rounded-full border-2 border-accent-500 border-t-transparent" />
|
||||
</div>
|
||||
) : methods.length > 0 ? (
|
||||
<DndContext sensors={sensors} onDragEnd={handleDragEnd}>
|
||||
<DndContext
|
||||
sensors={sensors}
|
||||
onDragStart={handleDragStart}
|
||||
onDragEnd={handleDragEnd}
|
||||
onDragCancel={handleDragCancel}
|
||||
>
|
||||
<SortableContext
|
||||
items={methods.map((m) => m.method_id)}
|
||||
strategy={verticalListSortingStrategy}
|
||||
|
||||
Reference in New Issue
Block a user