mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-10-14 21:20:48 +08:00
fix(profiles): stabilize drag reorder motion
Close: 7798
This commit is contained in:
@@ -4,6 +4,8 @@ import { Box } from '@mui/material'
|
|||||||
|
|
||||||
import { ProfileItem, type ProfileItemProps } from './profile-item'
|
import { ProfileItem, type ProfileItemProps } from './profile-item'
|
||||||
|
|
||||||
|
const SORT_TRANSITION = 'transform 160ms cubic-bezier(0.2, 0, 0, 1)'
|
||||||
|
|
||||||
type SortableProfileItemProps = Omit<
|
type SortableProfileItemProps = Omit<
|
||||||
ProfileItemProps,
|
ProfileItemProps,
|
||||||
'dragHandleRef' | 'dragHandleAttributes' | 'dragHandleListeners'
|
'dragHandleRef' | 'dragHandleAttributes' | 'dragHandleListeners'
|
||||||
@@ -18,24 +20,33 @@ export const SortableProfileItem = ({
|
|||||||
const {
|
const {
|
||||||
attributes,
|
attributes,
|
||||||
listeners,
|
listeners,
|
||||||
|
setActivatorNodeRef,
|
||||||
setNodeRef,
|
setNodeRef,
|
||||||
transform,
|
transform,
|
||||||
transition,
|
isSorting,
|
||||||
isDragging,
|
isDragging,
|
||||||
} = useSortable({ id })
|
isOver,
|
||||||
|
} = useSortable({ id, transition: null })
|
||||||
|
|
||||||
|
const isDiagonalMove =
|
||||||
|
transform !== null && transform.x !== 0 && transform.y !== 0
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
|
ref={setNodeRef}
|
||||||
sx={{
|
sx={{
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
transform: CSS.Transform.toString(transform),
|
transform: CSS.Translate.toString(transform),
|
||||||
transition,
|
transition:
|
||||||
|
isSorting && !isDragging && isOver && !isDiagonalMove
|
||||||
|
? SORT_TRANSITION
|
||||||
|
: undefined,
|
||||||
zIndex: isDragging ? 'calc(infinity)' : undefined,
|
zIndex: isDragging ? 'calc(infinity)' : undefined,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ProfileItem
|
<ProfileItem
|
||||||
{...profileItemProps}
|
{...profileItemProps}
|
||||||
dragHandleRef={setNodeRef}
|
dragHandleRef={setActivatorNodeRef}
|
||||||
dragHandleAttributes={attributes}
|
dragHandleAttributes={attributes}
|
||||||
dragHandleListeners={listeners}
|
dragHandleListeners={listeners}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import {
|
import {
|
||||||
closestCenter,
|
closestCenter,
|
||||||
|
type CollisionDetection,
|
||||||
DndContext,
|
DndContext,
|
||||||
type DragEndEvent,
|
type DragEndEvent,
|
||||||
DragOverlay,
|
DragOverlay,
|
||||||
KeyboardSensor,
|
KeyboardSensor,
|
||||||
|
pointerWithin,
|
||||||
PointerSensor,
|
PointerSensor,
|
||||||
useSensor,
|
useSensor,
|
||||||
useSensors,
|
useSensors,
|
||||||
@@ -77,6 +79,11 @@ import { debugLog } from '@/utils/debug'
|
|||||||
const PROFILE_UPDATE_WORKER_LIMIT = 8
|
const PROFILE_UPDATE_WORKER_LIMIT = 8
|
||||||
const PROFILE_SWITCH_LOADING_DELAY = 400
|
const PROFILE_SWITCH_LOADING_DELAY = 400
|
||||||
|
|
||||||
|
const profileCollisionDetection: CollisionDetection = (args) => {
|
||||||
|
const pointerCollisions = pointerWithin(args)
|
||||||
|
return pointerCollisions.length > 0 ? pointerCollisions : closestCenter(args)
|
||||||
|
}
|
||||||
|
|
||||||
// Equivalent to rectSortingStrategy without copying the full rect array for every item.
|
// Equivalent to rectSortingStrategy without copying the full rect array for every item.
|
||||||
const profileRectSortingStrategy: SortingStrategy = ({
|
const profileRectSortingStrategy: SortingStrategy = ({
|
||||||
rects,
|
rects,
|
||||||
@@ -928,7 +935,7 @@ const ProfilePage = () => {
|
|||||||
|
|
||||||
<DndContext
|
<DndContext
|
||||||
sensors={sensors}
|
sensors={sensors}
|
||||||
collisionDetection={closestCenter}
|
collisionDetection={profileCollisionDetection}
|
||||||
onDragEnd={onDragEnd}
|
onDragEnd={onDragEnd}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
|
|||||||
Reference in New Issue
Block a user