Improve performance by computing room names at sync, rather than on view.

This commit is contained in:
Danila Fedorin 2019-09-02 00:46:59 -07:00
parent 5d5418e9c6
commit f395259137
3 changed files with 41 additions and 16 deletions

View File

@ -52,6 +52,7 @@ init _ url key =
, sending = Dict.empty , sending = Dict.empty
, transactionId = 0 , transactionId = 0
, userData = Dict.empty , userData = Dict.empty
, roomNames = Dict.empty
, connected = True , connected = True
, searchText = "" , searchText = ""
} }
@ -319,7 +320,7 @@ updateSyncResponse model r notify =
notificationCmd sr = if notify notificationCmd sr = if notify
then Maybe.withDefault Cmd.none then Maybe.withDefault Cmd.none
<| Maybe.map (\(s, e) -> sendNotificationPort <| Maybe.map (\(s, e) -> sendNotificationPort
{ name = displayName model e.sender { name = displayName model.userData e.sender
, text = notificationText e , text = notificationText e
, room = s , room = s
}) <| notification sr }) <| notification sr
@ -343,9 +344,16 @@ updateSyncResponse model r notify =
_ -> Cmd.none _ -> Cmd.none
receivedEvents sr = List.map Just <| allTimelineEventIds sr receivedEvents sr = List.map Just <| allTimelineEventIds sr
sending sr = Dict.filter (\_ (rid, { body, id }) -> not <| List.member id <| receivedEvents sr) model.sending 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 in
case r of 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 [ syncCmd
, newUserCmd sr , newUserCmd sr
, notificationCmd sr , notificationCmd sr

View File

@ -1,6 +1,6 @@
module Scylla.Model exposing (..) module Scylla.Model exposing (..)
import Scylla.Api 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.Login exposing (LoginResponse, Username, Password)
import Scylla.UserData exposing (UserData) import Scylla.UserData exposing (UserData)
import Scylla.Route exposing (Route(..), RoomId) import Scylla.Route exposing (Route(..), RoomId)
@ -31,6 +31,7 @@ type alias Model =
, sending : Dict Int (RoomId, SendingMessage) , sending : Dict Int (RoomId, SendingMessage)
, transactionId : Int , transactionId : Int
, userData : Dict Username UserData , userData : Dict Username UserData
, roomNames : Dict RoomId String
, connected : Bool , connected : Bool
, searchText : String , searchText : String
} }
@ -71,14 +72,18 @@ type Msg =
| AttemptReconnect | AttemptReconnect
| UpdateSearchText String | UpdateSearchText String
displayName : Model -> Username -> String displayName : Dict String UserData -> Username -> String
displayName m s = Maybe.withDefault (senderName s) <| Maybe.andThen .displayName <| Dict.get s m.userData displayName ud s = Maybe.withDefault (senderName s) <| Maybe.andThen .displayName <| Dict.get s ud
roomDisplayName : Model -> RoomId -> JoinedRoom -> String roomDisplayName : Model -> RoomId -> String
roomDisplayName m rid jr = roomDisplayName m rid =
Maybe.withDefault "<No Name>" <| Dict.get rid m.roomNames
computeRoomDisplayName : Dict String UserData -> Maybe AccountData -> RoomId -> JoinedRoom -> Maybe String
computeRoomDisplayName ud ad rid jr =
let let
customName = roomName jr customName = roomName jr
direct = m.sync.accountData direct = ad
|> Maybe.andThen .events |> Maybe.andThen .events
|> Maybe.andThen (findFirst ((==) "m.direct" << .type_)) |> Maybe.andThen (findFirst ((==) "m.direct" << .type_))
|> Maybe.map (Decode.decodeValue directMessagesDecoder << .content) |> Maybe.map (Decode.decodeValue directMessagesDecoder << .content)
@ -86,9 +91,21 @@ roomDisplayName m rid jr =
|> Maybe.andThen (Dict.get rid) |> Maybe.andThen (Dict.get rid)
in in
case (customName, direct) of case (customName, direct) of
(Just s, _) -> s (Just s, _) -> customName
(_, Just u) -> displayName m u (_, Just u) -> direct
_ -> "<No Name>" _ -> 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 : String -> String
roomUrl s = Url.Builder.absolute [ "room", s ] [] roomUrl s = Url.Builder.absolute [ "room", s ] []

View File

@ -109,14 +109,14 @@ homeserverView m hs rs =
let let
roomList = div [ class "rooms-list" ] roomList = div [ class "rooms-list" ]
<| List.map (\(rid, r) -> roomListElementView m rid r) <| 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 in
div [ class "homeserver-wrapper" ] [ h3 [] [ text hs ], roomList ] div [ class "homeserver-wrapper" ] [ h3 [] [ text hs ], roomList ]
roomListElementView : Model -> RoomId -> JoinedRoom -> Html Msg roomListElementView : Model -> RoomId -> JoinedRoom -> Html Msg
roomListElementView m rid jr = roomListElementView m rid jr =
let let
name = roomDisplayName m rid jr name = roomDisplayName m rid
isVisible = m.searchText == "" || (String.contains (String.toLower m.searchText) <| String.toLower name) isVisible = m.searchText == "" || (String.contains (String.toLower m.searchText) <| String.toLower name)
isCurrentRoom = case currentRoomId m of isCurrentRoom = case currentRoomId m of
Nothing -> False Nothing -> False
@ -161,7 +161,7 @@ joinedRoomView m roomId rd =
let let
renderedMessages = List.map (userMessagesView m) <| mergeMessages m.loginUsername <| extractMessages rd renderedMessages = List.map (userMessagesView m) <| mergeMessages m.loginUsername <| extractMessages rd
messagesWrapper = messagesWrapperView m roomId renderedMessages 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 typingText = String.join ", " typing
typingSuffix = case List.length typing of typingSuffix = case List.length typing of
0 -> "" 0 -> ""
@ -182,7 +182,7 @@ joinedRoomView m roomId rd =
] ]
in in
div [ class "room-wrapper" ] div [ class "room-wrapper" ]
[ h2 [] [ text <| roomDisplayName m roomId rd.joinedRoom ] [ h2 [] [ text <| roomDisplayName m roomId ]
, messagesWrapper , messagesWrapper
, messageInput , messageInput
, typingWrapper , typingWrapper
@ -215,7 +215,7 @@ messagesWrapperView m rid es = div [ class "messages-wrapper", id "messages-wrap
senderView : Model -> Username -> Html Msg senderView : Model -> Username -> Html Msg
senderView m s = 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 : Model -> (Username, List Message) -> Html Msg
userMessagesView m (u, ms) = userMessagesView m (u, ms) =