@@ -198,6 +198,58 @@ listWithKey vals mkChild = do
198 liftIO $ putStrLn "Triggering newChildren done"
198 liftIO $ putStrLn "Triggering newChildren done"
199 holdDyn Map.empty $ fmap (fmap (fst . fst)) newChildren
199 holdDyn Map.empty $ fmap (fmap (fst . fst)) newChildren
201+listWithKey' :: forall t m k v a. (Ord k, MonadWidget t m) => Map k v -> Event t (Map k (Maybe v)) -> (k -> v -> m a) -> m (Dynamic t (Map k a))
202+listWithKey' initialVals valsChanged mkChild = do
204+ startPlaceholder <- text' ""
205+ endPlaceholder <- text' ""
206+ (newChildren, newChildrenTriggerRef) <- newEventWithTriggerRef
207+-- performEvent_ $ fmap (const $ return ()) newChildren --TODO: Get rid of this hack
208+ runWidget <- getRunWidget
209+ let buildChild :: DocumentFragment -> k -> v -> WidgetHost m ((a, (Text, Text)), Event t (WidgetHost m ()))
210+ buildChild df k v = runWidget df $ do
211+ childStart <- text' ""
212+ result <- mkChild k v
213+ childEnd <- text' ""
214+ return (result, (childStart, childEnd))
215+ Just df <- liftIO $ documentCreateDocumentFragment doc
216+ initialState <- liftWidgetHost $ iforM initialVals $ buildChild df
217+ children <- hold initialState $ traceEventWith (\x -> "newChildren: " <> show (Map.size x)) newChildren
218+ addVoidAction $ switch $ fmap (mergeWith (>>) . map snd . Map.elems) children
219+ Just p <- liftIO $ nodeGetParentNode endPlaceholder
220+ liftIO $ nodeInsertBefore p (Just df) (Just endPlaceholder)
221+ addVoidAction $ flip fmap valsChanged $ \newVals -> do
222+ curState <- sample children
223+ --TODO: Should we remove the parent from the DOM first to avoid reflows?
224+ newState <- liftM (Map.mapMaybe id) $ iforM (align curState newVals) $ \k -> \case
225+ These ((_, (start, end)), _) Nothing -> do -- Deleting child
226+ liftIO $ deleteBetweenInclusive start end
228+ These ((_, (start, end)), _) (Just v) -> do -- Replacing existing child
229+ liftIO $ deleteBetweenExclusive start end
230+ Just df <- liftIO $ documentCreateDocumentFragment doc
231+ s <- buildChild df k v
232+ Just p <- liftIO $ nodeGetParentNode end
233+ liftIO $ nodeInsertBefore p (Just df) (Just end)
235+ That Nothing -> return Nothing -- Deleting non-existent child
236+ That (Just v) -> do -- Creating new child
237+ Just df <- liftIO $ documentCreateDocumentFragment doc
238+ s <- buildChild df k v
239+ let placeholder = case Map.lookupGT k curState of
240+ Nothing -> endPlaceholder
241+ Just (_, ((_, (start, _)), _)) -> start
242+ Just p <- liftIO $ nodeGetParentNode placeholder
243+ liftIO $ nodeInsertBefore p (Just df) (Just placeholder)
245+ This state -> do -- No change
247+ liftIO $ putStrLn "Triggering newChildren"
248+ liftIO $ putStrLn . ("newChildrenTriggerRef is Just? " <>) . show . isJust =<< readRef newChildrenTriggerRef
249+ runFrameWithTriggerRef newChildrenTriggerRef newState
250+ liftIO $ putStrLn "Triggering newChildren done"
251+ holdDyn Map.empty $ fmap (fmap (fst . fst)) newChildren
201selectViewListWithKey_ :: forall t m k v a. (MonadWidget t m, Ord k) => Dynamic t k -> Dynamic t (Map k v) -> (k -> Dynamic t v -> Dynamic t Bool -> m (Event t a)) -> m (Event t k)
253selectViewListWithKey_ :: forall t m k v a. (MonadWidget t m, Ord k) => Dynamic t k -> Dynamic t (Map k v) -> (k -> Dynamic t v -> Dynamic t Bool -> m (Event t a)) -> m (Event t k)
202selectViewListWithKey_ selection vals mkChild = do
254selectViewListWithKey_ selection vals mkChild = do
203 let selectionDemux = demux selection -- For good performance, this value must be shared across all children
255 let selectionDemux = demux selection -- For good performance, this value must be shared across all children