1
0
Fork 0
tooty/src/View/Account.elm

416 lines
16 KiB
Elm

module View.Account exposing (accountView)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Html.Keyed as Keyed
import Html.Lazy as Lazy
import List.Extra exposing (find)
import Mastodon.Helper exposing (extractStatusId)
import Mastodon.Model exposing (..)
import Types exposing (..)
import View.Common as Common
import View.Status exposing (statusEntryView)
import View.Formatter exposing (formatContent, textContent)
type alias CurrentUser =
Account
type alias CurrentUserRelation =
Maybe Relationship
movedIndicator : Account -> Html Msg
movedIndicator account =
let
displayName account =
if account.display_name == "" then
account.username
else
account.display_name
in
if account.moved.id /= "" then
div [ class "account-notice" ]
[ p []
[ Common.icon "briefcase"
, text <| " " ++ displayName account
, text " has moved to:"
]
, div [ class "status" ]
[ a
[ href
<| "#account/" ++ account.moved.id
]
[ img [ class "avatar", src account.moved.avatar ] []
, div [ class "username" ]
[ text <| displayName account.moved
, br [] []
, span [ class "acct" ] [ text <| "@" ++ account.moved.acct ]
]
, div [ class "status-text" ]
( formatContent account.moved.note [] [] )
]
]
]
else
text ""
followButton : CurrentUser -> CurrentUserRelation -> Account -> Html Msg
followButton currentUser relationship account =
if Mastodon.Helper.sameAccount account currentUser then
text ""
else
let
( followEvent, btnClasses, iconName, tooltip ) =
case relationship of
Nothing ->
( NoOp
, "btn btn-default btn-follow btn-disabled"
, "question-sign"
, "Unknown relationship"
)
Just relationship ->
if relationship.following then
( UnfollowAccount account
, "btn btn-default btn-follow btn-primary"
, "eye-close"
, "Unfollow"
)
else
if relationship.requested then
( UnfollowAccount account
, "btn btn-default btn-follow btn-warning"
, "remove-sign"
, "Cancel follow request"
)
else
( FollowAccount account
, "btn btn-default btn-follow"
, "eye-open"
, "Follow"
)
in
button [ class btnClasses, title tooltip, onClick followEvent ]
[ Common.icon iconName ]
followView : CurrentUser -> Maybe Relationship -> Account -> Html Msg
followView currentUser relationship account =
div [ class "follow-entry" ]
[ Common.accountAvatarLink False account
, div [ class "userinfo" ]
[ strong []
[ a
[ href <| "#account/" ++ account.id ]
[ text <|
if account.display_name /= "" then
account.display_name
else
account.username
]
]
, br [] []
, Common.accountAcctView True account
]
, muteButton currentUser relationship account
, followButton currentUser relationship account
]
muteButton : CurrentUser -> CurrentUserRelation -> Account -> Html Msg
muteButton currentUser relationship account =
if Mastodon.Helper.sameAccount account currentUser then
text ""
else
let
( muteEvent, btnClasses, iconName, tooltip ) =
case relationship of
Nothing ->
( NoOp
, "btn btn-default btn-mute btn-disabled"
, "question-sign"
, "Unknown relationship"
)
Just relationship ->
if relationship.muting then
( Unmute account
, "btn btn-default btn-mute btn-primary"
, "volume-up"
, "Unmute"
)
else
( Mute account
, "btn btn-default btn-mute"
, "volume-off"
, "Mute"
)
in
button [ class btnClasses, title tooltip, onClick muteEvent ]
[ Common.icon iconName ]
blockButton : CurrentUser -> CurrentUserRelation -> Account -> Html Msg
blockButton currentUser relationship account =
if Mastodon.Helper.sameAccount account currentUser then
text ""
else
let
( blockEvent, btnClasses, iconName, tooltip ) =
case relationship of
Nothing ->
( NoOp
, "btn btn-default btn-block btn-disabled"
, "question-sign"
, "Unknown relationship"
)
Just relationship ->
if relationship.blocking then
( Unblock account
, "btn btn-default btn-block btn-primary"
, "ok-circle"
, "Unblock"
)
else
( Block account
, "btn btn-default btn-block"
, "ban-circle"
, "Block"
)
in
button [ class btnClasses, title tooltip, onClick blockEvent ]
[ Common.icon iconName ]
accountFollowView : CurrentAccountView -> CurrentUser -> AccountInfo -> Html Msg
accountFollowView view currentUser accountInfo =
let
keyedEntry account =
( account.id
, li [ class "list-group-item status" ]
[ followView
currentUser
(find (\r -> r.id == account.id) accountInfo.relationships)
account
]
)
timeline =
if view == AccountFollowersView then
accountInfo.followers
else
accountInfo.following
entries =
List.map keyedEntry timeline.entries
in
case accountInfo.account of
Just account ->
Keyed.ul [ class "list-group" ] <|
(entries ++ [ ( "load-more", Common.loadMoreBtn timeline ) ])
Nothing ->
text ""
accountTimelineView : CurrentUser -> AccountInfo -> Bool -> Html Msg
accountTimelineView currentUser accountInfo pins =
let
keyedEntry status =
( extractStatusId status.id
, Lazy.lazy (statusEntryView "account" "status" currentUser) status
)
entries =
List.map keyedEntry accountInfo.timeline.entries
setPin status =
{ status | pinned = True }
pins =
List.map keyedEntry (List.map setPin accountInfo.pins)
in
case accountInfo.account of
Just account ->
Keyed.ul [ id accountInfo.timeline.id, class "list-group" ] <|
List.append pins (entries ++ [ ( "load-more", Common.loadMoreBtn accountInfo.timeline ) ])
Nothing ->
text ""
counterLink : String -> String -> Int -> Bool -> Html Msg
counterLink href_ label count active =
a
[ href href_
, class <|
"col-md-3"
++ (if active then
" active"
else
""
)
]
[ text label
, br [] []
, text <| toString count
]
counterLinks : CurrentAccountView -> Account -> Html Msg
counterLinks subView account =
let
{ statuses_count, following_count, followers_count } =
account
in
div [ class "row account-infos" ]
[ counterLink
("#account/" ++ account.id)
"Statuses"
statuses_count
(subView == AccountStatusesView)
, counterLink
("#account/" ++ account.id ++ "/replies")
"With Replies"
statuses_count
(subView == AccountStatusesRepliesView)
, counterLink
("#account/" ++ account.id ++ "/following")
"Following"
following_count
(subView == AccountFollowingView)
, counterLink
("#account/" ++ account.id ++ "/followers")
"Followers"
followers_count
(subView == AccountFollowersView)
]
makeField : Field -> Html Msg
makeField field =
let
dd_class =
if field.verified_at == "" then
""
else
"verified"
checkmark =
if field.verified_at == "" then
text ""
else
span
[ title ("Verified at " ++ Common.formatDate field.verified_at)
, style [ ( "margin-right", "4px") ]
] [ Common.icon "check" ]
in
dl []
[ dt [ title field.name ] [ text field.name ]
, dd [ title (textContent field.value)
, class dd_class ]
(checkmark :: (formatContent field.value [] []))
]
fields : CurrentAccountView -> Account -> Html Msg
fields subView account =
div [ class "row account-fields" ]
(List.map makeField account.fields)
accountView : CurrentAccountView -> CurrentUser -> AccountInfo -> Html Msg
accountView subView currentUser accountInfo =
case accountInfo.account of
Nothing ->
text ""
Just account ->
div [ class "col-md-3 column" ]
[ div [ class "panel panel-default" ]
[ Common.closeablePanelheading "account" "user" "Account"
, div
[ id "account"
, class
<| "timeline" ++
if account.moved.id /= "" then
" inactive"
else
""
]
[ movedIndicator account
, div
[ class "account-detail"
, style [ ( "background-image", "url('" ++ account.header ++ "')" ),
( "background-position", "center" ),
( "background-size", "cover" ) ]
]
[ div [ class "opacity-layer" ]
[ followButton currentUser accountInfo.relationship account
, muteButton currentUser accountInfo.relationship account
, blockButton currentUser accountInfo.relationship account
, Common.accountAvatarLink True account
, span [ class "account-display-name" ] <| Common.accountDisplayNameRich account
, span [ class "account-username" ]
[ Common.accountLink True account
, if account.locked then
span
[
title "Locked account. The owner will manually approve their followers.",
style [ ( "margin-left", "4px") ]
]
[ Common.icon "lock" ]
else
text ""
, case accountInfo.relationship of
Just relationship ->
span []
[ if relationship.followed_by then
span [ class "badge followed-by" ] [ text "Follows you" ]
else
text ""
, text " "
, if relationship.muting then
span [ class "badge muting" ] [ text "Muted" ]
else
text ""
, text " "
, if relationship.blocking then
span [ class "badge blocking" ] [ text "Blocked" ]
else
text ""
, if relationship.blocked_by then
span [ class "badge blocking" ] [ text "Blocks you" ]
else
text ""
]
Nothing ->
text ""
, if account.bot then
span [ class "badge bot" ] [ text "Bot" ]
else
text ""
]
, span [ class "account-note" ] (formatContent account.note [] account.emojis)
]
]
, fields subView account
, counterLinks subView account
, case subView of
AccountStatusesView ->
accountTimelineView currentUser accountInfo True
AccountStatusesRepliesView ->
accountTimelineView currentUser accountInfo False
_ ->
accountFollowView subView currentUser accountInfo
]
]
]