diff options
Diffstat (limited to 'src/components/notifications')
| -rw-r--r-- | src/components/notifications/notifications.js | 55 | ||||
| -rw-r--r-- | src/components/notifications/notifications.scss | 18 | ||||
| -rw-r--r-- | src/components/notifications/notifications.vue | 70 |
3 files changed, 111 insertions, 32 deletions
diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index 9fc5e38a..26ffbab6 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -2,24 +2,35 @@ import Notification from '../notification/notification.vue' import notificationsFetcher from '../../services/notifications_fetcher/notifications_fetcher.service.js' import { notificationsFromStore, - visibleNotificationsFromStore, + filteredNotificationsFromStore, unseenNotificationsFromStore } from '../../services/notification_utils/notification_utils.js' -const Notifications = { - created () { - const store = this.$store - const credentials = store.state.users.currentUser.credentials +const DEFAULT_SEEN_TO_DISPLAY_COUNT = 30 - const fetcherId = notificationsFetcher.startFetching({ store, credentials }) - this.$store.commit('setNotificationFetcher', { fetcherId }) +const Notifications = { + props: { + // Disables display of panel header + noHeading: Boolean, + // 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 }, data () { return { - bottomedOut: 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 + // older notifications, and cut back to default whenever hitting "Read!". + seenToDisplayCount: DEFAULT_SEEN_TO_DISPLAY_COUNT } }, computed: { + mainClass () { + return this.minimalMode ? '' : 'panel panel-default' + }, notifications () { return notificationsFromStore(this.$store) }, @@ -29,19 +40,27 @@ const Notifications = { unseenNotifications () { return unseenNotificationsFromStore(this.$store) }, - visibleNotifications () { - return visibleNotificationsFromStore(this.$store) + filteredNotifications () { + return filteredNotificationsFromStore(this.$store, this.filterMode) }, unseenCount () { return this.unseenNotifications.length }, loading () { return this.$store.state.statuses.notifications.loading + }, + notificationsToDisplay () { + return this.filteredNotifications.slice(0, this.unseenCount + this.seenToDisplayCount) } }, components: { Notification }, + created () { + const { dispatch } = this.$store + + dispatch('fetchAndUpdateNotifications') + }, watch: { unseenCount (count) { if (count > 0) { @@ -53,9 +72,22 @@ const Notifications = { }, methods: { markAsSeen () { - this.$store.dispatch('markNotificationsAsSeen', this.visibleNotifications) + 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 }) @@ -68,6 +100,7 @@ const Notifications = { if (notifs.length === 0) { this.bottomedOut = true } + this.seenToDisplayCount += notifs.length }) } } diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss index c0b458cc..148ac7f2 100644 --- a/src/components/notifications/notifications.scss +++ b/src/components/notifications/notifications.scss @@ -1,8 +1,10 @@ @import '../../_variables.scss'; .notifications { - // a bit of a hack to allow scrolling below notifications - padding-bottom: 15em; + &:not(.minimal) { + // a bit of a hack to allow scrolling below notifications + padding-bottom: 15em; + } .loadmore-error { color: $fallback--text; @@ -31,7 +33,6 @@ .notification { box-sizing: border-box; - display: flex; border-bottom: 1px solid; border-color: $fallback--border; border-color: var(--border, $fallback--border); @@ -45,6 +46,10 @@ } } + .muted { + padding: .25em .6em; + } + .non-mention { display: flex; flex: 1; @@ -71,7 +76,7 @@ } } - .follow-text { + .follow-text, .move-text { padding: 0.5em 0; } @@ -146,6 +151,11 @@ color: var(--cOrange, $fallback--cOrange); } + .icon-arrow-curved.lit { + color: $fallback--cBlue; + color: var(--cBlue, $fallback--cBlue); + } + .status-content { margin: 0; max-height: 300px; diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue index 6f162b62..d477a41b 100644 --- a/src/components/notifications/notifications.vue +++ b/src/components/notifications/notifications.vue @@ -1,31 +1,67 @@ <template> - <div class="notifications"> - <div class="panel panel-default"> - <div class="panel-heading"> + <div + :class="{ minimal: minimalMode }" + class="notifications" + > + <div :class="mainClass"> + <div + v-if="!noHeading" + class="panel-heading" + > <div class="title"> - {{$t('notifications.notifications')}} - <span class="badge badge-notification unseen-count" v-if="unseenCount">{{unseenCount}}</span> + {{ $t('notifications.notifications') }} + <span + v-if="unseenCount" + class="badge badge-notification unseen-count" + >{{ unseenCount }}</span> </div> - <div @click.prevent class="loadmore-error alert error" v-if="error"> - {{$t('timeline.error_fetching')}} + <div + v-if="error" + class="loadmore-error alert error" + @click.prevent + > + {{ $t('timeline.error_fetching') }} </div> - <button v-if="unseenCount" @click.prevent="markAsSeen" class="read-button">{{$t('notifications.read')}}</button> + <button + v-if="unseenCount" + class="read-button" + @click.prevent="markAsSeen" + > + {{ $t('notifications.read') }} + </button> </div> <div class="panel-body"> - <div v-for="notification in visibleNotifications" :key="notification.action.id" class="notification" :class='{"unseen": !notification.seen}'> - <div class="notification-overlay"></div> - <notification :notification="notification"></notification> + <div + v-for="notification in notificationsToDisplay" + :key="notification.id" + class="notification" + :class="{"unseen": !minimalMode && !notification.seen}" + > + <div class="notification-overlay" /> + <notification :notification="notification" /> </div> </div> <div class="panel-footer"> - <div v-if="bottomedOut" class="new-status-notification text-center panel-footer faint"> - {{$t('notifications.no_more_notifications')}} + <div + v-if="bottomedOut" + class="new-status-notification text-center panel-footer faint" + > + {{ $t('notifications.no_more_notifications') }} </div> - <a v-else-if="!loading" href="#" v-on:click.prevent="fetchOlderNotifications()"> - <div class="new-status-notification text-center panel-footer">{{$t('notifications.load_older')}}</div> + <a + v-else-if="!loading" + href="#" + @click.prevent="fetchOlderNotifications()" + > + <div class="new-status-notification text-center panel-footer"> + {{ minimalMode ? $t('interactions.load_older') : $t('notifications.load_older') }} + </div> </a> - <div v-else class="new-status-notification text-center panel-footer"> - <i class="icon-spin3 animate-spin"/> + <div + v-else + class="new-status-notification text-center panel-footer" + > + <i class="icon-spin3 animate-spin" /> </div> </div> </div> |
