From dc6f3664cb3d7a94eac817a6017e5fb67660f889 Mon Sep 17 00:00:00 2001
From: AkiraFukushima
Date: Tue, 27 Oct 2020 13:37:39 +0900
Subject: [PATCH] refs #1804 Add media column under account timeline
---
package.json | 2 +-
.../SideBar/AccountProfile/Timeline.vue | 6 +-
.../SideBar/AccountProfile/Timeline/Media.vue | 146 ++++++++++++++++++
.../Contents/SideBar/AccountProfile.ts | 1 +
.../SideBar/AccountProfile/Timeline.ts | 5 +-
.../SideBar/AccountProfile/Timeline/Media.ts | 112 ++++++++++++++
yarn.lock | 17 +-
7 files changed, 280 insertions(+), 9 deletions(-)
create mode 100644 src/renderer/components/TimelineSpace/Contents/SideBar/AccountProfile/Timeline/Media.vue
create mode 100644 src/renderer/store/TimelineSpace/Contents/SideBar/AccountProfile/Timeline/Media.ts
diff --git a/package.json b/package.json
index ece5f022..6459d908 100644
--- a/package.json
+++ b/package.json
@@ -181,7 +181,7 @@
"emojilib": "^2.4.0",
"i18next": "^19.6.3",
"lodash": "^4.17.20",
- "megalodon": "3.3.1",
+ "megalodon": "3.3.2",
"moment": "^2.28.0",
"mousetrap": "^1.6.5",
"nedb": "^1.8.0",
diff --git a/src/renderer/components/TimelineSpace/Contents/SideBar/AccountProfile/Timeline.vue b/src/renderer/components/TimelineSpace/Contents/SideBar/AccountProfile/Timeline.vue
index d24a2a31..71772661 100644
--- a/src/renderer/components/TimelineSpace/Contents/SideBar/AccountProfile/Timeline.vue
+++ b/src/renderer/components/TimelineSpace/Contents/SideBar/AccountProfile/Timeline.vue
@@ -3,7 +3,7 @@
- Media
+
@@ -11,13 +11,15 @@
+
+
diff --git a/src/renderer/store/TimelineSpace/Contents/SideBar/AccountProfile.ts b/src/renderer/store/TimelineSpace/Contents/SideBar/AccountProfile.ts
index d240730b..ed9c9037 100644
--- a/src/renderer/store/TimelineSpace/Contents/SideBar/AccountProfile.ts
+++ b/src/renderer/store/TimelineSpace/Contents/SideBar/AccountProfile.ts
@@ -129,6 +129,7 @@ const actions: ActionTree = {
dispatch('fetchRelationship', state.account),
dispatch('TimelineSpace/Contents/SideBar/AccountProfile/Timeline/Posts/fetchTimeline', state.account, { root: true }),
dispatch('TimelineSpace/Contents/SideBar/AccountProfile/Timeline/PostsAndReplies/fetchTimeline', state.account, { root: true }),
+ dispatch('TimelineSpace/Contents/SideBar/AccountProfile/Timeline/Media/fetchTimeline', state.account, { root: true }),
dispatch('TimelineSpace/Contents/SideBar/AccountProfile/Followers/fetchFollowers', state.account, { root: true }),
dispatch('TimelineSpace/Contents/SideBar/AccountProfile/Follows/fetchFollows', state.account, { root: true })
]).finally(() => {
diff --git a/src/renderer/store/TimelineSpace/Contents/SideBar/AccountProfile/Timeline.ts b/src/renderer/store/TimelineSpace/Contents/SideBar/AccountProfile/Timeline.ts
index 052c987d..f0407f05 100644
--- a/src/renderer/store/TimelineSpace/Contents/SideBar/AccountProfile/Timeline.ts
+++ b/src/renderer/store/TimelineSpace/Contents/SideBar/AccountProfile/Timeline.ts
@@ -3,12 +3,14 @@ import { RootState } from '@/store'
import Posts, { PostsState } from './Timeline/Posts'
import PostsAndReplies, { PostsAndRepliesState } from './Timeline/PostsAndReplies'
+import Media, { MediaState } from './Timeline/Media'
export type TimelineState = {}
type TimelineModule = {
Posts: PostsState
PostsAndReplies: PostsAndRepliesState
+ Media: MediaState
}
export type TimelineModuleState = TimelineModule & TimelineState
@@ -19,7 +21,8 @@ const Timeline: Module = {
namespaced: true,
modules: {
Posts,
- PostsAndReplies
+ PostsAndReplies,
+ Media
},
state: state
}
diff --git a/src/renderer/store/TimelineSpace/Contents/SideBar/AccountProfile/Timeline/Media.ts b/src/renderer/store/TimelineSpace/Contents/SideBar/AccountProfile/Timeline/Media.ts
new file mode 100644
index 00000000..a69b9332
--- /dev/null
+++ b/src/renderer/store/TimelineSpace/Contents/SideBar/AccountProfile/Timeline/Media.ts
@@ -0,0 +1,112 @@
+import { RootState } from '@/store'
+import generator, { Entity } from 'megalodon'
+import { Module, MutationTree, ActionTree } from 'vuex'
+import { LoadPositionWithAccount } from '@/types/loadPosition'
+
+export type MediaState = {
+ timeline: Array
+ lazyLoading: boolean
+}
+
+const state = (): MediaState => ({
+ timeline: [],
+ lazyLoading: false
+})
+
+export const MUTATION_TYPES = {
+ UPDATE_TIMELINE: 'updateTimeline',
+ INSERT_TIMELINE: 'insertTimeline',
+ CHANGE_LAZY_LOADING: 'changeLazyLoading',
+ UPDATE_TOOT: 'updateToot',
+ DELETE_TOOT: 'deleteToot'
+}
+
+const mutations: MutationTree = {
+ [MUTATION_TYPES.UPDATE_TIMELINE]: (state, timeline: Array) => {
+ state.timeline = timeline
+ },
+ [MUTATION_TYPES.INSERT_TIMELINE]: (state, message: Array) => {
+ state.timeline = state.timeline.concat(message)
+ },
+ [MUTATION_TYPES.CHANGE_LAZY_LOADING]: (state, value: boolean) => {
+ state.lazyLoading = value
+ },
+ [MUTATION_TYPES.UPDATE_TOOT]: (state, message: Entity.Status) => {
+ // Replace target message in timeline
+ state.timeline = state.timeline.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.timeline = state.timeline.filter(toot => {
+ if (toot.reblog !== null && toot.reblog.id === message.id) {
+ return false
+ } else {
+ return toot.id !== message.id
+ }
+ })
+ }
+}
+
+const actions: ActionTree = {
+ fetchTimeline: async ({ commit, rootState }, account: Account) => {
+ commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', true, { root: true })
+ const client = generator(
+ rootState.TimelineSpace.sns,
+ rootState.TimelineSpace.account.baseURL,
+ rootState.TimelineSpace.account.accessToken,
+ rootState.App.userAgent
+ )
+ const res = await client.getAccountStatuses(account.id, { limit: 40, pinned: false, only_media: true })
+ commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', false, { root: true })
+ commit(MUTATION_TYPES.UPDATE_TIMELINE, res.data)
+ return res.data
+ },
+ lazyFetchTimeline: async ({ state, commit, rootState }, loadPosition: LoadPositionWithAccount): Promise => {
+ if (state.lazyLoading) {
+ return Promise.resolve(null)
+ }
+ commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true)
+ const client = generator(
+ rootState.TimelineSpace.sns,
+ rootState.TimelineSpace.account.baseURL,
+ rootState.TimelineSpace.account.accessToken,
+ rootState.App.userAgent
+ )
+ try {
+ const res = await client.getAccountStatuses(loadPosition.account.id, {
+ max_id: loadPosition.status.id,
+ limit: 40,
+ pinned: false,
+ only_media: true
+ })
+ commit(MUTATION_TYPES.INSERT_TIMELINE, res.data)
+ } finally {
+ commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, false)
+ }
+ return null
+ },
+ clearTimeline: ({ commit }) => {
+ commit(MUTATION_TYPES.UPDATE_TIMELINE, [])
+ }
+}
+
+const Media: Module = {
+ namespaced: true,
+ state: state,
+ mutations: mutations,
+ actions: actions
+}
+
+export default Media
diff --git a/yarn.lock b/yarn.lock
index e2fb44df..712e9df6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2297,6 +2297,13 @@ axios@^0.20.0:
dependencies:
follow-redirects "^1.10.0"
+axios@^0.21.0:
+ version "0.21.0"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.0.tgz#26df088803a2350dff2c27f96fef99fe49442aca"
+ integrity sha512-fmkJBknJKoZwem3/IKSSLpkdNXZeBu5Q7GA/aRsr2btgrptmSCxi2oFjZHqGdK9DoTil9PIHlPIZw2EcRJXRvw==
+ dependencies:
+ follow-redirects "^1.10.0"
+
babel-code-frame@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
@@ -8530,14 +8537,14 @@ media-typer@0.3.0:
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
-megalodon@3.3.1:
- version "3.3.1"
- resolved "https://registry.yarnpkg.com/megalodon/-/megalodon-3.3.1.tgz#0e62c006049790269b0d6ab6ea8f6ca919b4a447"
- integrity sha512-vdCW6xCc0yp47eZ8SLrTzQKACoIzd3LnYEk62NSyHUzTzpMP6N5s0BuTfBAWnSn8m6Zx1q6865rNp/tBrKTpww==
+megalodon@3.3.2:
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/megalodon/-/megalodon-3.3.2.tgz#20737f47589feb8209f8129a921c3308be10d7b0"
+ integrity sha512-lmqkwEL4Yrb459gL2SUM7mFpdzZDxmXMG8xb7RWNeo93OuVY+jukqI8mZI/g4v4WoVHYfSaVlB7Tqm0DwuqXIw==
dependencies:
"@types/oauth" "^0.9.0"
"@types/ws" "^7.2.0"
- axios "^0.20.0"
+ axios "^0.21.0"
https-proxy-agent "^5.0.0"
moment "^2.24.0"
oauth "^0.9.15"