Skip to content

Instantly share code, notes, and snippets.

@psfblair
Last active June 24, 2016 19:29
Show Gist options
  • Select an option

  • Save psfblair/2a15a2cf82540fd0405b76715492108c to your computer and use it in GitHub Desktop.

Select an option

Save psfblair/2a15a2cf82540fd0405b76715492108c to your computer and use it in GitHub Desktop.
Import Directory
Import Store
-- MODEL
{- Each new workflow requires:
1. A new case of Workflow
2. A new field in the model holding the workflow's state
3. An init value of that field in init (not shown; it's uninteresting)
-}
type Workflow
= DirectoryWorkflow
| StoreWorkflow
type alias Model =
{ activeWorkflow: Workflow
, directoryModel: Directory.Model
, storeModel: Store.Model
}
-- UPDATE
{- Each new workflow requires:
1. A new case of Msg to wrap its messages
2. A new case match in update to dispatch its messages
3. A new handleXXXMsg function to determine if the relevant workflow is active before dispatch.
-}
type Msg
= DirectoryMsg Directory.Msg
| StoreMsg Store.Msg
-- Omitting complications of messages that switch the active workflow
update :: Msg -> Model -> Model
update msg model =
case msg of
DirectoryMsg innerMsg -> handleDirectoryMsg innerMsg model
StoreMsg innerMsg -> handleStoreMsg innerMsg model
handleDirectoryMsg :: Directory.Msg -> Model -> Model
handleDirectoryMsg dirmsg {activeWorkflow, directoryModel} as model =
case activeWorkflow of
DirectoryWorkflow -> { model | directoryModel = Directory.update dirmsg directoryModel }
_ -> model
handleStoreMsg :: Store.Msg -> Model -> Model
handleStoreMsg storemsg {activeWorkflow, storeModel} as model =
case activeWorkflow of
StoreWorkflow -> { model | storeModel = Store.update storemsg storeModel }
_ -> model
-- SUBSCRIPTIONS
{- Each new workflow requires:
1. An entry in the messageWorkflows dict for each server-side message type
that the workflow can handle. These types are represented by strings in
JSON coming in from the server.
2. A case in eventToMsg wrapping an incoming EventFromServer in the wrapper
type for messages belonging to that workflow.
-}
type alias EventFromServer =
{ eventType: String
, data: Json.Decode.Value
}
port eventsFromServer : (EventFromServer -> msg) -> Sub msg
subscriptions : Model -> Sub Msg
subscriptions model = eventsFromServer eventToMsg
eventToMsg : EventFromServer -> Msg
eventToMsg eventFromServer =
case eventFromServer.eventType |> Dict.get messageWorkflows of
DirectoryWorkflow ->
Directory.fromServerEvent eventFromServer |> DirectoryMsg
StoreWorkflow ->
Store.fromServerEvent eventFromServer |> StoreMsg
messageWorkflows : Dict String Workflow
messageWorkflows =
Dict.fromList
[ ("directoryListing", DirectoryWorkflow)
, ("cart" StoreWorkflow)
]
-- VIEW
{- Each new workflow requires a new case.
-}
view :: Model -> Html Msg
view {activeWorkflow} as model =
case activeWorkflow of
DirectoryWorkflow -> Directory.view model.directoryModel |> App.map DirectoryMsg
StoreWorkflow -> Store.view model.storeModel |> App.map StoreMsg
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment