From dfe27307ddea9d6e95ce593dba313002fbbf3359 Mon Sep 17 00:00:00 2001
From: Albin Henriksson <albhe428@student.liu.se>
Date: Fri, 30 Apr 2021 20:54:04 +0200
Subject: [PATCH] Fix move slides on front-end

---
 .../PresentationEditorPage.tsx                | 48 +++++++++++++++----
 1 file changed, 39 insertions(+), 9 deletions(-)

diff --git a/client/src/pages/presentationEditor/PresentationEditorPage.tsx b/client/src/pages/presentationEditor/PresentationEditorPage.tsx
index ddbe7468..08d2ec7e 100644
--- a/client/src/pages/presentationEditor/PresentationEditorPage.tsx
+++ b/client/src/pages/presentationEditor/PresentationEditorPage.tsx
@@ -10,6 +10,7 @@ import { getCities } from '../../actions/cities'
 import { getEditorCompetition, setEditorSlideId, setEditorViewId } from '../../actions/editor'
 import { getTypes } from '../../actions/typesAction'
 import { useAppDispatch, useAppSelector } from '../../hooks'
+import { RichSlide } from '../../interfaces/ApiRichModels'
 import { renderSlideIcon } from '../../utils/renderSlideIcon'
 import { RemoveMenuItem } from '../admin/styledComp'
 import { Content, InnerContent } from '../views/styled'
@@ -50,6 +51,7 @@ interface CompetitionParams {
 const PresentationEditorPage: React.FC = () => {
   const { competitionId }: CompetitionParams = useParams()
   const dispatch = useAppDispatch()
+  const [slides, setSlides] = useState<RichSlide[]>([])
   const activeSlideId = useAppSelector((state) => state.editor.activeSlideId)
   const activeViewTypeId = useAppSelector((state) => state.editor.activeViewTypeId)
   const competition = useAppSelector((state) => state.editor.competition)
@@ -60,6 +62,10 @@ const PresentationEditorPage: React.FC = () => {
     dispatch(getCities())
   }, [])
 
+  useEffect(() => {
+    setSlides(competition.slides)
+  }, [competition])
+
   const setActiveSlideId = (id: number) => {
     dispatch(setEditorSlideId(id))
   }
@@ -111,16 +117,38 @@ const PresentationEditorPage: React.FC = () => {
   }
 
   const onDragEnd = async (result: DropResult) => {
-    // dropped outside the list
-    if (!result.destination) {
+    // dropped outside the list or same place
+    if (!result.destination || result.destination.index === result.source.index) {
       return
     }
     const draggedIndex = result.source.index
-    const draggedSlideId = competition.slides.find((slide) => slide.order === draggedIndex)?.id
+    const draggedSlideId = slides.find((slide) => slide.order === draggedIndex)?.id
+    const slidesCopy = slides
+    const diff = result.destination.index - result.source.index
+    slides.map((slide) => {
+      if (slide.order === draggedIndex && result.destination) {
+        slide.order = result.destination.index
+      } else if (
+        result.destination &&
+        diff > 0 &&
+        slide.order > result.source.index &&
+        slide.order <= result.destination.index
+      ) {
+        slide.order = slide.order - 1
+      } else if (
+        result.destination &&
+        diff < 0 &&
+        slide.order < result.source.index &&
+        slide.order >= result.destination.index
+      ) {
+        slide.order = slide.order + 1
+      }
+    })
+    setSlides(slidesCopy)
+
     if (draggedSlideId) {
       await axios
         .put(`/api/competitions/${competitionId}/slides/${draggedSlideId}/order`, { order: result.destination.index })
-        .then(() => dispatch(getEditorCompetition(competitionId)))
         .catch(console.log)
     }
   }
@@ -161,21 +189,23 @@ const PresentationEditorPage: React.FC = () => {
             <DragDropContext onDragEnd={onDragEnd}>
               <Droppable droppableId="droppable">
                 {(provided) => (
-                  <div key={provided.innerRef.toString()} ref={provided.innerRef} {...provided.droppableProps}>
-                    {competition.slides &&
-                      competition.slides.map((slide, index) => (
-                        <Draggable key={slide.order} draggableId={slide.id.toString()} index={index}>
+                  <div ref={provided.innerRef} {...provided.droppableProps}>
+                    {slides
+                      .sort((a, b) => (a.order > b.order ? 1 : -1))
+                      .map((slide, index) => (
+                        <Draggable key={slide.id} draggableId={slide.id.toString()} index={index}>
                           {(provided, snapshot) => (
                             <div ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
                               <SlideListItem
                                 divider
+                                key={slide.order}
                                 button
                                 selected={slide.id === activeSlideId}
                                 onClick={() => setActiveSlideId(slide.id)}
                                 onContextMenu={(event) => handleRightClick(event, slide.id)}
                               >
                                 {renderSlideIcon(slide)}
-                                <ListItemText primary={`Sida ${slide.order + 1}`} />
+                                <ListItemText primary={`Sida ${slide.id}`} />
                               </SlideListItem>
                             </div>
                           )}
-- 
GitLab