From 66db37395ec8b6c842e22907e7bfd8567b1a2055 Mon Sep 17 00:00:00 2001 From: AkiraFukushima Date: Thu, 30 May 2019 22:01:45 +0900 Subject: [PATCH] refs #630 Handle delete event for tag streaming --- .../Contents/Hashtag/Tag.spec.ts | 154 ++++++++++++++++++ .../TimelineSpace/Contents/Hashtag/Tag.vue | 2 +- .../TimelineSpace/Contents/Hashtag/Tag.ts | 44 ++--- 3 files changed, 177 insertions(+), 23 deletions(-) create mode 100644 spec/renderer/unit/store/TimelineSpace/Contents/Hashtag/Tag.spec.ts diff --git a/spec/renderer/unit/store/TimelineSpace/Contents/Hashtag/Tag.spec.ts b/spec/renderer/unit/store/TimelineSpace/Contents/Hashtag/Tag.spec.ts new file mode 100644 index 00000000..6d65e3b9 --- /dev/null +++ b/spec/renderer/unit/store/TimelineSpace/Contents/Hashtag/Tag.spec.ts @@ -0,0 +1,154 @@ +import { Account, Status, Application } from 'megalodon' +import Tag, { TagState, MUTATION_TYPES } from '@/store/TimelineSpace/Contents/Hashtag/Tag' + +const account: 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 status1: Status = { + id: '1', + uri: 'http://example.com', + url: 'http://example.com', + account: account, + in_reply_to_id: null, + in_reply_to_account_id: null, + reblog: null, + 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, + application: { + name: 'Web' + } as Application, + language: null, + pinned: null +} +const status2: Status = { + id: '2', + uri: 'http://example.com', + url: 'http://example.com', + account: account, + in_reply_to_id: null, + in_reply_to_account_id: null, + reblog: null, + content: 'fuga', + 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, + application: { + name: 'Web' + } as Application, + language: null, + pinned: null +} + +describe('TimelineSpace/Contents/Hashtag/Tag', () => { + describe('mutations', () => { + let state: TagState + + describe('deleteToot', () => { + describe('message is not reblogged', () => { + beforeEach(() => { + state = { + lazyLoading: false, + heading: true, + timeline: [status2, status1], + unreadTimeline: [], + filter: '' + } + }) + it('should be deleted', () => { + Tag.mutations![MUTATION_TYPES.DELETE_TOOT](state, status1.id) + expect(state.timeline).toEqual([status2]) + }) + }) + + describe('message is reblogged', () => { + beforeEach(() => { + const rebloggedStatus: Status = { + id: '3', + uri: 'http://example.com', + url: 'http://example.com', + account: account, + in_reply_to_id: null, + in_reply_to_account_id: null, + reblog: status1, + content: '', + created_at: '2019-03-31T21: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, + application: { + name: 'Web' + } as Application, + language: null, + pinned: null + } + state = { + lazyLoading: false, + heading: true, + timeline: [status2, rebloggedStatus], + unreadTimeline: [], + filter: '' + } + }) + it('should be deleted', () => { + Tag.mutations![MUTATION_TYPES.DELETE_TOOT](state, status1.id) + expect(state.timeline).toEqual([status2]) + }) + }) + }) + }) +}) diff --git a/src/renderer/components/TimelineSpace/Contents/Hashtag/Tag.vue b/src/renderer/components/TimelineSpace/Contents/Hashtag/Tag.vue index fb350205..7b68e571 100644 --- a/src/renderer/components/TimelineSpace/Contents/Hashtag/Tag.vue +++ b/src/renderer/components/TimelineSpace/Contents/Hashtag/Tag.vue @@ -142,7 +142,7 @@ export default { this.$store.commit('TimelineSpace/Contents/Hashtag/Tag/updateToot', toot) }, deleteToot(toot) { - this.$store.commit('TimelineSpace/Contents/Hashtag/Tag/deleteToot', toot) + this.$store.commit('TimelineSpace/Contents/Hashtag/Tag/deleteToot', toot.id) }, onScroll(event) { if ( diff --git a/src/renderer/store/TimelineSpace/Contents/Hashtag/Tag.ts b/src/renderer/store/TimelineSpace/Contents/Hashtag/Tag.ts index 46d99c4f..c7d46df3 100644 --- a/src/renderer/store/TimelineSpace/Contents/Hashtag/Tag.ts +++ b/src/renderer/store/TimelineSpace/Contents/Hashtag/Tag.ts @@ -5,10 +5,10 @@ import { RootState } from '@/store' import { LoadPositionWithTag } from '@/types/loadPosition' export interface TagState { - timeline: Array, - unreadTimeline: Array, - lazyLoading: boolean, - heading: boolean, + timeline: Array + unreadTimeline: Array + lazyLoading: boolean + heading: boolean filter: string } @@ -48,22 +48,22 @@ const mutations: MutationTree = { [MUTATION_TYPES.UPDATE_TIMELINE]: (state, timeline: Array) => { state.timeline = timeline }, - [MUTATION_TYPES.MERGE_TIMELINE]: (state) => { + [MUTATION_TYPES.MERGE_TIMELINE]: state => { state.timeline = state.unreadTimeline.slice(0, 80).concat(state.timeline) state.unreadTimeline = [] }, [MUTATION_TYPES.INSERT_TIMELINE]: (state, messages: Array) => { state.timeline = state.timeline.concat(messages) }, - [MUTATION_TYPES.ARCHIVE_TIMELINE]: (state) => { + [MUTATION_TYPES.ARCHIVE_TIMELINE]: state => { state.timeline = state.timeline.slice(0, 40) }, - [MUTATION_TYPES.CLEAR_TIMELINE]: (state) => { + [MUTATION_TYPES.CLEAR_TIMELINE]: state => { state.timeline = [] state.unreadTimeline = [] }, [MUTATION_TYPES.UPDATE_TOOT]: (state, message: Status) => { - state.timeline = state.timeline.map((toot) => { + state.timeline = state.timeline.map(toot => { if (toot.id === message.id) { return message } else if (toot.reblog !== null && toot.reblog.id === message.id) { @@ -78,12 +78,12 @@ const mutations: MutationTree = { } }) }, - [MUTATION_TYPES.DELETE_TOOT]: (state, message: Status) => { - state.timeline = state.timeline.filter((toot) => { - if (toot.reblog !== null && toot.reblog.id === message.id) { + [MUTATION_TYPES.DELETE_TOOT]: (state, id: string) => { + state.timeline = state.timeline.filter(toot => { + if (toot.reblog !== null && toot.reblog.id === id) { return false } else { - return toot.id !== message.id + return toot.id !== id } }) }, @@ -97,10 +97,7 @@ const mutations: MutationTree = { const actions: ActionTree = { fetch: async ({ commit, rootState }, tag: string): Promise> => { - const client = new Mastodon( - rootState.TimelineSpace.account.accessToken!, - rootState.TimelineSpace.account.baseURL + '/api/v1' - ) + const client = new Mastodon(rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.account.baseURL + '/api/v1') const res: Response> = await client.get>(`/timelines/tag/${encodeURIComponent(tag)}`, { limit: 40 }) commit(MUTATION_TYPES.UPDATE_TIMELINE, res.data) return res.data @@ -112,8 +109,12 @@ const actions: ActionTree = { commit(MUTATION_TYPES.ARCHIVE_TIMELINE) } }) + ipcRenderer.on('delete-start-tag-streaming', (_, id: string) => { + commit(MUTATION_TYPES.DELETE_TOOT, id) + }) // @ts-ignore - return new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars + return new Promise((resolve, reject) => { + // eslint-disable-line no-unused-vars ipcRenderer.send('start-tag-streaming', { tag: encodeURIComponent(tag), account: rootState.TimelineSpace.account, @@ -128,6 +129,7 @@ const actions: ActionTree = { return new Promise(resolve => { ipcRenderer.removeAllListeners('error-start-tag-streaming') ipcRenderer.removeAllListeners('update-start-tag-streaming') + ipcRenderer.removeAllListeners('delete-start-tag-streaming') ipcRenderer.send('stop-tag-streaming') resolve() }) @@ -137,11 +139,9 @@ const actions: ActionTree = { return Promise.resolve(null) } commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true) - const client = new Mastodon( - rootState.TimelineSpace.account.accessToken!, - rootState.TimelineSpace.account.baseURL + '/api/v1' - ) - return client.get>(`/timelines/tag/${loadPosition.tag}`, { max_id: loadPosition.status.id, limit: 40 }) + const client = new Mastodon(rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.account.baseURL + '/api/v1') + return client + .get>(`/timelines/tag/${loadPosition.tag}`, { max_id: loadPosition.status.id, limit: 40 }) .then(res => { commit(MUTATION_TYPES.INSERT_TIMELINE, res.data) return res.data