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" || type_ == "follow_request" 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.accountLinkSmall 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.lazy3 statusView context status True , Lazy.lazy3 statusActionsView status currentUser False ] notificationFollowView : CurrentUser -> NotificationAggregate -> Html Msg notificationFollowView currentUser { type_, accounts } = let profileView : AccountNotificationDate -> Html Msg profileView { account, created_at } = div [ class "status follow-profile" ] [ Common.accountAvatarLink False account , div [ class "username" ] [ Common.accountLinkLarge 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) ] ] message = if type_ == "follow_request" then "sent you a follow request" else "started following you" in div [ class "notification follow" ] [ notificationHeading accounts message "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 ) ]) ] ]