Scylla/src/Scylla/Model.elm

131 lines
5.3 KiB
Elm
Raw Normal View History

2018-12-08 13:49:30 -08:00
module Scylla.Model exposing (..)
import Scylla.Api exposing (..)
import Scylla.Sync exposing (SyncResponse, HistoryResponse, JoinedRoom, senderName, roomName, roomJoinedUsers, findFirst, AccountData)
import Scylla.AccountData exposing (directMessagesDecoder)
2018-12-08 15:06:14 -08:00
import Scylla.Login exposing (LoginResponse, Username, Password)
2018-12-13 02:15:14 -08:00
import Scylla.UserData exposing (UserData)
import Scylla.Route exposing (Route(..), RoomId)
2019-02-25 19:54:54 -08:00
import Scylla.Messages exposing (..)
import Scylla.Storage exposing (..)
2018-12-20 22:01:09 -08:00
import Scylla.Markdown exposing (..)
2018-12-08 13:49:30 -08:00
import Browser.Navigation as Nav
import Browser.Dom exposing (Viewport)
2018-12-13 14:06:15 -08:00
import Url.Builder
2018-12-08 17:15:35 -08:00
import Dict exposing (Dict)
2018-12-17 19:56:50 -08:00
import Time exposing (Posix)
import File exposing (File)
2019-08-31 23:03:57 -07:00
import Json.Decode as Decode
2018-12-08 13:49:30 -08:00
import Browser
import Http
import Url exposing (Url)
type alias Model =
{ key : Nav.Key
2018-12-08 19:09:20 -08:00
, route : Route
2018-12-08 13:49:30 -08:00
, token : Maybe ApiToken
2018-12-08 15:06:14 -08:00
, loginUsername : Username
, loginPassword : Password
2018-12-08 13:49:30 -08:00
, apiUrl : ApiUrl
2018-12-08 17:15:35 -08:00
, sync : SyncResponse
, errors : List String
2019-02-25 19:54:54 -08:00
, roomText : Dict RoomId String
, sending : Dict Int (RoomId, SendingMessage)
2018-12-09 23:38:43 -08:00
, transactionId : Int
, userData : Dict Username UserData
, roomNames : Dict RoomId String
2018-12-27 00:12:48 -08:00
, connected : Bool
2019-05-19 13:42:22 -07:00
, searchText : String
2018-12-08 13:49:30 -08:00
}
type Msg =
2018-12-08 15:06:14 -08:00
ChangeApiUrl ApiUrl -- During login screen: the API URL (homeserver)
| ChangeLoginUsername Username -- During login screen: the username
| ChangeLoginPassword Password -- During login screen: the password
| AttemptLogin -- During login screen, login button presed
| TryUrl Browser.UrlRequest -- User attempts to change URL
2018-12-13 14:06:15 -08:00
| OpenRoom String -- We try open a room
2018-12-08 19:09:20 -08:00
| ChangeRoute Route -- URL changes
2018-12-09 23:38:43 -08:00
| ChangeRoomText String String -- Change to a room's input text
| SendRoomText String -- Sends a message typed into a given room's input
2019-03-15 18:01:26 -07:00
| SendRoomTextResponse Int (Result Http.Error String) -- A send message response finished
| ViewportAfterMessage (Result Browser.Dom.Error Viewport) -- A message has been received, try scroll (maybe)
| ViewportChangeComplete (Result Browser.Dom.Error ()) -- We're done changing the viewport.
| ReceiveFirstSyncResponse (Result Http.Error SyncResponse) -- HTTP, Sync has finished
2018-12-08 15:06:14 -08:00
| ReceiveSyncResponse (Result Http.Error SyncResponse) -- HTTP, Sync has finished
| ReceiveLoginResponse ApiUrl (Result Http.Error LoginResponse) -- HTTP, Login has finished
2018-12-17 19:56:50 -08:00
| ReceiveUserData Username (Result Http.Error UserData) -- HTTP, receive user data
| ReceiveCompletedReadMarker (Result Http.Error ()) -- HTTP, read marker request completed
| ReceiveCompletedTypingIndicator (Result Http.Error ()) -- HTTP, typing indicator request completed
2019-08-31 23:03:57 -07:00
| ReceiveStoreData Decode.Value -- We are send back a value on request from localStorage.
2018-12-17 19:56:50 -08:00
| TypingTick Posix -- Tick for updating the typing status
2018-12-19 21:52:07 -08:00
| History RoomId -- Load history for a room
| ReceiveHistoryResponse RoomId (Result Http.Error HistoryResponse) -- HTTP, receive history
| SendImages RoomId
| SendFiles RoomId
| ImagesSelected RoomId File (List File)
| FilesSelected RoomId File (List File)
| ImageUploadComplete RoomId File (Result Http.Error String)
| FileUploadComplete RoomId File (Result Http.Error String)
2019-03-15 18:01:26 -07:00
| SendImageResponse (Result Http.Error String)
| SendFileResponse (Result Http.Error String)
2018-12-20 22:01:09 -08:00
| ReceiveMarkdown MarkdownResponse
2018-12-23 00:23:48 -08:00
| DismissError Int
2018-12-27 00:12:48 -08:00
| AttemptReconnect
2019-05-19 13:42:22 -07:00
| UpdateSearchText String
2018-12-08 13:49:30 -08:00
displayName : Dict String UserData -> Username -> String
displayName ud s = Maybe.withDefault (senderName s) <| Maybe.andThen .displayName <| Dict.get s ud
2018-12-13 14:06:15 -08:00
roomDisplayName : Model -> RoomId -> String
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
customName = roomName jr
direct = ad
2019-08-31 23:03:57 -07:00
|> Maybe.andThen .events
|> Maybe.andThen (findFirst ((==) "m.direct" << .type_))
|> Maybe.map (Decode.decodeValue directMessagesDecoder << .content)
|> Maybe.andThen Result.toMaybe
|> Maybe.andThen (Dict.get rid)
in
2019-08-31 23:03:57 -07:00
case (customName, direct) of
(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
2018-12-13 14:06:15 -08:00
roomUrl : String -> String
roomUrl s = Url.Builder.absolute [ "room", s ] []
loginUrl : String
loginUrl = Url.Builder.absolute [ "login" ] []
2018-12-20 16:39:10 -08:00
newUsers : Model -> List Username -> List Username
newUsers m lus = List.filter (\u -> not <| Dict.member u m.userData) lus
joinedRooms : Model -> Dict RoomId JoinedRoom
joinedRooms m = Maybe.withDefault Dict.empty <| Maybe.andThen .join <| m.sync.rooms
currentRoom : Model -> Maybe JoinedRoom
currentRoom m =
Maybe.andThen (\s -> Dict.get s <| joinedRooms m) <| currentRoomId m
currentRoomId : Model -> Maybe RoomId
currentRoomId m = case m.route of
Room r -> Just r
_ -> Nothing