diff options
| -rw-r--r-- | src/components/mobile_nav/mobile_nav.js | 9 | ||||
| -rw-r--r-- | src/components/mobile_nav/mobile_nav.vue | 11 | ||||
| -rw-r--r-- | src/components/notifications/notifications.js | 25 | ||||
| -rw-r--r-- | src/components/notifications/notifications.vue | 2 | ||||
| -rw-r--r-- | src/components/settings_modal/tabs/notifications_tab.vue | 23 | ||||
| -rw-r--r-- | src/i18n/en.json | 5 | ||||
| -rw-r--r-- | src/modules/config.js | 5 | ||||
| -rw-r--r-- | src/modules/instance.js | 3 |
8 files changed, 76 insertions, 7 deletions
diff --git a/src/components/mobile_nav/mobile_nav.js b/src/components/mobile_nav/mobile_nav.js index b5325116..6f4e35e5 100644 --- a/src/components/mobile_nav/mobile_nav.js +++ b/src/components/mobile_nav/mobile_nav.js @@ -14,7 +14,8 @@ import { faBell, faBars, faArrowUp, - faMinus + faMinus, + faCheckDouble } from '@fortawesome/free-solid-svg-icons' library.add( @@ -22,7 +23,8 @@ library.add( faBell, faBars, faArrowUp, - faMinus + faMinus, + faCheckDouble ) const MobileNav = { @@ -67,6 +69,9 @@ const MobileNav = { shouldConfirmLogout () { return this.$store.getters.mergedConfig.modalOnLogout }, + closingDrawerMarksAsSeen () { + return this.$store.getters.mergedConfig.closingDrawerMarksAsSeen + }, ...mapGetters(['unreadChatCount']) }, methods: { diff --git a/src/components/mobile_nav/mobile_nav.vue b/src/components/mobile_nav/mobile_nav.vue index c2746abe..ecd8290a 100644 --- a/src/components/mobile_nav/mobile_nav.vue +++ b/src/components/mobile_nav/mobile_nav.vue @@ -67,6 +67,17 @@ </FALayers> </button> <button + v-if="!closingDrawerMarksAsSeen" + class="button-unstyled mobile-nav-button" + :title="$t('nav.mobile_notifications_close')" + @click.stop.prevent="markNotificationsAsSeen()" + > + <FAIcon + class="fa-scale-110 fa-old-padding" + icon="check-double" + /> + </button> + <button class="button-unstyled mobile-nav-button" :title="$t('nav.mobile_notifications_close')" @click.stop.prevent="closeMobileNotifications(true)" diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index a210e19d..00d3a511 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -21,6 +21,7 @@ library.add( ) const DEFAULT_SEEN_TO_DISPLAY_COUNT = 30 +const ACTIONABLE_NOTIFICATION_TYPES = new Set(['mention', 'pleroma:report', 'follow_request']) const Notifications = { components: { @@ -71,14 +72,26 @@ const Notifications = { return unseenNotificationsFromStore(this.$store) }, filteredNotifications () { - return filteredNotificationsFromStore(this.$store, this.filterMode) + if (this.unseenAtTop) { + return [ + ...filteredNotificationsFromStore(this.$store).filter(n => this.shouldShowUnseen(n)), + ...filteredNotificationsFromStore(this.$store).filter(n => !this.shouldShowUnseen(n)) + ] + } else { + return filteredNotificationsFromStore(this.$store, this.filterMode) + } }, unseenCountBadgeText () { return `${this.unseenCount ? this.unseenCount : ''}${this.extraNotificationsCount ? '*' : ''}` }, unseenCount () { - return this.unseenNotifications.length + if (this.ignoreInactionableSeen) { + return this.unseenNotifications.filter(n => ACTIONABLE_NOTIFICATION_TYPES.has(n.type)).length + } else { + return this.unseenNotifications.length + } }, + ignoreInactionableSeen () { return this.$store.getters.mergedConfig.ignoreInactionableSeen }, extraNotificationsCount () { return countExtraNotifications(this.$store) }, @@ -108,6 +121,7 @@ const Notifications = { return this.filteredNotifications.slice(0, this.unseenCount + this.seenToDisplayCount) }, noSticky () { return this.$store.getters.mergedConfig.disableStickyHeaders }, + unseenAtTop () { return this.$store.getters.mergedConfig.unseenAtTop }, showExtraNotifications () { return !this.noExtra }, @@ -154,11 +168,16 @@ const Notifications = { scrollToTop () { const scrollable = this.scrollerRef scrollable.scrollTo({ top: this.$refs.root.offsetTop }) - // this.$refs.root.scrollIntoView({ behavior: 'smooth', block: 'start' }) }, updateScrollPosition () { this.showScrollTop = this.$refs.root.offsetTop < this.scrollerRef.scrollTop }, + shouldShowUnseen (notification) { + if (notification.seen) return false + + const actionable = ACTIONABLE_NOTIFICATION_TYPES.has(notification.type) + return this.ignoreInactionableSeen ? actionable : true + }, /* "Interacted" really refers to "actionable" notifications that require user input, * everything else (likes/repeats/reacts) cannot be acted and therefore we just clear * the "seen" status upon any clicks on them diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue index 27ae23cf..a0025182 100644 --- a/src/components/notifications/notifications.vue +++ b/src/components/notifications/notifications.vue @@ -66,7 +66,7 @@ :key="notification.id" role="listitem" class="notification" - :class="{unseen: !minimalMode && !notification.seen}" + :class="{unseen: !minimalMode && shouldShowUnseen(notification)}" @click="e => notificationClicked(notification)" > <div class="notification-overlay" /> diff --git a/src/components/settings_modal/tabs/notifications_tab.vue b/src/components/settings_modal/tabs/notifications_tab.vue index 4dfba444..fcee85a0 100644 --- a/src/components/settings_modal/tabs/notifications_tab.vue +++ b/src/components/settings_modal/tabs/notifications_tab.vue @@ -1,6 +1,29 @@ <template> <div :label="$t('settings.notifications')"> <div class="setting-item"> + <h2>{{ $t('settings.notification_setting_annoyance') }}</h2> + <ul class="setting-list"> + <li> + <BooleanSetting path="closingDrawerMarksAsSeen"> + {{ $t('settings.notification_setting_drawer_marks_as_seen') }} + </BooleanSetting> + </li> + <li> + <BooleanSetting path="ignoreInactionableSeen"> + {{ $t('settings.notification_setting_ignore_inactionable_seen') }} + </BooleanSetting> + <p> + {{ $t('settings.notification_setting_ignore_inactionable_seen_tip') }} + </p> + </li> + <li> + <BooleanSetting path="unseenAtTop"> + {{ $t('settings.notification_setting_unseen_at_top') }} + </BooleanSetting> + </li> + </ul> + </div> + <div class="setting-item"> <h2>{{ $t('settings.notification_setting_filters') }}</h2> <ul class="setting-list"> <li> diff --git a/src/i18n/en.json b/src/i18n/en.json index 034022cb..b31793cb 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -688,6 +688,11 @@ "greentext": "Meme arrows", "show_yous": "Show (You)s", "notifications": "Notifications", + "notification_setting_annoyance": "Annoyance", + "notification_setting_drawer_marks_as_seen": "Closing drawer (mobile) marks all notifications as read", + "notification_setting_ignore_inactionable_seen": "Ignore read state of inactionable notifications (likes, repeats etc)", + "notification_setting_ignore_inactionable_seen_tip": "This will not actually mark those notifications as read, and you'll still get desktop notifications about them if you chose so", + "notification_setting_unseen_at_top": "Show unread notifications above others", "notification_setting_filters": "Filters", "notification_setting_block_from_strangers": "Block notifications from users who you do not follow", "notification_setting_privacy": "Privacy", diff --git a/src/modules/config.js b/src/modules/config.js index 05c15998..a3f7bcaf 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -127,7 +127,10 @@ export const defaultState = { showAnnouncementsInExtraNotifications: undefined, // instance default showFollowRequestsInExtraNotifications: undefined, // instance default maxDepthInThread: undefined, // instance default - autocompleteSelect: undefined // instance default + autocompleteSelect: undefined, // instance default + closingDrawerMarksAsSeen: undefined, // instance default + unseenAtTop: undefined, // instance default + ignoreInactionableSeen: undefined // instance default } // caching the instance default properties diff --git a/src/modules/instance.js b/src/modules/instance.js index 034348ff..3022a41a 100644 --- a/src/modules/instance.js +++ b/src/modules/instance.js @@ -110,6 +110,9 @@ const defaultState = { showFollowRequestsInExtraNotifications: true, maxDepthInThread: 6, autocompleteSelect: false, + closingDrawerMarksAsSeen: true, + unseenAtTop: false, + ignoreInactionableSeen: false, // Nasty stuff customEmoji: [], |
