diff options
Diffstat (limited to 'src/components/notifications')
| -rw-r--r-- | src/components/notifications/notification_filters.vue | 19 | ||||
| -rw-r--r-- | src/components/notifications/notifications.js | 39 | ||||
| -rw-r--r-- | src/components/notifications/notifications.vue | 34 |
3 files changed, 67 insertions, 25 deletions
diff --git a/src/components/notifications/notification_filters.vue b/src/components/notifications/notification_filters.vue index b0213167..1315b51a 100644 --- a/src/components/notifications/notification_filters.vue +++ b/src/components/notifications/notification_filters.vue @@ -109,22 +109,3 @@ export default { } } </script> - -<style lang="scss"> - -.NotificationFilters { - align-self: stretch; - - > button { - line-height: 100%; - height: 100%; - width: var(--__panel-heading-height-inner); - text-align: center; - - svg { - font-size: 1.2em; - } - } -} - -</style> diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index 0851f407..c3acd9e0 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -10,10 +10,12 @@ import { } 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' +import { faCircleNotch, faArrowUp, faMinus } from '@fortawesome/free-solid-svg-icons' library.add( - faCircleNotch + faCircleNotch, + faArrowUp, + faMinus ) const DEFAULT_SEEN_TO_DISPLAY_COUNT = 30 @@ -34,6 +36,7 @@ const Notifications = { }, data () { return { + showScrollTop: false, 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 @@ -90,8 +93,20 @@ const Notifications = { notificationsToDisplay () { return this.filteredNotifications.slice(0, this.unseenCount + this.seenToDisplayCount) }, + noSticky () { return this.$store.getters.mergedConfig.disableStickyHeaders }, ...mapGetters(['unreadChatCount']) }, + mounted () { + this.scrollerRef = this.$refs.root.closest('.column.-scrollable') + if (!this.scrollerRef) { + this.scrollerRef = this.$refs.root.closest('.mobile-notifications') + } + this.scrollerRef.addEventListener('scroll', this.updateScrollPosition) + }, + unmounted () { + if (!this.scrollerRef) return + this.scrollerRef.removeEventListener('scroll', this.updateScrollPosition) + }, watch: { unseenCountTitle (count) { if (count > 0) { @@ -101,9 +116,29 @@ const Notifications = { FaviconService.clearFaviconBadge() this.$store.dispatch('setPageTitle', '') } + }, + teleportTarget () { + // handle scroller change + this.$nextTick(() => { + this.scrollerRef.removeEventListener('scroll', this.updateScrollPosition) + this.scrollerRef = this.$refs.root.closest('.column.-scrollable') + if (!this.scrollerRef) { + this.scrollerRef = this.$refs.root.closest('.mobile-notifications') + } + this.scrollerRef.addEventListener('scroll', this.updateScrollPosition) + this.updateScrollPosition() + }) } }, methods: { + 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 + }, markAsSeen () { this.$store.dispatch('markNotificationsAsSeen') this.seenToDisplayCount = DEFAULT_SEEN_TO_DISPLAY_COUNT diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue index e778e27b..3d5878d4 100644 --- a/src/components/notifications/notifications.vue +++ b/src/components/notifications/notifications.vue @@ -3,7 +3,9 @@ :disabled="minimalMode || disableTeleport" :to="teleportTarget" > - <div + <component + :is="noHeading ? 'div' : 'aside'" + ref="root" :class="{ minimal: minimalMode }" class="Notifications" > @@ -19,19 +21,43 @@ class="badge badge-notification unseen-count" >{{ unseenCount }}</span> </div> + <div + class="rightside-button" + v-if="showScrollTop" + > + <button + class="button-unstyled scroll-to-top-button" + type="button" + :title="$t('general.scroll_to_top')" + @click="scrollToTop" + > + <FALayers class="fa-scale-110 fa-old-padding-layer"> + <FAIcon icon="arrow-up" /> + <FAIcon + icon="minus" + transform="up-7" + /> + </FALayers> + </button> + </div> <button v-if="unseenCount" class="button-default read-button" + type="button" @click.prevent="markAsSeen" > {{ $t('notifications.read') }} </button> - <NotificationFilters /> + <NotificationFilters class="rightside-button" /> </div> - <div class="panel-body"> + <div + class="panel-body" + role="feed" + > <div v-for="notification in notificationsToDisplay" :key="notification.id" + role="listitem" class="notification" :class="{unseen: !minimalMode && !notification.seen}" > @@ -67,7 +93,7 @@ </div> </div> </div> - </div> + </component> </teleport> </template> |
