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