Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic example? #25

Open
seanhess opened this issue Oct 6, 2023 · 1 comment
Open

Basic example? #25

seanhess opened this issue Oct 6, 2023 · 1 comment

Comments

@seanhess
Copy link

seanhess commented Oct 6, 2023

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
Copy link

ludat commented Jan 7, 2024

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

  • the name of the attribute for click should be "onclick" instead, since on the client only attrs that start with on are considered for event handling
  • the action callback should never return a Nothing. A Nothing means that the websocket will be closed by the backend (and it's never opened again), AFAICT the best value for that here is forever $ threadDelay 1_000_000

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants