Remove unread timeline and fix scroll position in mentions

This commit is contained in:
AkiraFukushima 2021-07-25 22:19:41 +09:00
parent 24e2a80236
commit ce4780f587
No known key found for this signature in database
GPG Key ID: B6E51BAC4DE1A957
4 changed files with 40 additions and 94 deletions

View File

@ -115,8 +115,7 @@ let state: Function = () => {
return {
lazyLoading: false,
heading: true,
mentions: [],
unreadMentions: []
mentions: []
}
}
@ -176,8 +175,7 @@ describe('Mentions', () => {
return {
lazyLoading: true,
heading: true,
mentions: [],
unreadMentions: []
mentions: []
}
}
})
@ -193,8 +191,7 @@ describe('Mentions', () => {
return {
lazyLoading: false,
heading: true,
mentions: [mention, reblog],
unreadMentions: []
mentions: [mention, reblog]
}
}
})
@ -224,8 +221,7 @@ describe('Mentions', () => {
return {
lazyLoading: false,
heading: true,
mentions: [mention, favourite, reblog, follow],
unreadMentions: []
mentions: [mention, favourite, reblog, follow]
}
}
})

View File

@ -173,8 +173,7 @@ describe('TimelineSpace/Contents/Mentions', () => {
state = {
lazyLoading: false,
heading: true,
mentions: [],
unreadMentions: []
mentions: []
}
})
@ -185,14 +184,12 @@ describe('TimelineSpace/Contents/Mentions', () => {
state = {
lazyLoading: false,
heading: true,
mentions: [notification1],
unreadMentions: []
mentions: [notification1]
}
})
it('should update mentions', () => {
Mentions.mutations![MUTATION_TYPES.APPEND_MENTIONS](state, notification2)
expect(state.mentions).toEqual([notification2, notification1])
expect(state.unreadMentions).toEqual([])
})
})
@ -201,14 +198,12 @@ describe('TimelineSpace/Contents/Mentions', () => {
state = {
lazyLoading: false,
heading: true,
mentions: [notification2, notification1],
unreadMentions: []
mentions: [notification2, notification1]
}
})
it('should not be updated mentions', () => {
Mentions.mutations![MUTATION_TYPES.APPEND_MENTIONS](state, notification2)
expect(state.mentions).toEqual([notification2, notification1])
expect(state.unreadMentions).toEqual([])
})
})
})
@ -219,14 +214,12 @@ describe('TimelineSpace/Contents/Mentions', () => {
state = {
lazyLoading: false,
heading: false,
mentions: [notification1],
unreadMentions: []
mentions: [notification1]
}
})
it('should update mentions', () => {
Mentions.mutations![MUTATION_TYPES.APPEND_MENTIONS](state, notification2)
expect(state.mentions).toEqual([notification1])
expect(state.unreadMentions).toEqual([notification2])
expect(state.mentions).toEqual([notification2, notification1])
})
})
@ -235,42 +228,23 @@ describe('TimelineSpace/Contents/Mentions', () => {
state = {
lazyLoading: false,
heading: false,
mentions: [notification1],
unreadMentions: [notification2]
mentions: [notification2, notification1]
}
})
it('should not be updated mentions', () => {
Mentions.mutations![MUTATION_TYPES.APPEND_MENTIONS](state, notification2)
expect(state.mentions).toEqual([notification1])
expect(state.unreadMentions).toEqual([notification2])
expect(state.mentions).toEqual([notification2, notification1])
})
})
})
})
describe('mergeMentions', () => {
beforeEach(() => {
state = {
lazyLoading: false,
heading: false,
mentions: [notification1],
unreadMentions: [notification2]
}
})
it('should be merged', () => {
Mentions.mutations![MUTATION_TYPES.MERGE_MENTIONS](state, null)
expect(state.mentions).toEqual([notification2, notification1])
expect(state.unreadMentions).toEqual([])
})
})
describe('insertMentions', () => {
beforeEach(() => {
state = {
lazyLoading: false,
heading: false,
mentions: [notification2],
unreadMentions: []
mentions: [notification2]
}
})
it('should be inserted', () => {
@ -284,8 +258,7 @@ describe('TimelineSpace/Contents/Mentions', () => {
state = {
lazyLoading: false,
heading: false,
mentions: [notification2, notification1],
unreadMentions: []
mentions: [notification2, notification1]
}
})
it('should be updated', () => {
@ -304,8 +277,7 @@ describe('TimelineSpace/Contents/Mentions', () => {
state = {
lazyLoading: false,
heading: true,
mentions: [notification2, notification1],
unreadMentions: []
mentions: [notification2, notification1]
}
})
it('should be deleted', () => {
@ -318,8 +290,7 @@ describe('TimelineSpace/Contents/Mentions', () => {
state = {
lazyLoading: false,
heading: true,
mentions: [notification2, notification1],
unreadMentions: []
mentions: [notification2, notification1]
}
})
it('should be deleted', () => {

View File

@ -1,8 +1,7 @@
<template>
<div id="mentions" 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>
<DynamicScroller :items="mentions" :min-item-size="60" id="scroller" class="scroller" ref="scroller">
<DynamicScroller :items="mentions" :min-item-size="86" id="scroller" class="scroller" ref="scroller">
<template v-slot="{ item, index, active }">
<DynamicScrollerItem :item="item" :active="active" :size-dependencies="[item.url]" :data-index="index" :watchData="true">
<notification
@ -31,6 +30,7 @@ import { mapState, mapGetters } from 'vuex'
import Notification from '~/src/renderer/components/organisms/Notification'
import reloadable from '~/src/renderer/components/mixins/reloadable'
import { Event } from '~/src/renderer/components/event'
import { ScrollPosition } from '~/src/renderer/components/utils/scroll'
export default {
name: 'mentions',
@ -38,7 +38,8 @@ export default {
mixins: [reloadable],
data() {
return {
focusedId: null
focusedId: null,
scroll: null
}
},
computed: {
@ -53,8 +54,7 @@ export default {
}),
...mapState('TimelineSpace/Contents/Mentions', {
lazyLoading: state => state.lazyLoading,
heading: state => state.heading,
unread: state => state.unreadMentions
heading: state => state.heading
}),
...mapGetters('TimelineSpace/Modals', ['modalOpened']),
...mapGetters('TimelineSpace/Contents/Mentions', ['mentions']),
@ -81,18 +81,30 @@ export default {
this.focusedId = previousFocusedId
})
})
const el = document.getElementById('scroller')
this.scroll = new ScrollPosition(el)
this.scroll.prepare()
},
beforeUpdate() {
if (this.$store.state.TimelineSpace.SideMenu.unreadMentions && this.heading) {
this.$store.commit('TimelineSpace/SideMenu/changeUnreadMentions', 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() {
Event.$off('focus-timeline')
},
destroyed() {
this.$store.commit('TimelineSpace/Contents/Mentions/changeHeading', true)
this.$store.commit('TimelineSpace/Contents/Mentions/mergeMentions')
this.$store.commit('TimelineSpace/Contents/Mentions/archiveMentions')
if (document.getElementById('scroller') !== undefined && document.getElementById('scroller') !== null) {
document.getElementById('scroller').removeEventListener('scroll', this.onScroll)
@ -112,7 +124,6 @@ export default {
this.$store.commit('TimelineSpace/Contents/Mentions/changeHeading', false)
} else if (newState === null && !this.heading) {
this.$store.commit('TimelineSpace/Contents/Mentions/changeHeading', true)
this.$store.commit('TimelineSpace/Contents/Mentions/mergeMentions')
}
}
},
@ -130,16 +141,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/Mentions/changeHeading', false)
} else if (event.target.scrollTop <= 5 && !this.heading) {
const currentPos = this.unread.length
if (currentPos === 0) {
this.$store.commit('TimelineSpace/Contents/Mentions/changeHeading', true)
}
this.$store.commit('TimelineSpace/Contents/Mentions/mergeMentions')
this.$refs.scroller.scrollToItem(currentPos)
} else if (event.target.scrollTop <= 10 && !this.heading) {
this.$store.commit('TimelineSpace/Contents/Mentions/changeHeading', true)
}
},
async reload() {
@ -200,21 +206,6 @@ export default {
height: 100%;
}
.unread {
position: fixed;
right: 24px;
top: 48px;
background-color: rgba(0, 0, 0, 0.7);
color: #fff;
padding: 4px 8px;
border-radius: 0 0 2px 2px;
z-index: 1;
&:empty {
display: none;
}
}
.loading-card {
height: 60px;
}

View File

@ -6,14 +6,12 @@ export type MentionsState = {
lazyLoading: boolean
heading: boolean
mentions: Array<Entity.Notification>
unreadMentions: Array<Entity.Notification>
}
const state = (): MentionsState => ({
lazyLoading: false,
heading: true,
mentions: [],
unreadMentions: []
mentions: []
})
export const MUTATION_TYPES = {
@ -21,7 +19,6 @@ export const MUTATION_TYPES = {
CHANGE_HEADING: 'changeHeading',
APPEND_MENTIONS: 'appendMentions',
UPDATE_MENTIONS: 'updateMentions',
MERGE_MENTIONS: 'mergeMentions',
INSERT_MENTIONS: 'insertMentions',
ARCHIVE_MENTIONS: 'archiveMentions',
CLEAR_MENTIONS: 'clearMentions',
@ -38,21 +35,13 @@ const mutations: MutationTree<MentionsState> = {
},
[MUTATION_TYPES.APPEND_MENTIONS]: (state, update: Entity.Notification) => {
// Reject duplicated status in timeline
if (!state.mentions.find(item => item.id === update.id) && !state.unreadMentions.find(item => item.id === update.id)) {
if (state.heading) {
state.mentions = [update].concat(state.mentions)
} else {
state.unreadMentions = [update].concat(state.unreadMentions)
}
if (!state.mentions.find(item => item.id === update.id)) {
state.mentions = [update].concat(state.mentions)
}
},
[MUTATION_TYPES.UPDATE_MENTIONS]: (state, messages: Array<Entity.Notification>) => {
state.mentions = messages
},
[MUTATION_TYPES.MERGE_MENTIONS]: state => {
state.mentions = state.unreadMentions.slice(0, 80).concat(state.mentions)
state.unreadMentions = []
},
[MUTATION_TYPES.INSERT_MENTIONS]: (state, messages: Array<Entity.Notification>) => {
state.mentions = state.mentions.concat(messages)
},
@ -61,7 +50,6 @@ const mutations: MutationTree<MentionsState> = {
},
[MUTATION_TYPES.CLEAR_MENTIONS]: state => {
state.mentions = []
state.unreadMentions = []
},
[MUTATION_TYPES.UPDATE_TOOT]: (state, message: Entity.Notification) => {
state.mentions = state.mentions.map(mention => {