2018-12-08 15:06:14 -08:00
|
|
|
module Scylla.Views exposing (..)
|
|
|
|
import Scylla.Model exposing (..)
|
2018-12-08 17:15:35 -08:00
|
|
|
import Scylla.Sync exposing (..)
|
2018-12-08 19:09:20 -08:00
|
|
|
import Scylla.Route exposing (..)
|
2018-12-10 14:20:06 -08:00
|
|
|
import Scylla.Fnv as Fnv
|
2018-12-10 16:16:39 -08:00
|
|
|
import Svg
|
|
|
|
import Svg.Attributes
|
2018-12-08 20:02:29 -08:00
|
|
|
import Url.Builder
|
2018-12-08 17:15:35 -08:00
|
|
|
import Json.Decode as Decode
|
2018-12-10 14:20:06 -08:00
|
|
|
import Html exposing (Html, div, input, text, button, div, span, a, h2, table, td, tr)
|
|
|
|
import Html.Attributes exposing (type_, value, href, class, style)
|
2018-12-08 15:06:14 -08:00
|
|
|
import Html.Events exposing (onInput, onClick)
|
2018-12-08 17:15:35 -08:00
|
|
|
import Dict
|
2018-12-08 15:06:14 -08:00
|
|
|
|
2018-12-10 14:20:06 -08:00
|
|
|
stringColor : String -> String
|
|
|
|
stringColor s =
|
|
|
|
let
|
|
|
|
hue = String.fromFloat <| (toFloat (Fnv.hash s)) / 4294967296 * 360
|
|
|
|
in
|
|
|
|
"hsl(" ++ hue ++ ", 82%, 71%)"
|
|
|
|
|
2018-12-08 17:15:35 -08:00
|
|
|
viewFull : Model -> List (Html Msg)
|
|
|
|
viewFull model =
|
|
|
|
let
|
2018-12-10 13:18:02 -08:00
|
|
|
room r = Maybe.map (\jr -> (r, jr))
|
|
|
|
<| Maybe.andThen (Dict.get r)
|
|
|
|
<| Maybe.andThen .join model.sync.rooms
|
2018-12-08 19:09:20 -08:00
|
|
|
core = case model.route of
|
|
|
|
Login -> loginView model
|
2018-12-10 13:18:02 -08:00
|
|
|
Base -> baseView model Nothing
|
|
|
|
Room r -> baseView model <| room r
|
2018-12-08 19:09:20 -08:00
|
|
|
_ -> div [] []
|
2018-12-08 17:15:35 -08:00
|
|
|
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 ]
|
2018-12-08 15:06:14 -08:00
|
|
|
|
2018-12-10 13:18:02 -08:00
|
|
|
baseView : Model -> Maybe (String, JoinedRoom) -> Html Msg
|
|
|
|
baseView m jr =
|
|
|
|
let
|
|
|
|
roomView = case jr of
|
|
|
|
Just (id, r) -> joinedRoomView m id r
|
|
|
|
Nothing -> div [] []
|
|
|
|
in
|
|
|
|
div [ class "base-wrapper" ]
|
|
|
|
[ roomListView m
|
|
|
|
, roomView
|
|
|
|
]
|
|
|
|
|
|
|
|
roomListView : Model -> Html Msg
|
|
|
|
roomListView m =
|
|
|
|
let
|
2018-12-08 20:02:29 -08:00
|
|
|
rooms = Maybe.withDefault (Dict.empty) <| Maybe.andThen .join <| m.sync.rooms
|
2018-12-10 13:18:02 -08:00
|
|
|
roomList = div [ class "rooms-list" ] <| Dict.values <| Dict.map roomListElementView rooms
|
2018-12-08 20:02:29 -08:00
|
|
|
in
|
2018-12-10 12:47:40 -08:00
|
|
|
div [ class "rooms-wrapper" ]
|
|
|
|
[ h2 [] [ text "Rooms" ]
|
|
|
|
, roomList
|
|
|
|
]
|
2018-12-08 20:02:29 -08:00
|
|
|
|
2018-12-10 13:18:02 -08:00
|
|
|
roomListElementView : String -> JoinedRoom -> Html Msg
|
|
|
|
roomListElementView s jr =
|
2018-12-08 20:02:29 -08:00
|
|
|
let
|
|
|
|
name = Maybe.withDefault "<No Name>" <| roomName jr
|
|
|
|
in
|
|
|
|
a [ href <| Url.Builder.absolute [ "room", s ] [] ] [ text name ]
|
2018-12-08 15:06:14 -08:00
|
|
|
|
|
|
|
loginView : Model -> Html Msg
|
2018-12-10 12:21:08 -08:00
|
|
|
loginView m = div [ class "login-wrapper" ]
|
|
|
|
[ h2 [] [ text "Log In" ]
|
|
|
|
, input [ type_ "text", value m.loginUsername, onInput ChangeLoginUsername] []
|
2018-12-08 15:06:14 -08:00
|
|
|
, input [ type_ "password", value m.loginPassword, onInput ChangeLoginPassword ] []
|
|
|
|
, input [ type_ "text", value m.apiUrl, onInput ChangeApiUrl ] []
|
|
|
|
, button [ onClick AttemptLogin ] [ text "Log In" ]
|
|
|
|
]
|
2018-12-08 17:15:35 -08:00
|
|
|
|
2018-12-09 23:38:43 -08:00
|
|
|
joinedRoomView : Model -> String -> JoinedRoom -> Html Msg
|
|
|
|
joinedRoomView m roomId jr =
|
2018-12-08 17:15:35 -08:00
|
|
|
let
|
|
|
|
events = Maybe.withDefault [] <| Maybe.andThen .events jr.timeline
|
|
|
|
renderedEvents = List.filterMap (eventView m) events
|
2018-12-10 12:47:40 -08:00
|
|
|
eventWrapper = eventWrapperView m renderedEvents
|
2018-12-10 13:18:02 -08:00
|
|
|
messageInput = div [ class "message-wrapper" ]
|
2018-12-09 23:38:43 -08:00
|
|
|
[ input
|
|
|
|
[ type_ "text"
|
|
|
|
, onInput <| ChangeRoomText roomId
|
|
|
|
, value <| Maybe.withDefault "" <| Dict.get roomId m.roomText
|
|
|
|
] []
|
2018-12-10 16:16:39 -08:00
|
|
|
, button [ onClick <| SendRoomText roomId ] [ iconView "send" ]
|
2018-12-09 23:38:43 -08:00
|
|
|
]
|
2018-12-08 17:15:35 -08:00
|
|
|
in
|
2018-12-10 13:18:02 -08:00
|
|
|
div [ class "room-wrapper" ]
|
|
|
|
[ h2 [] [ text <| Maybe.withDefault "<No Name>" <| roomName jr ]
|
|
|
|
, eventWrapper
|
|
|
|
, messageInput
|
|
|
|
]
|
2018-12-08 17:15:35 -08:00
|
|
|
|
2018-12-10 16:16:39 -08:00
|
|
|
iconView : String -> Html Msg
|
|
|
|
iconView name =
|
|
|
|
let
|
|
|
|
url = Url.Builder.absolute [ "static", "svg", "feather-sprite.svg" ] []
|
|
|
|
in
|
|
|
|
Svg.svg
|
|
|
|
[ Svg.Attributes.class "feather-icon"
|
|
|
|
] [ Svg.use [ Svg.Attributes.xlinkHref (url ++ "#" ++ name) ] [] ]
|
|
|
|
|
2018-12-10 12:47:40 -08:00
|
|
|
eventWrapperView : Model -> List (Html Msg) -> Html Msg
|
2018-12-10 15:27:18 -08:00
|
|
|
eventWrapperView m es = div [ class "events-wrapper" ] [ table [ class "events-table" ] es ]
|
2018-12-08 17:15:35 -08:00
|
|
|
|
|
|
|
eventView : Model -> RoomEvent -> Maybe (Html Msg)
|
2018-12-10 14:20:06 -08:00
|
|
|
eventView m re =
|
|
|
|
let
|
|
|
|
viewFunction = case re.type_ of
|
|
|
|
"m.room.message" -> Just messageView
|
|
|
|
_ -> Nothing
|
|
|
|
createRow mhtml = tr []
|
2018-12-13 12:45:30 -08:00
|
|
|
[ td [] [ eventSenderView m re.sender ]
|
2018-12-10 14:20:06 -08:00
|
|
|
, td [] [ mhtml ]
|
|
|
|
]
|
|
|
|
in
|
|
|
|
Maybe.map createRow
|
|
|
|
<| Maybe.andThen (\f -> f m re) viewFunction
|
|
|
|
|
2018-12-13 12:45:30 -08:00
|
|
|
eventSenderView : Model -> String -> 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 ]
|
2018-12-08 17:15:35 -08:00
|
|
|
|
|
|
|
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
|
2018-12-10 14:20:06 -08:00
|
|
|
wrap mtext = span [] [ text mtext ]
|
2018-12-08 17:15:35 -08:00
|
|
|
in
|
|
|
|
Maybe.map wrap <| Result.toMaybe body
|