pkamenarsky / replica

A remote virtual DOM library for Haskell
BSD 3-Clause "New" or "Revised" License
139 stars 14 forks source link

Basic example? #25

Open seanhess opened 10 months ago

seanhess commented 10 months ago

Hi there, I'm revisiting a LiveView-esque framework I was toying with after a few years. I found replica, and I think the idea of having a lower-level remote VDOM library is fantastic. I'd like to get it running and see if it makes sense to build on top of it.

I can't figure out how to get a basic example working. How can I make an app where a button changes the message? I'm particular confused by the separate "fire" and "io" parts of step. If the action/io part returns a Just (IO ()) then it loops forever.

Thanks for your help!

{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE OverloadedStrings #-}

module Example where

import Data.Text (Text)
import Network.Wai.Handler.Replica as Replica
import Network.Wai.Handler.Warp as Warp
import Network.WebSockets.Connection (defaultConnectionOptions)
import Replica.VDOM as V
import qualified Replica.VDOM.Render as R
import Replica.VDOM.Types

newtype State = State Text
type Session = ()

example :: IO ()
example = do
  putStrLn "http://localhost:3002"
  Warp.run 3002 $ Replica.app (V.defaultIndex "Title" []) defaultConnectionOptions id getInitial getSession step
 where
  getInitial :: IO State
  getInitial = pure $ State "NONE"

  getSession :: Context -> IO Session
  getSession _ = pure ()

  step :: (Context -> State -> Session -> IO (V.HTML, Event -> Maybe (IO ()), IO (Maybe State)))
  step _ (State msg) _ = do
    pure (newDom, fire, action)
   where
    -- pure (newDom, doStuff)

    fire :: Event -> Maybe (IO ())
    fire ev = fireEvent newDom (evtPath ev) (evtType ev) (DOMEvent (evtEvent ev))

    action :: IO (Maybe State)
    action = do
      putStrLn "ACTION"
      -- pure $ Just $ State "new message"
      pure Nothing

    myStuff :: DOMEvent -> IO ()
    myStuff ev = do
      print "MY STUFF!"

    newDom =
      [ VNode "div" mempty Nothing [VText msg]
      , VNode "button" [("id", AText "woot"), ("click", AEvent (EventOptions True False False) myStuff)] Nothing [VText "Button"]
      ]
ludat commented 7 months ago

I've been trying to use this library and I've found the way to make this example work, there are two things wrong: