From 47a6e02c21a56fac04a4c23660071314167e4f54 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Thu, 30 Jun 2022 15:58:46 +0700 Subject: [PATCH] added SortableAudioGrid --- .../comment/CommentFormAttaches/index.tsx | 20 +---- .../CommentFormAttaches/styles.module.scss | 4 - src/components/editors/AudioGrid/index.tsx | 24 +----- .../editors/AudioGrid/styles.module.scss | 6 -- .../editors/SortableAudioGrid/index.tsx | 50 ------------ .../sortable/SortableAudioGrid/index.tsx | 57 ++++++++++++++ .../SortableAudioGrid/styles.module.scss | 0 .../sortable/SortableGrid/index.tsx | 33 +++----- .../index.tsx | 4 +- .../styles.module.scss | 0 .../sortable/SortableList/index.tsx | 76 +++++++++++++++++++ .../sortable/SortableList/styles.module.scss | 15 ++++ src/components/sortable/index.ts | 2 +- src/components/upload/AudioUpload/index.tsx | 15 ++-- 14 files changed, 175 insertions(+), 131 deletions(-) delete mode 100644 src/components/editors/AudioGrid/styles.module.scss delete mode 100644 src/components/editors/SortableAudioGrid/index.tsx create mode 100644 src/components/sortable/SortableAudioGrid/index.tsx rename src/components/{editors => sortable}/SortableAudioGrid/styles.module.scss (100%) rename src/components/sortable/{SortableGridItem => SortableItem}/index.tsx (88%) rename src/components/sortable/{SortableGridItem => SortableItem}/styles.module.scss (100%) create mode 100644 src/components/sortable/SortableList/index.tsx create mode 100644 src/components/sortable/SortableList/styles.module.scss diff --git a/src/components/comment/CommentFormAttaches/index.tsx b/src/components/comment/CommentFormAttaches/index.tsx index 248ae954..e23b3965 100644 --- a/src/components/comment/CommentFormAttaches/index.tsx +++ b/src/components/comment/CommentFormAttaches/index.tsx @@ -1,14 +1,10 @@ import React, { FC, useCallback } from 'react'; -import { SortEnd } from 'react-sortable-hoc'; - -import { SortableAudioGrid } from '~/components/editors/SortableAudioGrid'; -import { SortableImageGrid } from '~/components/sortable'; +import { SortableAudioGrid, SortableImageGrid } from '~/components/sortable'; import { COMMENT_FILE_TYPES } from '~/constants/uploads'; import { useFileDropZone } from '~/hooks'; import { IFile } from '~/types'; import { useUploaderContext } from '~/utils/context/UploaderContextProvider'; -import { moveArrItem } from '~/utils/fn'; import styles from './styles.module.scss'; @@ -37,15 +33,8 @@ const CommentFormAttaches: FC = () => { ); const onAudioMove = useCallback( - ({ oldIndex, newIndex }: SortEnd) => { - setFiles([ - ...filesImages, - ...(moveArrItem( - oldIndex, - newIndex, - filesAudios.filter(file => !!file) - ) as IFile[]), - ]); + (newFiles: IFile[]) => { + setFiles([...filesImages, ...newFiles]); }, [setFiles, filesImages, filesAudios] ); @@ -88,10 +77,7 @@ const CommentFormAttaches: FC = () => { onDelete={onFileDelete} onTitleChange={onAudioTitleChange} onSortEnd={onAudioMove} - axis="y" locked={pendingAudios} - pressDelay={50} - helperClass={styles.helper} /> )} diff --git a/src/components/comment/CommentFormAttaches/styles.module.scss b/src/components/comment/CommentFormAttaches/styles.module.scss index 015e6414..57ac2ca4 100644 --- a/src/components/comment/CommentFormAttaches/styles.module.scss +++ b/src/components/comment/CommentFormAttaches/styles.module.scss @@ -3,7 +3,3 @@ .attaches { @include outer_shadow(); } - -.helper { - z-index: 10000 !important; -} diff --git a/src/components/editors/AudioGrid/index.tsx b/src/components/editors/AudioGrid/index.tsx index d4f9f14b..7233a82e 100644 --- a/src/components/editors/AudioGrid/index.tsx +++ b/src/components/editors/AudioGrid/index.tsx @@ -1,15 +1,8 @@ import React, { FC, useCallback } from 'react'; -import { SortEnd } from 'react-sortable-hoc'; - -import { SortableAudioGrid } from '~/components/editors/SortableAudioGrid'; -import { useWindowSize } from '~/hooks/dom/useWindowSize'; +import { SortableAudioGrid } from '~/components/sortable'; import { UploadStatus } from '~/store/uploader/UploaderStore'; import { IFile } from '~/types'; -import { moveArrItem } from '~/utils/fn'; - -import styles from './styles.module.scss'; - interface IProps { files: IFile[]; @@ -18,17 +11,9 @@ interface IProps { } const AudioGrid: FC = ({ files, setFiles, locked }) => { - const { innerWidth } = useWindowSize(); - const onMove = useCallback( - ({ oldIndex, newIndex }: SortEnd) => { - setFiles( - moveArrItem( - oldIndex, - newIndex, - files.filter(file => !!file) - ) as IFile[] - ); + (newFiles: IFile[]) => { + setFiles(newFiles); }, [setFiles, files] ); @@ -56,11 +41,8 @@ const AudioGrid: FC = ({ files, setFiles, locked }) => { onDelete={onDrop} onTitleChange={onTitleChange} onSortEnd={onMove} - axis="xy" items={files} locked={locked} - pressDelay={innerWidth < 768 ? 200 : 0} - helperClass={styles.helper} /> ); }; diff --git a/src/components/editors/AudioGrid/styles.module.scss b/src/components/editors/AudioGrid/styles.module.scss deleted file mode 100644 index 9713beb5..00000000 --- a/src/components/editors/AudioGrid/styles.module.scss +++ /dev/null @@ -1,6 +0,0 @@ -@import "src/styles/variables"; - -.helper { - opacity: 0.5; - z-index: 10 !important; -} diff --git a/src/components/editors/SortableAudioGrid/index.tsx b/src/components/editors/SortableAudioGrid/index.tsx deleted file mode 100644 index ab809880..00000000 --- a/src/components/editors/SortableAudioGrid/index.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React from 'react'; - -import { SortableContainer } from 'react-sortable-hoc'; - -import { SortableAudioGridItem } from '~/components/editors/SortableAudioGridItem'; -import { AudioPlayer } from '~/components/media/AudioPlayer'; -import { AudioUpload } from '~/components/upload/AudioUpload'; -import { UploadStatus } from '~/store/uploader/UploaderStore'; -import { IFile } from '~/types'; - -import styles from './styles.module.scss'; - -const SortableAudioGrid = SortableContainer( - ({ - items, - locked, - onDelete, - onTitleChange, - }: { - items: IFile[]; - locked: UploadStatus[]; - onDelete: (file_id: IFile['id']) => void; - onTitleChange: (file_id: IFile['id'], title: string) => void; - }) => { - return ( -
- {items - .filter(file => file && file.id) - .map((file, index) => ( - - - - ))} - - {locked.map((item, index) => ( - - - - ))} -
- ); - } -); - -export { SortableAudioGrid }; diff --git a/src/components/sortable/SortableAudioGrid/index.tsx b/src/components/sortable/SortableAudioGrid/index.tsx new file mode 100644 index 00000000..da8ded3f --- /dev/null +++ b/src/components/sortable/SortableAudioGrid/index.tsx @@ -0,0 +1,57 @@ +import React, { FC, useCallback } from 'react'; + +import { AudioPlayer } from '~/components/media/AudioPlayer'; +import { AudioUpload } from '~/components/upload/AudioUpload'; +import { UploadStatus } from '~/store/uploader/UploaderStore'; +import { IFile } from '~/types'; + +import { SortableList } from '../SortableList'; + +type OnSortEnd = (newValue: IFile[]) => void; + +interface SortableAudioGridProps { + onSortEnd: OnSortEnd; + items: IFile[]; + locked: UploadStatus[]; + className?: string; + onDelete: (file_id: IFile['id']) => void; + onTitleChange: (file_id: IFile['id'], title: string) => void; +} + +const SortableAudioGrid: FC = ({ + items, + locked, + onDelete, + className, + onSortEnd, + onTitleChange, +}) => { + const renderItem = useCallback>( + ({ item }) => ( + + ), + [] + ); + + const renderLocked = useCallback>( + ({ locked }) => ( + + ), + [] + ); + + return ( + it.id} + getLockedID={it => it.id} + renderItem={renderItem} + renderLocked={renderLocked} + onSortEnd={onSortEnd} + className={className} + /> + ); +}; + +export { SortableAudioGrid }; diff --git a/src/components/editors/SortableAudioGrid/styles.module.scss b/src/components/sortable/SortableAudioGrid/styles.module.scss similarity index 100% rename from src/components/editors/SortableAudioGrid/styles.module.scss rename to src/components/sortable/SortableAudioGrid/styles.module.scss diff --git a/src/components/sortable/SortableGrid/index.tsx b/src/components/sortable/SortableGrid/index.tsx index 86a7e238..8fdbd0db 100644 --- a/src/components/sortable/SortableGrid/index.tsx +++ b/src/components/sortable/SortableGrid/index.tsx @@ -1,27 +1,16 @@ -import React, { createElement, FC, useCallback, useMemo, useState } from 'react'; +import React, { createElement, FC, useMemo } from "react"; -import { - closestCenter, - DndContext, - DragOverlay, - DragStartEvent, - MouseSensor, - TouchSensor, - useSensor, - useSensors, -} from '@dnd-kit/core'; -import { DragEndEvent } from '@dnd-kit/core/dist/types'; -import { rectSortingStrategy, SortableContext } from '@dnd-kit/sortable'; -import classNames from 'classnames'; +import { closestCenter, DndContext, DragOverlay } from "@dnd-kit/core"; +import { rectSortingStrategy, SortableContext } from "@dnd-kit/sortable"; +import classNames from "classnames"; -import { DragOverlayItem } from '~/components/sortable/DragOverlayItem'; -import { useSortableActions } from '~/hooks/sortable'; -import { moveArrItem } from '~/utils/fn'; -import { DivProps } from '~/utils/types'; +import { DragOverlayItem } from "~/components/sortable/DragOverlayItem"; +import { useSortableActions } from "~/hooks/sortable"; +import { DivProps } from "~/utils/types"; -import { SortableImageGridItem } from '../SortableGridItem'; +import { SortableItem } from "../SortableItem"; -import styles from './styles.module.scss'; +import styles from "./styles.module.scss"; interface SortableGridProps { items: T[]; @@ -70,7 +59,7 @@ const SortableGrid = ({
{items.map(item => ( - ({ } > {createElement(renderItem, { item })} - + ))} {locked.map(item => diff --git a/src/components/sortable/SortableGridItem/index.tsx b/src/components/sortable/SortableItem/index.tsx similarity index 88% rename from src/components/sortable/SortableGridItem/index.tsx rename to src/components/sortable/SortableItem/index.tsx index f33b1774..9d4ebf8a 100644 --- a/src/components/sortable/SortableGridItem/index.tsx +++ b/src/components/sortable/SortableItem/index.tsx @@ -12,7 +12,7 @@ interface SortableImageGridItemProps { className?: string; } -const SortableImageGridItem: FC = ({ +const SortableItem: FC = ({ children, id, disabled = false, @@ -41,4 +41,4 @@ const SortableImageGridItem: FC = ({ ); }; -export { SortableImageGridItem }; +export { SortableItem }; diff --git a/src/components/sortable/SortableGridItem/styles.module.scss b/src/components/sortable/SortableItem/styles.module.scss similarity index 100% rename from src/components/sortable/SortableGridItem/styles.module.scss rename to src/components/sortable/SortableItem/styles.module.scss diff --git a/src/components/sortable/SortableList/index.tsx b/src/components/sortable/SortableList/index.tsx new file mode 100644 index 00000000..2cdabec7 --- /dev/null +++ b/src/components/sortable/SortableList/index.tsx @@ -0,0 +1,76 @@ +import React, { createElement, FC } from 'react'; + +import { closestCenter, DndContext, DragOverlay } from '@dnd-kit/core'; +import { SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable'; +import classNames from 'classnames'; + +import { DragOverlayItem } from '~/components/sortable/DragOverlayItem'; +import { SortableItem } from '~/components/sortable/SortableItem'; +import { useSortableActions } from '~/hooks/sortable'; + +import styles from './styles.module.scss'; + +interface SortableListProps { + items: T[]; + locked: R[]; + getID: (item: T) => number | string; + getLockedID: (locked: R) => number | string; + renderItem: FC<{ item: T }>; + renderLocked: FC<{ locked: R }>; + onSortEnd: (newVal: T[]) => void; + className?: string; +} + +const SortableList = ({ + items, + locked, + getID, + getLockedID, + className, + renderItem, + renderLocked, + onSortEnd, +}: SortableListProps) => { + const { sensors, onDragEnd, onDragStart, draggingItem, ids } = useSortableActions( + items, + getID, + onSortEnd + ); + + return ( + + +
+ {items.map(item => ( + + {createElement(renderItem, { item })} + + ))} + + {locked.map(item => + createElement(renderLocked, { locked: item, key: getLockedID(item) }) + )} + + + {draggingItem ? ( + {createElement(renderItem, { item: draggingItem })} + ) : null} + +
+
+
+ ); +}; + +export { SortableList }; diff --git a/src/components/sortable/SortableList/styles.module.scss b/src/components/sortable/SortableList/styles.module.scss new file mode 100644 index 00000000..26426029 --- /dev/null +++ b/src/components/sortable/SortableList/styles.module.scss @@ -0,0 +1,15 @@ +@import "src/styles/variables"; + +.grid { + box-sizing: border-box; + + display: grid; + grid-row-gap: $gap; + grid-template-columns: 1fr; + grid-template-rows: auto; + grid-auto-flow: row; +} + +.dragging { + opacity: 0.1; +} diff --git a/src/components/sortable/index.ts b/src/components/sortable/index.ts index 28e360df..0246de31 100644 --- a/src/components/sortable/index.ts +++ b/src/components/sortable/index.ts @@ -1,2 +1,2 @@ export * from './SortableImageGrid'; -export * from './SortableGrid'; +export * from './SortableAudioGrid'; diff --git a/src/components/upload/AudioUpload/index.tsx b/src/components/upload/AudioUpload/index.tsx index 32d2d52f..33819389 100644 --- a/src/components/upload/AudioUpload/index.tsx +++ b/src/components/upload/AudioUpload/index.tsx @@ -1,18 +1,17 @@ -import React, { FC, useCallback } from 'react'; +import React, { FC, useCallback } from "react"; -import classNames from 'classnames'; +import classNames from "classnames"; -import { ArcProgress } from '~/components/input/ArcProgress'; -import { Icon } from '~/components/input/Icon'; -import { IFile } from '~/types'; +import { ArcProgress } from "~/components/input/ArcProgress"; +import { Icon } from "~/components/input/Icon"; -import styles from './styles.module.scss'; +import styles from "./styles.module.scss"; interface IProps { - id?: IFile['id']; + id?: string; title?: string; progress?: number; - onDrop?: (file_id: IFile['id']) => void; + onDrop?: (file_id: string) => void; is_uploading?: boolean; }