~sjm/builds-character

dc28e3c36fa16b7c63808609726e1f0ca628cf1f — Sam Marshall 2 years ago 3710596
chore: remove practice files
6 files changed, 0 insertions(+), 329 deletions(-)

D src/Counter.purs
D src/CounterParent.purs
D src/EmitterDOMEvents.purs
D src/EmitterTimer.purs
D src/HTTPRequest.purs
D src/ParentChild.purs
D src/Counter.purs => src/Counter.purs +0 -33
@@ 1,33 0,0 @@
module Counter where

import Prelude

import Data.Maybe (Maybe(..))
import Halogen as H
import Halogen.HTML as HH

data Query a
  = Increment a
  | GetCount (Int -> a)

type State = { count :: Int }

component :: forall i out m. H.Component Query i out m
component = H.mkComponent { initialState: \_ -> { count: 0 }
                          , render
                          , eval: H.mkEval $ H.defaultEval { handleQuery = handleQuery }}
            where

              render { count } =
                HH.div_
                  [ HH.text $ show count ]

              handleQuery :: forall action a. Query a -> H.HalogenM State action () out m (Maybe a)
              handleQuery = case _ of
                Increment a -> do
                  H.modify_ \s -> s { count = s.count + 1 }
                  pure (Just a)

                GetCount reply -> do
                  { count } <- H.get
                  pure (Just (reply count))

D src/CounterParent.purs => src/CounterParent.purs +0 -34
@@ 1,34 0,0 @@
module CounterParent where

import Prelude

import Counter as Counter
import Data.Maybe (Maybe(..))
import Halogen as H
import Halogen.HTML as HH
import Type.Proxy (Proxy(..))

type Slots = ( counter :: H.Slot Counter.Query Void Unit )

_counter = Proxy :: Proxy "counter"

data Action = Initialize

parent :: forall q i o m. H.Component q i o m
parent  = H.mkComponent { initialState: identity
                        , render
                        , eval: H.mkEval $ H.defaultEval { handleAction = handleAction
                                                         , initialize = Just Initialize }}
          where

            render :: forall s. s -> H.ComponentHTML Action Slots m
            render _ =
              HH.div_
                [ HH.slot_ _counter unit Counter.component unit ]

            handleAction :: forall s. Action -> H.HalogenM s Action Slots o m Unit
            handleAction = case _ of
              Initialize -> do
                startCount <- H.request _counter unit Counter.GetCount

                H.tell _counter unit Counter.Increment

D src/EmitterDOMEvents.purs => src/EmitterDOMEvents.purs +0 -63
@@ 1,63 0,0 @@
module EmitterDOMEvents where

import Prelude

import Data.Maybe (Maybe(..))
import Data.String as String
import Effect.Aff.Class (class MonadAff)
import Halogen as H
import Halogen.HTML as HH
import Halogen.Query.Event (eventListener)
import Web.Event.Event as E
import Web.HTML (window)
import Web.HTML.HTMLDocument as HTMLDocument
import Web.HTML.Window (document)
import Web.UIEvent.KeyboardEvent as KE
import Web.UIEvent.KeyboardEvent.EventTypes as KET

type State = { chars :: String }

data Action
  = Initialize
  | HandleKey H.SubscriptionId KE.KeyboardEvent

component :: forall q i o m. MonadAff m => H.Component q i o m
component =
  H.mkComponent { initialState
                , render
                , eval : H.mkEval $ H.defaultEval { handleAction = handleAction
                                                  , initialize = Just Initialize}
                }

initialState :: forall input. input -> State
initialState _ = { chars: "" }

render :: forall m. State -> H.ComponentHTML Action () m
render state = HH.div_ [ HH.p_ [ HH.text "Hold down shift and type some characters" ]
                       , HH.p_ [ HH.text "Press ENTER to remove the listener and clear input" ]
                       , HH.p_ [ HH.text state.chars ]]

handleAction :: forall output m. MonadAff m => Action -> H.HalogenM State Action () output m Unit
handleAction = case _ of
  Initialize -> do
    document <- H.liftEffect $ document =<< window
    H.subscribe' \sid ->
      eventListener
        KET.keyup
        (HTMLDocument.toEventTarget document)
        (map (HandleKey sid) <<< KE.fromEvent)

  HandleKey sid ev
    | KE.shiftKey ev -> do
      H.liftEffect $ E.preventDefault $ KE.toEvent ev
      let char = KE.key ev
      when (String.length char == 1) do
        H.modify_ \st -> st { chars = st.chars <> char }

    | KE.key ev == "Enter" -> do
      H.liftEffect $ E.preventDefault (KE.toEvent ev)
      H.modify_ _ { chars = "" }
      H.unsubscribe sid

    | otherwise ->
      pure unit

D src/EmitterTimer.purs => src/EmitterTimer.purs +0 -48
@@ 1,48 0,0 @@
module EmitterTimer where

import Prelude

import Control.Monad.Rec.Class (forever)
import Data.Maybe (Maybe(..))
import Effect.Aff (Milliseconds(..))
import Effect.Aff as Aff
import Effect.Aff.Class (class MonadAff)
import Halogen as H
import Halogen.HTML as HH
import Halogen.Subscription as HS

data Action = Initialize | Tick

type State = Int

component :: forall query input output m. MonadAff m => H.Component query input output m
component =
  H.mkComponent
        { initialState
        , render
        , eval: H.mkEval $ H.defaultEval { handleAction = handleAction
                                         , initialize = Just Initialize }}

initialState :: forall input. input -> State
initialState _ = 0

render :: forall m. State -> H.ComponentHTML Action () m
render seconds =
  HH.text ("You've been here for " <> show seconds <> " seconds.")

