mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
140 lines
3.6 KiB
Vue
140 lines
3.6 KiB
Vue
<template>
|
|
<div
|
|
v-if="totalNotifications <= 0"
|
|
class="notifications-menu-pointer"
|
|
@click.prevent="updateNotifications"
|
|
>
|
|
<ds-button class="notifications-menu" disabled icon="bell">{{ unreadNotifications }}</ds-button>
|
|
</div>
|
|
<dropdown v-else class="notifications-menu" :placement="placement">
|
|
<template slot="default" slot-scope="{ toggleMenu }">
|
|
<ds-button
|
|
primary
|
|
icon="bell"
|
|
@click.prevent="
|
|
toggleMenu()
|
|
updateNotifications()
|
|
"
|
|
>
|
|
{{ unreadNotifications }}
|
|
</ds-button>
|
|
</template>
|
|
<template slot="popover">
|
|
<div class="notifications-menu-popover">
|
|
<notification-list :notifications="notifications" @markAsRead="markAsRead" />
|
|
</div>
|
|
</template>
|
|
</dropdown>
|
|
</template>
|
|
|
|
<script>
|
|
import Dropdown from '~/components/Dropdown'
|
|
import { REFRESH_MILLISEC } from '~/constants/notifications'
|
|
import { notificationQuery, markAsReadMutation } from '~/graphql/User'
|
|
import NotificationList from '../NotificationList/NotificationList'
|
|
|
|
export default {
|
|
name: 'NotificationMenu',
|
|
components: {
|
|
NotificationList,
|
|
Dropdown,
|
|
},
|
|
data() {
|
|
return {
|
|
notifications: [],
|
|
}
|
|
},
|
|
props: {
|
|
placement: { type: String },
|
|
},
|
|
created() {
|
|
setInterval(this.updateNotifications, REFRESH_MILLISEC)
|
|
},
|
|
destroyed() {
|
|
clearInterval(this.updateNotifications)
|
|
},
|
|
methods: {
|
|
async updateNotifications() {
|
|
try {
|
|
let oldNotifications = this.notifications
|
|
this.$apollo.queries.notifications.refetch()
|
|
const udatedNotifications = this.notifications
|
|
|
|
// add all the new notifications to the old notifications at top of the list
|
|
if (udatedNotifications) {
|
|
udatedNotifications.forEach(udatedListNotification => {
|
|
const sameNotification = oldNotifications.find(function(oldListNotification) {
|
|
return (
|
|
oldListNotification.from.id === udatedListNotification.from.id &&
|
|
oldListNotification.createdAt === udatedListNotification.createdAt &&
|
|
oldListNotification.reason === udatedListNotification.reason
|
|
)
|
|
})
|
|
if (sameNotification === undefined) {
|
|
oldNotifications.unshift(udatedListNotification)
|
|
}
|
|
})
|
|
|
|
this.notifications = oldNotifications
|
|
}
|
|
} catch (err) {
|
|
throw new Error(err)
|
|
}
|
|
},
|
|
async markAsRead(notificationSourceId) {
|
|
const variables = { id: notificationSourceId }
|
|
try {
|
|
const {
|
|
data: { markAsRead },
|
|
} = await this.$apollo.mutate({
|
|
mutation: markAsReadMutation(this.$i18n),
|
|
variables,
|
|
})
|
|
if (!(markAsRead && markAsRead.read === true)) return
|
|
this.notifications = this.notifications.map(n => {
|
|
return n.from.id === markAsRead.from.id ? markAsRead : n
|
|
})
|
|
} catch (err) {
|
|
throw new Error(err)
|
|
}
|
|
},
|
|
},
|
|
computed: {
|
|
totalNotifications() {
|
|
return (this.notifications || []).length
|
|
},
|
|
unreadNotifications() {
|
|
let countUnread = 0
|
|
if (this.notifications) {
|
|
this.notifications.forEach(notification => {
|
|
if (!notification.read) countUnread++
|
|
})
|
|
}
|
|
return countUnread
|
|
},
|
|
},
|
|
apollo: {
|
|
notifications: {
|
|
query() {
|
|
return notificationQuery(this.$i18n)
|
|
},
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.notifications-menu {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.notifications-menu-pointer {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.notifications-menu-popover {
|
|
max-width: 500px;
|
|
}
|
|
</style>
|