diff --git a/src/Main.elm b/src/Main.elm index ecde96e..9a5dbfb 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -7,6 +7,7 @@ import Scylla.Http exposing (..) import Scylla.Views exposing (viewFull) import Scylla.Route exposing (Route(..)) import Scylla.UserData exposing (..) +import Scylla.Notification exposing (..) import Url exposing (Url) import Url.Parser exposing (parse) import Url.Builder @@ -90,7 +91,7 @@ updateTryUrl m ur = case ur of updateLoginResponse : Model -> Result Http.Error LoginResponse -> (Model, Cmd Msg) updateLoginResponse model r = case r of - Ok lr -> ( { model | token = Just lr.accessToken } , Cmd.batch + Ok lr -> ( { model | token = Just lr.accessToken, loginUsername = lr.userId } , Cmd.batch [ firstSync model.apiUrl lr.accessToken , Nav.pushUrl model.key <| Url.Builder.absolute [] [] ] ) @@ -104,10 +105,27 @@ updateSyncResponse model r notify = <| Result.map .nextBatch r syncCmd = sync nextBatch model.apiUrl token newUsers sr = List.filter (\s -> not <| Dict.member s model.userData) <| roomsUsers sr - newUserCommands sr = Cmd.batch <| List.map (userData model.apiUrl <| Maybe.withDefault "" model.token) <| newUsers sr + newUserCommands sr = Cmd.batch + <| List.map (userData model.apiUrl + <| Maybe.withDefault "" model.token) + <| newUsers sr + notification sr = List.head + <| List.filter (\(s, e) -> e.sender /= model.loginUsername) + <| notificationEvents sr + notificationCommand sr = Maybe.withDefault Cmd.none + <| Maybe.map (\(s, e) -> sendNotificationPort + { name = displayName model e.sender + , text = notificationText e + , room = s + }) + <| notification sr in case r of - Ok sr -> ({ model | sync = mergeSyncResponse model.sync sr }, Cmd.batch [ syncCmd, newUserCommands sr ]) + Ok sr -> ({ model | sync = mergeSyncResponse model.sync sr }, Cmd.batch + [ syncCmd + , newUserCommands sr + , if notify then notificationCommand sr else Cmd.none + ]) _ -> (model, syncCmd) subscriptions : Model -> Sub Msg diff --git a/src/Scylla/Model.elm b/src/Scylla/Model.elm index 47d27f9..bb8e26a 100644 --- a/src/Scylla/Model.elm +++ b/src/Scylla/Model.elm @@ -1,6 +1,6 @@ module Scylla.Model exposing (..) import Scylla.Api exposing (..) -import Scylla.Sync exposing (SyncResponse, JoinedRoom) +import Scylla.Sync exposing (SyncResponse, JoinedRoom, senderName) import Scylla.Login exposing (LoginResponse, Username, Password) import Scylla.UserData exposing (UserData) import Scylla.Route exposing (Route) @@ -39,3 +39,5 @@ type Msg = | ReceiveLoginResponse (Result Http.Error LoginResponse) -- HTTP, Login has finished | ReceiveUserData Username (Result Http.Error UserData) +displayName : Model -> Username -> String +displayName m s = Maybe.withDefault (senderName s) <| Maybe.andThen .displayName <| Dict.get s m.userData diff --git a/src/Scylla/Sync.elm b/src/Scylla/Sync.elm index 2d25e5e..f8b33d5 100644 --- a/src/Scylla/Sync.elm +++ b/src/Scylla/Sync.elm @@ -370,13 +370,17 @@ roomName jr = Maybe.andThen name <| Maybe.andThen nameEvent <| Maybe.andThen .events <| state -- Business Logic: Event Extraction -notificationEvent : SyncResponse -> Maybe (String, RoomEvent) -notificationEvent s = +notificationText : RoomEvent -> String +notificationText re = case (Decode.decodeValue (field "msgtype" string) re.content) of + Ok "m.text" -> Result.withDefault "" <| (Decode.decodeValue (field "body" string) re.content) + _ -> "" + +notificationEvents : SyncResponse -> List (String, RoomEvent) +notificationEvents s = let applyPair k = List.map (\v -> (k, v)) in - List.head - <| List.sortBy (\(k, v) -> v.originServerTs) + List.sortBy (\(k, v) -> v.originServerTs) <| Dict.foldl (\k v a -> a ++ applyPair k v) [] <| joinedRoomsEvents s diff --git a/src/Scylla/Views.elm b/src/Scylla/Views.elm index 5ba7fef..03bfcdf 100644 --- a/src/Scylla/Views.elm +++ b/src/Scylla/Views.elm @@ -3,6 +3,7 @@ import Scylla.Model exposing (..) import Scylla.Sync exposing (..) import Scylla.Route exposing (..) import Scylla.Fnv as Fnv +import Scylla.Login exposing (Username) import Svg import Svg.Attributes import Url.Builder @@ -126,12 +127,9 @@ eventView m re = Maybe.map createRow <| Maybe.andThen (\f -> f m re) viewFunction -eventSenderView : Model -> String -> Html Msg +eventSenderView : Model -> Username -> Html Msg eventSenderView m s = - let - displayName = Maybe.withDefault (senderName s) <| Maybe.andThen .displayName <| Dict.get s m.userData - in - span [ style "background-color" <| stringColor s, class "sender-wrapper" ] [ text displayName ] + span [ style "background-color" <| stringColor s, class "sender-wrapper" ] [ text <| displayName m s ] messageView : Model -> RoomEvent -> Maybe (Html Msg) messageView m re =