Skip to content
This repository has been archived by the owner on Apr 21, 2020. It is now read-only.

Private pusher channel #138

Merged
merged 24 commits into from
Jul 10, 2017
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
d3f5efb
WIP: Private pusher channel [skip ci]
bitamar Jul 7, 2017
a1348fc
Re-adding offline interop [skip ci]
bitamar Jul 7, 2017
ee7995c
Pusher auth [skip ci]
bitamar Jul 7, 2017
0ade019
Subscribing to the private channel [skip ci]
bitamar Jul 8, 2017
4f1c80a
Cleaning up me endpoint [skip ci]
bitamar Jul 8, 2017
b44ccbf
Fetching user's pusher channel from backend [skip ci]
bitamar Jul 8, 2017
5b62d1b
Logging into pusher only after user is fetched [skip ci]
bitamar Jul 8, 2017
d0b4b32
Updating dummyUser
bitamar Jul 8, 2017
54475bf
Sniffer fixes
bitamar Jul 8, 2017
9a79611
Merge branch 'master' into 123-private-pusher-channel
bitamar Jul 9, 2017
0a74252
Cleaning up pusher login call [skip ci]
bitamar Jul 9, 2017
a539ed1
Adding private note on items [skip ci]
bitamar Jul 9, 2017
95384b8
Displaying private note
bitamar Jul 9, 2017
006bb53
Removing unused pusher parts, and wiring pusher logout
bitamar Jul 9, 2017
fde3b02
Fixing pusher test
bitamar Jul 9, 2017
7e77f7c
Updating the pusher model when calling pusherLogin and pusherLogout […
bitamar Jul 10, 2017
3babb2e
Ordering msgs [skip ci]
bitamar Jul 10, 2017
034394c
Cleaning up item view [skip ci]
bitamar Jul 10, 2017
e6d7ef6
cleanup login message creation [skip ci]
bitamar Jul 10, 2017
14507ff
showMaybe privateNote [skip ci]
bitamar Jul 10, 2017
47cc8ff
Fixes
bitamar Jul 10, 2017
73b2f88
Replacing "access private pusher channel" with "access private fields"
bitamar Jul 10, 2017
7dcf9be
Adding information about the private pusher channel to the readme
bitamar Jul 10, 2017
6c49099
Updating pusher description
bitamar Jul 10, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions client/src/elm/App/Model.elm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import App.PageType exposing (Page(..))
import Config.Model
import Date exposing (Date)
import Pages.Login.Model exposing (emptyModel, Model)
import Pusher.Model
import RemoteData exposing (RemoteData(..), WebData)
import ItemManager.Model exposing (emptyModel, Model)
import Time exposing (Time)
Expand All @@ -21,11 +22,13 @@ type Msg
= HandleOfflineEvent (Result String Bool)
| Logout
| MsgItemManager ItemManager.Model.Msg
| MsgPusher Pusher.Model.Msg
| PageLogin Pages.Login.Model.Msg
| SetActivePage Page
| SetCurrentDate Date
| Tick Time
| ToggleSideBar
| NoOp
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

order by alpha bet



type alias Model =
Expand All @@ -36,6 +39,7 @@ type alias Model =
, offline : Bool
, pageLogin : Pages.Login.Model.Model
, pageItem : ItemManager.Model.Model
, pusher : Pusher.Model.Model
, sidebarOpen : Bool
, user : WebData User
}
Expand All @@ -61,6 +65,7 @@ emptyModel =
, offline = False
, pageLogin = Pages.Login.Model.emptyModel
, pageItem = ItemManager.Model.emptyModel
, pusher = Pusher.Model.emptyModel
, sidebarOpen = False
, user = NotAsked
}
2 changes: 1 addition & 1 deletion client/src/elm/App/PageType.elm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module App.PageType exposing (Page(..))

