[refactor] Remove mentions
This commit is contained in:
parent
49f5be6230
commit
3b46bda835
|
@ -1,306 +0,0 @@
|
|||
import { Entity } from 'megalodon'
|
||||
import Mentions, { MentionsState, MUTATION_TYPES } from '@/store/TimelineSpace/Contents/Mentions'
|
||||
|
||||
const account1: Entity.Account = {
|
||||
id: '1',
|
||||
username: 'h3poteto',
|
||||
acct: 'h3poteto@pleroma.io',
|
||||
display_name: 'h3poteto',
|
||||
locked: false,
|
||||
created_at: '2019-03-26T21:30:32',
|
||||
followers_count: 10,
|
||||
following_count: 10,
|
||||
statuses_count: 100,
|
||||
note: 'engineer',
|
||||
url: 'https://pleroma.io',
|
||||
avatar: '',
|
||||
avatar_static: '',
|
||||
header: '',
|
||||
header_static: '',
|
||||
emojis: [],
|
||||
moved: null,
|
||||
fields: null,
|
||||
bot: false
|
||||
}
|
||||
|
||||
const account2: Entity.Account = {
|
||||
id: '2',
|
||||
username: 'h3poteto',
|
||||
acct: 'h3poteto@mstdn.io',
|
||||
display_name: 'h3poteto',
|
||||
locked: false,
|
||||
created_at: '2019-03-26T21:30:32',
|
||||
followers_count: 10,
|
||||
following_count: 10,
|
||||
statuses_count: 100,
|
||||
note: 'engineer',
|
||||
url: 'https://mstdn.io',
|
||||
avatar: '',
|
||||
avatar_static: '',
|
||||
header: '',
|
||||
header_static: '',
|
||||
emojis: [],
|
||||
moved: null,
|
||||
fields: null,
|
||||
bot: false
|
||||
}
|
||||
|
||||
const status1: Entity.Status = {
|
||||
id: '1',
|
||||
uri: 'http://example.com',
|
||||
url: 'http://example.com',
|
||||
account: account1,
|
||||
in_reply_to_id: null,
|
||||
in_reply_to_account_id: null,
|
||||
reblog: null,
|
||||
content: 'hoge',
|
||||
plain_content: 'hoge',
|
||||
created_at: '2019-03-26T21:40:32',
|
||||
emojis: [],
|
||||
replies_count: 0,
|
||||
reblogs_count: 0,
|
||||
favourites_count: 0,
|
||||
reblogged: null,
|
||||
favourited: null,
|
||||
muted: null,
|
||||
sensitive: false,
|
||||
spoiler_text: '',
|
||||
visibility: 'public',
|
||||
media_attachments: [],
|
||||
mentions: [],
|
||||
tags: [],
|
||||
card: null,
|
||||
poll: null,
|
||||
application: {
|
||||
name: 'Web'
|
||||
} as Entity.Application,
|
||||
language: null,
|
||||
pinned: null,
|
||||
emoji_reactions: [],
|
||||
bookmarked: false,
|
||||
quote: false
|
||||
}
|
||||
|
||||
const status2: Entity.Status = {
|
||||
id: '2',
|
||||
uri: 'http://example.com',
|
||||
url: 'http://example.com',
|
||||
account: account1,
|
||||
in_reply_to_id: null,
|
||||
in_reply_to_account_id: null,
|
||||
reblog: null,
|
||||
content: 'hoge',
|
||||
plain_content: 'hoge',
|
||||
created_at: '2019-03-26T21:40:32',
|
||||
emojis: [],
|
||||
replies_count: 0,
|
||||
reblogs_count: 0,
|
||||
favourites_count: 0,
|
||||
reblogged: null,
|
||||
favourited: null,
|
||||
muted: null,
|
||||
sensitive: false,
|
||||
spoiler_text: '',
|
||||
visibility: 'public',
|
||||
media_attachments: [],
|
||||
mentions: [],
|
||||
tags: [],
|
||||
card: null,
|
||||
poll: null,
|
||||
application: {
|
||||
name: 'Web'
|
||||
} as Entity.Application,
|
||||
language: null,
|
||||
pinned: null,
|
||||
emoji_reactions: [],
|
||||
bookmarked: false,
|
||||
quote: false
|
||||
}
|
||||
|
||||
const rebloggedStatus: Entity.Status = {
|
||||
id: '3',
|
||||
uri: 'http://example.com',
|
||||
url: 'http://example.com',
|
||||
account: account1,
|
||||
in_reply_to_id: null,
|
||||
in_reply_to_account_id: null,
|
||||
reblog: status2,
|
||||
content: 'hoge',
|
||||
plain_content: 'hoge',
|
||||
created_at: '2019-03-26T21:40:32',
|
||||
emojis: [],
|
||||
replies_count: 0,
|
||||
reblogs_count: 0,
|
||||
favourites_count: 0,
|
||||
reblogged: null,
|
||||
favourited: null,
|
||||
muted: null,
|
||||
sensitive: false,
|
||||
spoiler_text: '',
|
||||
visibility: 'public',
|
||||
media_attachments: [],
|
||||
mentions: [],
|
||||
tags: [],
|
||||
card: null,
|
||||
poll: null,
|
||||
application: {
|
||||
name: 'Web'
|
||||
} as Entity.Application,
|
||||
language: null,
|
||||
pinned: null,
|
||||
emoji_reactions: [],
|
||||
bookmarked: false,
|
||||
quote: false
|
||||
}
|
||||
|
||||
const notification1: Entity.Notification = {
|
||||
id: '1',
|
||||
account: account2,
|
||||
status: status1,
|
||||
type: 'mention',
|
||||
created_at: '2019-04-01T17:01:32'
|
||||
}
|
||||
|
||||
const notification2: Entity.Notification = {
|
||||
id: '2',
|
||||
account: account2,
|
||||
status: rebloggedStatus,
|
||||
type: 'mention',
|
||||
created_at: '2019-04-01T17:01:32'
|
||||
}
|
||||
|
||||
describe('TimelineSpace/Contents/Mentions', () => {
|
||||
describe('mutations', () => {
|
||||
let state: MentionsState
|
||||
beforeEach(() => {
|
||||
state = {
|
||||
lazyLoading: false,
|
||||
heading: true,
|
||||
mentions: []
|
||||
}
|
||||
})
|
||||
|
||||
describe('appendMentions', () => {
|
||||
describe('heading', () => {
|
||||
describe('normal', () => {
|
||||
beforeEach(() => {
|
||||
state = {
|
||||
lazyLoading: false,
|
||||
heading: true,
|
||||
mentions: [notification1]
|
||||
}
|
||||
})
|
||||
it('should update mentions', () => {
|
||||
Mentions.mutations![MUTATION_TYPES.APPEND_MENTIONS](state, notification2)
|
||||
expect(state.mentions).toEqual([notification2, notification1])
|
||||
})
|
||||
})
|
||||
|
||||
describe('duplicated status', () => {
|
||||
beforeEach(() => {
|
||||
state = {
|
||||
lazyLoading: false,
|
||||
heading: true,
|
||||
mentions: [notification2, notification1]
|
||||
}
|
||||
})
|
||||
it('should not be updated mentions', () => {
|
||||
Mentions.mutations![MUTATION_TYPES.APPEND_MENTIONS](state, notification2)
|
||||
expect(state.mentions).toEqual([notification2, notification1])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('not heading', () => {
|
||||
describe('normal', () => {
|
||||
beforeEach(() => {
|
||||
state = {
|
||||
lazyLoading: false,
|
||||
heading: false,
|
||||
mentions: [notification1]
|
||||
}
|
||||
})
|
||||
it('should update mentions', () => {
|
||||
Mentions.mutations![MUTATION_TYPES.APPEND_MENTIONS](state, notification2)
|
||||
expect(state.mentions).toEqual([notification2, notification1])
|
||||
})
|
||||
})
|
||||
|
||||
describe('duplicated status', () => {
|
||||
beforeEach(() => {
|
||||
state = {
|
||||
lazyLoading: false,
|
||||
heading: false,
|
||||
mentions: [notification2, notification1]
|
||||
}
|
||||
})
|
||||
it('should not be updated mentions', () => {
|
||||
Mentions.mutations![MUTATION_TYPES.APPEND_MENTIONS](state, notification2)
|
||||
expect(state.mentions).toEqual([notification2, notification1])
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('insertMentions', () => {
|
||||
beforeEach(() => {
|
||||
state = {
|
||||
lazyLoading: false,
|
||||
heading: false,
|
||||
mentions: [notification2]
|
||||
}
|
||||
})
|
||||
it('should be inserted', () => {
|
||||
Mentions.mutations![MUTATION_TYPES.INSERT_MENTIONS](state, [notification1])
|
||||
expect(state.mentions).toEqual([notification2, notification1])
|
||||
})
|
||||
})
|
||||
|
||||
describe('updateToot', () => {
|
||||
beforeEach(() => {
|
||||
state = {
|
||||
lazyLoading: false,
|
||||
heading: false,
|
||||
mentions: [notification2, notification1]
|
||||
}
|
||||
})
|
||||
it('should be updated', () => {
|
||||
const favourited: Entity.Status = Object.assign(status1, {
|
||||
favourited: true
|
||||
})
|
||||
Mentions.mutations![MUTATION_TYPES.UPDATE_TOOT](state, favourited)
|
||||
expect((state.mentions[0] as Entity.Notification).status!.favourited).toEqual(null)
|
||||
expect((state.mentions[1] as Entity.Notification).status!.favourited).toEqual(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('deleteToot', () => {
|
||||
describe('message is not reblogged', () => {
|
||||
beforeEach(() => {
|
||||
state = {
|
||||
lazyLoading: false,
|
||||
heading: true,
|
||||
mentions: [notification2, notification1]
|
||||
}
|
||||
})
|
||||
it('should be deleted', () => {
|
||||
Mentions.mutations![MUTATION_TYPES.DELETE_TOOT](state, notification1.status!.id)
|
||||
expect(state.mentions.length).toEqual(1)
|
||||
})
|
||||
})
|
||||
describe('message is reblogged', () => {
|
||||
beforeEach(() => {
|
||||
state = {
|
||||
lazyLoading: false,
|
||||
heading: true,
|
||||
mentions: [notification2, notification1]
|
||||
}
|
||||
})
|
||||
it('should be deleted', () => {
|
||||
Mentions.mutations![MUTATION_TYPES.DELETE_TOOT](state, notification2.status!.id)
|
||||
expect(state.mentions.length).toEqual(1)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -50,7 +50,6 @@
|
|||
"expand": "Expand",
|
||||
"home": "Home",
|
||||
"notification": "Notification",
|
||||
"mention": "Mention",
|
||||
"direct": "Direct messages",
|
||||
"follow_requests": "Follow Requests",
|
||||
"favourite": "Favourite",
|
||||
|
@ -64,7 +63,6 @@
|
|||
"header_menu": {
|
||||
"home": "Home",
|
||||
"notification": "Notification",
|
||||
"mention": "Mention",
|
||||
"favourite": "Favourite",
|
||||
"bookmark": "Bookmark",
|
||||
"follow_requests": "Follow Requests",
|
||||
|
|
|
@ -1,226 +0,0 @@
|
|||
<template>
|
||||
<div id="mentions">
|
||||
<div></div>
|
||||
<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" :watch-data="true">
|
||||
<notification
|
||||
:message="item"
|
||||
:focused="item.id === focusedId"
|
||||
:overlaid="modalOpened"
|
||||
:filters="[]"
|
||||
@update="updateToot"
|
||||
@focus-right="focusSidebar"
|
||||
@select-notification="focusNotification(item)"
|
||||
>
|
||||
</notification>
|
||||
</DynamicScrollerItem>
|
||||
</template>
|
||||
</DynamicScroller>
|
||||
<div :class="openSideBar ? 'upper-with-side-bar' : 'upper'" v-show="!heading">
|
||||
<el-button type="primary" @click="upper" circle>
|
||||
<font-awesome-icon icon="angle-up" class="upper-icon" />
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, onBeforeUpdate, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
import { logicAnd } from '@vueuse/math'
|
||||
import { useMagicKeys, whenever } from '@vueuse/core'
|
||||
import { useI18next } from 'vue3-i18next'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { Entity } from 'megalodon'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { useStore } from '@/store'
|
||||
import Notification from '@/components/organisms/Notification.vue'
|
||||
import StatusLoading from '@/components/organisms/StatusLoading.vue'
|
||||
import { EventEmitter } from '@/components/event'
|
||||
import useReloadable from '@/components/utils/reloadable'
|
||||
import { LoadingCard } from '@/types/loading-card'
|
||||
import { ACTION_TYPES, MUTATION_TYPES } from '@/store/TimelineSpace/Contents/Mentions'
|
||||
import { MUTATION_TYPES as SIDE_MENU_MUTATION } from '@/store/TimelineSpace/SideMenu'
|
||||
import { MUTATION_TYPES as TIMELINE_MUTATION } from '@/store/TimelineSpace'
|
||||
import { MUTATION_TYPES as HEADER_MUTATION } from '@/store/TimelineSpace/HeaderMenu'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'mentions',
|
||||
components: { Notification, StatusLoading },
|
||||
setup() {
|
||||
const space = 'TimelineSpace/Contents/Mentions'
|
||||
const store = useStore()
|
||||
const route = useRoute()
|
||||
const i18n = useI18next()
|
||||
const { reloadable } = useReloadable(store, route, i18n)
|
||||
const { j, k, Ctrl_r } = useMagicKeys()
|
||||
|
||||
const focusedId = ref<string | null>(null)
|
||||
const scroller = ref<any>()
|
||||
|
||||
const mentions = computed<Array<Entity.Notification | LoadingCard>>(() => store.getters[`${space}/mentions`])
|
||||
const lazyLoading = computed(() => store.state.TimelineSpace.Contents.Mentions.lazyLoading)
|
||||
const heading = computed(() => store.state.TimelineSpace.Contents.Mentions.heading)
|
||||
const openSideBar = computed(() => store.state.TimelineSpace.Contents.SideBar.openSideBar)
|
||||
const startReload = computed(() => store.state.TimelineSpace.HeaderMenu.reload)
|
||||
const modalOpened = computed<boolean>(() => store.getters[`TimelineSpace/Modals/modalOpened`])
|
||||
const currentFocusedIndex = computed(() => mentions.value.findIndex(notification => focusedId.value === notification.id))
|
||||
const shortcutEnabled = computed(() => !modalOpened.value)
|
||||
|
||||
onMounted(() => {
|
||||
store.commit(`TimelineSpace/SideMenu/${SIDE_MENU_MUTATION.CHANGE_UNREAD_MENTIONS}`, false)
|
||||
document.getElementById('scroller')?.addEventListener('scroll', onScroll)
|
||||
})
|
||||
onBeforeUpdate(() => {
|
||||
if (store.state.TimelineSpace.SideMenu.unreadMentions && heading.value) {
|
||||
store.commit(`TimelineSpace/SideMenu/${SIDE_MENU_MUTATION.CHANGE_UNREAD_MENTIONS}`, false)
|
||||
}
|
||||
})
|
||||
onUnmounted(() => {
|
||||
store.commit(`${space}/${MUTATION_TYPES.CHANGE_HEADING}`, true)
|
||||
store.commit(`${space}/${MUTATION_TYPES.ARCHIVE_MENTIONS}`)
|
||||
const el = document.getElementById('scroller')
|
||||
if (el !== undefined && el !== null) {
|
||||
el.removeEventListener('scroll', onScroll)
|
||||
el.scrollTop = 0
|
||||
}
|
||||
})
|
||||
watch(startReload, (newVal, oldVal) => {
|
||||
if (!oldVal && newVal) {
|
||||
reload().finally(() => {
|
||||
store.commit(`TimelineSpace/HeaderMenu/${HEADER_MUTATION.CHANGE_RELOAD}`, false)
|
||||
})
|
||||
}
|
||||
})
|
||||
watch(focusedId, (newVal, _oldVal) => {
|
||||
if (newVal && heading.value) {
|
||||
store.commit(`${space}/${MUTATION_TYPES.CHANGE_HEADING}`, false)
|
||||
} else if (newVal === null && !heading.value) {
|
||||
store.commit(`${space}/${MUTATION_TYPES.CHANGE_HEADING}`, true)
|
||||
}
|
||||
})
|
||||
whenever(logicAnd(j, shortcutEnabled), () => {
|
||||
if (focusedId.value === null) {
|
||||
focusedId.value = mentions.value[0].id
|
||||
} else {
|
||||
focusNext()
|
||||
}
|
||||
})
|
||||
whenever(logicAnd(k, shortcutEnabled), () => {
|
||||
focusPrev()
|
||||
})
|
||||
whenever(logicAnd(Ctrl_r, shortcutEnabled), () => {
|
||||
reload()
|
||||
})
|
||||
|
||||
const onScroll = (event: Event) => {
|
||||
// for lazyLoading
|
||||
if (
|
||||
(event.target as HTMLElement)!.clientHeight + (event.target as HTMLElement)!.scrollTop >=
|
||||
document.getElementById('scroller')!.scrollHeight - 10 &&
|
||||
!lazyLoading.value
|
||||
) {
|
||||
store.dispatch(`${space}/${ACTION_TYPES.LAZY_FETCH_MENTIONS}`, mentions.value[mentions.value.length - 1]).catch(() => {
|
||||
ElMessage({
|
||||
message: i18n.t('message.timeline_fetch_error'),
|
||||
type: 'error'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if ((event.target as HTMLElement)!.scrollTop > 10 && heading.value) {
|
||||
store.commit(`${space}/${MUTATION_TYPES.CHANGE_HEADING}`, false)
|
||||
} else if ((event.target as HTMLElement)!.scrollTop <= 10 && !heading.value) {
|
||||
store.commit(`${space}/${MUTATION_TYPES.CHANGE_HEADING}`, true)
|
||||
}
|
||||
}
|
||||
const updateToot = (message: Entity.Status) => {
|
||||
store.commit(`${space}/${MUTATION_TYPES.UPDATE_TOOT}`, message)
|
||||
}
|
||||
const reload = async () => {
|
||||
store.commit(`TimelineSpace/${TIMELINE_MUTATION.CHANGE_LOADING}`, true)
|
||||
try {
|
||||
await reloadable()
|
||||
} finally {
|
||||
store.commit(`TimelineSpace/${TIMELINE_MUTATION.CHANGE_LOADING}`, false)
|
||||
}
|
||||
}
|
||||
const upper = () => {
|
||||
scroller.value.scrollToItem(0)
|
||||
focusedId.value = null
|
||||
}
|
||||
const focusNext = () => {
|
||||
if (currentFocusedIndex.value === -1) {
|
||||
focusedId.value = mentions.value[0].id
|
||||
} else if (currentFocusedIndex.value < mentions.value.length) {
|
||||
focusedId.value = mentions.value[currentFocusedIndex.value + 1].id
|
||||
}
|
||||
}
|
||||
const focusPrev = () => {
|
||||
if (currentFocusedIndex.value === 0) {
|
||||
focusedId.value = null
|
||||
} else if (currentFocusedIndex.value > 0) {
|
||||
focusedId.value = mentions.value[currentFocusedIndex.value - 1].id
|
||||
}
|
||||
}
|
||||
const focusNotification = (message: Entity.Notification) => {
|
||||
focusedId.value = message.id
|
||||
}
|
||||
const focusSidebar = () => {
|
||||
EventEmitter.emit('focus-sidebar')
|
||||
}
|
||||
|
||||
return {
|
||||
mentions,
|
||||
scroller,
|
||||
focusedId,
|
||||
modalOpened,
|
||||
updateToot,
|
||||
focusSidebar,
|
||||
focusNotification,
|
||||
openSideBar,
|
||||
heading,
|
||||
upper
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
#mentions {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
scroll-behavior: auto;
|
||||
|
||||
.scroller {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.loading-card {
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.loading-card:empty {
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.upper {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
}
|
||||
|
||||
.upper-with-side-bar {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: calc(20px + var(--current-sidebar-width));
|
||||
transition: all 0.5s;
|
||||
}
|
||||
|
||||
.upper-icon {
|
||||
padding: 3px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" src="@/assets/timeline-transition.scss"></style>
|
|
@ -87,9 +87,6 @@ export default defineComponent({
|
|||
case 'bookmarks':
|
||||
store.commit(`${space}/${MUTATION_TYPES.UPDATE_TITLE}`, i18n.t('header_menu.bookmark'))
|
||||
break
|
||||
case 'mentions':
|
||||
store.commit(`${space}/${MUTATION_TYPES.UPDATE_TITLE}`, i18n.t('header_menu.mention'))
|
||||
break
|
||||
case 'follow-requests':
|
||||
store.commit(`${space}/${MUTATION_TYPES.UPDATE_TITLE}`, i18n.t('header_menu.follow_requests'))
|
||||
break
|
||||
|
@ -133,7 +130,6 @@ export default defineComponent({
|
|||
switch (route.name) {
|
||||
case 'home':
|
||||
case 'notifications':
|
||||
case 'mentions':
|
||||
case 'favourites':
|
||||
case 'bookmarks':
|
||||
case 'local':
|
||||
|
@ -151,7 +147,6 @@ export default defineComponent({
|
|||
switch (route.name) {
|
||||
case 'home':
|
||||
case 'notifications':
|
||||
case 'mentions':
|
||||
case 'favourites':
|
||||
case 'bookmarks':
|
||||
case 'local':
|
||||
|
|
|
@ -71,23 +71,6 @@
|
|||
</div>
|
||||
</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item
|
||||
:index="`/${id}/mentions`"
|
||||
role="menuitem"
|
||||
:title="$t('side_menu.mention')"
|
||||
class="menu-item"
|
||||
v-if="enabledTimelines.mention"
|
||||
>
|
||||
<div class="menu-item-icon">
|
||||
<font-awesome-icon icon="at" />
|
||||
</div>
|
||||
<template #title>
|
||||
<div>
|
||||
<span>{{ $t('side_menu.mention') }}</span>
|
||||
<el-badge is-dot :hidden="!unreadMentions"> </el-badge>
|
||||
</div>
|
||||
</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item
|
||||
:index="`/${id}/direct-messages`"
|
||||
role="menuitem"
|
||||
|
@ -291,7 +274,6 @@ export default defineComponent({
|
|||
const enabledTimelines = reactive({
|
||||
home: true,
|
||||
notification: true,
|
||||
mention: true,
|
||||
direct: true,
|
||||
favourite: true,
|
||||
bookmark: true,
|
||||
|
@ -307,7 +289,6 @@ export default defineComponent({
|
|||
|
||||
const unreadHomeTimeline = computed(() => store.state.TimelineSpace.SideMenu.unreadHomeTimeline)
|
||||
const unreadNotifications = computed(() => store.state.TimelineSpace.SideMenu.unreadNotifications)
|
||||
const unreadMentions = computed(() => store.state.TimelineSpace.SideMenu.unreadMentions)
|
||||
const unreadLocalTimeline = computed(() => store.state.TimelineSpace.SideMenu.unreadLocalTimeline)
|
||||
const unreadDirectMessagesTimeline = computed(() => store.state.TimelineSpace.SideMenu.unreadDirectMessagesTimeline)
|
||||
const unreadPublicTimeline = computed(() => store.state.TimelineSpace.SideMenu.unreadPublicTimeline)
|
||||
|
@ -344,7 +325,6 @@ export default defineComponent({
|
|||
const notification = async () => {
|
||||
return client.getNotifications({ limit: 1 }).catch(() => {
|
||||
enabledTimelines.notification = false
|
||||
enabledTimelines.mention = false
|
||||
})
|
||||
}
|
||||
const direct = async () => {
|
||||
|
@ -415,7 +395,6 @@ export default defineComponent({
|
|||
return {
|
||||
unreadHomeTimeline,
|
||||
unreadNotifications,
|
||||
unreadMentions,
|
||||
unreadLocalTimeline,
|
||||
unreadDirectMessagesTimeline,
|
||||
unreadPublicTimeline,
|
||||
|
|
|
@ -18,7 +18,6 @@ import SettingsFiltersNew from '@/components/Settings/Filters/New.vue'
|
|||
import TimelineSpace from '@/components/TimelineSpace.vue'
|
||||
import TimelineSpaceContentsHome from '@/components/TimelineSpace/Contents/Home.vue'
|
||||
import TimelineSpaceContentsNotifications from '@/components/TimelineSpace/Contents/Notifications.vue'
|
||||
import TimelineSpaceContentsMentions from '@/components/TimelineSpace/Contents/Mentions.vue'
|
||||
import TimelineSpaceContentsFavourites from '@/components/TimelineSpace/Contents/Favourites.vue'
|
||||
import TimelineSpaceContentsLocal from '@/components/TimelineSpace/Contents/Local.vue'
|
||||
import TimelineSpaceContentsPublic from '@/components/TimelineSpace/Contents/Public.vue'
|
||||
|
@ -123,11 +122,6 @@ const routes = [
|
|||
name: 'notifications',
|
||||
component: TimelineSpaceContentsNotifications
|
||||
},
|
||||
{
|
||||
path: 'mentions',
|
||||
name: 'mentions',
|
||||
component: TimelineSpaceContentsMentions
|
||||
},
|
||||
{
|
||||
path: 'follow-requests',
|
||||
name: 'follow-requests',
|
||||
|
|
|
@ -200,7 +200,6 @@ const actions: ActionTree<TimelineSpaceState, RootState> = {
|
|||
},
|
||||
[ACTION_TYPES.FETCH_CONTENTS_TIMELINES]: async ({ dispatch }) => {
|
||||
await dispatch('TimelineSpace/Contents/Notifications/fetchNotifications', {}, { root: true })
|
||||
await dispatch('TimelineSpace/Contents/Mentions/fetchMentions', {}, { root: true })
|
||||
await dispatch('TimelineSpace/Contents/DirectMessages/fetchTimeline', {}, { root: true })
|
||||
await dispatch('TimelineSpace/Contents/Local/fetchLocalTimeline', {}, { root: true })
|
||||
await dispatch('TimelineSpace/Contents/Public/fetchPublicTimeline', {}, { root: true })
|
||||
|
@ -210,7 +209,6 @@ const actions: ActionTree<TimelineSpaceState, RootState> = {
|
|||
commit('TimelineSpace/Contents/DirectMessages/clearTimeline', {}, { root: true })
|
||||
commit('TimelineSpace/Contents/Notifications/clearNotifications', {}, { root: true })
|
||||
commit('TimelineSpace/Contents/Public/clearTimeline', {}, { root: true })
|
||||
commit('TimelineSpace/Contents/Mentions/clearMentions', {}, { root: true })
|
||||
},
|
||||
[ACTION_TYPES.BIND_STREAMINGS]: ({ dispatch }) => {
|
||||
dispatch('bindUserStreaming')
|
||||
|
@ -236,7 +234,6 @@ const actions: ActionTree<TimelineSpaceState, RootState> = {
|
|||
win.ipcRenderer.on(`delete-user-streamings-${state.account!.id}`, (_, id: string) => {
|
||||
commit('TimelineSpace/Contents/Home/deleteToot', id, { root: true })
|
||||
commit('TimelineSpace/Contents/Notifications/deleteToot', id, { root: true })
|
||||
commit('TimelineSpace/Contents/Mentions/deleteToot', id, { root: true })
|
||||
})
|
||||
},
|
||||
[ACTION_TYPES.BIND_LOCAL_STREAMING]: ({ commit, rootState, state }) => {
|
||||
|
@ -279,7 +276,6 @@ const actions: ActionTree<TimelineSpaceState, RootState> = {
|
|||
[ACTION_TYPES.UPDATE_TOOT_FOR_ALL_TIMELINES]: ({ commit }, status: Entity.Status): boolean => {
|
||||
commit('TimelineSpace/Contents/Home/updateToot', status, { root: true })
|
||||
commit('TimelineSpace/Contents/Notifications/updateToot', status, { root: true })
|
||||
commit('TimelineSpace/Contents/Mentions/updateToot', status, { root: true })
|
||||
commit('TimelineSpace/Contents/DirectMessages/updateToot', status, { root: true })
|
||||
commit('TimelineSpace/Contents/Local/updateToot', status, { root: true })
|
||||
commit('TimelineSpace/Contents/Public/updateToot', status, { root: true })
|
||||
|
|
|
@ -10,7 +10,6 @@ import Lists, { ListsModuleState } from './Contents/Lists'
|
|||
import Hashtag, { HashtagModuleState } from './Contents/Hashtag'
|
||||
import DirectMessages, { DirectMessagesState } from './Contents/DirectMessages'
|
||||
import FollowRequests, { FollowRequestsState } from './Contents/FollowRequests'
|
||||
import Mentions, { MentionsState } from './Contents/Mentions'
|
||||
import { Module, MutationTree, ActionTree } from 'vuex'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
|
@ -22,7 +21,6 @@ type ContentsModule = {
|
|||
SideBar: SideBarModuleState
|
||||
Home: HomeState
|
||||
Notifications: NotificationsState
|
||||
Mentions: MentionsState
|
||||
DirectMessages: DirectMessagesState
|
||||
Favourites: FavouritesState
|
||||
Bookmarks: BookmarksState
|
||||
|
@ -71,7 +69,6 @@ const Contents: Module<ContentsState, RootState> = {
|
|||
Bookmarks,
|
||||
Local,
|
||||
DirectMessages,
|
||||
Mentions,
|
||||
Public,
|
||||
Search,
|
||||
Lists,
|
||||
|
|
|
@ -1,167 +0,0 @@
|
|||
import generator, { Entity, NotificationType } from 'megalodon'
|
||||
import { Module, MutationTree, ActionTree, GetterTree } from 'vuex'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
const excludes: Array<string> = [
|
||||
NotificationType.Follow,
|
||||
NotificationType.Favourite,
|
||||
NotificationType.Reblog,
|
||||
NotificationType.PollVote,
|
||||
NotificationType.PollExpired,
|
||||
NotificationType.EmojiReaction
|
||||
]
|
||||
|
||||
export type MentionsState = {
|
||||
lazyLoading: boolean
|
||||
heading: boolean
|
||||
mentions: Array<Entity.Notification>
|
||||
}
|
||||
|
||||
const state = (): MentionsState => ({
|
||||
lazyLoading: false,
|
||||
heading: true,
|
||||
mentions: []
|
||||
})
|
||||
|
||||
export const MUTATION_TYPES = {
|
||||
CHANGE_LAZY_LOADING: 'changeLazyLoading',
|
||||
CHANGE_HEADING: 'changeHeading',
|
||||
APPEND_MENTIONS: 'appendMentions',
|
||||
UPDATE_MENTIONS: 'updateMentions',
|
||||
INSERT_MENTIONS: 'insertMentions',
|
||||
ARCHIVE_MENTIONS: 'archiveMentions',
|
||||
CLEAR_MENTIONS: 'clearMentions',
|
||||
UPDATE_TOOT: 'updateToot',
|
||||
DELETE_TOOT: 'deleteToot'
|
||||
}
|
||||
|
||||
const mutations: MutationTree<MentionsState> = {
|
||||
[MUTATION_TYPES.CHANGE_LAZY_LOADING]: (state, value: boolean) => {
|
||||
state.lazyLoading = value
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_HEADING]: (state, value: boolean) => {
|
||||
state.heading = value
|
||||
},
|
||||
[MUTATION_TYPES.APPEND_MENTIONS]: (state, update: Entity.Notification) => {
|
||||
// Reject duplicated status in timeline
|
||||
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.INSERT_MENTIONS]: (state, messages: Array<Entity.Notification>) => {
|
||||
state.mentions = state.mentions.concat(messages)
|
||||
},
|
||||
[MUTATION_TYPES.ARCHIVE_MENTIONS]: state => {
|
||||
state.mentions = state.mentions.slice(0, 30)
|
||||
},
|
||||
[MUTATION_TYPES.CLEAR_MENTIONS]: state => {
|
||||
state.mentions = []
|
||||
},
|
||||
[MUTATION_TYPES.UPDATE_TOOT]: (state, message: Entity.Status) => {
|
||||
state.mentions = state.mentions.map(mention => {
|
||||
if (mention.type === 'mention' && mention.status && mention.status.id === message.id) {
|
||||
const status = {
|
||||
status: message
|
||||
}
|
||||
return Object.assign(mention, status)
|
||||
} else {
|
||||
return mention
|
||||
}
|
||||
})
|
||||
},
|
||||
[MUTATION_TYPES.DELETE_TOOT]: (state, id: string) => {
|
||||
state.mentions = state.mentions.filter(m => {
|
||||
if (m.id === 'loading-card') {
|
||||
return true
|
||||
}
|
||||
const mention = m as Entity.Notification
|
||||
if (mention.status) {
|
||||
if (mention.status.reblog && mention.status.reblog.id === id) {
|
||||
return false
|
||||
} else {
|
||||
return mention.status.id !== id
|
||||
}
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const ACTION_TYPES = {
|
||||
FETCH_MENTIONS: 'fetchMentions',
|
||||
LAZY_FETCH_MENTIONS: 'lazyFetchMentions'
|
||||
}
|
||||
|
||||
const actions: ActionTree<MentionsState, RootState> = {
|
||||
[ACTION_TYPES.FETCH_MENTIONS]: async ({ commit, rootState }): Promise<Array<Entity.Notification>> => {
|
||||
const client = generator(
|
||||
rootState.TimelineSpace.server!.sns,
|
||||
rootState.TimelineSpace.server!.baseURL,
|
||||
rootState.TimelineSpace.account!.accessToken,
|
||||
rootState.App.userAgent
|
||||
)
|
||||
|
||||
const res = await client.getNotifications({
|
||||
limit: 30,
|
||||
exclude_types: excludes
|
||||
})
|
||||
commit(MUTATION_TYPES.UPDATE_MENTIONS, res.data)
|
||||
return res.data
|
||||
},
|
||||
[ACTION_TYPES.LAZY_FETCH_MENTIONS]: async (
|
||||
{ state, commit, rootState },
|
||||
lastMention: Entity.Notification
|
||||
): Promise<Array<Entity.Notification> | null> => {
|
||||
if (state.lazyLoading) {
|
||||
return Promise.resolve(null)
|
||||
}
|
||||
commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true)
|
||||
const client = generator(
|
||||
rootState.TimelineSpace.server!.sns,
|
||||
rootState.TimelineSpace.server!.baseURL,
|
||||
rootState.TimelineSpace.account!.accessToken,
|
||||
rootState.App.userAgent
|
||||
)
|
||||
return client
|
||||
.getNotifications({
|
||||
max_id: lastMention.id,
|
||||
limit: 30,
|
||||
exclude_types: excludes
|
||||
})
|
||||
.then(res => {
|
||||
commit(MUTATION_TYPES.INSERT_MENTIONS, res.data)
|
||||
return res.data
|
||||
})
|
||||
.finally(() => {
|
||||
commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, false)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const getters: GetterTree<MentionsState, RootState> = {
|
||||
mentions: state => {
|
||||
return state.mentions.filter(mention => {
|
||||
switch (mention.type) {
|
||||
case 'middle-load':
|
||||
case NotificationType.Mention:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const Mentions: Module<MentionsState, RootState> = {
|
||||
namespaced: true,
|
||||
state: state,
|
||||
mutations: mutations,
|
||||
actions: actions,
|
||||
getters: getters
|
||||
}
|
||||
|
||||
export default Mentions
|
|
@ -27,10 +27,6 @@ const state = (): JumpState => ({
|
|||
name: i18n.t('side_menu.notification'),
|
||||
path: 'notifications'
|
||||
},
|
||||
{
|
||||
name: i18n.t('side_menu.mention'),
|
||||
path: 'mentions'
|
||||
},
|
||||
{
|
||||
name: i18n.t('side_menu.favourite'),
|
||||
path: 'favourites'
|
||||
|
|
|
@ -7,7 +7,6 @@ const win = (window as any) as MyWindow
|
|||
export type SideMenuState = {
|
||||
unreadHomeTimeline: boolean
|
||||
unreadNotifications: boolean
|
||||
unreadMentions: boolean
|
||||
unreadLocalTimeline: boolean
|
||||
unreadDirectMessagesTimeline: boolean
|
||||
unreadPublicTimeline: boolean
|
||||
|
@ -18,7 +17,6 @@ export type SideMenuState = {
|
|||
const state = (): SideMenuState => ({
|
||||
unreadHomeTimeline: false,
|
||||
unreadNotifications: false,
|
||||
unreadMentions: false,
|
||||
unreadLocalTimeline: false,
|
||||
unreadDirectMessagesTimeline: false,
|
||||
unreadPublicTimeline: false,
|
||||
|
@ -29,7 +27,6 @@ const state = (): SideMenuState => ({
|
|||
export const MUTATION_TYPES = {
|
||||
CHANGE_UNREAD_HOME_TIMELINE: 'changeUnreadHomeTimeline',
|
||||
CHANGE_UNREAD_NOTIFICATIONS: 'changeUnreadNotifications',
|
||||
CHANGE_UNREAD_MENTIONS: 'changeUnreadMentions',
|
||||
CHANGE_UNREAD_LOCAL_TIMELINE: 'changeUnreadLocalTimeline',
|
||||
CHANGE_UNREAD_DIRECT_MESSAGES_TIMELINE: 'changeUnreadDirectMessagesTimeline',
|
||||
CHANGE_UNREAD_PUBLIC_TIMELINE: 'changeUnreadPublicTimeline',
|
||||
|
@ -44,9 +41,6 @@ const mutations: MutationTree<SideMenuState> = {
|
|||
[MUTATION_TYPES.CHANGE_UNREAD_NOTIFICATIONS]: (state, value: boolean) => {
|
||||
state.unreadNotifications = value
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_UNREAD_MENTIONS]: (state, value: boolean) => {
|
||||
state.unreadMentions = value
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_UNREAD_LOCAL_TIMELINE]: (state, value: boolean) => {
|
||||
state.unreadLocalTimeline = value
|
||||
},
|
||||
|
@ -74,7 +68,6 @@ const actions: ActionTree<SideMenuState, RootState> = {
|
|||
[ACTION_TYPES.CLEAR_UNREAD]: ({ commit }) => {
|
||||
commit(MUTATION_TYPES.CHANGE_UNREAD_HOME_TIMELINE, false)
|
||||
commit(MUTATION_TYPES.CHANGE_UNREAD_NOTIFICATIONS, false)
|
||||
commit(MUTATION_TYPES.CHANGE_UNREAD_MENTIONS, false)
|
||||
commit(MUTATION_TYPES.CHANGE_UNREAD_LOCAL_TIMELINE, false)
|
||||
commit(MUTATION_TYPES.CHANGE_UNREAD_DIRECT_MESSAGES_TIMELINE, false)
|
||||
commit(MUTATION_TYPES.CHANGE_UNREAD_PUBLIC_TIMELINE, false)
|
||||
|
|
Loading…
Reference in New Issue