416 lines
16 KiB
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
|
|
]
|
|
]
|
|
]
|