Remove unread timeline and fix scroll position in notifications
This commit is contained in:
parent
143849424e
commit
24e2a80236
|
@ -192,8 +192,7 @@ let state = (): NotificationsState => {
|
||||||
return {
|
return {
|
||||||
lazyLoading: false,
|
lazyLoading: false,
|
||||||
heading: true,
|
heading: true,
|
||||||
notifications: [],
|
notifications: []
|
||||||
unreadNotifications: []
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,8 +252,7 @@ describe('Notifications', () => {
|
||||||
return {
|
return {
|
||||||
lazyLoading: false,
|
lazyLoading: false,
|
||||||
heading: true,
|
heading: true,
|
||||||
notifications: [notification1],
|
notifications: [notification1]
|
||||||
unreadNotifications: []
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -179,7 +179,7 @@ describe('TimelineSpace/Contents/Home', () => {
|
||||||
showReplies: true
|
showReplies: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
it('should not update unreadTimeline', () => {
|
it('should not update timeline', () => {
|
||||||
Home.mutations![MUTATION_TYPES.APPEND_TIMELINE](state, status2)
|
Home.mutations![MUTATION_TYPES.APPEND_TIMELINE](state, status2)
|
||||||
expect(state.timeline).toEqual([status2, status1])
|
expect(state.timeline).toEqual([status2, status1])
|
||||||
})
|
})
|
||||||
|
|
|
@ -175,8 +175,7 @@ describe('TimelineSpace/Contents/Notifications', () => {
|
||||||
state = {
|
state = {
|
||||||
lazyLoading: false,
|
lazyLoading: false,
|
||||||
heading: true,
|
heading: true,
|
||||||
notifications: [notification2, notification1],
|
notifications: [notification2, notification1]
|
||||||
unreadNotifications: []
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
describe('message is not reblogged', () => {
|
describe('message is not reblogged', () => {
|
||||||
|
@ -200,14 +199,12 @@ describe('TimelineSpace/Contents/Notifications', () => {
|
||||||
state = {
|
state = {
|
||||||
lazyLoading: false,
|
lazyLoading: false,
|
||||||
heading: true,
|
heading: true,
|
||||||
notifications: [notification1],
|
notifications: [notification1]
|
||||||
unreadNotifications: []
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
it('should update timeline', () => {
|
it('should update timeline', () => {
|
||||||
Notifications.mutations![MUTATION_TYPES.APPEND_NOTIFICATIONS](state, notification2)
|
Notifications.mutations![MUTATION_TYPES.APPEND_NOTIFICATIONS](state, notification2)
|
||||||
expect(state.notifications).toEqual([notification2, notification1])
|
expect(state.notifications).toEqual([notification2, notification1])
|
||||||
expect(state.unreadNotifications).toEqual([])
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -216,14 +213,12 @@ describe('TimelineSpace/Contents/Notifications', () => {
|
||||||
state = {
|
state = {
|
||||||
lazyLoading: false,
|
lazyLoading: false,
|
||||||
heading: true,
|
heading: true,
|
||||||
notifications: [notification2, notification1],
|
notifications: [notification2, notification1]
|
||||||
unreadNotifications: []
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
it('should not update timeline', () => {
|
it('should not update timeline', () => {
|
||||||
Notifications.mutations![MUTATION_TYPES.APPEND_NOTIFICATIONS](state, notification2)
|
Notifications.mutations![MUTATION_TYPES.APPEND_NOTIFICATIONS](state, notification2)
|
||||||
expect(state.notifications).toEqual([notification2, notification1])
|
expect(state.notifications).toEqual([notification2, notification1])
|
||||||
expect(state.unreadNotifications).toEqual([])
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -234,14 +229,12 @@ describe('TimelineSpace/Contents/Notifications', () => {
|
||||||
state = {
|
state = {
|
||||||
lazyLoading: false,
|
lazyLoading: false,
|
||||||
heading: false,
|
heading: false,
|
||||||
notifications: [notification1],
|
notifications: [notification1]
|
||||||
unreadNotifications: []
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
it('should update unreadTimeline', () => {
|
it('should update timeline', () => {
|
||||||
Notifications.mutations![MUTATION_TYPES.APPEND_NOTIFICATIONS](state, notification2)
|
Notifications.mutations![MUTATION_TYPES.APPEND_NOTIFICATIONS](state, notification2)
|
||||||
expect(state.notifications).toEqual([notification1])
|
expect(state.notifications).toEqual([notification2, notification1])
|
||||||
expect(state.unreadNotifications).toEqual([notification2])
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('duplicated status', () => {
|
describe('duplicated status', () => {
|
||||||
|
@ -249,14 +242,12 @@ describe('TimelineSpace/Contents/Notifications', () => {
|
||||||
state = {
|
state = {
|
||||||
lazyLoading: false,
|
lazyLoading: false,
|
||||||
heading: false,
|
heading: false,
|
||||||
notifications: [notification1],
|
notifications: [notification2, notification1]
|
||||||
unreadNotifications: [notification2]
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
it('should not update unreadTimeline', () => {
|
it('should not update timeline', () => {
|
||||||
Notifications.mutations![MUTATION_TYPES.APPEND_NOTIFICATIONS](state, notification2)
|
Notifications.mutations![MUTATION_TYPES.APPEND_NOTIFICATIONS](state, notification2)
|
||||||
expect(state.notifications).toEqual([notification1])
|
expect(state.notifications).toEqual([notification2, notification1])
|
||||||
expect(state.unreadNotifications).toEqual([notification2])
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div id="notifications" v-shortkey="shortcutEnabled ? { next: ['j'] } : {}" @shortkey="handleKey">
|
<div id="notifications" v-shortkey="shortcutEnabled ? { next: ['j'] } : {}" @shortkey="handleKey">
|
||||||
<div class="unread">{{ unread.length > 0 ? unread.length : '' }}</div>
|
|
||||||
<div v-shortkey="{ linux: ['ctrl', 'r'], mac: ['meta', 'r'] }" @shortkey="reload()"></div>
|
<div v-shortkey="{ linux: ['ctrl', 'r'], mac: ['meta', 'r'] }" @shortkey="reload()"></div>
|
||||||
<DynamicScroller :items="handledNotifications" :min-item-size="20" id="scroller" class="scroller" ref="scroller">
|
<DynamicScroller :items="handledNotifications" :min-item-size="20" id="scroller" class="scroller" ref="scroller">
|
||||||
<template v-slot="{ item, index, active }">
|
<template v-slot="{ item, index, active }">
|
||||||
|
@ -31,6 +30,7 @@ import { mapState, mapGetters } from 'vuex'
|
||||||
import Notification from '~/src/renderer/components/organisms/Notification'
|
import Notification from '~/src/renderer/components/organisms/Notification'
|
||||||
import reloadable from '~/src/renderer/components/mixins/reloadable'
|
import reloadable from '~/src/renderer/components/mixins/reloadable'
|
||||||
import { Event } from '~/src/renderer/components/event'
|
import { Event } from '~/src/renderer/components/event'
|
||||||
|
import { ScrollPosition } from '~/src/renderer/components/utils/scroll'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'notifications',
|
name: 'notifications',
|
||||||
|
@ -38,7 +38,8 @@ export default {
|
||||||
mixins: [reloadable],
|
mixins: [reloadable],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
focusedId: null
|
focusedId: null,
|
||||||
|
scroll: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -49,8 +50,7 @@ export default {
|
||||||
}),
|
}),
|
||||||
...mapState('TimelineSpace/Contents/Notifications', {
|
...mapState('TimelineSpace/Contents/Notifications', {
|
||||||
lazyLoading: state => state.lazyLoading,
|
lazyLoading: state => state.lazyLoading,
|
||||||
heading: state => state.heading,
|
heading: state => state.heading
|
||||||
unread: state => state.unreadNotifications
|
|
||||||
}),
|
}),
|
||||||
...mapGetters('TimelineSpace/Contents/Notifications', ['handledNotifications', 'filters']),
|
...mapGetters('TimelineSpace/Contents/Notifications', ['handledNotifications', 'filters']),
|
||||||
...mapGetters('TimelineSpace/Modals', ['modalOpened']),
|
...mapGetters('TimelineSpace/Modals', ['modalOpened']),
|
||||||
|
@ -83,18 +83,30 @@ export default {
|
||||||
if (this.heading && this.handledNotifications.length > 0) {
|
if (this.heading && this.handledNotifications.length > 0) {
|
||||||
this.$store.dispatch('TimelineSpace/Contents/Notifications/saveMarker', this.handledNotifications[0].id)
|
this.$store.dispatch('TimelineSpace/Contents/Notifications/saveMarker', this.handledNotifications[0].id)
|
||||||
}
|
}
|
||||||
|
const el = document.getElementById('scroller')
|
||||||
|
this.scroll = new ScrollPosition(el)
|
||||||
|
this.scroll.prepare()
|
||||||
},
|
},
|
||||||
beforeUpdate() {
|
beforeUpdate() {
|
||||||
if (this.$store.state.TimelineSpace.SideMenu.unreadNotifications) {
|
if (this.$store.state.TimelineSpace.SideMenu.unreadNotifications && this.heading) {
|
||||||
this.$store.commit('TimelineSpace/SideMenu/changeUnreadNotifications', false)
|
this.$store.commit('TimelineSpace/SideMenu/changeUnreadNotifications', false)
|
||||||
}
|
}
|
||||||
|
if (!this.heading) {
|
||||||
|
const el = document.getElementById('scroller')
|
||||||
|
this.scroll = new ScrollPosition(el)
|
||||||
|
this.scroll.prepare()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updated() {
|
||||||
|
if (this.scroll && !this.heading) {
|
||||||
|
this.scroll.restore()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
Event.$off('focus-timeline')
|
Event.$off('focus-timeline')
|
||||||
},
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
this.$store.commit('TimelineSpace/Contents/Notifications/changeHeading', true)
|
this.$store.commit('TimelineSpace/Contents/Notifications/changeHeading', true)
|
||||||
this.$store.commit('TimelineSpace/Contents/Notifications/mergeNotifications')
|
|
||||||
this.$store.commit('TimelineSpace/Contents/Notifications/archiveNotifications')
|
this.$store.commit('TimelineSpace/Contents/Notifications/archiveNotifications')
|
||||||
if (document.getElementById('scroller') !== undefined && document.getElementById('scroller') !== null) {
|
if (document.getElementById('scroller') !== undefined && document.getElementById('scroller') !== null) {
|
||||||
document.getElementById('scroller').removeEventListener('scroll', this.onScroll)
|
document.getElementById('scroller').removeEventListener('scroll', this.onScroll)
|
||||||
|
@ -114,7 +126,6 @@ export default {
|
||||||
this.$store.commit('TimelineSpace/Contents/Notifications/changeHeading', false)
|
this.$store.commit('TimelineSpace/Contents/Notifications/changeHeading', false)
|
||||||
} else if (newState === null && !this.heading) {
|
} else if (newState === null && !this.heading) {
|
||||||
this.$store.commit('TimelineSpace/Contents/Notifications/changeHeading', true)
|
this.$store.commit('TimelineSpace/Contents/Notifications/changeHeading', true)
|
||||||
this.$store.commit('TimelineSpace/Contents/Notifications/mergeNotifications')
|
|
||||||
this.$store.dispatch('TimelineSpace/Contents/Notifications/resetBadge')
|
this.$store.dispatch('TimelineSpace/Contents/Notifications/resetBadge')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -142,16 +153,11 @@ export default {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// for unread control
|
|
||||||
if (event.target.scrollTop > 5 && this.heading) {
|
if (event.target.scrollTop > 10 && this.heading) {
|
||||||
this.$store.commit('TimelineSpace/Contents/Notifications/changeHeading', false)
|
this.$store.commit('TimelineSpace/Contents/Notifications/changeHeading', false)
|
||||||
} else if (event.target.scrollTop <= 5 && !this.heading) {
|
} else if (event.target.scrollTop <= 10 && !this.heading) {
|
||||||
const currentPos = this.unread.length
|
|
||||||
if (currentPos === 0) {
|
|
||||||
this.$store.commit('TimelineSpace/Contents/Notifications/changeHeading', true)
|
this.$store.commit('TimelineSpace/Contents/Notifications/changeHeading', true)
|
||||||
}
|
|
||||||
this.$store.commit('TimelineSpace/Contents/Notifications/mergeNotifications')
|
|
||||||
this.$refs.scroller.scrollToItem(currentPos)
|
|
||||||
this.$store.dispatch('TimelineSpace/Contents/Notifications/resetBadge')
|
this.$store.dispatch('TimelineSpace/Contents/Notifications/resetBadge')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -214,21 +220,6 @@ export default {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.unread {
|
|
||||||
position: fixed;
|
|
||||||
right: 24px;
|
|
||||||
top: 48px;
|
|
||||||
background-color: rgba(0, 0, 0, 0.7);
|
|
||||||
color: #ffffff;
|
|
||||||
padding: 4px 8px;
|
|
||||||
border-radius: 0 0 2px 2px;
|
|
||||||
z-index: 1;
|
|
||||||
|
|
||||||
&:empty {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading-card {
|
.loading-card {
|
||||||
height: 60px;
|
height: 60px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,14 +10,12 @@ export type NotificationsState = {
|
||||||
lazyLoading: boolean
|
lazyLoading: boolean
|
||||||
heading: boolean
|
heading: boolean
|
||||||
notifications: Array<Entity.Notification>
|
notifications: Array<Entity.Notification>
|
||||||
unreadNotifications: Array<Entity.Notification>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = (): NotificationsState => ({
|
const state = (): NotificationsState => ({
|
||||||
lazyLoading: false,
|
lazyLoading: false,
|
||||||
heading: true,
|
heading: true,
|
||||||
notifications: [],
|
notifications: []
|
||||||
unreadNotifications: []
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export const MUTATION_TYPES = {
|
export const MUTATION_TYPES = {
|
||||||
|
@ -25,7 +23,6 @@ export const MUTATION_TYPES = {
|
||||||
CHANGE_HEADING: 'changeHeading',
|
CHANGE_HEADING: 'changeHeading',
|
||||||
APPEND_NOTIFICATIONS: 'appendNotifications',
|
APPEND_NOTIFICATIONS: 'appendNotifications',
|
||||||
UPDATE_NOTIFICATIONS: 'updateNotifications',
|
UPDATE_NOTIFICATIONS: 'updateNotifications',
|
||||||
MERGE_NOTIFICATIONS: 'mergeNotifications',
|
|
||||||
INSERT_NOTIFICATIONS: 'insertNotifications',
|
INSERT_NOTIFICATIONS: 'insertNotifications',
|
||||||
UPDATE_TOOT: 'updateToot',
|
UPDATE_TOOT: 'updateToot',
|
||||||
DELETE_TOOT: 'deleteToot',
|
DELETE_TOOT: 'deleteToot',
|
||||||
|
@ -42,24 +39,13 @@ const mutations: MutationTree<NotificationsState> = {
|
||||||
},
|
},
|
||||||
[MUTATION_TYPES.APPEND_NOTIFICATIONS]: (state, notification: Entity.Notification) => {
|
[MUTATION_TYPES.APPEND_NOTIFICATIONS]: (state, notification: Entity.Notification) => {
|
||||||
// Reject duplicated status in timeline
|
// Reject duplicated status in timeline
|
||||||
if (
|
if (!state.notifications.find(item => item.id === notification.id)) {
|
||||||
!state.notifications.find(item => item.id === notification.id) &&
|
|
||||||
!state.unreadNotifications.find(item => item.id === notification.id)
|
|
||||||
) {
|
|
||||||
if (state.heading) {
|
|
||||||
state.notifications = [notification].concat(state.notifications)
|
state.notifications = [notification].concat(state.notifications)
|
||||||
} else {
|
|
||||||
state.unreadNotifications = [notification].concat(state.unreadNotifications)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[MUTATION_TYPES.UPDATE_NOTIFICATIONS]: (state, notifications: Array<Entity.Notification>) => {
|
[MUTATION_TYPES.UPDATE_NOTIFICATIONS]: (state, notifications: Array<Entity.Notification>) => {
|
||||||
state.notifications = notifications
|
state.notifications = notifications
|
||||||
},
|
},
|
||||||
[MUTATION_TYPES.MERGE_NOTIFICATIONS]: state => {
|
|
||||||
state.notifications = state.unreadNotifications.slice(0, 80).concat(state.notifications)
|
|
||||||
state.unreadNotifications = []
|
|
||||||
},
|
|
||||||
[MUTATION_TYPES.INSERT_NOTIFICATIONS]: (state, notifications: Array<Entity.Notification>) => {
|
[MUTATION_TYPES.INSERT_NOTIFICATIONS]: (state, notifications: Array<Entity.Notification>) => {
|
||||||
state.notifications = state.notifications.concat(notifications)
|
state.notifications = state.notifications.concat(notifications)
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue