4dc4a91224
* origin/develop: add SK (Slovak) translation ReactButton: Workaround for android composition mode EmojiPicker: Workaround to search immediately on mobile Fix top bar input text colour Show underlay for mobile Fix tests Add English translations for correctly i18nized time units Delegate relativeTime plural rules to vue-i18n restore notifications page, fix z-index issues Make lint happy Add English translations for backup UI Add backup UI Add English translation for list aliases error Log errors when listing aliases Add changelog Add Engilsh translation for migration Add frontend ui for aliases and migration Change translation key Explain better what delete does in moderation menu
143 lines
4.4 KiB
JavaScript
143 lines
4.4 KiB
JavaScript
import { computed } from 'vue'
|
|
import { mapGetters } from 'vuex'
|
|
import Notification from '../notification/notification.vue'
|
|
import NotificationFilters from './notification_filters.vue'
|
|
import notificationsFetcher from '../../services/notifications_fetcher/notifications_fetcher.service.js'
|
|
import {
|
|
notificationsFromStore,
|
|
filteredNotificationsFromStore,
|
|
unseenNotificationsFromStore
|
|
} from '../../services/notification_utils/notification_utils.js'
|
|
import FaviconService from '../../services/favicon_service/favicon_service.js'
|
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
|
import { faCircleNotch } from '@fortawesome/free-solid-svg-icons'
|
|
|
|
library.add(
|
|
faCircleNotch
|
|
)
|
|
|
|
const DEFAULT_SEEN_TO_DISPLAY_COUNT = 30
|
|
|
|
const Notifications = {
|
|
components: {
|
|
Notification,
|
|
NotificationFilters
|
|
},
|
|
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
|
|
filterMode: Array,
|
|
// Disable teleporting (i.e. for /users/user/notifications)
|
|
disableTeleport: Boolean
|
|
},
|
|
data () {
|
|
return {
|
|
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
|
|
}
|
|
},
|
|
provide () {
|
|
return {
|
|
popoversZLayer: computed(() => this.popoversZLayer)
|
|
}
|
|
},
|
|
computed: {
|
|
mainClass () {
|
|
return this.minimalMode ? '' : 'panel panel-default'
|
|
},
|
|
notifications () {
|
|
return notificationsFromStore(this.$store)
|
|
},
|
|
error () {
|
|
return this.$store.state.statuses.notifications.error
|
|
},
|
|
unseenNotifications () {
|
|
return unseenNotificationsFromStore(this.$store)
|
|
},
|
|
filteredNotifications () {
|
|
return filteredNotificationsFromStore(this.$store, this.filterMode)
|
|
},
|
|
unseenCount () {
|
|
return this.unseenNotifications.length
|
|
},
|
|
unseenCountTitle () {
|
|
return this.unseenCount + (this.unreadChatCount)
|
|
},
|
|
loading () {
|
|
return this.$store.state.statuses.notifications.loading
|
|
},
|
|
noHeading () {
|
|
const { layoutType } = this.$store.state.interface
|
|
return this.minimalMode || layoutType === 'mobile'
|
|
},
|
|
teleportTarget () {
|
|
const { layoutType } = this.$store.state.interface
|
|
const map = {
|
|
wide: '#notifs-column',
|
|
mobile: '#mobile-notifications'
|
|
}
|
|
return map[layoutType] || '#notifs-sidebar'
|
|
},
|
|
popoversZLayer () {
|
|
const { layoutType } = this.$store.state.interface
|
|
return layoutType === 'mobile' ? 'navbar' : null
|
|
},
|
|
notificationsToDisplay () {
|
|
return this.filteredNotifications.slice(0, this.unseenCount + this.seenToDisplayCount)
|
|
},
|
|
...mapGetters(['unreadChatCount'])
|
|
},
|
|
watch: {
|
|
unseenCountTitle (count) {
|
|
if (count > 0) {
|
|
FaviconService.drawFaviconBadge()
|
|
this.$store.dispatch('setPageTitle', `(${count})`)
|
|
} else {
|
|
FaviconService.clearFaviconBadge()
|
|
this.$store.dispatch('setPageTitle', '')
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
markAsSeen () {
|
|
this.$store.dispatch('markNotificationsAsSeen')
|
|
this.seenToDisplayCount = DEFAULT_SEEN_TO_DISPLAY_COUNT
|
|
},
|
|
fetchOlderNotifications () {
|
|
if (this.loading) {
|
|
return
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
const store = this.$store
|
|
const credentials = store.state.users.currentUser.credentials
|
|
store.commit('setNotificationsLoading', { value: true })
|
|
notificationsFetcher.fetchAndUpdate({
|
|
store,
|
|
credentials,
|
|
older: true
|
|
}).then(notifs => {
|
|
store.commit('setNotificationsLoading', { value: false })
|
|
if (notifs.length === 0) {
|
|
this.bottomedOut = true
|
|
}
|
|
this.seenToDisplayCount += notifs.length
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
export default Notifications
|