{-| Prevent circula dependency.
{-| Prevent circular dependency.
-}


Expand Down
6 changes: 5 additions & 1 deletion client/src/elm/App/Test.elm
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ getPageAsAuthenticated : Page -> Page
getPageAsAuthenticated page =
let
dummyUser =
{ id = 100, name = "Foo", avatarUrl = "https://example.com" }
{ id = 100
, name = "Foo"
, avatarUrl = "https://example.com"
, pusherChannel = "general"
}

model =
{ emptyModel | user = Success dummyUser }
Expand Down
79 changes: 59 additions & 20 deletions client/src/elm/App/Update.elm
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ import App.PageType exposing (Page(..))
import Config
import Date
import Dict
import Http
import ItemManager.Model
import ItemManager.Update
import Json.Decode exposing (bool, decodeValue)
import Json.Encode exposing (Value)
import Pages.Login.Update
import Pusher.Model
import Pusher.Utils exposing (getClusterName)
import Pusher.Update
import RemoteData exposing (RemoteData(..), WebData)
import Task
import Time exposing (minute)
Expand All @@ -30,12 +29,7 @@ init flags =
Just config ->
let
defaultCmds =
[ pusherKey
( config.pusherKey.key
, getClusterName config.pusherKey.cluster
, Pusher.Model.eventNames
)
, Task.perform SetCurrentDate Date.now
[ Task.perform SetCurrentDate Date.now
]

( cmds, activePage_ ) =
Expand Down Expand Up @@ -87,13 +81,20 @@ update msg model =
model ! []

Logout ->
( { emptyModel
| accessToken = ""
, activePage = Login
, config = model.config
}
, accessTokenPort ""
)
let
( _, pusherLogout ) =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should probably be ( pusherModelUpdated, pusherLogout ) = so we could update it as well:

1
--
( { emptyModel
   | accessToken = ""
   | pusher = pusherModelUpdated

update (MsgPusher Pusher.Model.Logout) model
in
( { emptyModel
| accessToken = ""
, activePage = Login
, config = model.config
}
, Cmd.batch
[ accessTokenPort ""
, pusherLogout
]
)

MsgItemManager subMsg ->
case model.user of
Expand Down Expand Up @@ -124,6 +125,15 @@ update msg model =
-- If we don't have a user, we have nothing to do.
model ! []

MsgPusher subMsg ->
let
( val, cmd ) =
Pusher.Update.update backendUrl subMsg model.pusher
in
( { model | pusher = val }
, Cmd.map MsgPusher cmd
)

PageLogin msg ->
let
( val, cmds, ( webDataUser, accessToken ) ) =
Expand Down Expand Up @@ -166,6 +176,7 @@ update msg model =
[ Cmd.map PageLogin cmds
, accessTokenPort accessToken
, setActivePageCmds
, pusherLogin model webDataUser accessToken
]
)

Expand Down Expand Up @@ -205,6 +216,9 @@ update msg model =
ToggleSideBar ->
{ model | sidebarOpen = not model.sidebarOpen } ! []

NoOp ->
model ! []


{-| Determine is a page can be accessed by a user (anonymous or authenticated),
and if not return a access denied page.
Expand Down Expand Up @@ -240,6 +254,7 @@ subscriptions model =
[ Sub.map MsgItemManager <| ItemManager.Update.subscriptions model.pageItem model.activePage
, Time.every minute Tick
, offline (decodeValue bool >> HandleOfflineEvent)
, Sub.map MsgPusher <| Pusher.Update.subscription
]


Expand All @@ -248,11 +263,35 @@ subscriptions model =
port accessTokenPort : String -> Cmd msg


{-| Send Pusher key and cluster to JS.
-}
port pusherKey : ( String, String, List String ) -> Cmd msg


{-| Get a singal if internet connection is lost.
-}
port offline : (Value -> msg) -> Sub msg


pusherLogin : Model -> WebData User -> String -> Cmd Msg
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

worth a comment on the function, and a bit more comments in the function itself.

pusherLogin model webDataUser accessToken =
let
pusherLoginMsg pusherKey pusherChannel =
MsgPusher <|
Pusher.Model.Login
pusherKey
pusherChannel
(Pusher.Model.AccessToken accessToken)

msg =
case webDataUser of
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried doing it with a combination of RemoteData.map and RemoteData.withDefault, but it looks way more complicated to me. Probably I didn't understand what's the proper way to handle it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Untested, but could be shorten to:

RemoteData.toMaybe webDataUser
|> Maybe.map (\user -> 
          RemoteData.toMaybe model.config 
          |> Maybe.map (\config -> pusherLoginMsg config.pusherKey user.pusherChannel)
          |> Maybe.withDefault NoOp
     )
|> Maybe.withDefault NoOp

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect. Thanks!

Success user ->
case model.config of
Success config ->
pusherLoginMsg config.pusherKey user.pusherChannel

_ ->
NoOp

_ ->
NoOp

( _, pusherLogin ) =
update msg model
in
pusherLogin
1 change: 1 addition & 0 deletions client/src/elm/Item/Decoder.elm
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ decodeItem =
decode Item
|> required "label" string
|> optionalAt [ "image", "styles", "large" ] string "http://placehold.it/350x150"
|> optional "private_note" (nullable string) Nothing


decodeItemsDict : Decoder ItemsDict
Expand Down
1 change: 1 addition & 0 deletions client/src/elm/Item/Model.elm
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type alias ItemId =
type alias Item =
{ name : String
, image : String
, privateNote : Maybe String
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}


Expand Down
46 changes: 28 additions & 18 deletions client/src/elm/Pages/Item/View.elm
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,33 @@ import User.Model exposing (User)

view : Date -> User -> ItemId -> Item -> Html Msg
view currentDate currentUser itemId item =
div []
[ div
[ class "ui secondary pointing fluid menu" ]
[ h2
[ class "ui header" ]
[ text item.name ]
, div
[ class "right menu" ]
[ a
[ class "ui active item" ]
[ text "Overview" ]
let
privateNote =
case item.privateNote of
Just note ->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use showMaybe (copy from here)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used Maybe.withDefault on the private note itself, because showMaybe wants a Maybe Html. Is there an elegant way to use it here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

div [] [ text note ]

_ ->
text ""
in
div []
[ div
[ class "ui secondary pointing fluid menu" ]
[ h2
[ class "ui header" ]
[ text item.name ]
, div
[ class "right menu" ]
[ a
[ class "ui active item" ]
[ text "Overview" ]
]
]
, div []
[ img [ src item.image, alt item.name ] []
]
, div
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copy divider

[ class "ui divider" ]
[]
, privateNote
]
, div []
[ img [ src item.image, alt item.name ] []
]
, div
[ class "ui divider" ]
[]
]
7 changes: 0 additions & 7 deletions client/src/elm/Pages/Login/Decoder.elm
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,6 @@ module Pages.Login.Decoder exposing (..)
import Base64 exposing (encode)
import Json.Decode as Decode
import Pages.Login.Model exposing (AccessToken)
import User.Decoder as UserDecoder exposing (decodeUser)
import User.Model exposing (User)


decodeUser : Decode.Decoder User
decodeUser =
Decode.at [ "data", "0" ] <| UserDecoder.decodeUser


decodeAccessToken : Decode.Decoder AccessToken
Expand Down
1 change: 1 addition & 0 deletions client/src/elm/Pages/Login/Update.elm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import User.Model exposing (..)
import Pages.Login.Model as Login exposing (..)
import Pages.Login.Decoder exposing (..)
import RemoteData exposing (RemoteData(..), WebData)
import User.Decoder exposing (decodeUser)
import Utils.WebData exposing (sendWithHandler)


Expand Down
53 changes: 53 additions & 0 deletions client/src/elm/Pusher/Model.elm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@ module Pusher.Model exposing (..)
import Item.Model exposing (Item, ItemId)


type alias Model =
{ connectionStatus : ConnectionStatus
, errors : List PusherError
}


emptyModel : Model
emptyModel =
{ connectionStatus = Initialized
, errors = []
}


type Cluster
= ApSouthEast1
| EuWest1
Expand All @@ -25,8 +38,48 @@ type PusherEventData
= ItemUpdate Item


type AccessToken
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

= AccessToken String


type alias PusherChannel =
String


type alias PusherConfig =
{ key : String
, cluster : String
, authEndpoint : String
, channel : String
, eventNames : List String
}


type ConnectionStatus
= Initialized
| Connecting (Maybe Int)
| Connected
| Unavailable (Maybe Int)
| Failed
| Disconnected
| Other String


type alias PusherError =
{ code : Maybe Int
, message : Maybe String
}


{-| Return the event names that should be added via JS.
-}
eventNames : List String
eventNames =
[ "item__update" ]


type Msg
= HandleError PusherError
| HandleStateChange String
| Login PusherAppKey PusherChannel AccessToken
| Logout
1 change: 1 addition & 0 deletions client/src/elm/Pusher/Test.elm
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ decodeTest =
, data =
{ name = "new-item"
, image = "http://placehold.it/350x150"
, privateNote = Nothing
}
|> ItemUpdate
}
Expand Down
Loading