tooty/src/View.elm

234 lines
8.2 KiB
Elm
Raw Normal View History

2017-04-20 07:46:18 +00:00
module View exposing (view)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import HtmlParser
2017-04-20 10:41:23 +00:00
import HtmlParser.Util exposing (toVirtualDom)
2017-04-20 07:46:18 +00:00
import Mastodon
2017-04-20 18:30:19 +00:00
import Model exposing (Model, DraftMsg(..), Msg(..))
2017-04-20 07:46:18 +00:00
replace : String -> String -> String -> String
replace from to str =
String.split from str |> String.join to
formatContent : String -> List (Html msg)
formatContent content =
content
|> replace "'" "'"
|> replace " ?" " ?"
|> replace " !" " !"
|> replace " :" " :"
|> HtmlParser.parse
|> toVirtualDom
2017-04-20 07:46:18 +00:00
errorView : String -> Html Msg
errorView error =
div [ class "alert alert-danger" ] [ text error ]
errorsListView : Model -> Html Msg
errorsListView model =
case model.errors of
[] ->
text ""
errors ->
div [] <| List.map errorView model.errors
icon : String -> Html Msg
icon name =
i [ class <| "glyphicon glyphicon-" ++ name ] []
2017-04-20 07:46:18 +00:00
statusView : Mastodon.Status -> Html Msg
statusView { account, content, reblog } =
case reblog of
2017-04-20 07:46:18 +00:00
Just (Mastodon.Reblog reblog) ->
div [ class "reblog" ]
[ p []
[ icon "fire"
, a [ href account.url, class "reblogger" ]
[ text <| " " ++ account.username ]
, text " boosted"
2017-04-20 07:46:18 +00:00
]
, statusView reblog
]
Nothing ->
div [ class "status" ]
[ img [ class "avatar", src account.avatar ] []
2017-04-20 13:43:15 +00:00
, div [ class "username" ]
[ a [ href account.url ]
[ text account.display_name
, span [ class "acct" ] [ text <| " @" ++ account.username ]
]
2017-04-20 13:43:15 +00:00
]
, div [ class "status-text" ] <| formatContent content
2017-04-20 07:46:18 +00:00
]
timelineView : List Mastodon.Status -> String -> String -> Html Msg
timelineView statuses label iconName =
2017-04-21 11:04:28 +00:00
div [ class "col-md-3" ]
2017-04-20 07:46:18 +00:00
[ div [ class "panel panel-default" ]
[ div [ class "panel-heading" ]
[ icon iconName
, text label
]
2017-04-20 07:46:18 +00:00
, ul [ class "list-group" ] <|
List.map
(\s ->
li [ class "list-group-item status" ]
[ statusView s ]
)
statuses
]
]
2017-04-20 18:30:19 +00:00
draftView : Model -> Html Msg
draftView { draft } =
let
hasSpoiler =
case draft.spoiler_text of
Nothing ->
False
Just _ ->
True
in
div [ class "col-md-3" ]
[ div [ class "panel panel-default" ]
[ div [ class "panel-heading" ] [ icon "envelope", text "Post a message" ]
2017-04-20 18:30:19 +00:00
, div [ class "panel-body" ]
[ Html.form [ class "form", onSubmit SubmitDraft ]
[ div [ class "form-group checkbox" ]
[ label []
[ input
[ type_ "checkbox"
, onCheck <| DraftEvent << ToggleSpoiler
, checked hasSpoiler
]
[]
, text " Add a spoiler"
]
]
, if hasSpoiler then
div [ class "form-group" ]
[ label [ for "spoiler" ] [ text "Visible part" ]
, textarea
[ id "spoiler"
, class "form-control"
, rows 5
, placeholder "This text will always be visible."
, onInput <| DraftEvent << UpdateSpoiler
, required True
, value <| Maybe.withDefault "" draft.spoiler_text
]
[]
]
else
text ""
, div [ class "form-group" ]
[ label [ for "status" ]
[ text <|
if hasSpoiler then
"Hidden part"
else
"Status"
]
, textarea
[ id "status"
, class "form-control"
, rows 8
, placeholder <|
if hasSpoiler then
"This text with be hidden by default, as you have enabled a spoiler."
else
"Once upon a time..."
, onInput <| DraftEvent << UpdateStatus
, required True
, value draft.status
]
[]
]
, div [ class "form-group checkbox" ]
[ label []
[ input
[ type_ "checkbox"
, onCheck <| DraftEvent << UpdateSensitive
, checked draft.sensitive
]
[]
, text " NSFW"
]
]
, p [ class "text-right" ]
[ button [ class "btn btn-primary" ]
[ text "Toot!" ]
]
]
]
]
]
2017-04-20 07:46:18 +00:00
homepageView : Model -> Html Msg
homepageView model =
div [ class "row" ]
2017-04-20 18:30:19 +00:00
[ draftView model
, timelineView model.userTimeline "Home timeline" "home"
, timelineView model.localTimeline "Local timeline" "th-large"
, timelineView model.publicTimeline "Public timeline" "globe"
2017-04-20 07:46:18 +00:00
]
authView : Model -> Html Msg
authView model =
div [ class "col-md-4 col-md-offset-4" ]
[ div [ class "panel panel-default" ]
[ div [ class "panel-heading" ] [ text "Authenticate" ]
, div [ class "panel-body" ]
[ Html.form [ class "form", onSubmit Register ]
[ div [ class "form-group" ]
[ label [ for "server" ] [ text "Mastodon server root URL" ]
, input
[ type_ "url"
, class "form-control"
, id "server"
, required True
, placeholder "https://mastodon.social"
, value model.server
, pattern "https://.+"
, onInput ServerChange
]
[]
, p [ class "help-block" ]
[ text "You'll be redirected to that server to authenticate yourself. We don't have access to your password." ]
]
, button [ class "btn btn-primary", type_ "submit" ]
[ text "Sign into Tooty" ]
]
]
]
]
view : Model -> Html Msg
view model =
div [ class "container-fluid" ]
[ h1 [] [ text "tooty" ]
, errorsListView model
, case model.client of
Just client ->
homepageView model
Nothing ->
authView model
]