mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-30 02:23:47 +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,
|
useContext,
|
||||||
useState,
|
useState,
|
||||||
useCallback,
|
useCallback,
|
||||||
|
useEffect,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { usePlatform } from '@/platform';
|
import { usePlatform } from '@/platform';
|
||||||
import { useBackButton } from '@/platform';
|
import { useBackButton } from '@/platform';
|
||||||
|
import { useTelegramSDK } from '@/hooks/useTelegramSDK';
|
||||||
import {
|
import {
|
||||||
backdrop,
|
backdrop,
|
||||||
backdropTransition,
|
backdropTransition,
|
||||||
@@ -138,10 +140,26 @@ export const SheetContent = forwardRef<HTMLDivElement, SheetContentProps>(
|
|||||||
const { open, onClose } = useContext(SheetContext);
|
const { open, onClose } = useContext(SheetContext);
|
||||||
const { haptic } = usePlatform();
|
const { haptic } = usePlatform();
|
||||||
const dragControls = useDragControls();
|
const dragControls = useDragControls();
|
||||||
|
const { disableVerticalSwipes, enableVerticalSwipes, isTelegramWebApp } = useTelegramSDK();
|
||||||
|
|
||||||
// Back button integration
|
// Back button integration
|
||||||
useBackButton(open ? onClose : null);
|
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(
|
const handleDragEnd = useCallback(
|
||||||
(_: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => {
|
(_: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => {
|
||||||
const velocity = info.velocity.y;
|
const velocity = info.velocity.y;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { useEffect, useRef, useCallback, useState, type ReactNode } from 'react'
|
|||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import { useBackButton } from '@/platform';
|
import { useBackButton } from '@/platform';
|
||||||
import { useHaptic } from '@/platform';
|
import { useHaptic } from '@/platform';
|
||||||
|
import { useTelegramSDK } from '@/hooks/useTelegramSDK';
|
||||||
|
|
||||||
export interface SheetProps {
|
export interface SheetProps {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@@ -104,10 +105,26 @@ export function Sheet({
|
|||||||
const [isVisible, setIsVisible] = useState(false);
|
const [isVisible, setIsVisible] = useState(false);
|
||||||
|
|
||||||
const haptic = useHaptic();
|
const haptic = useHaptic();
|
||||||
|
const { disableVerticalSwipes, enableVerticalSwipes, isTelegramWebApp } = useTelegramSDK();
|
||||||
|
|
||||||
// BackButton integration
|
// BackButton integration
|
||||||
useBackButton(isOpen ? onClose : null);
|
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
|
// Calculate current height based on snap point
|
||||||
const currentHeight = `${snapPoints[currentSnapIndex] * 100}vh`;
|
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,
|
useSensor,
|
||||||
useSensors,
|
useSensors,
|
||||||
type DragEndEvent,
|
type DragEndEvent,
|
||||||
|
type DragStartEvent,
|
||||||
} from '@dnd-kit/core';
|
} from '@dnd-kit/core';
|
||||||
|
import { useTelegramDnd } from '../hooks/useTelegramDnd';
|
||||||
import {
|
import {
|
||||||
arrayMove,
|
arrayMove,
|
||||||
SortableContext,
|
SortableContext,
|
||||||
@@ -674,7 +676,23 @@ export default function AdminPaymentMethods() {
|
|||||||
useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),
|
useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleDragEnd = useCallback((event: DragEndEvent) => {
|
// 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;
|
const { active, over } = event;
|
||||||
if (over && active.id !== over.id) {
|
if (over && active.id !== over.id) {
|
||||||
setMethods((prev) => {
|
setMethods((prev) => {
|
||||||
@@ -685,7 +703,13 @@ export default function AdminPaymentMethods() {
|
|||||||
});
|
});
|
||||||
setOrderChanged(true);
|
setOrderChanged(true);
|
||||||
}
|
}
|
||||||
}, []);
|
},
|
||||||
|
[onTelegramDragEnd],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDragCancel = useCallback(() => {
|
||||||
|
onTelegramDragCancel();
|
||||||
|
}, [onTelegramDragCancel]);
|
||||||
|
|
||||||
const handleSaveOrder = () => {
|
const handleSaveOrder = () => {
|
||||||
saveOrderMutation.mutate(methods.map((m) => m.method_id));
|
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 className="h-8 w-8 animate-spin rounded-full border-2 border-accent-500 border-t-transparent" />
|
||||||
</div>
|
</div>
|
||||||
) : methods.length > 0 ? (
|
) : methods.length > 0 ? (
|
||||||
<DndContext sensors={sensors} onDragEnd={handleDragEnd}>
|
<DndContext
|
||||||
|
sensors={sensors}
|
||||||
|
onDragStart={handleDragStart}
|
||||||
|
onDragEnd={handleDragEnd}
|
||||||
|
onDragCancel={handleDragCancel}
|
||||||
|
>
|
||||||
<SortableContext
|
<SortableContext
|
||||||
items={methods.map((m) => m.method_id)}
|
items={methods.map((m) => m.method_id)}
|
||||||
strategy={verticalListSortingStrategy}
|
strategy={verticalListSortingStrategy}
|
||||||
|
|||||||
Reference in New Issue
Block a user