handleAction :: forall output m. MonadAff m => Action -> H.HalogenM State Action () output m Unit
handleAction = case _ of
  Initialize -> do
    _ <- H.subscribe =<< timer Tick
    pure unit

  Tick ->
    H.modify_ \s -> s + 1

timer :: forall m a. MonadAff m => a -> m (HS.Emitter a)
timer val = do
  { emitter, listener } <- H.liftEffect HS.create
  _ <- H.liftAff $ Aff.forkAff $ forever do
    Aff.delay $ Milliseconds 1000.0
    H.liftEffect $ HS.notify listener val
  pure emitter

D src/HTTPRequest.purs => src/HTTPRequest.purs +0 -76
@@ 1,76 0,0 @@
module HTTPRequest where

import Prelude

import Affjax as AX
import Affjax.ResponseFormat as AXRF
import Data.Either (hush)
import Data.Maybe (Maybe(..))
import Effect.Aff.Class (class MonadAff)
import Halogen as H
import Halogen.HTML as HH
import Halogen.HTML.Events as HE
import Halogen.HTML.Properties as HP
import Web.Event.Event (Event)
import Web.Event.Event as Event

type State =
  { loading :: Boolean
  , username :: String
  , result :: Maybe String
  }

data Action
  = SetUsername String
  | MakeRequest Event

component :: forall query input output m. MonadAff m => H.Component query input output m
component =
  H.mkComponent
    { initialState
    , render
    , eval : H.mkEval $ H.defaultEval { handleAction = handleAction }}

initialState :: forall input. input -> State
initialState _ = { loading: false, username: "", result: Nothing }

render :: forall m. State -> H.ComponentHTML Action () m
render st =
  HH.form
    [ HE.onSubmit \ev -> MakeRequest ev  ]
    [ HH.h1_ [ HH.text "Look up GitLab user" ]
    , HH.label_
      [ HH.div_ [ HH.text "Enter Username: " ]
      , HH.input
        [ HP.value st.username
        , HE.onValueInput \str -> SetUsername str
        ]
      ]
    , HH.button
        [ HP.disabled st.loading
        , HP.type_ HP.ButtonSubmit
        ]
        [ HH.text "Fetch info" ]
    , HH.p_
        [ HH.text $ if st.loading then "Working..." else "" ]
    , HH.div_
        case st.result of
          Nothing -> []
          Just res ->
            [ HH.h2_
                [ HH.text "Response:" ]
            , HH.pre_
                [ HH.code_ [ HH.text res ] ]
            ]
    ]

handleAction :: forall output m. MonadAff m => Action -> H.HalogenM State Action () output m Unit
handleAction = case _ of
  SetUsername username -> do
    H.modify_ _ { username = username, result = Nothing }
  MakeRequest event -> do
    H.liftEffect $ Event.preventDefault event
    username <- H.gets _.username
    H.modify_ _ { loading = true }
    response <- H.liftAff $ AX.get AXRF.string ("https://api.github.com/users/" <> username)
    H.modify_ _ { loading = false, result = map _.body (hush response) }

D src/ParentChild.purs => src/ParentChild.purs +0 -75
@@ 1,75 0,0 @@
module ParentChild where

import Prelude

import Control.Monad.Rec.Class (forever)
import Data.Maybe (Maybe(..))
import Effect.Aff (Milliseconds(..))
import Effect.Aff as Aff
import Effect.Aff.Class (class MonadAff)
import Halogen as H
import Halogen.HTML as HH
import Halogen.HTML.Events as HE
import Halogen.Subscription as HS
import Type.Proxy (Proxy(..))

type Slots = ( button :: forall q. H.Slot q ButtonOutput Int )

_button = Proxy :: Proxy "button"

type ParentState = { count :: Int }
data ParentAction = Initialize | Increment | Reset | HandleButton

parent :: forall query input output m. MonadAff m => H.Component query input output m
parent =
  H.mkComponent { initialState
                , render
                , eval: H.mkEval $ H.defaultEval { handleAction = handleAction, initialize = Just Initialize } }
  where
    initialState :: input -> ParentState
    initialState _ = { count: 0 }

    render :: ParentState -> H.ComponentHTML ParentAction Slots m
    render { count } = HH.div_ [ HH.slot _button 0 button { label: show count } \_ -> HandleButton ]

    handleAction :: ParentAction -> H.HalogenM ParentState ParentAction Slots output m Unit
    handleAction = case _ of
      Initialize -> do
        { emitter, listener } <- H.liftEffect HS.create
        void $ H.subscribe emitter
        void
          $ H.liftAff
          $ Aff.forkAff
          $ forever do
                Aff.delay $ Milliseconds 1000.0
                H.liftEffect $ HS.notify listener Increment

      Increment -> H.modify_ \st -> st { count = st.count + 1 }
      Reset -> H.modify_ \st -> { count: 0 }
      HandleButton -> handleAction Reset



type ButtonInput = { label :: String }
type ButtonState = { label :: String }
data ButtonAction = Receive ButtonInput | Click
data ButtonOutput = Clicked

button :: forall query m . H.Component query ButtonInput ButtonOutput m
button = H.mkComponent { initialState
                       , render
                       , eval: H.mkEval $ H.defaultEval { handleAction = handleAction
                                                        , receive = Just <<< Receive } }
         where
           initialState :: ButtonInput -> ButtonState
           initialState = identity

           render ::  ButtonState -> H.ComponentHTML ButtonAction () m
           render { label } = HH.button [ HE.onClick \_ -> Click  ] [ HH.text label ]

           handleAction :: ButtonAction -> H.HalogenM ButtonState ButtonAction () ButtonOutput m Unit
           handleAction = case _ of
             Receive input ->
               H.modify_ _ { label = input.label }

             Click -> H.raise Clicked