diff --git a/src/Main.elm b/src/Main.elm index d549abd..3955620 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -22,6 +22,13 @@ init flags url key = , loginUsername = "" , loginPassword = "" , apiUrl = "https://matrix.org" + , sync = + { nextBatch = "" + , rooms = Nothing + , presence = Nothing + , accountData = Nothing + } + , errors = [] } cmd = case flags.token of Just _ -> Cmd.none @@ -32,7 +39,7 @@ init flags url key = view : Model -> Browser.Document Msg view m = { title = "Scylla" - , body = [ viewFull m ] + , body = viewFull m } update : Msg -> Model -> (Model, Cmd Msg) @@ -51,9 +58,9 @@ updateLoginResponse model r = case r of Err e -> (model, Cmd.none) updateSyncResponse : Model -> Result Http.Error SyncResponse -> (Model, Cmd Msg) -updateSyncResponse model r = case r of - Ok sr -> (model, Cmd.none) - Err e -> (model, Cmd.none) +updateSyncResponse model r = let sync = model.sync in case r of + Ok sr -> ({ model | sync = mergeSyncResponse model.sync sr }, Cmd.none) + _ -> (model, Cmd.none) subscriptions : Model -> Sub Msg subscriptions m = Sub.none diff --git a/src/Scylla/Model.elm b/src/Scylla/Model.elm index b7fa78b..830109f 100644 --- a/src/Scylla/Model.elm +++ b/src/Scylla/Model.elm @@ -1,8 +1,9 @@ module Scylla.Model exposing (..) import Scylla.Api exposing (..) -import Scylla.Sync exposing (SyncResponse) +import Scylla.Sync exposing (SyncResponse, JoinedRoom) import Scylla.Login exposing (LoginResponse, Username, Password) import Browser.Navigation as Nav +import Dict exposing (Dict) import Browser import Http import Url exposing (Url) @@ -13,6 +14,8 @@ type alias Model = , loginUsername : Username , loginPassword : Password , apiUrl : ApiUrl + , sync : SyncResponse + , errors : List String } type Msg = diff --git a/src/Scylla/Sync.elm b/src/Scylla/Sync.elm index 34a385c..4cd3f60 100644 --- a/src/Scylla/Sync.elm +++ b/src/Scylla/Sync.elm @@ -80,14 +80,14 @@ type alias StateEvent = stateEventDecoder : Decoder StateEvent stateEventDecoder = Decode.succeed StateEvent - |> required "required" value + |> required "content" value |> required "type" string |> required "event_id" string |> required "sender" string |> required "origin_server_ts" int |> maybeDecode "unsigned" unsignedDataDecoder |> maybeDecode "prev_content" eventContentDecoder - |> required "sate_key" string + |> required "state_key" string -- Rooms type alias Rooms = @@ -254,3 +254,7 @@ presenceDecoder : Decoder Presence presenceDecoder = Decode.succeed Presence |> maybeDecode "events" (list eventDecoder) + +-- Business Logic +mergeSyncResponse : SyncResponse -> SyncResponse -> SyncResponse +mergeSyncResponse l r = r diff --git a/src/Scylla/Views.elm b/src/Scylla/Views.elm index 0870527..4373110 100644 --- a/src/Scylla/Views.elm +++ b/src/Scylla/Views.elm @@ -1,16 +1,30 @@ module Scylla.Views exposing (..) import Scylla.Model exposing (..) -import Html exposing (Html, div, input, text, button) +import Scylla.Sync exposing (..) +import Json.Decode as Decode +import Html exposing (Html, div, input, text, button, div, span) import Html.Attributes exposing (type_, value) import Html.Events exposing (onInput, onClick) +import Dict -viewFull : Model -> Html Msg -viewFull model = case model.token of - Just _ -> normalView model - Nothing -> loginView model +viewFull : Model -> List (Html Msg) +viewFull model = + let + core = case model.token of + Just _ -> normalView model + Nothing -> loginView model + errorList = errorsView model.errors + in + [ errorList ] ++ [ core ] + +errorsView : List String -> Html Msg +errorsView = div [] << List.map errorView + +errorView : String -> Html Msg +errorView s = div [] [ text s ] normalView : Model -> Html Msg -normalView m = div [] [ text "You are logged in!" ] +normalView m = div [] [] loginView : Model -> Html Msg loginView m = div [] @@ -19,3 +33,40 @@ loginView m = div [] , input [ type_ "text", value m.apiUrl, onInput ChangeApiUrl ] [] , button [ onClick AttemptLogin ] [ text "Log In" ] ] + +joinedRoomView : Model -> JoinedRoom -> Html Msg +joinedRoomView m jr = + let + events = Maybe.withDefault [] <| Maybe.andThen .events jr.timeline + renderedEvents = List.filterMap (eventView m) events + eventContainer = eventContainerView m renderedEvents + in + div [] [ eventContainer ] + +eventContainerView : Model -> List (Html Msg) -> Html Msg +eventContainerView m = div [] + +eventView : Model -> RoomEvent -> Maybe (Html Msg) +eventView m re = case re.type_ of + "m.room.message" -> messageView m re + _ -> Nothing + +messageView : Model -> RoomEvent -> Maybe (Html Msg) +messageView m re = + let + msgtype = Decode.decodeValue (Decode.field "msgtype" Decode.string) re.content + in + case msgtype of + Ok "m.text" -> messageTextView m re + _ -> Nothing + +messageTextView : Model -> RoomEvent -> Maybe (Html Msg) +messageTextView m re = + let + body = Decode.decodeValue (Decode.field "body" Decode.string) re.content + wrap mtext = div [] + [ span [] [ text re.sender ] + , span [] [ text mtext ] + ] + in + Maybe.map wrap <| Result.toMaybe body