Merge branch 'tusooa/extra-notifications' into 'develop'
Extra notifications See merge request pleroma/pleroma-fe!1853
This commit is contained in:
commit
954d03150f
1
changelog.d/extra-notifications.add
Normal file
1
changelog.d/extra-notifications.add
Normal file
@ -0,0 +1 @@
|
|||||||
|
Support showing extra notifications in the notifications column
|
48
src/components/extra_notifications/extra_notifications.js
Normal file
48
src/components/extra_notifications/extra_notifications.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
|
import {
|
||||||
|
faUserPlus,
|
||||||
|
faComments,
|
||||||
|
faBullhorn
|
||||||
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
|
library.add(
|
||||||
|
faUserPlus,
|
||||||
|
faComments,
|
||||||
|
faBullhorn
|
||||||
|
)
|
||||||
|
|
||||||
|
const ExtraNotifications = {
|
||||||
|
computed: {
|
||||||
|
shouldShowChats () {
|
||||||
|
return this.mergedConfig.showExtraNotifications && this.mergedConfig.showChatsInExtraNotifications && this.unreadChatCount
|
||||||
|
},
|
||||||
|
shouldShowAnnouncements () {
|
||||||
|
return this.mergedConfig.showExtraNotifications && this.mergedConfig.showAnnouncementsInExtraNotifications && this.unreadAnnouncementCount
|
||||||
|
},
|
||||||
|
shouldShowFollowRequests () {
|
||||||
|
return this.mergedConfig.showExtraNotifications && this.mergedConfig.showFollowRequestsInExtraNotifications && this.followRequestCount
|
||||||
|
},
|
||||||
|
hasAnythingToShow () {
|
||||||
|
return this.shouldShowChats || this.shouldShowAnnouncements || this.shouldShowFollowRequests
|
||||||
|
},
|
||||||
|
shouldShowCustomizationTip () {
|
||||||
|
return this.mergedConfig.showExtraNotificationsTip && this.hasAnythingToShow
|
||||||
|
},
|
||||||
|
currentUser () {
|
||||||
|
return this.$store.state.users.currentUser
|
||||||
|
},
|
||||||
|
...mapGetters(['unreadChatCount', 'unreadAnnouncementCount', 'followRequestCount', 'mergedConfig'])
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
openNotificationSettings () {
|
||||||
|
return this.$store.dispatch('openSettingsModalTab', 'notifications')
|
||||||
|
},
|
||||||
|
dismissConfigurationTip () {
|
||||||
|
return this.$store.dispatch('setOption', { name: 'showExtraNotificationsTip', value: false })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ExtraNotifications
|
113
src/components/extra_notifications/extra_notifications.vue
Normal file
113
src/components/extra_notifications/extra_notifications.vue
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<template>
|
||||||
|
<div class="ExtraNotifications">
|
||||||
|
<div
|
||||||
|
v-if="shouldShowChats"
|
||||||
|
class="notification unseen"
|
||||||
|
>
|
||||||
|
<div class="notification-overlay" />
|
||||||
|
<router-link
|
||||||
|
class="button-unstyled -link extra-notification"
|
||||||
|
:to="{ name: 'chats', params: { username: currentUser.screen_name } }"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110 icon"
|
||||||
|
icon="comments"
|
||||||
|
/>
|
||||||
|
{{ $tc('notifications.unread_chats', unreadChatCount, { num: unreadChatCount }) }}
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="shouldShowAnnouncements"
|
||||||
|
class="notification unseen"
|
||||||
|
>
|
||||||
|
<div class="notification-overlay" />
|
||||||
|
<router-link
|
||||||
|
class="button-unstyled -link extra-notification"
|
||||||
|
:to="{ name: 'announcements' }"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110 icon"
|
||||||
|
icon="bullhorn"
|
||||||
|
/>
|
||||||
|
{{ $tc('notifications.unread_announcements', unreadAnnouncementCount, { num: unreadAnnouncementCount }) }}
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="shouldShowFollowRequests"
|
||||||
|
class="notification unseen"
|
||||||
|
>
|
||||||
|
<div class="notification-overlay" />
|
||||||
|
<router-link
|
||||||
|
class="button-unstyled -link extra-notification"
|
||||||
|
:to="{ name: 'friend-requests' }"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110 icon"
|
||||||
|
icon="user-plus"
|
||||||
|
/>
|
||||||
|
{{ $tc('notifications.unread_follow_requests', followRequestCount, { num: followRequestCount }) }}
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
<i18n-t
|
||||||
|
v-if="shouldShowCustomizationTip"
|
||||||
|
tag="span"
|
||||||
|
class="notification tip extra-notification"
|
||||||
|
keypath="notifications.configuration_tip"
|
||||||
|
>
|
||||||
|
<template #theSettings>
|
||||||
|
<button
|
||||||
|
class="button-unstyled -link"
|
||||||
|
@click="openNotificationSettings"
|
||||||
|
>
|
||||||
|
{{ $t('notifications.configuration_tip_settings') }}
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
<template #dismiss>
|
||||||
|
<button
|
||||||
|
class="button-unstyled -link"
|
||||||
|
@click="dismissConfigurationTip"
|
||||||
|
>
|
||||||
|
{{ $t('notifications.configuration_tip_dismiss') }}
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
</i18n-t>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./extra_notifications.js" />
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "../../variables";
|
||||||
|
|
||||||
|
.ExtraNotifications {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
|
||||||
|
.notification {
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: 1px solid;
|
||||||
|
border-color: $fallback--border;
|
||||||
|
border-color: var(--border, $fallback--border);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.extra-notification {
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -39,6 +39,7 @@
|
|||||||
<Notifications
|
<Notifications
|
||||||
ref="notifications"
|
ref="notifications"
|
||||||
:no-heading="true"
|
:no-heading="true"
|
||||||
|
:no-extra="true"
|
||||||
:minimal-mode="true"
|
:minimal-mode="true"
|
||||||
:filter-mode="filterMode"
|
:filter-mode="filterMode"
|
||||||
/>
|
/>
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import SideDrawer from '../side_drawer/side_drawer.vue'
|
import SideDrawer from '../side_drawer/side_drawer.vue'
|
||||||
import Notifications from '../notifications/notifications.vue'
|
import Notifications from '../notifications/notifications.vue'
|
||||||
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||||
import { unseenNotificationsFromStore } from '../../services/notification_utils/notification_utils'
|
import {
|
||||||
|
unseenNotificationsFromStore,
|
||||||
|
countExtraNotifications
|
||||||
|
} from '../../services/notification_utils/notification_utils'
|
||||||
import GestureService from '../../services/gesture_service/gesture_service'
|
import GestureService from '../../services/gesture_service/gesture_service'
|
||||||
import NavigationPins from 'src/components/navigation/navigation_pins.vue'
|
import NavigationPins from 'src/components/navigation/navigation_pins.vue'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
@ -50,7 +53,7 @@ const MobileNav = {
|
|||||||
return unseenNotificationsFromStore(this.$store)
|
return unseenNotificationsFromStore(this.$store)
|
||||||
},
|
},
|
||||||
unseenNotificationsCount () {
|
unseenNotificationsCount () {
|
||||||
return this.unseenNotifications.length
|
return this.unseenNotifications.length + countExtraNotifications(this.$store)
|
||||||
},
|
},
|
||||||
hideSitename () { return this.$store.state.instance.hideSitename },
|
hideSitename () { return this.$store.state.instance.hideSitename },
|
||||||
sitename () { return this.$store.state.instance.name },
|
sitename () { return this.$store.state.instance.name },
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import Notification from '../notification/notification.vue'
|
import Notification from '../notification/notification.vue'
|
||||||
|
import ExtraNotifications from '../extra_notifications/extra_notifications.vue'
|
||||||
import NotificationFilters from './notification_filters.vue'
|
import NotificationFilters from './notification_filters.vue'
|
||||||
import notificationsFetcher from '../../services/notifications_fetcher/notifications_fetcher.service.js'
|
import notificationsFetcher from '../../services/notifications_fetcher/notifications_fetcher.service.js'
|
||||||
import {
|
import {
|
||||||
notificationsFromStore,
|
notificationsFromStore,
|
||||||
filteredNotificationsFromStore,
|
filteredNotificationsFromStore,
|
||||||
unseenNotificationsFromStore
|
unseenNotificationsFromStore,
|
||||||
|
countExtraNotifications
|
||||||
} from '../../services/notification_utils/notification_utils.js'
|
} from '../../services/notification_utils/notification_utils.js'
|
||||||
import FaviconService from '../../services/favicon_service/favicon_service.js'
|
import FaviconService from '../../services/favicon_service/favicon_service.js'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
@ -23,7 +25,8 @@ const DEFAULT_SEEN_TO_DISPLAY_COUNT = 30
|
|||||||
const Notifications = {
|
const Notifications = {
|
||||||
components: {
|
components: {
|
||||||
Notification,
|
Notification,
|
||||||
NotificationFilters
|
NotificationFilters,
|
||||||
|
ExtraNotifications
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
// Disables panel styles, unread mark, potentially other notification-related actions
|
// Disables panel styles, unread mark, potentially other notification-related actions
|
||||||
@ -31,6 +34,11 @@ const Notifications = {
|
|||||||
minimalMode: Boolean,
|
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
|
// 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,
|
filterMode: Array,
|
||||||
|
// Do not show extra notifications
|
||||||
|
noExtra: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
// Disable teleporting (i.e. for /users/user/notifications)
|
// Disable teleporting (i.e. for /users/user/notifications)
|
||||||
disableTeleport: Boolean
|
disableTeleport: Boolean
|
||||||
},
|
},
|
||||||
@ -65,11 +73,17 @@ const Notifications = {
|
|||||||
filteredNotifications () {
|
filteredNotifications () {
|
||||||
return filteredNotificationsFromStore(this.$store, this.filterMode)
|
return filteredNotificationsFromStore(this.$store, this.filterMode)
|
||||||
},
|
},
|
||||||
|
unseenCountBadgeText () {
|
||||||
|
return `${this.unseenCount ? this.unseenCount : ''}${this.extraNotificationsCount ? '*' : ''}`
|
||||||
|
},
|
||||||
unseenCount () {
|
unseenCount () {
|
||||||
return this.unseenNotifications.length
|
return this.unseenNotifications.length
|
||||||
},
|
},
|
||||||
|
extraNotificationsCount () {
|
||||||
|
return countExtraNotifications(this.$store)
|
||||||
|
},
|
||||||
unseenCountTitle () {
|
unseenCountTitle () {
|
||||||
return this.unseenCount + (this.unreadChatCount) + this.unreadAnnouncementCount
|
return this.unseenNotifications.length + (this.unreadChatCount) + this.unreadAnnouncementCount
|
||||||
},
|
},
|
||||||
loading () {
|
loading () {
|
||||||
return this.$store.state.statuses.notifications.loading
|
return this.$store.state.statuses.notifications.loading
|
||||||
@ -94,6 +108,9 @@ const Notifications = {
|
|||||||
return this.filteredNotifications.slice(0, this.unseenCount + this.seenToDisplayCount)
|
return this.filteredNotifications.slice(0, this.unseenCount + this.seenToDisplayCount)
|
||||||
},
|
},
|
||||||
noSticky () { return this.$store.getters.mergedConfig.disableStickyHeaders },
|
noSticky () { return this.$store.getters.mergedConfig.disableStickyHeaders },
|
||||||
|
showExtraNotifications () {
|
||||||
|
return !this.noExtra
|
||||||
|
},
|
||||||
...mapGetters(['unreadChatCount', 'unreadAnnouncementCount'])
|
...mapGetters(['unreadChatCount', 'unreadAnnouncementCount'])
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
@ -17,9 +17,9 @@
|
|||||||
<div class="title">
|
<div class="title">
|
||||||
{{ $t('notifications.notifications') }}
|
{{ $t('notifications.notifications') }}
|
||||||
<span
|
<span
|
||||||
v-if="unseenCount"
|
v-if="unseenCountBadgeText"
|
||||||
class="badge badge-notification unseen-count"
|
class="badge badge-notification unseen-count"
|
||||||
>{{ unseenCount }}</span>
|
>{{ unseenCountBadgeText }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="showScrollTop"
|
v-if="showScrollTop"
|
||||||
@ -54,6 +54,13 @@
|
|||||||
class="panel-body"
|
class="panel-body"
|
||||||
role="feed"
|
role="feed"
|
||||||
>
|
>
|
||||||
|
<div
|
||||||
|
v-if="showExtraNotifications"
|
||||||
|
role="listitem"
|
||||||
|
class="notification"
|
||||||
|
>
|
||||||
|
<extra-notifications />
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
v-for="notification in notificationsToDisplay"
|
v-for="notification in notificationsToDisplay"
|
||||||
:key="notification.id"
|
:key="notification.id"
|
||||||
|
@ -51,6 +51,47 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting path="showExtraNotifications">
|
||||||
|
{{ $t('settings.notification_show_extra') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<ul class="setting-list suboptions">
|
||||||
|
<li>
|
||||||
|
<BooleanSetting
|
||||||
|
path="showChatsInExtraNotifications"
|
||||||
|
:disabled="!mergedConfig.showExtraNotifications"
|
||||||
|
>
|
||||||
|
{{ $t('settings.notification_extra_chats') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting
|
||||||
|
path="showAnnouncementsInExtraNotifications"
|
||||||
|
:disabled="!mergedConfig.showExtraNotifications"
|
||||||
|
>
|
||||||
|
{{ $t('settings.notification_extra_announcements') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting
|
||||||
|
path="showFollowRequestsInExtraNotifications"
|
||||||
|
:disabled="!mergedConfig.showExtraNotifications"
|
||||||
|
>
|
||||||
|
{{ $t('settings.notification_extra_follow_requests') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting
|
||||||
|
path="showExtraNotificationsTip"
|
||||||
|
:disabled="!mergedConfig.showExtraNotifications"
|
||||||
|
>
|
||||||
|
{{ $t('settings.notification_extra_tip') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -205,7 +205,13 @@
|
|||||||
"migrated_to": "migrated to",
|
"migrated_to": "migrated to",
|
||||||
"reacted_with": "reacted with {0}",
|
"reacted_with": "reacted with {0}",
|
||||||
"submitted_report": "submitted a report",
|
"submitted_report": "submitted a report",
|
||||||
"poll_ended": "poll has ended"
|
"poll_ended": "poll has ended",
|
||||||
|
"unread_announcements": "{num} unread announcement | {num} unread announcements",
|
||||||
|
"unread_chats": "{num} unread chat | {num} unread chats",
|
||||||
|
"unread_follow_requests": "{num} new follow request | {num} new follow requests",
|
||||||
|
"configuration_tip": "You can customize what to display here in {theSettings}. {dismiss}",
|
||||||
|
"configuration_tip_settings": "the settings",
|
||||||
|
"configuration_tip_dismiss": "Do not show again"
|
||||||
},
|
},
|
||||||
"polls": {
|
"polls": {
|
||||||
"add_poll": "Add poll",
|
"add_poll": "Add poll",
|
||||||
@ -561,6 +567,11 @@
|
|||||||
"notification_visibility_moves": "User Migrates",
|
"notification_visibility_moves": "User Migrates",
|
||||||
"notification_visibility_emoji_reactions": "Reactions",
|
"notification_visibility_emoji_reactions": "Reactions",
|
||||||
"notification_visibility_polls": "Ends of polls you voted in",
|
"notification_visibility_polls": "Ends of polls you voted in",
|
||||||
|
"notification_show_extra": "Show extra notifications in the notifications column",
|
||||||
|
"notification_extra_chats": "Show unread chats",
|
||||||
|
"notification_extra_announcements": "Show unread announcements",
|
||||||
|
"notification_extra_follow_requests": "Show new follow requests",
|
||||||
|
"notification_extra_tip": "Show the customization tip for extra notifications",
|
||||||
"no_rich_text_description": "Strip rich text formatting from all posts",
|
"no_rich_text_description": "Strip rich text formatting from all posts",
|
||||||
"no_blocks": "No blocks",
|
"no_blocks": "No blocks",
|
||||||
"no_mutes": "No mutes",
|
"no_mutes": "No mutes",
|
||||||
|
@ -117,6 +117,11 @@ export const defaultState = {
|
|||||||
conversationTreeAdvanced: undefined, // instance default
|
conversationTreeAdvanced: undefined, // instance default
|
||||||
conversationOtherRepliesButton: undefined, // instance default
|
conversationOtherRepliesButton: undefined, // instance default
|
||||||
conversationTreeFadeAncestors: undefined, // instance default
|
conversationTreeFadeAncestors: undefined, // instance default
|
||||||
|
showExtraNotifications: undefined, // instance default
|
||||||
|
showExtraNotificationsTip: undefined, // instance default
|
||||||
|
showChatsInExtraNotifications: undefined, // instance default
|
||||||
|
showAnnouncementsInExtraNotifications: undefined, // instance default
|
||||||
|
showFollowRequestsInExtraNotifications: undefined, // instance default
|
||||||
maxDepthInThread: undefined, // instance default
|
maxDepthInThread: undefined, // instance default
|
||||||
autocompleteSelect: undefined // instance default
|
autocompleteSelect: undefined // instance default
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,11 @@ const defaultState = {
|
|||||||
conversationTreeAdvanced: false,
|
conversationTreeAdvanced: false,
|
||||||
conversationOtherRepliesButton: 'below',
|
conversationOtherRepliesButton: 'below',
|
||||||
conversationTreeFadeAncestors: false,
|
conversationTreeFadeAncestors: false,
|
||||||
|
showExtraNotifications: true,
|
||||||
|
showExtraNotificationsTip: true,
|
||||||
|
showChatsInExtraNotifications: true,
|
||||||
|
showAnnouncementsInExtraNotifications: true,
|
||||||
|
showFollowRequestsInExtraNotifications: true,
|
||||||
maxDepthInThread: 6,
|
maxDepthInThread: 6,
|
||||||
autocompleteSelect: false,
|
autocompleteSelect: false,
|
||||||
|
|
||||||
|
@ -124,3 +124,17 @@ export const prepareNotificationObject = (notification, i18n) => {
|
|||||||
|
|
||||||
return notifObj
|
return notifObj
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const countExtraNotifications = (store) => {
|
||||||
|
const mergedConfig = store.getters.mergedConfig
|
||||||
|
|
||||||
|
if (!mergedConfig.showExtraNotifications) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
mergedConfig.showChatsInExtraNotifications ? store.getters.unreadChatCount : 0,
|
||||||
|
mergedConfig.showAnnouncementsInExtraNotifications ? store.getters.unreadAnnouncementCount : 0,
|
||||||
|
mergedConfig.showFollowRequestsInExtraNotifications ? store.getters.followRequestCount : 0
|
||||||
|
].reduce((a, c) => a + c, 0)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user