From f395259137f639cc5401ea63690e9f4957851a33 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Mon, 2 Sep 2019 00:46:59 -0700 Subject: [PATCH] Improve performance by computing room names at sync, rather than on view. --- src/Main.elm | 12 ++++++++++-- src/Scylla/Model.elm | 35 ++++++++++++++++++++++++++--------- src/Scylla/Views.elm | 10 +++++----- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/Main.elm b/src/Main.elm index eed1ad5..03caacb 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -52,6 +52,7 @@ init _ url key = , sending = Dict.empty , transactionId = 0 , userData = Dict.empty + , roomNames = Dict.empty , connected = True , searchText = "" } @@ -319,7 +320,7 @@ updateSyncResponse model r notify = notificationCmd sr = if notify then Maybe.withDefault Cmd.none <| Maybe.map (\(s, e) -> sendNotificationPort - { name = displayName model e.sender + { name = displayName model.userData e.sender , text = notificationText e , room = s }) <| notification sr @@ -343,9 +344,16 @@ updateSyncResponse model r notify = _ -> Cmd.none receivedEvents sr = List.map Just <| allTimelineEventIds sr sending sr = Dict.filter (\_ (rid, { body, id }) -> not <| List.member id <| receivedEvents sr) model.sending + newSync sr = mergeSyncResponse model.sync sr + newModel sr = + { model | sync = newSync sr + , sending = sending (mergeSyncResponse model.sync sr) + , roomNames = computeRoomsDisplayNames model.userData (newSync sr) + } in case r of - Ok sr -> ({ model | sync = mergeSyncResponse model.sync sr, sending = sending (mergeSyncResponse model.sync sr) }, Cmd.batch + Ok sr -> (newModel sr + , Cmd.batch [ syncCmd , newUserCmd sr , notificationCmd sr diff --git a/src/Scylla/Model.elm b/src/Scylla/Model.elm index 7f87b01..9b33f96 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, HistoryResponse, JoinedRoom, senderName, roomName, roomJoinedUsers, findFirst, directMessagesDecoder) +import Scylla.Sync exposing (SyncResponse, HistoryResponse, JoinedRoom, senderName, roomName, roomJoinedUsers, findFirst, directMessagesDecoder, AccountData) import Scylla.Login exposing (LoginResponse, Username, Password) import Scylla.UserData exposing (UserData) import Scylla.Route exposing (Route(..), RoomId) @@ -31,6 +31,7 @@ type alias Model = , sending : Dict Int (RoomId, SendingMessage) , transactionId : Int , userData : Dict Username UserData + , roomNames : Dict RoomId String , connected : Bool , searchText : String } @@ -71,14 +72,18 @@ type Msg = | AttemptReconnect | UpdateSearchText String -displayName : Model -> Username -> String -displayName m s = Maybe.withDefault (senderName s) <| Maybe.andThen .displayName <| Dict.get s m.userData +displayName : Dict String UserData -> Username -> String +displayName ud s = Maybe.withDefault (senderName s) <| Maybe.andThen .displayName <| Dict.get s ud -roomDisplayName : Model -> RoomId -> JoinedRoom -> String -roomDisplayName m rid jr = +roomDisplayName : Model -> RoomId -> String +roomDisplayName m rid = + Maybe.withDefault "" <| Dict.get rid m.roomNames + +computeRoomDisplayName : Dict String UserData -> Maybe AccountData -> RoomId -> JoinedRoom -> Maybe String +computeRoomDisplayName ud ad rid jr = let customName = roomName jr - direct = m.sync.accountData + direct = ad |> Maybe.andThen .events |> Maybe.andThen (findFirst ((==) "m.direct" << .type_)) |> Maybe.map (Decode.decodeValue directMessagesDecoder << .content) @@ -86,9 +91,21 @@ roomDisplayName m rid jr = |> Maybe.andThen (Dict.get rid) in case (customName, direct) of - (Just s, _) -> s - (_, Just u) -> displayName m u - _ -> "" + (Just s, _) -> customName + (_, Just u) -> direct + _ -> Nothing + +computeRoomsDisplayNames : Dict String UserData -> SyncResponse -> Dict String String +computeRoomsDisplayNames ud sr = + sr.rooms + |> Maybe.andThen .join + |> Maybe.map Dict.toList + |> Maybe.map (List.foldl + (\(rid, jr) d -> + computeRoomDisplayName ud sr.accountData rid jr + |> Maybe.map (\n -> Dict.insert rid n d) + |> Maybe.withDefault d) Dict.empty) + |> Maybe.withDefault Dict.empty roomUrl : String -> String roomUrl s = Url.Builder.absolute [ "room", s ] [] diff --git a/src/Scylla/Views.elm b/src/Scylla/Views.elm index dffa59e..3fb9586 100644 --- a/src/Scylla/Views.elm +++ b/src/Scylla/Views.elm @@ -109,14 +109,14 @@ homeserverView m hs rs = let roomList = div [ class "rooms-list" ] <| List.map (\(rid, r) -> roomListElementView m rid r) - <| List.sortBy (\(rid, r) -> roomDisplayName m rid r) rs + <| List.sortBy (\(rid, r) -> roomDisplayName m rid) rs in div [ class "homeserver-wrapper" ] [ h3 [] [ text hs ], roomList ] roomListElementView : Model -> RoomId -> JoinedRoom -> Html Msg roomListElementView m rid jr = let - name = roomDisplayName m rid jr + name = roomDisplayName m rid isVisible = m.searchText == "" || (String.contains (String.toLower m.searchText) <| String.toLower name) isCurrentRoom = case currentRoomId m of Nothing -> False @@ -161,7 +161,7 @@ joinedRoomView m roomId rd = let renderedMessages = List.map (userMessagesView m) <| mergeMessages m.loginUsername <| extractMessages rd messagesWrapper = messagesWrapperView m roomId renderedMessages - typing = List.map (displayName m) <| roomTypingUsers rd.joinedRoom + typing = List.map (displayName m.userData) <| roomTypingUsers rd.joinedRoom typingText = String.join ", " typing typingSuffix = case List.length typing of 0 -> "" @@ -182,7 +182,7 @@ joinedRoomView m roomId rd = ] in div [ class "room-wrapper" ] - [ h2 [] [ text <| roomDisplayName m roomId rd.joinedRoom ] + [ h2 [] [ text <| roomDisplayName m roomId ] , messagesWrapper , messageInput , typingWrapper @@ -215,7 +215,7 @@ messagesWrapperView m rid es = div [ class "messages-wrapper", id "messages-wrap senderView : Model -> Username -> Html Msg senderView m s = - span [ style "color" <| stringColor s, class "sender-wrapper" ] [ text <| displayName m s ] + span [ style "color" <| stringColor s, class "sender-wrapper" ] [ text <| displayName m.userData s ] userMessagesView : Model -> (Username, List Message) -> Html Msg userMessagesView m (u, ms) =