From 0e4724f9bd9e3e01fcb4679618af25e768d59ff2 Mon Sep 17 00:00:00 2001 From: Pas <74743263+Pasithea0@users.noreply.github.com> Date: Thu, 6 Nov 2025 00:44:25 -0700 Subject: [PATCH] Revert "add drag and drop bookmark reordering" This reverts commit c90e77ddf34c4bcb7036b353e411fe215fbc17ba. --- src/hooks/useBookmarkDragAndDrop.tsx | 201 --------------------- src/pages/parts/home/BookmarksCarousel.tsx | 170 +++++------------ src/pages/parts/home/BookmarksPart.tsx | 149 +++++---------- src/stores/bookmarks/index.ts | 16 -- 4 files changed, 89 insertions(+), 447 deletions(-) delete mode 100644 src/hooks/useBookmarkDragAndDrop.tsx diff --git a/src/hooks/useBookmarkDragAndDrop.tsx b/src/hooks/useBookmarkDragAndDrop.tsx deleted file mode 100644 index 248cad9d..00000000 --- a/src/hooks/useBookmarkDragAndDrop.tsx +++ /dev/null @@ -1,201 +0,0 @@ -import { - DragEndEvent, - KeyboardSensor, - MouseSensor, - TouchSensor, - useSensor, - useSensors, -} from "@dnd-kit/core"; -import { - arrayMove, - sortableKeyboardCoordinates, - useSortable, -} from "@dnd-kit/sortable"; -import { CSS } from "@dnd-kit/utilities"; -import React, { useEffect, useRef, useState } from "react"; - -import { WatchedMediaCard } from "@/components/media/WatchedMediaCard"; -import { useBookmarkStore } from "@/stores/bookmarks"; -import { MediaItem } from "@/utils/mediaTypes"; - -interface SortableMediaCardProps { - media: MediaItem; - closable?: boolean; - onClose?: () => void; - onShowDetails?: (media: MediaItem) => void; - editable?: boolean; - onEdit?: () => void; - isEditing?: boolean; -} - -export function SortableMediaCard({ - media, - closable, - onClose, - onShowDetails, - editable, - onEdit, - isEditing, -}: SortableMediaCardProps): JSX.Element { - const { - attributes, - listeners, - setNodeRef, - transform, - transition, - isDragging, - } = useSortable({ id: media.id }); - - const style = { - transform: CSS.Transform.toString(transform), - transition, - opacity: isDragging ? 0.5 : 1, - }; - - return ( -
- -
- ); -} - -interface UseBookmarkDragAndDropProps { - editing: boolean; - items: MediaItem[]; - groupedItems: Record; -} - -export function useBookmarkDragAndDrop({ - editing, - items, - groupedItems, -}: UseBookmarkDragAndDropProps) { - const bookmarks = useBookmarkStore((s) => s.bookmarks); - const updateBookmarkOrder = useBookmarkStore((s) => s.updateBookmarkOrder); - - // Drag and drop sensors - const sensors = useSensors( - useSensor(TouchSensor, { - activationConstraint: { - delay: 75, - tolerance: 1, - }, - }), - useSensor(MouseSensor), - useSensor(KeyboardSensor, { - coordinateGetter: sortableKeyboardCoordinates, - }), - ); - - // Track order during editing - const [orderedItems, setOrderedItems] = useState([]); - const [orderedGroupedItems, setOrderedGroupedItems] = useState< - Record - >({}); - const isApplyingOrderRef = useRef(false); - - // Initialize ordered items when entering edit mode - useEffect(() => { - if (editing) { - setOrderedItems([...items]); - setOrderedGroupedItems({ ...groupedItems }); - isApplyingOrderRef.current = false; - } - }, [editing, items, groupedItems]); - - // Apply order when exiting edit mode - useEffect(() => { - if (!editing && orderedItems.length > 0 && !isApplyingOrderRef.current) { - isApplyingOrderRef.current = true; - - // Apply order for regular items - const regularOrder = orderedItems - .filter((item) => { - const bookmark = bookmarks[item.id]; - return !Array.isArray(bookmark?.group) || bookmark.group.length === 0; - }) - .map((item) => item.id); - if (regularOrder.length > 0) { - updateBookmarkOrder(regularOrder); - } - - // Apply order for grouped items - Object.entries(orderedGroupedItems).forEach( - ([_groupName, groupItems]) => { - const groupOrderIds = groupItems.map((item) => item.id); - if (groupOrderIds.length > 0) { - updateBookmarkOrder(groupOrderIds); - } - }, - ); - - // Reset ordered items after a short delay to allow state updates to complete - setTimeout(() => { - setOrderedItems([]); - setOrderedGroupedItems({}); - isApplyingOrderRef.current = false; - }, 0); - } - }, [ - editing, - orderedItems, - orderedGroupedItems, - bookmarks, - updateBookmarkOrder, - ]); - - const handleDragEnd = (event: DragEndEvent, groupName?: string) => { - const { active, over } = event; - if (!over || active.id === over.id) return; - - if (groupName) { - // Handle grouped items - const currentItems = orderedGroupedItems[groupName] || []; - const oldIndex = currentItems.findIndex((item) => item.id === active.id); - const newIndex = currentItems.findIndex((item) => item.id === over.id); - if (oldIndex !== -1 && newIndex !== -1) { - const newItems = arrayMove(currentItems, oldIndex, newIndex); - setOrderedGroupedItems({ - ...orderedGroupedItems, - [groupName]: newItems, - }); - } - } else { - // Handle regular items - const currentItems = orderedItems.filter((item) => { - const bookmark = bookmarks[item.id]; - return !Array.isArray(bookmark?.group) || bookmark.group.length === 0; - }); - const oldIndex = currentItems.findIndex((item) => item.id === active.id); - const newIndex = currentItems.findIndex((item) => item.id === over.id); - if (oldIndex !== -1 && newIndex !== -1) { - const newItems = arrayMove(currentItems, oldIndex, newIndex); - // Update orderedItems with the new order - const otherItems = orderedItems.filter((item) => { - const bookmark = bookmarks[item.id]; - return Array.isArray(bookmark?.group) && bookmark.group.length > 0; - }); - setOrderedItems([...newItems, ...otherItems]); - } - } - }; - - return { - sensors, - orderedItems, - orderedGroupedItems, - handleDragEnd, - }; -} diff --git a/src/pages/parts/home/BookmarksCarousel.tsx b/src/pages/parts/home/BookmarksCarousel.tsx index 58cea30d..1498d544 100644 --- a/src/pages/parts/home/BookmarksCarousel.tsx +++ b/src/pages/parts/home/BookmarksCarousel.tsx @@ -1,5 +1,3 @@ -import { DndContext, closestCenter } from "@dnd-kit/core"; -import { SortableContext, rectSortingStrategy } from "@dnd-kit/sortable"; import React, { useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; @@ -9,6 +7,7 @@ import { EditButtonWithText } from "@/components/buttons/EditButtonWithText"; import { Item } from "@/components/form/SortableList"; import { Icon, Icons } from "@/components/Icon"; import { SectionHeading } from "@/components/layout/SectionHeading"; +import { WatchedMediaCard } from "@/components/media/WatchedMediaCard"; import { EditBookmarkModal } from "@/components/overlays/EditBookmarkModal"; import { EditGroupModal } from "@/components/overlays/EditGroupModal"; import { EditGroupOrderModal } from "@/components/overlays/EditGroupOrderModal"; @@ -16,10 +15,6 @@ import { useModal } from "@/components/overlays/Modal"; import { UserIcon, UserIcons } from "@/components/UserIcon"; import { Flare } from "@/components/utils/Flare"; import { useBackendUrl } from "@/hooks/auth/useBackendUrl"; -import { - SortableMediaCard, - useBookmarkDragAndDrop, -} from "@/hooks/useBookmarkDragAndDrop"; import { useIsMobile } from "@/hooks/useIsMobile"; import { CarouselNavButtons } from "@/pages/discover/components/CarouselNavButtons"; import { useAuthStore } from "@/stores/auth"; @@ -186,14 +181,6 @@ export function BookmarksCarousel({ return { groupedItems: grouped, regularItems: regular }; }, [items, bookmarks, progressItems]); - // Drag and drop hook - const { sensors, orderedItems, orderedGroupedItems, handleDragEnd } = - useBookmarkDragAndDrop({ - editing, - items, - groupedItems, - }); - // group sorting const allGroups = useMemo(() => { const groups = new Set(); @@ -448,50 +435,27 @@ export function BookmarksCarousel({ >
- handleDragEnd(e, section.group)} - > - item.id) - : section.items - .slice(0, MAX_ITEMS_PER_SECTION) - .map((item) => item.id) - } - strategy={rectSortingStrategy} - > - {(editing && orderedGroupedItems[section.group || ""] - ? orderedGroupedItems[section.group || ""] - : section.items - ) - .slice(0, MAX_ITEMS_PER_SECTION) - .map((media) => ( -
, - ) => e.preventDefault()} - className="relative mt-4 group cursor-pointer rounded-xl p-2 bg-transparent transition-colors duration-300 w-[10rem] md:w-[11.5rem] h-auto" - > - removeBookmark(media.id)} - editable={editing} - onEdit={() => handleEditBookmark(media.id)} - isEditing={editing} - /> -
- ))} -
-
+ {section.items + .slice(0, MAX_ITEMS_PER_SECTION) + .map((media) => ( +
) => + e.preventDefault() + } + className="relative mt-4 group cursor-pointer rounded-xl p-2 bg-transparent transition-colors duration-300 w-[10rem] md:w-[11.5rem] h-auto" + > + removeBookmark(media.id)} + editable={editing} + onEdit={() => handleEditBookmark(media.id)} + /> +
+ ))} {section.items.length > MAX_ITEMS_PER_SECTION && ( @@ -545,71 +509,33 @@ export function BookmarksCarousel({ >
- {section.items.length > 0 ? ( - handleDragEnd(e)} - > - { - const bookmark = bookmarks[item.id]; - return ( - !Array.isArray(bookmark?.group) || - bookmark.group.length === 0 - ); - }) - .slice(0, MAX_ITEMS_PER_SECTION) - .map((item) => item.id) - : section.items - .slice(0, MAX_ITEMS_PER_SECTION) - .map((item) => item.id) - } - strategy={rectSortingStrategy} - > - {(editing - ? orderedItems.filter((item) => { - const bookmark = bookmarks[item.id]; - return ( - !Array.isArray(bookmark?.group) || - bookmark.group.length === 0 - ); - }) - : section.items - ) - .slice(0, MAX_ITEMS_PER_SECTION) - .map((media) => ( -
0 + ? section.items + .slice(0, MAX_ITEMS_PER_SECTION) + .map((media) => ( +
, + ) => e.preventDefault()} + className="relative mt-4 group cursor-pointer rounded-xl p-2 bg-transparent transition-colors duration-300 w-[10rem] md:w-[11.5rem] h-auto" + > + , - ) => e.preventDefault()} - className="relative mt-4 group cursor-pointer rounded-xl p-2 bg-transparent transition-colors duration-300 w-[10rem] md:w-[11.5rem] h-auto" - > - removeBookmark(media.id)} - editable={editing} - onEdit={() => handleEditBookmark(media.id)} - isEditing={editing} - /> -
- ))} - - - ) : ( - Array.from({ length: SKELETON_COUNT }).map(() => ( - - )) - )} + media={media} + onShowDetails={onShowDetails} + closable={editing} + onClose={() => removeBookmark(media.id)} + editable={editing} + onEdit={() => handleEditBookmark(media.id)} + /> +
+ )) + : Array.from({ length: SKELETON_COUNT }).map(() => ( + + ))} {section.items.length > MAX_ITEMS_PER_SECTION && ( diff --git a/src/pages/parts/home/BookmarksPart.tsx b/src/pages/parts/home/BookmarksPart.tsx index 84d942d7..97227bf9 100644 --- a/src/pages/parts/home/BookmarksPart.tsx +++ b/src/pages/parts/home/BookmarksPart.tsx @@ -1,5 +1,3 @@ -import { DndContext, closestCenter } from "@dnd-kit/core"; -import { SortableContext, rectSortingStrategy } from "@dnd-kit/sortable"; import { useAutoAnimate } from "@formkit/auto-animate/react"; import { useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -10,16 +8,13 @@ import { Item } from "@/components/form/SortableList"; import { Icons } from "@/components/Icon"; import { SectionHeading } from "@/components/layout/SectionHeading"; import { MediaGrid } from "@/components/media/MediaGrid"; +import { WatchedMediaCard } from "@/components/media/WatchedMediaCard"; import { EditBookmarkModal } from "@/components/overlays/EditBookmarkModal"; import { EditGroupModal } from "@/components/overlays/EditGroupModal"; import { EditGroupOrderModal } from "@/components/overlays/EditGroupOrderModal"; import { useModal } from "@/components/overlays/Modal"; import { UserIcon, UserIcons } from "@/components/UserIcon"; import { useBackendUrl } from "@/hooks/auth/useBackendUrl"; -import { - SortableMediaCard, - useBookmarkDragAndDrop, -} from "@/hooks/useBookmarkDragAndDrop"; import { useAuthStore } from "@/stores/auth"; import { useBookmarkStore } from "@/stores/bookmarks"; import { useGroupOrderStore } from "@/stores/groupOrder"; @@ -125,14 +120,6 @@ export function BookmarksPart({ return { groupedItems: grouped, regularItems: regular }; }, [items, bookmarks, progressItems]); - // Drag and drop hook - const { sensors, orderedItems, orderedGroupedItems, handleDragEnd } = - useBookmarkDragAndDrop({ - editing, - items, - groupedItems, - }); - // group sorting const allGroups = useMemo(() => { const groups = new Set(); @@ -351,47 +338,26 @@ export function BookmarksPart({ />
- handleDragEnd(e, section.group)} - > - item.id, - ) - : section.items.map((item) => item.id) - } - strategy={rectSortingStrategy} - > - - {(editing && orderedGroupedItems[section.group || ""] - ? orderedGroupedItems[section.group || ""] - : section.items - ).map((v) => ( -
) => - e.preventDefault() - } - className="relative group" - > - removeBookmark(v.id)} - onShowDetails={onShowDetails} - editable={editing} - onEdit={() => handleEditBookmark(v.id)} - isEditing={editing} - /> -
- ))} -
-
-
+ + {section.items.map((v) => ( +
) => + e.preventDefault() + } + className="relative group" + > + removeBookmark(v.id)} + onShowDetails={onShowDetails} + editable={editing} + onEdit={() => handleEditBookmark(v.id)} + /> +
+ ))} +
); } // regular items @@ -418,59 +384,26 @@ export function BookmarksPart({ /> - handleDragEnd(e)} - > - { - const bookmark = bookmarks[item.id]; - return ( - !Array.isArray(bookmark?.group) || - bookmark.group.length === 0 - ); - }) - .map((item) => item.id) - : section.items.map((item) => item.id) - } - strategy={rectSortingStrategy} - > - - {(editing - ? orderedItems.filter((item) => { - const bookmark = bookmarks[item.id]; - return ( - !Array.isArray(bookmark?.group) || - bookmark.group.length === 0 - ); - }) - : section.items - ).map((v) => ( -
) => - e.preventDefault() - } - className="relative group" - > - removeBookmark(v.id)} - onShowDetails={onShowDetails} - editable={editing} - onEdit={() => handleEditBookmark(v.id)} - isEditing={editing} - /> -
- ))} -
-
-
+ + {section.items.map((v) => ( +
) => + e.preventDefault() + } + className="relative group" + > + removeBookmark(v.id)} + onShowDetails={onShowDetails} + editable={editing} + onEdit={() => handleEditBookmark(v.id)} + /> +
+ ))} +
); })} diff --git a/src/stores/bookmarks/index.ts b/src/stores/bookmarks/index.ts index 7df352c4..9e048fc3 100644 --- a/src/stores/bookmarks/index.ts +++ b/src/stores/bookmarks/index.ts @@ -54,7 +54,6 @@ export interface BookmarkStore { modifyBookmarksByGroup( options: BulkGroupModificationOptions, ): BookmarkModificationResult; - updateBookmarkOrder(bookmarkIds: string[]): void; clear(): void; clearUpdateQueue(): void; removeUpdateItem(id: string): void; @@ -278,21 +277,6 @@ export const useBookmarkStore = create( return result; }, - updateBookmarkOrder(bookmarkIds: string[]) { - set((s) => { - const baseTime = Date.now(); - bookmarkIds.forEach((bookmarkId, index) => { - const bookmark = s.bookmarks[bookmarkId]; - if (bookmark) { - // Update timestamp to reflect order (earlier items have higher timestamps) - // This ensures they appear first when sorted by date descending - // Note: We don't add to update queue here to avoid quota errors. - // Order is persisted locally via updatedAt timestamps. - bookmark.updatedAt = baseTime - index; - } - }); - }); - }, })), { name: "__MW::bookmarks",