|
|
|
@@ -1,9 +1,11 @@ |
|
|
|
import { DndContext, |
|
|
|
DragOverlay, |
|
|
|
MouseSensor, |
|
|
|
TouchSensor, |
|
|
|
useDroppable, |
|
|
|
useSensor, |
|
|
|
useSensors } from '@dnd-kit/core' |
|
|
|
import { restrictToWindowEdges } from '@dnd-kit/modifiers' |
|
|
|
import axios from 'axios' |
|
|
|
import toCamel from 'camelcase-keys' |
|
|
|
import { AnimatePresence, motion } from 'framer-motion' |
|
|
|
@@ -11,6 +13,7 @@ import { useEffect, useRef, useState } from 'react' |
|
|
|
import { Link } from 'react-router-dom' |
|
|
|
|
|
|
|
import DraggableDroppableTagRow from '@/components/DraggableDroppableTagRow' |
|
|
|
import TagLink from '@/components/TagLink' |
|
|
|
import TagSearch from '@/components/TagSearch' |
|
|
|
import SectionTitle from '@/components/common/SectionTitle' |
|
|
|
import SubsectionTitle from '@/components/common/SubsectionTitle' |
|
|
|
@@ -152,6 +155,7 @@ type Props = { post: Post | null } |
|
|
|
|
|
|
|
|
|
|
|
export default (({ post }: Props) => { |
|
|
|
const [activeTagId, setActiveTagId] = useState<number | null> (null) |
|
|
|
const [dragging, setDragging] = useState (false) |
|
|
|
const [saving, setSaving] = useState (false) |
|
|
|
const [tags, setTags] = useState ({ } as TagByCategory) |
|
|
|
@@ -304,7 +308,9 @@ export default (({ post }: Props) => { |
|
|
|
<TagSearch/> |
|
|
|
<DndContext |
|
|
|
sensors={sensors} |
|
|
|
onDragStart={() => { |
|
|
|
onDragStart={e => { |
|
|
|
if (e.active.data.current?.kind === 'tag') |
|
|
|
setActiveTagId (e.active.data.current?.tagId ?? null) |
|
|
|
setDragging (true) |
|
|
|
suppressClickRef.current = true |
|
|
|
document.body.style.userSelect = 'none' |
|
|
|
@@ -316,15 +322,18 @@ export default (({ post }: Props) => { |
|
|
|
}, { capture: true, once: true }) |
|
|
|
}} |
|
|
|
onDragCancel={() => { |
|
|
|
setActiveTagId (null) |
|
|
|
setDragging (false) |
|
|
|
document.body.style.userSelect = '' |
|
|
|
suppressClickRef.current = false |
|
|
|
}} |
|
|
|
onDragEnd={e => { |
|
|
|
onDragEnd={async e => { |
|
|
|
setActiveTagId (null) |
|
|
|
setDragging (false) |
|
|
|
onDragEnd (e) |
|
|
|
await onDragEnd (e) |
|
|
|
document.body.style.userSelect = '' |
|
|
|
}}> |
|
|
|
}} |
|
|
|
modifiers={[restrictToWindowEdges]}> |
|
|
|
<motion.div key={post?.id ?? 0} layout> |
|
|
|
{CATEGORIES.map ((cat: Category) => ((tags[cat] ?? []).length > 0 || dragging) && ( |
|
|
|
<motion.div layout className="my-3" key={cat}> |
|
|
|
@@ -385,6 +394,15 @@ export default (({ post }: Props) => { |
|
|
|
</ul> |
|
|
|
</div>)} |
|
|
|
</motion.div> |
|
|
|
|
|
|
|
<DragOverlay adjustScale={false}> |
|
|
|
<div className="pointer-events-none"> |
|
|
|
{activeTagId != null && (() => { |
|
|
|
const tag = findTag (tags, activeTagId) |
|
|
|
return tag && <TagLink tag={tag}/> |
|
|
|
}) ()} |
|
|
|
</div> |
|
|
|
</DragOverlay> |
|
|
|
</DndContext> |
|
|
|
</SidebarComponent>) |
|
|
|
}) satisfies FC<Props> |