[refactor] Favourites store

This commit is contained in:
AkiraFukushima 2023-01-03 00:41:46 +09:00
parent 44d36d48fb
commit f2393b33cb
No known key found for this signature in database
GPG Key ID: B6E51BAC4DE1A957
3 changed files with 54 additions and 41 deletions

View File

@ -5,10 +5,13 @@
<template v-slot="{ item, index, active }"> <template v-slot="{ item, index, active }">
<DynamicScrollerItem :item="item" :active="active" :size-dependencies="[item.uri]" :data-index="index" :watchData="true"> <DynamicScrollerItem :item="item" :active="active" :size-dependencies="[item.uri]" :data-index="index" :watchData="true">
<toot <toot
v-if="account.account && account.server"
:message="item" :message="item"
:focused="item.uri === focusedId" :focused="item.uri === focusedId"
:overlaid="modalOpened" :overlaid="modalOpened"
:filters="[]" :filters="[]"
:account="account.account"
:server="account.server"
v-on:update="updateToot" v-on:update="updateToot"
v-on:delete="deleteToot" v-on:delete="deleteToot"
@focusRight="focusSidebar" @focusRight="focusSidebar"
@ -27,7 +30,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, computed, ref, onMounted, onUnmounted, watch } from 'vue' import { defineComponent, computed, ref, onMounted, onUnmounted, watch, reactive } from 'vue'
import { logicAnd } from '@vueuse/math' import { logicAnd } from '@vueuse/math'
import { useMagicKeys, whenever } from '@vueuse/core' import { useMagicKeys, whenever } from '@vueuse/core'
import { useStore } from '@/store' import { useStore } from '@/store'
@ -40,6 +43,10 @@ import { ACTION_TYPES, MUTATION_TYPES } from '@/store/TimelineSpace/Contents/Fav
import { MUTATION_TYPES as CONTENTS_MUTATION } from '@/store/TimelineSpace/Contents' import { MUTATION_TYPES as CONTENTS_MUTATION } from '@/store/TimelineSpace/Contents'
import { MUTATION_TYPES as HEADER_MUTATION } from '@/store/TimelineSpace/HeaderMenu' import { MUTATION_TYPES as HEADER_MUTATION } from '@/store/TimelineSpace/HeaderMenu'
import { MUTATION_TYPES as TIMELINE_MUTATION } from '@/store/TimelineSpace' import { MUTATION_TYPES as TIMELINE_MUTATION } from '@/store/TimelineSpace'
import { LocalAccount } from '~/src/types/localAccount'
import { LocalServer } from '~/src/types/localServer'
import { MyWindow } from '~/src/types/global'
import { useRoute } from 'vue-router'
export default defineComponent({ export default defineComponent({
name: 'favourites', name: 'favourites',
@ -47,6 +54,7 @@ export default defineComponent({
setup() { setup() {
const space = 'TimelineSpace/Contents/Favourites' const space = 'TimelineSpace/Contents/Favourites'
const store = useStore() const store = useStore()
const route = useRoute()
const i18n = useI18next() const i18n = useI18next()
const heading = ref<boolean>(false) const heading = ref<boolean>(false)
@ -54,20 +62,32 @@ export default defineComponent({
const scroller = ref<any>() const scroller = ref<any>()
const { j, k, Ctrl_r } = useMagicKeys() const { j, k, Ctrl_r } = useMagicKeys()
const win = (window as any) as MyWindow
const id = computed(() => parseInt(route.params.id as string))
const lazyLoading = ref(false)
const account = reactive<{ account: LocalAccount | null; server: LocalServer | null }>({
account: null,
server: null
})
const openSideBar = computed(() => store.state.TimelineSpace.Contents.SideBar.openSideBar) const openSideBar = computed(() => store.state.TimelineSpace.Contents.SideBar.openSideBar)
const startReload = computed(() => store.state.TimelineSpace.HeaderMenu.reload) const startReload = computed(() => store.state.TimelineSpace.HeaderMenu.reload)
const favourites = computed(() => store.state.TimelineSpace.Contents.Favourites.favourites) const favourites = computed(() => store.state.TimelineSpace.Contents.Favourites.favourites)
const lazyLoading = computed(() => store.state.TimelineSpace.Contents.Favourites.lazyLoading)
const modalOpened = computed<boolean>(() => store.getters[`TimelineSpace/Modals/modalOpened`]) const modalOpened = computed<boolean>(() => store.getters[`TimelineSpace/Modals/modalOpened`])
const currentFocusedIndex = computed(() => favourites.value.findIndex(status => focusedId.value === status.uri)) const currentFocusedIndex = computed(() => favourites.value.findIndex(status => focusedId.value === status.uri))
const shortcutEnabled = computed(() => !modalOpened.value) const shortcutEnabled = computed(() => !modalOpened.value)
onMounted(() => { onMounted(async () => {
const [a, s]: [LocalAccount, LocalServer] = await win.ipcRenderer.invoke('get-local-account', id.value)
account.account = a
account.server = s
document.getElementById('scroller')?.addEventListener('scroll', onScroll) document.getElementById('scroller')?.addEventListener('scroll', onScroll)
store.commit(`TimelineSpace/Contents/${CONTENTS_MUTATION.CHANGE_LOADING}`, true) store.commit(`TimelineSpace/Contents/${CONTENTS_MUTATION.CHANGE_LOADING}`, true)
store store
.dispatch(`${space}/${ACTION_TYPES.FETCH_FAVOURITES}`) .dispatch(`${space}/${ACTION_TYPES.FETCH_FAVOURITES}`, account)
.catch(() => { .catch(() => {
ElMessage({ ElMessage({
message: i18n.t('message.favourite_fetch_error'), message: i18n.t('message.favourite_fetch_error'),
@ -115,12 +135,18 @@ export default defineComponent({
document.getElementById('scroller')!.scrollHeight - 10 && document.getElementById('scroller')!.scrollHeight - 10 &&
!lazyLoading.value !lazyLoading.value
) { ) {
store.dispatch(`${space}/${ACTION_TYPES.LAZY_FETCH_FAVOURITES}`, favourites.value[favourites.value.length - 1]).catch(() => { lazyLoading.value = true
ElMessage({ store
message: i18n.t('message.favourite_fetch_error'), .dispatch(`${space}/${ACTION_TYPES.LAZY_FETCH_FAVOURITES}`, account)
type: 'error' .catch(() => {
ElMessage({
message: i18n.t('message.favourite_fetch_error'),
type: 'error'
})
})
.finally(() => {
lazyLoading.value = false
}) })
})
} }
// for upper // for upper
if ((event.target as HTMLElement)!.scrollTop > 10 && heading.value) { if ((event.target as HTMLElement)!.scrollTop > 10 && heading.value) {
@ -138,7 +164,7 @@ export default defineComponent({
const reload = async () => { const reload = async () => {
store.commit(`TimelineSpace/${TIMELINE_MUTATION.CHANGE_LOADING}`, true) store.commit(`TimelineSpace/${TIMELINE_MUTATION.CHANGE_LOADING}`, true)
try { try {
await store.dispatch(`${space}/${ACTION_TYPES.FETCH_FAVOURITES}`).catch(() => { await store.dispatch(`${space}/${ACTION_TYPES.FETCH_FAVOURITES}`, account).catch(() => {
ElMessage({ ElMessage({
message: i18n.t('message.favourite_fetch_error'), message: i18n.t('message.favourite_fetch_error'),
type: 'error' type: 'error'
@ -184,7 +210,8 @@ export default defineComponent({
focusToot, focusToot,
openSideBar, openSideBar,
heading, heading,
upper upper,
account
} }
} }
}) })

View File

@ -100,7 +100,7 @@ const actions: ActionTree<BookmarksState, RootState> = {
// Parse link header // Parse link header
try { try {
const link = parse(res.headers.link) const link = parse(res.headers.link)
if (link !== null) { if (link !== null && link.next) {
commit(MUTATION_TYPES.CHANGE_MAX_ID, link.next.max_id) commit(MUTATION_TYPES.CHANGE_MAX_ID, link.next.max_id)
} else { } else {
commit(MUTATION_TYPES.CHANGE_MAX_ID, null) commit(MUTATION_TYPES.CHANGE_MAX_ID, null)

View File

@ -2,16 +2,16 @@ import generator, { Entity } from 'megalodon'
import parse from 'parse-link-header' import parse from 'parse-link-header'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
import { LocalAccount } from '~/src/types/localAccount'
import { LocalServer } from '~/src/types/localServer'
export type FavouritesState = { export type FavouritesState = {
favourites: Array<Entity.Status> favourites: Array<Entity.Status>
lazyLoading: boolean
maxId: string | null maxId: string | null
} }
const state = (): FavouritesState => ({ const state = (): FavouritesState => ({
favourites: [], favourites: [],
lazyLoading: false,
maxId: null maxId: null
}) })
@ -20,7 +20,6 @@ export const MUTATION_TYPES = {
INSERT_FAVOURITES: 'insertFavourites', INSERT_FAVOURITES: 'insertFavourites',
UPDATE_TOOT: 'updateToot', UPDATE_TOOT: 'updateToot',
DELETE_TOOT: 'deleteToot', DELETE_TOOT: 'deleteToot',
CHANGE_LAZY_LOADING: 'changeLazyLoading',
CHANGE_MAX_ID: 'changeMaxId' CHANGE_MAX_ID: 'changeMaxId'
} }
@ -56,9 +55,6 @@ const mutations: MutationTree<FavouritesState> = {
} }
}) })
}, },
[MUTATION_TYPES.CHANGE_LAZY_LOADING]: (state, value: boolean) => {
state.lazyLoading = value
},
[MUTATION_TYPES.CHANGE_MAX_ID]: (state, id: string | null) => { [MUTATION_TYPES.CHANGE_MAX_ID]: (state, id: string | null) => {
state.maxId = id state.maxId = id
} }
@ -70,19 +66,17 @@ export const ACTION_TYPES = {
} }
const actions: ActionTree<FavouritesState, RootState> = { const actions: ActionTree<FavouritesState, RootState> = {
[ACTION_TYPES.FETCH_FAVOURITES]: async ({ commit, rootState }): Promise<Array<Entity.Status>> => { [ACTION_TYPES.FETCH_FAVOURITES]: async (
const client = generator( { commit, rootState },
rootState.TimelineSpace.server!.sns, req: { account: LocalAccount; server: LocalServer }
rootState.TimelineSpace.server!.baseURL, ): Promise<Array<Entity.Status>> => {
rootState.TimelineSpace.account!.accessToken, const client = generator(req.server.sns, req.server.baseURL, req.account.accessToken, rootState.App.userAgent)
rootState.App.userAgent
)
const res = await client.getFavourites({ limit: 20 }) const res = await client.getFavourites({ limit: 20 })
commit(MUTATION_TYPES.UPDATE_FAVOURITES, res.data) commit(MUTATION_TYPES.UPDATE_FAVOURITES, res.data)
// Parse link header // Parse link header
try { try {
const link = parse(res.headers.link) const link = parse(res.headers.link)
if (link !== null) { if (link !== null && link.next) {
commit(MUTATION_TYPES.CHANGE_MAX_ID, link.next.max_id) commit(MUTATION_TYPES.CHANGE_MAX_ID, link.next.max_id)
} else { } else {
commit(MUTATION_TYPES.CHANGE_MAX_ID, null) commit(MUTATION_TYPES.CHANGE_MAX_ID, null)
@ -93,28 +87,20 @@ const actions: ActionTree<FavouritesState, RootState> = {
} }
return res.data return res.data
}, },
lazyFetchFavourites: async ({ state, commit, rootState }): Promise<Array<Entity.Status> | null> => { lazyFetchFavourites: async (
if (state.lazyLoading) { { state, commit, rootState },
return Promise.resolve(null) req: { account: LocalAccount; server: LocalServer }
} ): Promise<Array<Entity.Status> | null> => {
if (!state.maxId) { if (!state.maxId) {
return Promise.resolve(null) return Promise.resolve(null)
} }
commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true) const client = generator(req.server.sns, req.server.baseURL, req.account.accessToken, rootState.App.userAgent)
const client = generator( const res = await client.getFavourites({ max_id: state.maxId, limit: 20 })
rootState.TimelineSpace.server!.sns,
rootState.TimelineSpace.server!.baseURL,
rootState.TimelineSpace.account!.accessToken,
rootState.App.userAgent
)
const res = await client.getFavourites({ max_id: state.maxId, limit: 20 }).finally(() => {
commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, false)
})
commit(MUTATION_TYPES.INSERT_FAVOURITES, res.data) commit(MUTATION_TYPES.INSERT_FAVOURITES, res.data)
// Parse link header // Parse link header
try { try {
const link = parse(res.headers.link) const link = parse(res.headers.link)
if (link !== null) { if (link !== null && link.next) {
commit(MUTATION_TYPES.CHANGE_MAX_ID, link.next.max_id) commit(MUTATION_TYPES.CHANGE_MAX_ID, link.next.max_id)
} else { } else {
commit(MUTATION_TYPES.CHANGE_MAX_ID, null) commit(MUTATION_TYPES.CHANGE_MAX_ID, null)