git.iko.soy/rowtype-yoga/psfp
on master help sign in
Finally resize works
8e9130cMark Eibes
components/src/Yoga/Grimoire/Component.purs+106−85
@@ -1,24 +1,27 @@
1module Yoga.Grimoire.Component where
1module Yoga.Grimoire.Component where
2
2
3import Prelude
3import Prelude
4−import Data.Array (mapWithIndex, zip, (!!))
4+import Data.Array (length, mapWithIndex, zip, (!!), (..))
5import Data.Array as Array
5import Data.Array as Array
6import Data.FoldableWithIndex (findWithIndex)
6import Data.FoldableWithIndex (findWithIndex)
7import Data.Interpolate as Interp
7import Data.Interpolate as Interp
8import Data.Lens (set)
8import Data.Lens (set)
9import Data.Lens.Index (ix)
9import Data.Lens.Index (ix)
10−import Data.Maybe (Maybe(..), fromMaybe)
10+import Data.Maybe (Maybe(..), fromMaybe, fromMaybe')
11import Data.Nullable (Nullable)
11import Data.Nullable (Nullable)
12import Data.Nullable as Nullable
12import Data.Nullable as Nullable
13import Data.Symbol (SProxy(..))
13import Data.Symbol (SProxy(..))
14import Data.Traversable (for, sequence)
14import Data.Traversable (for, sequence)
15import Data.Tuple.Nested ((/\), type (/\))
15import Data.Tuple.Nested ((/\), type (/\))
16+import Debug.Trace (spy)
16import Effect (Effect)
17import Effect (Effect)
18+import Effect.Class.Console (log)
17import Justifill (justifill)
19import Justifill (justifill)
20+import Partial.Unsafe (unsafeCrashWith)
18import React.Basic (ReactComponent)
21import React.Basic (ReactComponent)
19import React.Basic.DOM (css)
22import React.Basic.DOM (css)
20import React.Basic.Helpers (jsx)
23import React.Basic.Helpers (jsx)
21−import React.Basic.Hooks (Ref, component, element, readRef, useLayoutEffect, useRef, writeRef)
24+import React.Basic.Hooks (Ref, component, element, readRef, useLayoutEffect, useRef, useState, writeRef)
22import React.Basic.Hooks as React
25import React.Basic.Hooks as React
23import React.Basic.Hooks.Spring (animatedDiv, useSprings)
26import React.Basic.Hooks.Spring (animatedDiv, useSprings)
24import React.Basic.Hooks.UseGesture (useDrag, withDragProps)
27import React.Basic.Hooks.UseGesture (useDrag, withDragProps)
@@ -31,7 +34,6 @@ import Web.HTML.HTMLElement as HTMLElement
31import Yoga.Grid.Component as Grid
34import Yoga.Grid.Component as Grid
32import Yoga.Grimoire.Spell.Component as GrimoireSpell
35import Yoga.Grimoire.Spell.Component as GrimoireSpell
33import Yoga.Grimoire.Styles (styles)
36import Yoga.Grimoire.Styles (styles)
34−import Yoga.Helpers ((?||))
35import Yoga.Resize.Hook (useResize)
37import Yoga.Resize.Hook (useResize)
36import Yoga.Spell.Types (Spell)
38import Yoga.Spell.Types (Spell)
37import Yoga.Theme.Styles (makeStylesJSS, useTheme)
39import Yoga.Theme.Styles (makeStylesJSS, useTheme)
@@ -69,11 +71,80 @@ translate (x /\ y) { top, right, bottom, left, width, height } =
69 , height
71 , height
70 }
72 }
71
73
74+orDie msg =
75+ fromMaybe'
76+ (\_ -> unsafeCrashWith msg)
77+
78+idxOrThrow ∷ ∀ a. Array a -> Int -> a
79+idxOrThrow arr i = arr !! i # orDie (Interp.i "Invalid index " i " in array")
80+
81+infixl 8 idxOrThrow as !!!
82+
72−swap ∷ ∀ a. Int -> Int -> Array a -> Maybe (Array a)
83+swap ∷ ∀ a. Int -> Int -> Array a -> Array a
73−swap i j arr = do
84+swap i j arr = swapped # orDie "Couldn't swap"
85+ where
86+ swapped = do
74− valueI <- arr !! i
87+ valueI <- arr !! i
75− valueJ <- arr !! j
88+ valueJ <- arr !! j
76− pure $ (set (ix i) valueJ <<< set (ix j) valueI) arr
89+ pure $ (set (ix i) valueJ <<< set (ix j) valueI) arr
90+
91+springsteen init rectsRef positionsRef arg mx my down springs = do
92+ init
93+ rects <- readRef rectsRef
94+ positionsBefore <- readRef positionsRef
95+ let
96+ rectDragged = rects !!! (positionsBefore !!! arg)
97+ currentPosDragged = rectDragged # translate (mx /\ my)
98+ orderedRectsBefore = positionsBefore <#> (rects !!! _)
99+ overlapsOtherBefore = orderedRectsBefore # findWithIndex \i rect -> i /= arg && overlaps currentPosDragged rect
100+ case down, overlapsOtherBefore of
101+ false, Just { index } -> do
102+ let
103+ newPositions = swap arg index positionsBefore
104+ writeRef positionsRef $ spy "new posis" newPositions
105+ _, _ -> mempty
106+ -- alles gut bis hierher, glaube ich
107+ positions <- readRef positionsRef
108+ springs.set \i -> do
109+ let
110+ j = positions !!! i
111+ isTheDraggedOne = i == arg
112+ originalRect = rects !!! i
113+ currentRect = rects !!! j
114+ leftOffset = currentRect.left - originalRect.left
115+ topOffset = currentRect.top - originalRect.top
116+ case isTheDraggedOne, down, overlapsOtherBefore of
117+ true, true, _ ->
118+ { x: mx + leftOffset
119+ , y: my + topOffset
120+ , zIndex: 1
121+ , transform: "scale3d(1.1, 1.1, 1.1)"
122+ , borderRadius: "var(--s-2)"
123+ , height: "100px"
124+ , shadow: 20
125+ , immediate: \n -> n == "x" || n == "y" || n == "zIndex"
126+ }
127+ false, true, Just { index, value }
128+ | index == i ->
129+ { x: rectDragged.left - currentRect.left + leftOffset
130+ , y: rectDragged.top - currentRect.top + topOffset
131+ , zIndex: 0
132+ , shadow: 2
133+ , height: "100px"
134+ , transform: "scale3d(1.0, 1.0, 1.0)"
135+ , borderRadius: "var(--s-2)"
136+ , immediate: const false
137+ }
138+ _, _, _ ->
139+ { x: leftOffset
140+ , y: topOffset
141+ , shadow: 2
142+ , height: "100px"
143+ , borderRadius: "var(--s-2)"
144+ , zIndex: 0
145+ , transform: "scale3d(1.0, 1.0, 1.0)"
146+ , immediate: const false
147+ }
77
148
78makeComponent ∷ Effect (ReactComponent Props)
149makeComponent ∷ Effect (ReactComponent Props)
79makeComponent = do
150makeComponent = do
@@ -90,95 +161,45 @@ makeComponent = do
90 , shadow: 2
161 , shadow: 2
91 , borderRadius: "var(--s-2)"
162 , borderRadius: "var(--s-2)"
92 , zIndex: 0
163 , zIndex: 0
93− , immediate: const false
164+ , immediate: const true
94 , transform: "scale3d(1.0,1.0,1.0)"
165 , transform: "scale3d(1.0,1.0,1.0)"
95 }
166 }
96− springs <-
97− useSprings (Array.length props.spells) defaultSprings
167+ springs <- useSprings (Array.length props.spells) defaultSprings
98− nodeRefs <- useRef (props.spells $> Nullable.null)
168+ nodeRefs ∷ Ref (Array (Nullable (_))) <- useRef (props.spells $> Nullable.null)
169+ spells /\ updateSpells <- useState props.spells
99− positionsRef <- useRef ([] ∷ _ DOMRect)
170+ positionsRef <- useRef ([] ∷ _ Int)
100− originalPositionsRef <- useRef ([] ∷ _ DOMRect)
171+ rectsRef <- useRef ([] ∷ _ DOMRect)
101 initialisedRef <- useRef false
172 initialisedRef <- useRef false
102 windowSize <- useResize
173 windowSize <- useResize
103 let
174 let
104 init = do
175 init = do
105 initialised <- readRef initialisedRef
176 initialised <- readRef initialisedRef
106 unless initialised do
177 unless initialised do
178+ log "initialising"
107− rects <- getRects nodeRefs
179+ refs <- getRects nodeRefs
180+ positions <- readRef positionsRef
108− writeRef positionsRef (rects <#> fromMaybe emptyDomRect)
181+ writeRef positionsRef (0 .. (length props.spells - 1))
182+ let
109− writeRef originalPositionsRef (rects <#> fromMaybe emptyDomRect)
183+ rects = refs <#> fromMaybe emptyDomRect
184+ writeRef rectsRef rects
110 writeRef initialisedRef true
185 writeRef initialisedRef true
111 useLayoutEffect windowSize do
186 useLayoutEffect windowSize do
112− springs.stop
113− writeRef initialisedRef false
114 springs.set defaultSprings
187 springs.set defaultSprings
188+ positionsBefore <- readRef positionsRef
189+ when (positionsBefore == []) do
190+ log "resetting positions"
191+ writeRef positionsRef (0 .. (length props.spells - 1))
192+ positions <- readRef positionsRef
193+ updateSpells (const $ positions <#> (spells !!! _))
194+ nodes <- readRef nodeRefs
195+ writeRef nodeRefs (positions <#> (nodes !!! _))
196+ writeRef initialisedRef false
197+ init
115 mempty
198 mempty
116 theme ∷ CSSTheme <- useTheme
199 theme ∷ CSSTheme <- useTheme
117 bindDragProps <-
200 bindDragProps <-
118− useDrag (justifill { filterTaps: true }) \{ arg, down, movement: mx /\ my } -> do
201+ useDrag (justifill { filterTaps: true }) \{ arg, down, movement: mx /\ my } ->
119− init
202+ springsteen init rectsRef positionsRef arg mx my down springs
120− originalPositions <- readRef originalPositionsRef
121− positionsBefore <- readRef positionsRef
122− let
123− originalPosDraggedBefore = positionsBefore !! arg ?|| emptyDomRect
124−
125− currentPosDraggedBefore = originalPosDraggedBefore # translate (mx /\ my)
126−
127− overlapsOtherBefore = positionsBefore # findWithIndex \i' pos -> i' /= arg && overlaps currentPosDraggedBefore pos
128− case down, overlapsOtherBefore of
129− false, Just { index, value } -> do
130− let
131− swapped = swap arg index positionsBefore ?|| positionsBefore
132− writeRef positionsRef swapped
133− _, _ -> mempty
134− positions <- readRef positionsRef
135− let
136− originalPosDragged = positions !! arg ?|| emptyDomRect
137−
138− currentPosDragged = originalPosDragged # translate (mx /\ my)
139−
140− overlapsOther = positions # findWithIndex \i' pos -> i' /= arg && overlaps currentPosDragged pos
141− springs.set \i -> do
142− let
143− iPos = positions !! i ?|| emptyDomRect
144−
145− origIPos = originalPositions !! i ?|| emptyDomRect
146−
147− leftOffset = if iPos == origIPos then 0.0 else iPos.left - origIPos.left
148−
149− topOffset = if iPos == origIPos then 0.0 else iPos.top - origIPos.top
150− case i == arg, down, overlapsOther of
151− false, true, Just { index, value }
152− | index == i ->
153− { x: originalPosDragged.left - value.left + leftOffset
154− , y: originalPosDragged.top - value.top + topOffset
155− , zIndex: 0
156− , shadow: 2
157− , height: "100px"
158− , transform: "scale3d(1.0, 1.0, 1.0)"
159− , borderRadius: "var(--s-2)"
160− , immediate: const false
161− }
162− true, true, _ ->
163− { x: mx + leftOffset
164− , y: my + topOffset
165− , zIndex: 1
166− , transform: "scale3d(1.1, 1.1, 1.1)"
167− , borderRadius: "var(--s-2)"
168− , height: "100px"
169− , shadow: 20
170− , immediate: \n -> n == "x" || n == "y" || n == "zIndex"
171− }
172− _, _, _ ->
173− { x: leftOffset
174− , y: topOffset
175− , shadow: 2
176− , height: "100px"
177− , borderRadius: "var(--s-2)"
178− , zIndex: 0
179− , transform: "scale3d(1.0, 1.0, 1.0)"
180− , immediate: const false
181− }
182 let
203 let
183 renderSpells =
204 renderSpells =
184 mapWithIndex \i (spell /\ style) ->
205 mapWithIndex \i (spell /\ style) ->
@@ -196,7 +217,7 @@ makeComponent = do
196 `withDragProps`
217 `withDragProps`
197 bindDragProps i
218 bindDragProps i
198 pure
219 pure
199− $ jsx grid {} (renderSpells (props.spells `zip` springs.styles))
220+ $ jsx grid {} (renderSpells (spells `zip` springs.styles))
200
221
201foreign import unsafeArraySetAt ∷ ∀ a. Int -> a -> Array a -> Array a
222foreign import unsafeArraySetAt ∷ ∀ a. Int -> a -> Array a -> Array a
202
223