From abcea8f333f58e997b504d64a1679f7f876112c8 Mon Sep 17 00:00:00 2001
From: AkiraFukushima
Date: Sun, 29 Jan 2023 22:54:15 +0900
Subject: [PATCH] [refactor] Remove bookmarks store
---
.../TimelineSpace/Contents/Bookmarks.vue | 107 +++++++++------
.../TimelineSpace/Contents/DirectMessages.vue | 5 -
.../TimelineSpace/Contents/Local.vue | 12 +-
.../TimelineSpace/Contents/Notifications.vue | 14 +-
.../TimelineSpace/Contents/Public.vue | 1 -
src/renderer/components/utils/reloadable.ts | 23 ----
src/renderer/store/TimelineSpace/Contents.ts | 3 -
.../store/TimelineSpace/Contents/Bookmarks.ts | 123 ------------------
8 files changed, 78 insertions(+), 210 deletions(-)
delete mode 100644 src/renderer/components/utils/reloadable.ts
delete mode 100644 src/renderer/store/TimelineSpace/Contents/Bookmarks.ts
diff --git a/src/renderer/components/TimelineSpace/Contents/Bookmarks.vue b/src/renderer/components/TimelineSpace/Contents/Bookmarks.vue
index f50307e5..5f66f3c1 100644
--- a/src/renderer/components/TimelineSpace/Contents/Bookmarks.vue
+++ b/src/renderer/components/TimelineSpace/Contents/Bookmarks.vue
@@ -30,10 +30,9 @@ import { useStore } from '@/store'
import { useI18next } from 'vue3-i18next'
import { useRoute } from 'vue-router'
import { ElMessage } from 'element-plus'
-import { Entity } from 'megalodon'
-import useReloadable from '@/components/utils/reloadable'
+import parse from 'parse-link-header'
+import generator, { Entity, MegalodonInterface } from 'megalodon'
import Toot from '@/components/organisms/Toot.vue'
-import { ACTION_TYPES, MUTATION_TYPES } from '@/store/TimelineSpace/Contents/Bookmarks'
import { MUTATION_TYPES as TIMELINE_MUTATION } from '@/store/TimelineSpace'
import { MUTATION_TYPES as HEADER_MUTATION } from '@/store/TimelineSpace/HeaderMenu'
import { LocalAccount } from '~/src/types/localAccount'
@@ -44,15 +43,14 @@ export default defineComponent({
name: 'bookmarks',
components: { Toot },
setup() {
- const space = 'TimelineSpace/Contents/Bookmarks'
const store = useStore()
const route = useRoute()
const i18n = useI18next()
- const { reloadable } = useReloadable(store, route, i18n)
const focusedId = ref(null)
const heading = ref(true)
const scroller = ref()
+ const loading = ref(false)
const lazyLoading = ref(false)
const { j, k, Ctrl_r } = useMagicKeys()
@@ -63,12 +61,15 @@ export default defineComponent({
account: null,
server: null
})
+ const client = ref(null)
- const bookmarks = computed(() => store.state.TimelineSpace.Contents.Bookmarks.bookmarks)
+ const bookmarks = ref>([])
+ const nextMaxId = ref(null)
const startReload = computed(() => store.state.TimelineSpace.HeaderMenu.reload)
const modalOpened = computed(() => store.getters[`TimelineSpace/Modals/modalOpened`])
const currentFocusedIndex = computed(() => bookmarks.value.findIndex(toot => focusedId.value === toot.uri))
const shortcutEnabled = computed(() => !modalOpened.value)
+ const userAgent = computed(() => store.state.App.userAgent)
onMounted(async () => {
const [a, s]: [LocalAccount, LocalServer] = await win.ipcRenderer.invoke('get-local-account', id.value)
@@ -76,18 +77,27 @@ export default defineComponent({
account.server = s
document.getElementById('scroller')?.addEventListener('scroll', onScroll)
- store.commit(`TimelineSpace/Contents/${TIMELINE_MUTATION.CHANGE_LOADING}`, true)
- store
- .dispatch(`${space}/${ACTION_TYPES.FETCH_BOOKMARKS}`, account)
- .catch(() => {
- ElMessage({
- message: i18n.t('message.bookmark_fetch_error'),
- type: 'error'
- })
- })
- .finally(() => {
- store.commit(`TimelineSpace/Contents/${TIMELINE_MUTATION.CHANGE_LOADING}`, false)
+
+ client.value = generator(s.sns, s.baseURL, a.accessToken, userAgent.value)
+ loading.value = true
+ try {
+ const res = await client.value.getBookmarks({ limit: 20 })
+ bookmarks.value = res.data
+ const link = parse(res.headers.link)
+ if (link !== null && link.next) {
+ nextMaxId.value = link.next.max_id
+ } else {
+ nextMaxId.value = null
+ }
+ } catch (err) {
+ console.error(err)
+ ElMessage({
+ message: i18n.t('message.bookmark_fetch_error'),
+ type: 'error'
})
+ } finally {
+ loading.value = false
+ }
})
watch(startReload, (newVal, oldVal) => {
if (!oldVal && newVal) {
@@ -115,12 +125,23 @@ export default defineComponent({
if (
(event.target as HTMLElement)!.clientHeight + (event.target as HTMLElement)!.scrollTop >=
document.getElementById('scroller')!.scrollHeight - 10 &&
- !lazyLoading.value
+ !lazyLoading.value &&
+ nextMaxId.value
) {
lazyLoading.value = true
- store
- .dispatch(`${space}/${ACTION_TYPES.LAZY_FETCH_BOOKMARKS}`, account)
- .catch(() => {
+ client.value
+ ?.getBookmarks({ limit: 20, max_id: nextMaxId.value })
+ .then(res => {
+ bookmarks.value = [...bookmarks.value, ...res.data]
+ const link = parse(res.headers.link)
+ if (link !== null && link.next) {
+ nextMaxId.value = link.next.max_id
+ } else {
+ nextMaxId.value = null
+ }
+ })
+ .catch(err => {
+ console.error(err)
ElMessage({
message: i18n.t('message.bookmark_fetch_error'),
type: 'error'
@@ -130,7 +151,7 @@ export default defineComponent({
lazyLoading.value = false
})
}
- // for upper
+
if ((event.target as HTMLElement)!.scrollTop > 10 && heading.value) {
heading.value = false
} else if ((event.target as HTMLElement)!.scrollTop <= 10 && !heading.value) {
@@ -139,27 +160,40 @@ export default defineComponent({
}
const reload = async () => {
store.commit(`TimelineSpace/${TIMELINE_MUTATION.CHANGE_LOADING}`, true)
+ if (!client.value) return
try {
- await reloadable()
- await store.dispatch(`${space}/${ACTION_TYPES.FETCH_BOOKMARKS}`, account).catch(() => {
- ElMessage({
- message: i18n.t('message.bookmark_fetch_error'),
- type: 'error'
- })
- })
+ const res = await client.value.getBookmarks({ limit: 20 })
+ bookmarks.value = res.data
+ const link = parse(res.headers.link)
+ if (link !== null && link.next) {
+ nextMaxId.value = link.next.max_id
+ } else {
+ nextMaxId.value = null
+ }
} finally {
store.commit(`TimelineSpace/${TIMELINE_MUTATION.CHANGE_LOADING}`, false)
}
}
const updateToot = (message: Entity.Status) => {
- store.commit(`${space}/${MUTATION_TYPES.UPDATE_TOOT}`, message)
+ bookmarks.value = bookmarks.value.map(status => {
+ if (status.id === message.id) {
+ return message
+ } else if (status.reblog && status.reblog.id === message.id) {
+ return Object.assign(status, {
+ reblog: message
+ })
+ }
+ return status
+ })
}
- const deleteToot = (message: Entity.Status) => {
- store.commit(`${space}/${MUTATION_TYPES.DELETE_TOOT}`, message)
- }
- const upper = () => {
- scroller.value.scrollToItem(0)
- focusedId.value = null
+ const deleteToot = (id: string) => {
+ bookmarks.value = bookmarks.value.filter(status => {
+ if (status.reblog !== null && status.reblog.id === id) {
+ return false
+ } else {
+ return status.id !== id
+ }
+ })
}
const focusNext = () => {
if (currentFocusedIndex.value === -1) {
@@ -188,7 +222,6 @@ export default defineComponent({
deleteToot,
focusToot,
heading,
- upper,
account
}
}
diff --git a/src/renderer/components/TimelineSpace/Contents/DirectMessages.vue b/src/renderer/components/TimelineSpace/Contents/DirectMessages.vue
index 84465c8f..ddaf6e18 100644
--- a/src/renderer/components/TimelineSpace/Contents/DirectMessages.vue
+++ b/src/renderer/components/TimelineSpace/Contents/DirectMessages.vue
@@ -137,10 +137,6 @@ export default defineComponent({
store.commit(`${space}/${MUTATION_TYPES.DELETE_TOOT}`, { statusId: id, accountId: account.account.id })
}
}
- const upper = () => {
- scroller.value.scrollToItem(0)
- focusedId.value = null
- }
const focusNext = () => {
if (currentFocusedIndex.value === -1) {
focusedId.value = timeline.value[0].uri + timeline.value[0].id
@@ -168,7 +164,6 @@ export default defineComponent({
deleteToot,
focusToot,
heading,
- upper,
account
}
}
diff --git a/src/renderer/components/TimelineSpace/Contents/Local.vue b/src/renderer/components/TimelineSpace/Contents/Local.vue
index 020a37b1..dbfc6acf 100644
--- a/src/renderer/components/TimelineSpace/Contents/Local.vue
+++ b/src/renderer/components/TimelineSpace/Contents/Local.vue
@@ -11,9 +11,9 @@
:filters="[]"
:account="account.account"
:server="account.server"
- v-on:update="updateToot"
- v-on:delete="deleteToot"
- @selectToot="focusToot(item)"
+ @update="updateToot"
+ @delete="deleteToot"
+ @select-toot="focusToot(item)"
>
@@ -145,10 +145,6 @@ export default defineComponent({
store.commit(`${space}/${MUTATION_TYPES.DELETE_TOOT}`, { statusId: message.id, accountId: account.account.id })
}
}
- const upper = () => {
- scroller.value.scrollToItem(0)
- focusedId.value = null
- }
const focusNext = () => {
if (currentFocusedIndex.value === -1) {
focusedId.value = timeline.value[0].uri + timeline.value[0].id
@@ -175,8 +171,6 @@ export default defineComponent({
updateToot,
deleteToot,
focusToot,
- heading,
- upper,
account
}
}
diff --git a/src/renderer/components/TimelineSpace/Contents/Notifications.vue b/src/renderer/components/TimelineSpace/Contents/Notifications.vue
index 5fd99f25..85feb71a 100644
--- a/src/renderer/components/TimelineSpace/Contents/Notifications.vue
+++ b/src/renderer/components/TimelineSpace/Contents/Notifications.vue
@@ -17,8 +17,8 @@
:filters="filters"
:account="account.account"
:server="account.server"
- v-on:update="updateToot"
- @selectNotification="focusNotification(item)"
+ @update="updateToot"
+ @select-notification="focusNotification(item)"
>
@@ -180,10 +180,7 @@ export default defineComponent({
}, 500)
})
}
- const upper = () => {
- scroller.value.scrollToItem(0)
- focusedId.value = null
- }
+
const focusNext = () => {
if (currentFocusedIndex.value === -1) {
focusedId.value = notifications.value[0].id
@@ -213,9 +210,8 @@ export default defineComponent({
focusNext,
focusPrev,
focusNotification,
- heading,
- upper,
- account
+ account,
+ scroller
}
}
})
diff --git a/src/renderer/components/TimelineSpace/Contents/Public.vue b/src/renderer/components/TimelineSpace/Contents/Public.vue
index f4a9b461..6185bafc 100644
--- a/src/renderer/components/TimelineSpace/Contents/Public.vue
+++ b/src/renderer/components/TimelineSpace/Contents/Public.vue
@@ -208,7 +208,6 @@ export default defineComponent({
updateToot,
deleteToot,
focusToot,
- heading,
account,
backgroundColor
}
diff --git a/src/renderer/components/utils/reloadable.ts b/src/renderer/components/utils/reloadable.ts
deleted file mode 100644
index 54f122c8..00000000
--- a/src/renderer/components/utils/reloadable.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { Store } from 'vuex'
-import { RootState } from '@/store'
-import { RouteLocationNormalizedLoaded } from 'vue-router'
-import { i18n } from 'i18next'
-import { ElMessage } from 'element-plus'
-import { ACTION_TYPES } from '@/store/TimelineSpace'
-
-export default function useReloadable(store: Store, route: RouteLocationNormalizedLoaded, i18next: i18n) {
- async function reloadable() {
- const account = await store.dispatch(`TimelineSpace/${ACTION_TYPES.LOCAL_ACCOUNT}`, route.params.id).catch(err => {
- ElMessage({
- message: i18next.t('message.account_load_error'),
- type: 'error'
- })
- throw err
- })
- return account
- }
-
- return {
- reloadable
- }
-}
diff --git a/src/renderer/store/TimelineSpace/Contents.ts b/src/renderer/store/TimelineSpace/Contents.ts
index b6a1d649..45ecdf11 100644
--- a/src/renderer/store/TimelineSpace/Contents.ts
+++ b/src/renderer/store/TimelineSpace/Contents.ts
@@ -1,6 +1,5 @@
import Home, { HomeState } from './Contents/Home'
import Notifications, { NotificationsState } from './Contents/Notifications'
-import Bookmarks, { BookmarksState } from './Contents/Bookmarks'
import Local, { LocalState } from './Contents/Local'
import Search, { SearchModuleState } from './Contents/Search'
import Lists, { ListsModuleState } from './Contents/Lists'
@@ -17,7 +16,6 @@ type ContentsModule = {
Home: HomeState
Notifications: NotificationsState
DirectMessages: DirectMessagesState
- Bookmarks: BookmarksState
Local: LocalState
Search: SearchModuleState
Hashtag: HashtagModuleState
@@ -56,7 +54,6 @@ const Contents: Module = {
modules: {
Home,
Notifications,
- Bookmarks,
Local,
DirectMessages,
Search,
diff --git a/src/renderer/store/TimelineSpace/Contents/Bookmarks.ts b/src/renderer/store/TimelineSpace/Contents/Bookmarks.ts
deleted file mode 100644
index a5a00c6c..00000000
--- a/src/renderer/store/TimelineSpace/Contents/Bookmarks.ts
+++ /dev/null
@@ -1,123 +0,0 @@
-import generator, { Entity } from 'megalodon'
-import parse from 'parse-link-header'
-import { Module, MutationTree, ActionTree } from 'vuex'
-import { RootState } from '@/store'
-import { LocalAccount } from '~src/types/localAccount'
-import { LocalServer } from '~src/types/localServer'
-
-export type BookmarksState = {
- bookmarks: Array
- maxId: string | null
-}
-
-const state = (): BookmarksState => ({
- bookmarks: [],
- maxId: null
-})
-
-export const MUTATION_TYPES = {
- UPDATE_BOOKMARKS: 'updateBookmarks',
- INSERT_BOOKMARKS: 'insertBookmarks',
- UPDATE_TOOT: 'updateToot',
- DELETE_TOOT: 'deleteToot',
- CHANGE_MAX_ID: 'changeMaxId'
-}
-
-const mutations: MutationTree = {
- [MUTATION_TYPES.UPDATE_BOOKMARKS]: (state, bookmarks: Array) => {
- state.bookmarks = bookmarks
- },
- [MUTATION_TYPES.INSERT_BOOKMARKS]: (state, bookmarks: Array) => {
- state.bookmarks = state.bookmarks.concat(bookmarks)
- },
- [MUTATION_TYPES.UPDATE_TOOT]: (state, message: Entity.Status) => {
- state.bookmarks = state.bookmarks.map(toot => {
- if (toot.id === message.id) {
- return message
- } else if (toot.reblog !== null && toot.reblog.id === message.id) {
- // When user reblog/favourite a reblogged toot, target message is a original toot.
- // So, a message which is received now is original toot.
- const reblog = {
- reblog: message
- }
- return Object.assign(toot, reblog)
- } else {
- return toot
- }
- })
- },
- [MUTATION_TYPES.DELETE_TOOT]: (state, message: Entity.Status) => {
- state.bookmarks = state.bookmarks.filter(toot => {
- if (toot.reblog !== null && toot.reblog.id === message.id) {
- return false
- } else {
- return toot.id !== message.id
- }
- })
- },
- [MUTATION_TYPES.CHANGE_MAX_ID]: (state, id: string | null) => {
- state.maxId = id
- }
-}
-
-export const ACTION_TYPES = {
- FETCH_BOOKMARKS: 'fetchBookmarks',
- LAZY_FETCH_BOOKMARKS: 'lazyFetchBookmarks'
-}
-
-const actions: ActionTree = {
- [ACTION_TYPES.FETCH_BOOKMARKS]: async (
- { commit, rootState },
- req: { account: LocalAccount; server: LocalServer }
- ): Promise> => {
- const client = generator(req.server.sns, req.server.baseURL, req.account.accessToken, rootState.App.userAgent)
- const res = await client.getBookmarks({ limit: 20 })
- commit(MUTATION_TYPES.UPDATE_BOOKMARKS, res.data)
- // Parse link header
- try {
- const link = parse(res.headers.link)
- if (link !== null && link.next) {
- commit(MUTATION_TYPES.CHANGE_MAX_ID, link.next.max_id)
- } else {
- commit(MUTATION_TYPES.CHANGE_MAX_ID, null)
- }
- } catch (err) {
- commit(MUTATION_TYPES.CHANGE_MAX_ID, null)
- console.error(err)
- }
- return res.data
- },
- [ACTION_TYPES.LAZY_FETCH_BOOKMARKS]: async (
- { state, commit, rootState },
- req: { account: LocalAccount; server: LocalServer }
- ): Promise | null> => {
- if (!state.maxId) {
- return Promise.resolve(null)
- }
- const client = generator(req.server.sns, req.server.baseURL, req.account.accessToken, rootState.App.userAgent)
- const res = await client.getFavourites({ max_id: state.maxId, limit: 20 })
- commit(MUTATION_TYPES.INSERT_BOOKMARKS, res.data)
- // Parse link header
- try {
- const link = parse(res.headers.link)
- if (link !== null && link.next) {
- commit(MUTATION_TYPES.CHANGE_MAX_ID, link.next.max_id)
- } else {
- commit(MUTATION_TYPES.CHANGE_MAX_ID, null)
- }
- } catch (err) {
- commit(MUTATION_TYPES.CHANGE_MAX_ID, null)
- console.error(err)
- }
- return res.data
- }
-}
-
-const Bookmark: Module = {
- namespaced: true,
- state: state,
- mutations: mutations,
- actions: actions
-}
-
-export default Bookmark