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

192 lines
6.8 KiB
Elm

module View.Notification exposing (notificationListView)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Html.Keyed as Keyed
import Html.Lazy as Lazy
import Mastodon.Model exposing (..)
import Types exposing (..)
import View.Common as Common
import View.Events exposing (..)
import View.Formatter exposing (formatContent)
import View.Status exposing (statusActionsView, statusView)
type alias CurrentUser =
Account
filterNotifications : NotificationFilter -> List NotificationAggregate -> List NotificationAggregate
filterNotifications filter notifications =
let
applyFilter { type_, status } =
let
visibility =
case status of
Just status ->
status.visibility
Nothing ->
""
in
case filter of
NotificationAll ->
True
NotificationOnlyMentions ->
type_ == "mention" && visibility /= "direct"
NotificationOnlyDirect ->
type_ == "mention" && visibility == "direct"
NotificationOnlyBoosts ->
type_ == "reblog"
NotificationOnlyFavourites ->
type_ == "favourite"
NotificationOnlyFollows ->
type_ == "follow"
in
if filter == NotificationAll then
notifications
else
List.filter applyFilter notifications
notificationHeading : List AccountNotificationDate -> String -> String -> Html Msg
notificationHeading accountsAndDate str iconType =
let
( firstAccounts, finalStr ) =
case accountsAndDate of
[ a1 ] ->
( [ a1.account ], str )
[ a1, a2 ] ->
( [ a1.account, a2.account ], str )
[ a1, a2, a3 ] ->
( [ a1.account, a2.account, a3.account ], str )
a1 :: a2 :: a3 :: xs ->
( [ a1.account, a2.account, a3.account ], " and " ++ (toString <| List.length xs) ++ " others " ++ str )
_ ->
( [], "" )
in
div [ class "status-info" ]
[ div [ class "avatars" ] <|
List.map (Common.accountAvatarLink False) (List.map .account accountsAndDate)
, p [ class "status-info-text" ] <|
List.intersperse (text " ")
[ Common.icon iconType
, span [] <| List.intersperse (text ", ") (List.map (Common.accountLink False) firstAccounts)
, text finalStr
]
]
notificationStatusView : ( String, CurrentUser, Status, NotificationAggregate ) -> Html Msg
notificationStatusView ( context, currentUser, status, { type_, accounts } ) =
div [ class <| "notification " ++ type_ ]
[ case type_ of
"reblog" ->
notificationHeading accounts "boosted your toot" "fire"
"favourite" ->
notificationHeading accounts "favourited your toot" "star"
_ ->
text ""
, Lazy.lazy2 statusView context status
, Lazy.lazy3 statusActionsView status currentUser False
]
notificationFollowView : CurrentUser -> NotificationAggregate -> Html Msg
notificationFollowView currentUser { accounts } =
let
profileView : AccountNotificationDate -> Html Msg
profileView { account, created_at } =
div [ class "status follow-profile" ]
[ Common.accountAvatarLink False account
, div [ class "username" ]
[ Common.accountLink False account
, span [ class "btn-sm follow-profile-date" ]
[ Common.icon "time", text <| Common.formatDate created_at ]
]
, formatContent account.note []
|> div
[ class "status-text"
, onClick <| Navigate ("#account/" ++ account.id)
]
]
in
div [ class "notification follow" ]
[ notificationHeading accounts "started following you" "user"
, div [ class "" ] <| List.map profileView (List.take 3 accounts)
]
notificationEntryView : CurrentUser -> NotificationAggregate -> Html Msg
notificationEntryView currentUser notification =
li [ class "list-group-item" ]
[ case notification.status of
Just status ->
Lazy.lazy notificationStatusView ( "notification", currentUser, status, notification )
Nothing ->
notificationFollowView currentUser notification
]
notificationFilterView : NotificationFilter -> Html Msg
notificationFilterView filter =
let
filterBtn tooltip iconName event =
button
[ class <|
if filter == event then
"btn btn-primary active"
else
"btn btn-default"
, title tooltip
, onClick <| FilterNotifications event
]
[ Common.icon iconName ]
in
Common.justifiedButtonGroup "column-menu notification-filters"
[ filterBtn "All notifications" "asterisk" NotificationAll
, filterBtn "Mentions" "share-alt" NotificationOnlyMentions
, filterBtn "Direct" "envelope" NotificationOnlyDirect
, filterBtn "Boosts" "fire" NotificationOnlyBoosts
, filterBtn "Favorites" "star" NotificationOnlyFavourites
, filterBtn "Follows" "user" NotificationOnlyFollows
]
notificationListView : CurrentUser -> NotificationFilter -> Timeline NotificationAggregate -> Html Msg
notificationListView currentUser filter notifications =
let
keyedEntry notification =
( notification.id
, Lazy.lazy2 notificationEntryView currentUser notification
)
entries =
notifications.entries
|> filterNotifications filter
|> List.map keyedEntry
in
div [ class "col-md-3 column" ]
[ div [ class "panel panel-default notifications-panel" ]
[ a
[ href "", onClickWithPreventAndStop <| ScrollColumn ScrollTop "notifications" ]
[ div [ class "panel-heading" ] [ Common.icon "bell", text "Notifications" ] ]
, notificationFilterView filter
, Keyed.ul [ id "notifications", class "list-group timeline" ] <|
(entries ++ [ ( "load-more", Common.loadMoreBtn notifications ) ])
]
]