2020-05-07 13:10:53 +00:00
import { mapGetters } from 'vuex'
2018-04-09 17:44:37 +00:00
import Notification from '../notification/notification.vue'
2021-03-01 14:21:35 +00:00
import NotificationFilters from './notification_filters.vue'
2018-08-12 11:14:34 +00:00
import notificationsFetcher from '../../services/notifications_fetcher/notifications_fetcher.service.js'
2018-12-28 19:39:54 +00:00
import {
notificationsFromStore ,
2020-01-14 13:28:57 +00:00
filteredNotificationsFromStore ,
2018-12-28 19:39:54 +00:00
unseenNotificationsFromStore
} from '../../services/notification_utils/notification_utils.js'
2020-11-02 13:46:49 +00:00
import FaviconService from '../../services/favicon_service/favicon_service.js'
2020-10-19 19:35:46 +00:00
import { library } from '@fortawesome/fontawesome-svg-core'
import { faCircleNotch } from '@fortawesome/free-solid-svg-icons'
library . add (
faCircleNotch
)
2016-11-27 18:44:56 +00:00
2020-01-14 13:28:57 +00:00
const DEFAULT _SEEN _TO _DISPLAY _COUNT = 30
2016-11-27 18:44:56 +00:00
const Notifications = {
2021-03-01 14:21:35 +00:00
components : {
Notification ,
NotificationFilters
} ,
2019-05-15 17:44:35 +00:00
props : {
// Disables panel styles, unread mark, potentially other notification-related actions
// meant for "Interactions" timeline
minimalMode : Boolean ,
// Custom filter mode, an array of strings, possible values 'mention', 'repeat', 'like', 'follow', used to override global filter for use in "Interactions" timeline
2022-06-07 13:52:03 +00:00
filterMode : Array ,
// Disable teleporting (i.e. for /users/user/notifications)
disableTeleport : Boolean
2019-05-15 17:49:46 +00:00
} ,
2019-01-29 19:04:52 +00:00
data ( ) {
return {
2020-01-14 13:28:57 +00:00
bottomedOut : false ,
// How many seen notifications to display in the list. The more there are,
// the heavier the page becomes. This count is increased when loading
// older notifications, and cut back to default whenever hitting "Read!".
seenToDisplayCount : DEFAULT _SEEN _TO _DISPLAY _COUNT
2019-01-29 19:04:52 +00:00
}
} ,
2016-11-27 18:44:56 +00:00
computed : {
2019-05-14 19:38:16 +00:00
mainClass ( ) {
return this . minimalMode ? '' : 'panel panel-default'
} ,
2017-02-18 19:42:00 +00:00
notifications ( ) {
2018-12-28 19:39:54 +00:00
return notificationsFromStore ( this . $store )
2017-02-18 19:42:00 +00:00
} ,
2018-08-20 17:45:54 +00:00
error ( ) {
return this . $store . state . statuses . notifications . error
} ,
2017-02-18 19:42:00 +00:00
unseenNotifications ( ) {
2018-12-28 19:39:54 +00:00
return unseenNotificationsFromStore ( this . $store )
2017-02-18 19:42:00 +00:00
} ,
2020-01-14 13:28:57 +00:00
filteredNotifications ( ) {
return filteredNotificationsFromStore ( this . $store , this . filterMode )
2017-02-18 19:42:00 +00:00
} ,
unseenCount ( ) {
return this . unseenNotifications . length
2019-01-29 19:04:52 +00:00
} ,
2020-05-07 13:10:53 +00:00
unseenCountTitle ( ) {
return this . unseenCount + ( this . unreadChatCount )
} ,
2019-01-29 19:04:52 +00:00
loading ( ) {
return this . $store . state . statuses . notifications . loading
2020-01-14 13:28:57 +00:00
} ,
2022-04-05 16:22:15 +00:00
noHeading ( ) {
const { layoutType } = this . $store . state . interface
2022-04-07 11:37:16 +00:00
return this . minimalMode || layoutType === 'mobile'
2022-04-05 16:22:15 +00:00
} ,
teleportTarget ( ) {
const { layoutType } = this . $store . state . interface
const map = {
wide : '#notifs-column' ,
mobile : '#mobile-notifications'
}
return map [ layoutType ] || '#notifs-sidebar'
} ,
2020-01-14 13:28:57 +00:00
notificationsToDisplay ( ) {
return this . filteredNotifications . slice ( 0 , this . unseenCount + this . seenToDisplayCount )
2020-05-07 13:10:53 +00:00
} ,
... mapGetters ( [ 'unreadChatCount' ] )
2017-02-18 19:42:00 +00:00
} ,
watch : {
2020-05-07 13:10:53 +00:00
unseenCountTitle ( count ) {
2017-02-19 11:19:47 +00:00
if ( count > 0 ) {
2020-11-02 13:46:49 +00:00
FaviconService . drawFaviconBadge ( )
2017-02-19 11:19:47 +00:00
this . $store . dispatch ( 'setPageTitle' , ` ( ${ count } ) ` )
} else {
2020-11-02 13:46:49 +00:00
FaviconService . clearFaviconBadge ( )
2017-02-19 11:19:47 +00:00
this . $store . dispatch ( 'setPageTitle' , '' )
}
2017-02-18 19:42:00 +00:00
}
} ,
methods : {
markAsSeen ( ) {
2019-03-12 21:16:57 +00:00
this . $store . dispatch ( 'markNotificationsAsSeen' )
2020-01-14 13:28:57 +00:00
this . seenToDisplayCount = DEFAULT _SEEN _TO _DISPLAY _COUNT
2019-03-12 21:16:57 +00:00
} ,
2018-08-12 11:14:34 +00:00
fetchOlderNotifications ( ) {
2019-05-03 11:52:22 +00:00
if ( this . loading ) {
return
}
2020-01-14 13:28:57 +00:00
const seenCount = this . filteredNotifications . length - this . unseenCount
if ( this . seenToDisplayCount < seenCount ) {
this . seenToDisplayCount = Math . min ( this . seenToDisplayCount + 20 , seenCount )
return
} else if ( this . seenToDisplayCount > seenCount ) {
this . seenToDisplayCount = seenCount
}
2018-08-12 11:14:34 +00:00
const store = this . $store
const credentials = store . state . users . currentUser . credentials
2019-01-29 19:04:52 +00:00
store . commit ( 'setNotificationsLoading' , { value : true } )
2018-08-12 11:14:34 +00:00
notificationsFetcher . fetchAndUpdate ( {
store ,
credentials ,
older : true
2019-01-29 19:04:52 +00:00
} ) . then ( notifs => {
store . commit ( 'setNotificationsLoading' , { value : false } )
if ( notifs . length === 0 ) {
this . bottomedOut = true
}
2020-01-14 13:28:57 +00:00
this . seenToDisplayCount += notifs . length
2018-08-12 11:14:34 +00:00
} )
2016-11-27 18:44:56 +00:00
}
}
}
export default Notifications