Last active
July 19, 2016 18:58
-
-
Save note89/d09dd227a151cac0ef6883fac411276a to your computer and use it in GitHub Desktop.
Elm websockets controller
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module App.State exposing (..) | |
{- | |
We need the URL for the websocket. This will be the phoenix server url, then | |
the route for the socket, then "websocket" because that's the transport we're | |
communicating with. | |
-} | |
socketServer : String | |
socketServer = | |
"ws://localhost:4000/socket/websocket" | |
{- | |
initPhxSocket uses Phoenix.Socket.init on the socketServer, and we pipe it | |
through Phoenix.Socket.withDebug so we can get debug information out of it. | |
This will print every incoming Phoenix message to the console. | |
-} | |
initPhxSocket : Phoenix.Socket.Socket Msg | |
initPhxSocket = | |
Phoenix.Socket.init socketServer | |
subscriptions : Model -> Sub Msg | |
subscriptions model = | |
Phoenix.Socket.listen model.phxSocket PhoenixMsg | |
processPhx : Phx.Msg -> Model -> ( Model, Cmd Msg ) | |
processPhx msg model = | |
case msg of | |
Phx.NoOp -> | |
model ! [] | |
Phx.JoinChannel ( events, channel, component ) -> | |
let | |
payload = | |
JE.object [ ( "guardian_token", JE.string model.guardian_token ) ] | |
phxChannel = | |
Phoenix.Channel.init channel | |
|> Phoenix.Channel.withPayload payload | |
sendTo = | |
case component of | |
Phx.Chat -> | |
(Chat channel << CT.ReceiveMessage) | |
Phx.Notification -> | |
(Notification << NT.ReceiveNotification) | |
phxSocket = | |
List.foldl (\event socket -> Phoenix.Socket.on event channel sendTo socket) model.phxSocket events | |
( phxSocket', phxCmd ) = | |
phxSocket | |
|> Phoenix.Socket.join phxChannel | |
in | |
( { model | phxSocket = phxSocket' }, Cmd.map PhoenixMsg phxCmd ) | |
Phx.LeaveChannel channel -> | |
let | |
( phxSocket, phxCmd ) = | |
Phoenix.Socket.leave channel model.phxSocket | |
in | |
{ model | phxSocket = phxSocket } ! [ Cmd.map PhoenixMsg phxCmd ] | |
Phx.SendMessage ( msgType, channel, payload ) -> | |
let | |
push' = | |
Phoenix.Push.init msgType channel | |
|> Phoenix.Push.withPayload payload | |
( phxSocket', phxCmd ) = | |
Phoenix.Socket.push push' model.phxSocket | |
in | |
{ model | phxSocket = phxSocket' } ! [ Cmd.map PhoenixMsg phxCmd ] | |
processChat : CT.OutMsg -> Model -> ( Model, Cmd Msg ) | |
processChat msg model = | |
case msg of | |
CT.OnNoOp -> | |
model ! [] | |
CT.OnClose channelId -> | |
let | |
( model1, fx1 ) = | |
update (RemoveChat channelId) model | |
( model2, fx2 ) = | |
processPhx (Phx.LeaveChannel channelId) model1 | |
in | |
model2 ! [ fx1, fx2 ] | |
CT.ToPhx phxMsg -> | |
processPhx phxMsg model | |
update : Msg -> Model -> ( Model, Cmd Msg ) | |
update msg model = | |
case msg of | |
NoOp -> | |
( model, Cmd.none ) | |
Notification subMsg -> | |
let | |
( ( notification', cmdFromNotification ), outMsg ) = | |
NS.update subMsg model.notification model.user | |
model' = | |
{ model | notification = notification' } | |
( model'', cmdFromPhx ) = | |
processNotification outMsg model' | |
in | |
model'' | |
! [ cmdFromPhx | |
, Cmd.map Notification cmdFromNotification | |
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Common.Phx exposing (..) | |
import Json.Encode as JE | |
type Msg | |
= NoOp | |
| JoinChannel ( List String, String, Component ) | |
| SendMessage ( String, String, JE.Value ) | |
| LeaveChannel String | |
type Component | |
= Chat | |
| Notification |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Notification.State exposing (..) | |
import Notification.Types exposing (..) | |
import App.Types as AT | |
import User.Types as User | |
import Phoenix.Socket | |
import Phoenix.Channel | |
import Phoenix.Push | |
import Json.Encode as JE | |
import Json.Decode as JD exposing ((:=)) | |
import Ports | |
import Common.Phx as Phx | |
initialModel = | |
() | |
type alias Notification = | |
{ text : String | |
, id : String | |
} | |
notificationDecoder = | |
JD.object2 Notification | |
("text" := JD.string) | |
("id" := JD.string) | |
update : Msg -> Model -> User.Model -> ( ( Model, Cmd Msg ), OutMsg ) | |
update msg model user = | |
case msg of | |
NoOp -> | |
( model ! [], OnNoOp ) | |
OnStart -> | |
update JoinChannel model user | |
JoinChannel -> | |
let | |
msgs = | |
[ "new:event:notification", "new:group:notification" ] | |
channel = | |
"notifications:" ++ user.id | |
in | |
( model ! [] | |
, ToPhx <| Phx.JoinChannel ( msgs, channel, Phx.Notification ) | |
) | |
ReceiveNotification raw -> | |
let | |
_ = | |
Debug.log "raw" raw | |
in | |
case JD.decodeValue notificationDecoder raw of | |
Ok notification -> | |
( model ! [ Ports.toaster notification.text ] | |
, OnNoOp | |
) | |
Err error -> | |
let | |
_ = | |
Debug.log "error parsing notification" error | |
in | |
( model ! [], OnNoOp ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment