1
0
Fork 0

Fix #175: Implement muting and blocking of users. (#182)

This commit is contained in:
Nicolas Perriault 2017-05-25 23:07:17 +02:00 committed by GitHub
parent 868490abab
commit dfc0362242
14 changed files with 644 additions and 32 deletions

View File

@ -62,19 +62,30 @@ body {
.timeline {
overflow-y: auto;
overflow-x: hidden;
max-height: calc(100vh - 45px);
max-height: calc(100vh - 44px);
overflow: hidden;
overflow-y: scroll;
}
.timeline > .list-group-item {
.timeline .list-group-item {
padding: 8px 12px;
}
.empty-timeline-text {
font-size: 30px;
font-weight: bold;
text-align: center;
line-height: 35px;
opacity: .5;
padding: 100px 20px;
}
#blocks-timeline,
#favorite-timeline,
#global-timeline,
#local-timeline,
#global-timeline {
max-height: calc(100vh - 80px);
#mutes-timeline {
max-height: calc(100vh - 81px);
}
@ -83,7 +94,7 @@ li.load-more {
}
.notifications-panel .timeline {
max-height: calc(100vh - 80px);
max-height: calc(100vh - 81px);
}
.panel a {
@ -223,8 +234,9 @@ span.applink {
order: 0;
flex: 0 1 auto;
align-self: auto;
width: 40px;
height: 40px;
width: 38px;
height: 38px;
margin-left: 2px;
}
.acct {
@ -618,7 +630,7 @@ input.form-control[type=file] {
text-align: center;
}
.account-detail .opacity-layer{
.account-detail .opacity-layer {
background: rgba(49,53,67,0.9);
}
@ -631,13 +643,21 @@ input.form-control[type=file] {
.account-detail .btn {
position: absolute;
top: 1em;
left: 1em;
width: 50px;
height: 50px;
top: 10px;
right: 10px;
width: 42px;
height: 42px;
opacity: .8;
}
.account-detail .btn-mute {
top: 54px;
}
.account-detail .btn-block {
top: 98px;
}
.account-detail .account-display-name {
display: block;
font-size: 130%;

View File

@ -15,6 +15,8 @@ module Command
, loadGlobalTimeline
, loadAccountTimeline
, loadFavoriteTimeline
, loadMutes
, loadBlocks
, loadNextTimeline
, loadRelationships
, loadThread
@ -28,6 +30,10 @@ module Command
, unfavouriteStatus
, follow
, unfollow
, mute
, unmute
, block
, unblock
, uploadMedia
, focusId
, scrollColumnToTop
@ -332,6 +338,34 @@ loadFavoriteTimeline client url =
Cmd.none
loadMutes : Maybe Client -> Maybe String -> Cmd Msg
loadMutes client url =
case client of
Just client ->
HttpBuilder.get (Maybe.withDefault ApiUrl.mutes url)
|> withClient client
|> withBodyDecoder (Decode.list accountDecoder)
|> withQueryParams [ ( "limit", "60" ) ]
|> send (MastodonEvent << Mutes (url /= Nothing))
Nothing ->
Cmd.none
loadBlocks : Maybe Client -> Maybe String -> Cmd Msg
loadBlocks client url =
case client of
Just client ->
HttpBuilder.get (Maybe.withDefault ApiUrl.blocks url)
|> withClient client
|> withBodyDecoder (Decode.list accountDecoder)
|> withQueryParams [ ( "limit", "60" ) ]
|> send (MastodonEvent << Blocks (url /= Nothing))
Nothing ->
Cmd.none
loadTimelines : Maybe Client -> Cmd Msg
loadTimelines client =
Cmd.batch
@ -498,6 +532,58 @@ unfollow client account =
Cmd.none
mute : Maybe Client -> Account -> Cmd Msg
mute client account =
case client of
Just client ->
HttpBuilder.post (ApiUrl.mute account.id)
|> withClient client
|> withBodyDecoder relationshipDecoder
|> send (MastodonEvent << (AccountMuted account))
Nothing ->
Cmd.none
unmute : Maybe Client -> Account -> Cmd Msg
unmute client account =
case client of
Just client ->
HttpBuilder.post (ApiUrl.unmute account.id)
|> withClient client
|> withBodyDecoder relationshipDecoder
|> send (MastodonEvent << (AccountUnmuted account))
Nothing ->
Cmd.none
block : Maybe Client -> Account -> Cmd Msg
block client account =
case client of
Just client ->
HttpBuilder.post (ApiUrl.block account.id)
|> withClient client
|> withBodyDecoder relationshipDecoder
|> send (MastodonEvent << (AccountBlocked account))
Nothing ->
Cmd.none
unblock : Maybe Client -> Account -> Cmd Msg
unblock client account =
case client of
Just client ->
HttpBuilder.post (ApiUrl.unblock account.id)
|> withClient client
|> withBodyDecoder relationshipDecoder
|> send (MastodonEvent << (AccountUnblocked account))
Nothing ->
Cmd.none
uploadMedia : Maybe Client -> String -> Cmd Msg
uploadMedia client fileInputId =
case client of

View File

@ -18,6 +18,8 @@ init { registration, clients } location =
, localTimeline = Update.Timeline.empty "local-timeline"
, globalTimeline = Update.Timeline.empty "global-timeline"
, favoriteTimeline = Update.Timeline.empty "favorite-timeline"
, mutes = Update.Timeline.empty "mutes-timeline"
, blocks = Update.Timeline.empty "blocks-timeline"
, accountTimeline = Update.Timeline.empty "account-timeline"
, accountFollowers = Update.Timeline.empty "account-followers"
, accountFollowing = Update.Timeline.empty "account-following"

View File

@ -12,6 +12,8 @@ module Mastodon.ApiUrl
, homeTimeline
, publicTimeline
, favouriteTimeline
, mutes
, blocks
, notifications
, relationships
, statuses
@ -22,6 +24,10 @@ module Mastodon.ApiUrl
, unfavourite
, follow
, unfollow
, mute
, unmute
, block
, unblock
, uploadMedia
, streaming
, searchAccount
@ -68,6 +74,26 @@ unfollow id =
accounts ++ (toString id) ++ "/unfollow"
mute : Int -> String
mute id =
accounts ++ (toString id) ++ "/mute"
unmute : Int -> String
unmute id =
accounts ++ (toString id) ++ "/unmute"
block : Int -> String
block id =
accounts ++ (toString id) ++ "/block"
unblock : Int -> String
unblock id =
accounts ++ (toString id) ++ "/unblock"
userAccount : String
userAccount =
accounts ++ "verify_credentials"
@ -113,6 +139,16 @@ favouriteTimeline =
apiPrefix ++ "/favourites"
mutes : String
mutes =
apiPrefix ++ "/mutes"
blocks : String
blocks =
apiPrefix ++ "/blocks"
notifications : String
notifications =
apiPrefix ++ "/notifications"

View File

@ -45,13 +45,18 @@ type MastodonMsg
| AccountFollowed Account (MastodonResult Relationship)
| AccountFollowers Bool (MastodonResult (List Account))
| AccountFollowing Bool (MastodonResult (List Account))
| AccountBlocked Account (MastodonResult Relationship)
| AccountMuted Account (MastodonResult Relationship)
| AccountReceived (MastodonResult Account)
| AccountRelationship (MastodonResult (List Relationship))
| AccountRelationships (MastodonResult (List Relationship))
| AccountTimeline Bool (MastodonResult (List Status))
| AccountUnfollowed Account (MastodonResult Relationship)
| AccountUnblocked Account (MastodonResult Relationship)
| AccountUnmuted Account (MastodonResult Relationship)
| AppRegistered (MastodonResult AppRegistration)
| AutoSearch (MastodonResult (List Account))
| Blocks Bool (MastodonResult (List Account))
| ContextLoaded Status (MastodonResult Context)
| CurrentUser (MastodonResult Account)
| FavoriteAdded (MastodonResult Status)
@ -60,6 +65,7 @@ type MastodonMsg
| GlobalTimeline Bool (MastodonResult (List Status))
| HomeTimeline Bool (MastodonResult (List Status))
| LocalTimeline Bool (MastodonResult (List Status))
| Mutes Bool (MastodonResult (List Account))
| Notifications Bool (MastodonResult (List Notification))
| Reblogged (MastodonResult Status)
| StatusDeleted (MastodonResult Int)
@ -76,9 +82,9 @@ type WebSocketMsg
type Msg
= AddFavorite Status
| AskConfirm String Msg Msg
| Block Account
| ClearError Int
| CloseAccount
| CloseAccountSelector
| CloseThread
| ConfirmCancelled Msg
| Confirmed Msg
@ -90,6 +96,7 @@ type Msg
| LogoutClient Client
| TimelineLoadNext String String
| MastodonEvent MastodonMsg
| Mute Account
| NoOp
| OpenThread Status
| ReblogStatus Status
@ -102,8 +109,10 @@ type Msg
| SwitchClient Client
| Tick Time
| UnfollowAccount Account
| UrlChange Navigation.Location
| Unblock Account
| Unmute Account
| UnreblogStatus Status
| UrlChange Navigation.Location
| ViewAccountFollowing Account
| ViewAccountFollowers Account
| ViewAccountStatuses Account
@ -124,9 +133,11 @@ type CurrentView
| AccountFollowingView Account (Timeline Account)
| AccountView Account
| AccountSelectorView
| BlocksView
| FavoriteTimelineView
| GlobalTimelineView
| LocalTimelineView
| MutesView
| ThreadView Thread
@ -200,6 +211,8 @@ type alias Model =
, localTimeline : Timeline Status
, globalTimeline : Timeline Status
, favoriteTimeline : Timeline Status
, mutes : Timeline Account
, blocks : Timeline Account
, accountTimeline : Timeline Status
, accountFollowers : Timeline Account
, accountFollowing : Timeline Account

View File

@ -60,9 +60,26 @@ update msg model =
{ model | currentView = view, server = "" } ! []
FavoriteTimelineView ->
{ model | currentView = view }
{ model
| currentView = view
, favoriteTimeline = Update.Timeline.setLoading True model.favoriteTimeline
}
! [ Command.loadFavoriteTimeline (List.head model.clients) Nothing ]
BlocksView ->
{ model
| currentView = view
, blocks = Update.Timeline.setLoading True model.blocks
}
! [ Command.loadBlocks (List.head model.clients) Nothing ]
MutesView ->
{ model
| currentView = view
, mutes = Update.Timeline.setLoading True model.mutes
}
! [ Command.loadMutes (List.head model.clients) Nothing ]
_ ->
{ model | currentView = view } ! []
@ -141,6 +158,18 @@ update msg model =
UnfollowAccount account ->
model ! [ Command.unfollow (List.head model.clients) account ]
Mute account ->
model ! [ Command.mute (List.head model.clients) account ]
Unmute account ->
model ! [ Command.unmute (List.head model.clients) account ]
Block account ->
model ! [ Command.block (List.head model.clients) account ]
Unblock account ->
model ! [ Command.unblock (List.head model.clients) account ]
DeleteStatus id ->
model ! [ Command.deleteStatus (List.head model.clients) id ]
@ -221,9 +250,6 @@ update msg model =
}
! []
CloseAccountSelector ->
{ model | currentView = LocalTimelineView } ! []
FilterNotifications filter ->
{ model | notificationFilter = filter } ! []

View File

@ -50,7 +50,7 @@ update msg model =
AccountFollowed _ result ->
case result of
Ok { decoded } ->
processFollowEvent decoded True model ! []
processFollowEvent decoded model ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
@ -63,6 +63,38 @@ update msg model =
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
AccountMuted account result ->
case result of
Ok { decoded } ->
processMuteEvent account decoded model ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
AccountUnmuted account result ->
case result of
Ok { decoded } ->
processMuteEvent account decoded model ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
AccountBlocked account result ->
case result of
Ok { decoded } ->
processBlockEvent account decoded model ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
AccountUnblocked account result ->
case result of
Ok { decoded } ->
processBlockEvent account decoded model ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
AppRegistered result ->
case result of
Ok { decoded } ->
@ -157,6 +189,22 @@ update msg model =
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
Mutes append result ->
case result of
Ok { decoded, links } ->
{ model | mutes = Update.Timeline.update append decoded links model.mutes } ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
Blocks append result ->
case result of
Ok { decoded, links } ->
{ model | blocks = Update.Timeline.update append decoded links model.blocks } ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
Reblogged result ->
case result of
Ok _ ->
@ -301,12 +349,12 @@ update msg model =
{-| Update viewed account relationships as well as the relationship with the
current connected user, both according to the "following" status provided.
-}
processFollowEvent : Relationship -> Bool -> Model -> Model
processFollowEvent relationship flag model =
processFollowEvent : Relationship -> Model -> Model
processFollowEvent relationship model =
let
updateRelationship r =
if r.id == relationship.id then
{ r | following = flag }
{ r | following = relationship.following }
else
r
@ -317,7 +365,7 @@ processFollowEvent relationship flag model =
case model.accountRelationship of
Just accountRelationship ->
if accountRelationship.id == relationship.id then
Just { relationship | following = flag }
Just { relationship | following = relationship.following }
else
model.accountRelationship
@ -334,7 +382,7 @@ processUnfollowEvent : Account -> Relationship -> Model -> Model
processUnfollowEvent account relationship model =
let
newModel =
processFollowEvent relationship False model
processFollowEvent relationship model
in
case model.currentUser of
Just currentUser ->
@ -344,3 +392,76 @@ processUnfollowEvent account relationship model =
Nothing ->
newModel
{-| Update viewed account relationships as well as the relationship with the
current connected user, both according to the "muting" status provided.
-}
processMuteEvent : Account -> Relationship -> Model -> Model
processMuteEvent account relationship model =
let
updateRelationship r =
if r.id == relationship.id then
{ r | muting = relationship.muting }
else
r
accountRelationships =
model.accountRelationships |> List.map updateRelationship
accountRelationship =
case model.accountRelationship of
Just accountRelationship ->
if accountRelationship.id == relationship.id then
Just { relationship | muting = relationship.muting }
else
model.accountRelationship
Nothing ->
Nothing
in
{ model
| accountRelationships = accountRelationships
, accountRelationship = accountRelationship
, homeTimeline = Update.Timeline.dropAccountStatuses account model.homeTimeline
, localTimeline = Update.Timeline.dropAccountStatuses account model.localTimeline
, globalTimeline = Update.Timeline.dropAccountStatuses account model.globalTimeline
, mutes = Update.Timeline.removeMute account model.mutes
}
{-| Update viewed account relationships as well as the relationship with the
current connected user, both according to the "blocking" status provided.
-}
processBlockEvent : Account -> Relationship -> Model -> Model
processBlockEvent account relationship model =
let
updateRelationship r =
if r.id == relationship.id then
{ r | blocking = relationship.blocking }
else
r
accountRelationships =
model.accountRelationships |> List.map updateRelationship
accountRelationship =
case model.accountRelationship of
Just accountRelationship ->
if accountRelationship.id == relationship.id then
Just { relationship | blocking = relationship.blocking }
else
model.accountRelationship
Nothing ->
Nothing
in
{ model
| accountRelationships = accountRelationships
, accountRelationship = accountRelationship
, homeTimeline = Update.Timeline.dropAccountStatuses account model.homeTimeline
, localTimeline = Update.Timeline.dropAccountStatuses account model.localTimeline
, globalTimeline = Update.Timeline.dropAccountStatuses account model.globalTimeline
, blocks = Update.Timeline.removeBlock account model.blocks
, notifications = Update.Timeline.dropNotificationsFromAccount account model.notifications
}

View File

@ -3,11 +3,16 @@ module Update.Timeline
( cleanUnfollow
, deleteStatusFromAllTimelines
, deleteStatus
, dropAccountStatuses
, dropNotificationsFromAccount
, empty
, markAsLoading
, prepend
, processReblog
, processFavourite
, removeBlock
, removeMute
, setLoading
, update
, updateWithBoolFlag
)
@ -101,6 +106,29 @@ deleteStatus statusId ({ entries } as timeline) =
}
dropAccountStatuses : Account -> Timeline Status -> Timeline Status
dropAccountStatuses account timeline =
let
keep status =
not <| Mastodon.Helper.sameAccount account status.account
in
{ timeline | entries = List.filter keep timeline.entries }
dropNotificationsFromAccount : Account -> Timeline NotificationAggregate -> Timeline NotificationAggregate
dropNotificationsFromAccount account timeline =
let
keepNotification notification =
case notification.status of
Just status ->
status.account /= account
Nothing ->
True
in
{ timeline | entries = List.filter keepNotification timeline.entries }
empty : String -> Timeline a
empty id =
{ id = id
@ -197,6 +225,29 @@ processReblog status added model =
model
removeBlock : Account -> Timeline Account -> Timeline Account
removeBlock account timeline =
let
keep blockedAccount =
not <| Mastodon.Helper.sameAccount account blockedAccount
in
{ timeline | entries = List.filter keep timeline.entries }
removeMute : Account -> Timeline Account -> Timeline Account
removeMute account timeline =
let
keep mutedAccount =
not <| Mastodon.Helper.sameAccount account mutedAccount
in
{ timeline | entries = List.filter keep timeline.entries }
setLoading : Bool -> Timeline a -> Timeline a
setLoading flag timeline =
{ timeline | loading = flag }
update : Bool -> List a -> Links -> Timeline a -> Timeline a
update append entries links timeline =
let

View File

@ -51,7 +51,7 @@ followButton currentUser relationship account =
case relationship of
Nothing ->
( NoOp
, "btn btn-default btn-disabled"
, "btn btn-default btn-follow btn-disabled"
, "question-sign"
, "Unknown relationship"
)
@ -59,13 +59,13 @@ followButton currentUser relationship account =
Just relationship ->
if relationship.following then
( UnfollowAccount account
, "btn btn-default btn-primary"
, "btn btn-default btn-follow btn-primary"
, "eye-close"
, "Unfollow"
)
else
( FollowAccount account
, "btn btn-default"
, "btn btn-default btn-follow"
, "eye-open"
, "Follow"
)
@ -94,10 +94,77 @@ followView currentUser relationship account =
, br [] []
, text <| "@" ++ account.acct
]
, 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 :
CurrentUser
-> Timeline Account
@ -157,16 +224,30 @@ accountView currentUser account relationship panelContent =
]
[ div [ class "opacity-layer" ]
[ followButton currentUser relationship account
, muteButton currentUser relationship account
, blockButton currentUser relationship account
, Common.accountAvatarLink True account
, span [ class "account-display-name" ] [ text account.display_name ]
, span [ class "account-username" ]
[ Common.accountLink True account
, case relationship of
Just relationship ->
if relationship.followed_by then
span [ class "badge followed-by" ] [ text "Follows you" ]
else
text ""
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 ""
]
Nothing ->
text ""

View File

@ -80,7 +80,7 @@ accountSelectorView : Model -> Html Msg
accountSelectorView model =
div [ class "col-md-3 column" ]
[ div [ class "panel panel-default" ]
[ closeablePanelheading "account-selector" "user" "Account selector" CloseAccountSelector
[ closeablePanelheading "account-selector" "user" "Account selector" (SetView LocalTimelineView)
, contextualTimelineMenu model.currentView
, ul [ class "list-group " ] <|
List.map (accountIdentityView model.currentUser) model.clients

View File

@ -8,9 +8,11 @@ import Types exposing (..)
import View.Account exposing (accountFollowView, accountTimelineView)
import View.AccountSelector exposing (accountSelectorView)
import View.Auth exposing (authView)
import View.Blocks exposing (blocksView)
import View.Common as Common
import View.Draft exposing (draftView)
import View.Error exposing (errorsListView)
import View.Mutes exposing (mutesView)
import View.Notification exposing (notificationListView)
import View.Thread exposing (threadView)
import View.Timeline exposing (contextualTimelineView, homeTimelineView)
@ -58,6 +60,12 @@ homepageView model =
AccountSelectorView ->
accountSelectorView model
MutesView ->
mutesView model
BlocksView ->
blocksView model
AccountFollowersView account followers ->
accountFollowView
currentUser

83
src/View/Blocks.elm Normal file
View File

@ -0,0 +1,83 @@
module View.Blocks exposing (blocksView)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Html.Keyed as Keyed
import Mastodon.Helper exposing (..)
import Mastodon.Model exposing (..)
import Types exposing (..)
import View.Common as Common
import View.Events exposing (..)
import View.Timeline exposing (contextualTimelineMenu)
type alias CurrentUser =
Maybe Account
blockView : CurrentUser -> Account -> Html Msg
blockView currentUser account =
let
( isCurrentUser, entryClass ) =
case currentUser of
Just currentUser ->
if sameAccount account currentUser then
( True, "active" )
else
( False, "" )
Nothing ->
( False, "" )
in
li [ class <| "list-group-item status " ++ entryClass ]
[ div [ class "follow-entry" ]
[ Common.accountAvatarLink False account
, div [ class "userinfo" ]
[ strong []
[ a
[ href account.url
, onClickWithPreventAndStop <| LoadAccount account.id
]
[ text <|
if account.display_name /= "" then
account.display_name
else
account.username
]
]
, br [] []
, text <| "@" ++ account.acct
]
, button
[ class "btn btn-default btn-block btn-primary"
, title "Unblock"
, onClick <| Unblock account
]
[ Common.icon "ok-circle" ]
]
]
blocksView : Model -> Html Msg
blocksView model =
let
keyedEntry account =
( toString account.id
, blockView model.currentUser account
)
entries =
List.map keyedEntry model.blocks.entries
in
div [ class "col-md-3 column" ]
[ div [ class "panel panel-default" ]
[ Common.closeablePanelheading "blocks-timeline" "ban-circle" "Blocked accounts" (SetView LocalTimelineView)
, contextualTimelineMenu model.currentView
, if List.length model.blocks.entries == 0 then
p [ class "empty-timeline-text" ] [ text "Nobody's muted here." ]
else
Keyed.ul [ id "blocks-timeline", class "list-group timeline" ] <|
(entries ++ [ ( "load-more", Common.loadMoreBtn model.blocks ) ])
]
]

83
src/View/Mutes.elm Normal file
View File

@ -0,0 +1,83 @@
module View.Mutes exposing (mutesView)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Html.Keyed as Keyed
import Mastodon.Helper exposing (..)
import Mastodon.Model exposing (..)
import Types exposing (..)
import View.Common as Common
import View.Events exposing (..)
import View.Timeline exposing (contextualTimelineMenu)
type alias CurrentUser =
Maybe Account
muteView : CurrentUser -> Account -> Html Msg
muteView currentUser account =
let
( isCurrentUser, entryClass ) =
case currentUser of
Just currentUser ->
if sameAccount account currentUser then
( True, "active" )
else
( False, "" )
Nothing ->
( False, "" )
in
li [ class <| "list-group-item status " ++ entryClass ]
[ div [ class "follow-entry" ]
[ Common.accountAvatarLink False account
, div [ class "userinfo" ]
[ strong []
[ a
[ href account.url
, onClickWithPreventAndStop <| LoadAccount account.id
]
[ text <|
if account.display_name /= "" then
account.display_name
else
account.username
]
]
, br [] []
, text <| "@" ++ account.acct
]
, button
[ class "btn btn-default btn-mute btn-primary"
, title "Unmute"
, onClick <| Unmute account
]
[ Common.icon "volume-up" ]
]
]
mutesView : Model -> Html Msg
mutesView model =
let
keyedEntry account =
( toString account.id
, muteView model.currentUser account
)
entries =
List.map keyedEntry model.mutes.entries
in
div [ class "col-md-3 column" ]
[ div [ class "panel panel-default" ]
[ Common.closeablePanelheading "mutes-timeline" "volume-off" "Muted accounts" (SetView LocalTimelineView)
, contextualTimelineMenu model.currentView
, if (not model.mutes.loading && List.length model.mutes.entries == 0) then
p [ class "empty-timeline-text" ] [ text "Nobody's blocked here." ]
else
Keyed.ul [ id "mutes-timeline", class "list-group timeline" ] <|
(entries ++ [ ( "load-more", Common.loadMoreBtn model.mutes ) ])
]
]

View File

@ -81,6 +81,8 @@ contextualTimelineMenu currentView =
[ btnView "Local timeline" "th-large" LocalTimelineView
, btnView "Global timeline" "globe" GlobalTimelineView
, btnView "Favorites" "star" FavoriteTimelineView
, btnView "Blocks" "ban-circle" BlocksView
, btnView "Mutes" "volume-off" MutesView
, btnView "Accounts" "user" AccountSelectorView
]