From b6d3aeaf843fd657c5e9931158effa17d1b7a0fa Mon Sep 17 00:00:00 2001
From: AkiraFukushima
Date: Fri, 15 Mar 2019 01:02:10 +0900
Subject: [PATCH 1/8] refs #843 Add Mention timeline
---
src/config/locales/en/translation.json | 2 +
src/main/index.js | 5 +
.../TimelineSpace/Contents/Mentions.vue | 198 ++++++++++++++++++
.../TimelineSpace/Contents/Notifications.vue | 4 +
.../components/TimelineSpace/HeaderMenu.vue | 12 ++
.../components/TimelineSpace/SideMenu.vue | 13 +-
.../components/molecules/Notification.vue | 12 +-
.../molecules/Notification/Mention.vue | 6 +-
src/renderer/router/index.js | 5 +
src/renderer/store/TimelineSpace.js | 9 +
src/renderer/store/TimelineSpace/Contents.js | 2 +
.../store/TimelineSpace/Contents/Mentions.js | 96 +++++++++
src/renderer/store/TimelineSpace/SideMenu.js | 5 +
13 files changed, 364 insertions(+), 5 deletions(-)
create mode 100644 src/renderer/components/TimelineSpace/Contents/Mentions.vue
create mode 100644 src/renderer/store/TimelineSpace/Contents/Mentions.js
diff --git a/src/config/locales/en/translation.json b/src/config/locales/en/translation.json
index 2e63297b..ebcf2f16 100644
--- a/src/config/locales/en/translation.json
+++ b/src/config/locales/en/translation.json
@@ -47,6 +47,7 @@
"expand": "Expand",
"home": "Home",
"notification": "Notification",
+ "mention": "Mention",
"direct": "Direct messages",
"favourite": "Favourite",
"local": "Local timeline",
@@ -58,6 +59,7 @@
"header_menu": {
"home": "Home",
"notification": "Notification",
+ "mention": "Mention",
"favourite": "Favourite",
"local": "Local timeline",
"public": "Public timeline",
diff --git a/src/main/index.js b/src/main/index.js
index f47942cd..9204255d 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -413,6 +413,11 @@ ipcMain.on('start-user-streaming', (event, obj) => {
},
(notification) => {
event.sender.send('notification-start-user-streaming', notification)
+ // Does not exist a endpoint for only mention. And mention is a part of notification.
+ // So we have to get mention from notification.
+ if (notification.type === 'mention') {
+ event.sender.send('mention-start-user-streaming', notification)
+ }
if (process.platform === 'darwin') {
app.dock.setBadge('•')
}
diff --git a/src/renderer/components/TimelineSpace/Contents/Mentions.vue b/src/renderer/components/TimelineSpace/Contents/Mentions.vue
new file mode 100644
index 00000000..8eb8b3b9
--- /dev/null
+++ b/src/renderer/components/TimelineSpace/Contents/Mentions.vue
@@ -0,0 +1,198 @@
+
+
+
{{ unread.length > 0 ? unread.length : '' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/renderer/components/TimelineSpace/Contents/Notifications.vue b/src/renderer/components/TimelineSpace/Contents/Notifications.vue
index ee38a023..9a84553c 100644
--- a/src/renderer/components/TimelineSpace/Contents/Notifications.vue
+++ b/src/renderer/components/TimelineSpace/Contents/Notifications.vue
@@ -10,6 +10,7 @@
:filter="filter"
:focused="message.id === focusedId"
:overlaid="modalOpened"
+ v-on:update="updateToot"
@focusNext="focusNext"
@focusPrev="focusPrev"
@focusRight="focusSidebar"
@@ -148,6 +149,9 @@ export default {
this.$store.commit('TimelineSpace/changeLoading', false)
}
},
+ updateToot (message) {
+ this.$store.commit('TimelineSpace/Contents/Notifications/updateToot', message)
+ },
upper () {
scrollTop(
document.getElementById('scrollable'),
diff --git a/src/renderer/components/TimelineSpace/HeaderMenu.vue b/src/renderer/components/TimelineSpace/HeaderMenu.vue
index 8efce734..fbfebd0d 100644
--- a/src/renderer/components/TimelineSpace/HeaderMenu.vue
+++ b/src/renderer/components/TimelineSpace/HeaderMenu.vue
@@ -103,6 +103,9 @@ export default {
case 'favourites':
this.$store.commit('TimelineSpace/HeaderMenu/updateTitle', this.$t('header_menu.favourite'))
break
+ case 'mentions':
+ this.$store.commit('TimelineSpace/HeaderMenu/updateTitle', this.$t('header_menu.mention'))
+ break
case 'local':
this.$store.commit('TimelineSpace/HeaderMenu/updateTitle', this.$t('header_menu.local'))
break
@@ -148,6 +151,7 @@ export default {
switch (this.$route.name) {
case 'home':
case 'notifications':
+ case 'mentions':
case 'favourites':
case 'local':
case 'public':
@@ -164,6 +168,7 @@ export default {
switch (this.$route.name) {
case 'home':
case 'notifications':
+ case 'mentiont':
case 'favourites':
case 'local':
case 'public':
@@ -185,6 +190,9 @@ export default {
case 'notifications':
this.filter = this.$store.state.TimelineSpace.Contents.Notifications.filter
break
+ case 'mentions':
+ this.filter = this.$store.state.TimelineSpace.Contents.Mentions.filter
+ break
case 'favourites':
this.filter = this.$store.state.TimelineSpace.Contents.Favourites.filter
break
@@ -217,6 +225,9 @@ export default {
case 'notifications':
this.$store.commit('TimelineSpace/Contents/Notifications/changeFilter', filter)
break
+ case 'mentions':
+ this.$store.commit('TimelineSpace/Contents/Mentions/changeFilter', filter)
+ break
case 'favourites':
this.$store.commit('TimelineSpace/Contents/Favourites/changeFilter', filter)
break
@@ -244,6 +255,7 @@ export default {
switch (this.$route.name) {
case 'home':
case 'notifications':
+ case 'mentions':
case 'favourites':
case 'local':
case 'public':
diff --git a/src/renderer/components/TimelineSpace/SideMenu.vue b/src/renderer/components/TimelineSpace/SideMenu.vue
index 419faa8b..8a85cae6 100644
--- a/src/renderer/components/TimelineSpace/SideMenu.vue
+++ b/src/renderer/components/TimelineSpace/SideMenu.vue
@@ -52,9 +52,11 @@
-
-
- {{ $t("side_menu.favourite") }}
+
+
+ {{ $t("side_menu.mention") }}
+
+
@@ -62,6 +64,10 @@
+
+
+ {{ $t("side_menu.favourite") }}
+
{{ $t("side_menu.local") }}
@@ -118,6 +124,7 @@ export default {
...mapState('TimelineSpace/SideMenu', {
unreadHomeTimeline: state => state.unreadHomeTimeline,
unreadNotifications: state => state.unreadNotifications,
+ unreadMentions: state => state.unreadMentions,
unreadLocalTimeline: state => state.unreadLocalTimeline,
unreadDirectMessagesTimeline: state => state.unreadDirectMessagesTimeline,
unreadPublicTimeline: state => state.unreadPublicTimeline,
diff --git a/src/renderer/components/molecules/Notification.vue b/src/renderer/components/molecules/Notification.vue
index d13c7932..3855988e 100644
--- a/src/renderer/components/molecules/Notification.vue
+++ b/src/renderer/components/molecules/Notification.vue
@@ -26,6 +26,8 @@
:filter="filter"
:focused="focused"
:overlaid="overlaid"
+ v-on:update="updateToot"
+ v-on:delete="deleteToot"
@focusNext="$emit('focusNext')"
@focusPrev="$emit('focusPrev')"
@focusRight="$emit('focusRight')"
@@ -72,7 +74,15 @@ export default {
default: false
}
},
- components: { Favourite, Follow, Mention, Reblog }
+ components: { Favourite, Follow, Mention, Reblog },
+ methods: {
+ updateToot (message) {
+ return this.$emit('update', message)
+ },
+ deleteToot (message) {
+ return this.$emit('delete', message)
+ }
+ }
}
diff --git a/src/renderer/components/molecules/Notification/Mention.vue b/src/renderer/components/molecules/Notification/Mention.vue
index db0451d3..d0f1ccda 100644
--- a/src/renderer/components/molecules/Notification/Mention.vue
+++ b/src/renderer/components/molecules/Notification/Mention.vue
@@ -6,6 +6,7 @@
:focused="focused"
:overlaid="overlaid"
v-on:update="updateToot"
+ v-on:delete="deleteToot"
@focusNext="$emit('focusNext')"
@focusPrev="$emit('focusPrev')"
@focusRight="$emit('focusRight')"
@@ -41,7 +42,10 @@ export default {
components: { Toot },
methods: {
updateToot (message) {
- this.$store.commit('TimelineSpace/Contents/Notifications/updateToot', message)
+ return this.$emit('update', message)
+ },
+ deleteToot (message) {
+ return this.$emit('delete', message)
}
}
}
diff --git a/src/renderer/router/index.js b/src/renderer/router/index.js
index c0e1e2a6..acb452ee 100644
--- a/src/renderer/router/index.js
+++ b/src/renderer/router/index.js
@@ -82,6 +82,11 @@ export default new Router({
name: 'notifications',
component: require('@/components/TimelineSpace/Contents/Notifications').default
},
+ {
+ path: 'mentions',
+ name: 'mentions',
+ component: require('@/components/TimelineSpace/Contents/Mentions').default
+ },
{
path: 'favourites',
name: 'favourites',
diff --git a/src/renderer/store/TimelineSpace.js b/src/renderer/store/TimelineSpace.js
index 6abf622d..eec98351 100644
--- a/src/renderer/store/TimelineSpace.js
+++ b/src/renderer/store/TimelineSpace.js
@@ -189,6 +189,7 @@ const TimelineSpace = {
async fetchContentsTimelines ({ dispatch, state }, account) {
await dispatch('TimelineSpace/Contents/Home/fetchTimeline', account, { root: true })
await dispatch('TimelineSpace/Contents/Notifications/fetchNotifications', account, { root: true })
+ await dispatch('TimelineSpace/Contents/Mentions/fetchMentions', {}, { root: true })
if (state.unreadNotification.direct) {
await dispatch('TimelineSpace/Contents/DirectMessages/fetchTimeline', {}, { root: true })
}
@@ -205,6 +206,7 @@ const TimelineSpace = {
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 })
},
bindStreamings ({ dispatch, state }, account) {
dispatch('bindUserStreaming', account)
@@ -267,6 +269,13 @@ const TimelineSpace = {
}
commit('TimelineSpace/SideMenu/changeUnreadNotifications', true, { root: true })
})
+ ipcRenderer.on('mention-start-user-streaming', (event, mention) => {
+ commit('TimelineSpace/Contents/Mentions/appendMentions', mention, { root: true })
+ if (rootState.TimelineSpace.Contents.Mentions.heading && Math.random() > 0.8) {
+ commit('TimelineSpace/Contents/Mentions/archiveMentions', null, { root: true })
+ }
+ commit('TimelineSpace/SideMenu/changeUnreadMentions', true, { root: true })
+ })
},
startUserStreaming ({ state }) {
return new Promise((resolve, reject) => {
diff --git a/src/renderer/store/TimelineSpace/Contents.js b/src/renderer/store/TimelineSpace/Contents.js
index d1758451..81b91d7a 100644
--- a/src/renderer/store/TimelineSpace/Contents.js
+++ b/src/renderer/store/TimelineSpace/Contents.js
@@ -8,6 +8,7 @@ import Search from './Contents/Search'
import Lists from './Contents/Lists'
import Hashtag from './Contents/Hashtag'
import DirectMessages from './Contents/DirectMessages'
+import Mentions from './Contents/Mentions'
const Contents = {
namespaced: true,
@@ -18,6 +19,7 @@ const Contents = {
Favourites,
Local,
DirectMessages,
+ Mentions,
Public,
Search,
Lists,
diff --git a/src/renderer/store/TimelineSpace/Contents/Mentions.js b/src/renderer/store/TimelineSpace/Contents/Mentions.js
new file mode 100644
index 00000000..ef3111da
--- /dev/null
+++ b/src/renderer/store/TimelineSpace/Contents/Mentions.js
@@ -0,0 +1,96 @@
+import Mastodon from 'megalodon'
+
+const Mentions = {
+ namespaced: true,
+ state: {
+ lazyLoading: false,
+ heading: true,
+ mentions: [],
+ unreadMentions: [],
+ filter: ''
+ },
+ mutations: {
+ changeLazyLoading (state, value) {
+ state.lazyLoading = value
+ },
+ changeHeading (state, value) {
+ state.heading = value
+ },
+ appendMentions (state, update) {
+ if (state.heading) {
+ state.mentions = [update].concat(state.mentions)
+ } else {
+ state.unreadMentions = [update].concat(state.unreadMentions)
+ }
+ },
+ updateMentions (state, messages) {
+ state.mentions = messages
+ },
+ mergeMentions (state) {
+ state.mentions = state.unreadMentions.slice(0, 80).concat(state.mentions)
+ state.unreadMentions = []
+ },
+ insertMentions (state, messages) {
+ state.mentions = state.mentions.concat(messages)
+ },
+ archiveMentions (state) {
+ state.mentions = state.mentions.slice(0, 40)
+ },
+ clearMentions (state) {
+ state.mentions = []
+ state.unreadMentions = []
+ },
+ updateToot (state, message) {
+ console.log(message)
+ state.mentions = state.mentions.map((mention) => {
+ if (mention.type === 'mention' && mention.status.id === message.id) {
+ const status = {
+ status: message
+ }
+ return Object.assign(mention, status)
+ } else {
+ return mention
+ }
+ })
+ },
+ changeFilter (state, filter) {
+ state.filter = filter
+ }
+ },
+ actions: {
+ fetchMentions ({ state, commit, rootState }) {
+ const client = new Mastodon(
+ rootState.TimelineSpace.account.accessToken,
+ rootState.TimelineSpace.account.baseURL + '/api/v1'
+ )
+ return client.get('/notifications', { limit: 30, exclude_types: ['follow', 'favourite', 'reblog'] })
+ .then(res => {
+ commit('updateMentions', res.data)
+ return res.data
+ })
+ },
+ lazyFetchMentions ({ state, commit, rootState }, last) {
+ if (last === undefined || last === null) {
+ return Promise.resolve(null)
+ }
+ if (state.lazyLoading) {
+ return Promise.resolve(null)
+ }
+ commit('changeLazyLoading', true)
+ const client = new Mastodon(
+ rootState.TimelineSpace.account.accessToken,
+ rootState.TimelineSpace.account.baseURL + '/api/v1'
+ )
+ return client.get('/notifications', { max_id: last.id, limit: 30, exclude_types: ['follow', 'favourite', 'reblog'] })
+ .then(res => {
+ commit('insertMentions', res.data)
+ return res.data
+ })
+ .finally(() => {
+ commit('changeLazyLoading', false)
+ })
+ }
+ }
+}
+
+export default Mentions
diff --git a/src/renderer/store/TimelineSpace/SideMenu.js b/src/renderer/store/TimelineSpace/SideMenu.js
index db72d8cc..1342db52 100644
--- a/src/renderer/store/TimelineSpace/SideMenu.js
+++ b/src/renderer/store/TimelineSpace/SideMenu.js
@@ -6,6 +6,7 @@ const SideMenu = {
state: {
unreadHomeTimeline: false,
unreadNotifications: false,
+ unreadMentions: false,
unreadLocalTimeline: false,
unreadDirectMessagesTimeline: false,
unreadPublicTimeline: false,
@@ -20,6 +21,9 @@ const SideMenu = {
changeUnreadNotifications (state, value) {
state.unreadNotifications = value
},
+ changeUnreadMentions (state, value) {
+ state.unreadMentions = value
+ },
changeUnreadLocalTimeline (state, value) {
state.unreadLocalTimeline = value
},
@@ -55,6 +59,7 @@ const SideMenu = {
clearUnread ({ commit }) {
commit('changeUnreadHomeTimeline', false)
commit('changeUnreadNotifications', false)
+ commit('changeUnreadMentions', false)
commit('changeUnreadLocalTimeline', false)
commit('changeUnreadDirectMessagesTimeline', false)
commit('changeUnreadPublicTimeline', false)
From f4ea67ff0a6e0f2d763c3012c879095ecf9df20e Mon Sep 17 00:00:00 2001
From: AkiraFukushima
Date: Fri, 15 Mar 2019 01:04:37 +0900
Subject: [PATCH 2/8] refs #843 Fix reloadable for mentions
---
src/renderer/components/TimelineSpace/HeaderMenu.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/renderer/components/TimelineSpace/HeaderMenu.vue b/src/renderer/components/TimelineSpace/HeaderMenu.vue
index fbfebd0d..49c63ca6 100644
--- a/src/renderer/components/TimelineSpace/HeaderMenu.vue
+++ b/src/renderer/components/TimelineSpace/HeaderMenu.vue
@@ -168,7 +168,7 @@ export default {
switch (this.$route.name) {
case 'home':
case 'notifications':
- case 'mentiont':
+ case 'mentions':
case 'favourites':
case 'local':
case 'public':
From 0520b3406a10142a374cb832046cf35e42d8609a Mon Sep 17 00:00:00 2001
From: AkiraFukushima
Date: Fri, 15 Mar 2019 01:12:37 +0900
Subject: [PATCH 3/8] refs #843 fix: Filter mentions to get only mentions for
pleroma
---
src/renderer/components/TimelineSpace/Contents/Mentions.vue | 4 +++-
src/renderer/store/TimelineSpace/Contents/Mentions.js | 5 +++++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/renderer/components/TimelineSpace/Contents/Mentions.vue b/src/renderer/components/TimelineSpace/Contents/Mentions.vue
index 8eb8b3b9..d7fd7bda 100644
--- a/src/renderer/components/TimelineSpace/Contents/Mentions.vue
+++ b/src/renderer/components/TimelineSpace/Contents/Mentions.vue
@@ -55,7 +55,6 @@ export default {
openSideBar: state => state.openSideBar
}),
...mapState('TimelineSpace/Contents/Mentions', {
- mentions: state => state.mentions,
lazyLoading: state => state.lazyLoading,
heading: state => state.heading,
unread: state => state.unreadMentions,
@@ -64,6 +63,9 @@ export default {
...mapGetters('TimelineSpace/Modals', [
'modalOpened'
]),
+ ...mapGetters('TimelineSpace/Contents/Mentions', [
+ 'mentions'
+ ]),
shortcutEnabled: function () {
if (this.modalOpened) {
return false
diff --git a/src/renderer/store/TimelineSpace/Contents/Mentions.js b/src/renderer/store/TimelineSpace/Contents/Mentions.js
index ef3111da..9adac1a0 100644
--- a/src/renderer/store/TimelineSpace/Contents/Mentions.js
+++ b/src/renderer/store/TimelineSpace/Contents/Mentions.js
@@ -90,6 +90,11 @@ const Mentions = {
commit('changeLazyLoading', false)
})
}
+ },
+ getters: {
+ mentions (state) {
+ return state.mentions.filter(mention => mention.type === 'mention')
+ }
}
}
From 89ddb4c4d3f723f6f57a68a4eaeb9378c7303b68 Mon Sep 17 00:00:00 2001
From: AkiraFukushima
Date: Fri, 15 Mar 2019 01:13:26 +0900
Subject: [PATCH 4/8] refs #843 Fix scroll design in Mentions
---
.../TimelineSpace/Contents/Mentions.vue | 36 +++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/src/renderer/components/TimelineSpace/Contents/Mentions.vue b/src/renderer/components/TimelineSpace/Contents/Mentions.vue
index d7fd7bda..562f19e5 100644
--- a/src/renderer/components/TimelineSpace/Contents/Mentions.vue
+++ b/src/renderer/components/TimelineSpace/Contents/Mentions.vue
@@ -197,4 +197,40 @@ export default {
+
From dfd705b9d37cc9f4ff00b7eb0482cdde73e04cfb Mon Sep 17 00:00:00 2001
From: AkiraFukushima
Date: Tue, 19 Mar 2019 09:07:13 +0900
Subject: [PATCH 5/8] refs #843 Add integration spec for mentions
---
.../integration/store/TimelineSpace.spec.js | 10 +-
.../store/TimelineSpace/Contents/Home.spec.js | 20 ++-
.../TimelineSpace/Contents/Mentions.spec.js | 152 ++++++++++++++++++
3 files changed, 180 insertions(+), 2 deletions(-)
create mode 100644 spec/renderer/integration/store/TimelineSpace/Contents/Mentions.spec.js
diff --git a/spec/renderer/integration/store/TimelineSpace.spec.js b/spec/renderer/integration/store/TimelineSpace.spec.js
index 1180614d..9f3e0898 100644
--- a/spec/renderer/integration/store/TimelineSpace.spec.js
+++ b/spec/renderer/integration/store/TimelineSpace.spec.js
@@ -63,6 +63,13 @@ const PublicStore = {
}
}
+const MentionStore = {
+ namespaced: true,
+ actions: {
+ fetchMentions: jest.fn()
+ }
+}
+
const contentsStore = {
namespaced: true,
modules: {
@@ -70,7 +77,8 @@ const contentsStore = {
Notifications: notificationStore,
DirectMessages: DMStore,
Local: LocalStore,
- Public: PublicStore
+ Public: PublicStore,
+ Mentions: MentionStore
}
}
diff --git a/spec/renderer/integration/store/TimelineSpace/Contents/Home.spec.js b/spec/renderer/integration/store/TimelineSpace/Contents/Home.spec.js
index adf9c6c7..59daba6f 100644
--- a/spec/renderer/integration/store/TimelineSpace/Contents/Home.spec.js
+++ b/spec/renderer/integration/store/TimelineSpace/Contents/Home.spec.js
@@ -6,7 +6,7 @@ import Home from '~/src/renderer/store/TimelineSpace/Contents/Home'
jest.genMockFromModule('megalodon')
jest.mock('megalodon')
-const state = () => {
+let state = () => {
return {
lazyLoading: false,
heading: true,
@@ -89,6 +89,22 @@ describe('Home', () => {
})
})
describe('success', () => {
+ beforeAll(() => {
+ state = () => {
+ return {
+ lazyLoading: false,
+ heading: true,
+ timeline: [
+ { id: 3 },
+ { id: 4 }
+ ],
+ unreadTimeline: [],
+ filter: '',
+ showReblogs: true,
+ showReplies: true
+ }
+ }
+ })
it('should be updated', async () => {
const mockClient = {
get: () => {
@@ -106,6 +122,8 @@ describe('Home', () => {
await store.dispatch('Home/lazyFetchTimeline', { id: 20 })
expect(store.state.Home.lazyLoading).toEqual(false)
expect(store.state.Home.timeline).toEqual([
+ { id: 3 },
+ { id: 4 },
{ id: 19 },
{ id: 18 }
])
diff --git a/spec/renderer/integration/store/TimelineSpace/Contents/Mentions.spec.js b/spec/renderer/integration/store/TimelineSpace/Contents/Mentions.spec.js
new file mode 100644
index 00000000..905c4e31
--- /dev/null
+++ b/spec/renderer/integration/store/TimelineSpace/Contents/Mentions.spec.js
@@ -0,0 +1,152 @@
+import Mastodon from 'megalodon'
+import { createLocalVue } from '@vue/test-utils'
+import Vuex from 'vuex'
+import Mentions from '~/src/renderer/store/TimelineSpace/Contents/Mentions'
+
+jest.genMockFromModule('megalodon')
+jest.mock('megalodon')
+
+let state = () => {
+ return {
+ lazyLoading: false,
+ heading: true,
+ mentions: [],
+ unreadMentions: [],
+ filter: ''
+ }
+}
+
+const initStore =() => {
+ return {
+ namespaced: true,
+ state: state(),
+ actions: Mentions.actions,
+ mutations: Mentions.mutations
+ }
+}
+const timelineState = {
+ namespaced: true,
+ state: {
+ account: {
+ accessToken: 'token',
+ baseURL: 'http://localhost'
+ }
+ }
+}
+
+describe('Mentions', () => {
+ let store
+ let localVue
+
+ beforeEach(() => {
+ localVue = createLocalVue()
+ localVue.use(Vuex)
+ store = new Vuex.Store({
+ modules: {
+ Mentions: initStore(),
+ TimelineSpace: timelineState
+ }
+ })
+ Mastodon.mockClear()
+ })
+
+ describe('fetchMentions', () => {
+ it('should be updated', async () => {
+ const mockClient = {
+ get: () => {
+ return new Promise((resolve, reject) => {
+ resolve({
+ data: [
+ { id: 1, type: 'mention' },
+ { id: 2, type: 'favourite' },
+ { id: 3, type: 'reblog' },
+ { id: 4, type: 'follow' }
+ ]
+ })
+ })
+ }
+ }
+
+ Mastodon.mockImplementation(() => mockClient)
+ const mentions = await store.dispatch('Mentions/fetchMentions')
+ expect(store.state.Mentions.mentions).toEqual([
+ { id: 1, type: 'mention' },
+ { id: 2, type: 'favourite' },
+ { id: 3, type: 'reblog' },
+ { id: 4, type: 'follow' }
+ ])
+ })
+ })
+
+ describe('lazyFetchMentions', () => {
+ describe('last is null', () => {
+ it('should not be updated', async () => {
+ const result = await store.dispatch('Mentions/lazyFetchMentions', null)
+ expect(result).toEqual(null)
+ })
+ })
+
+ describe('loading', () => {
+ beforeAll(() => {
+ state = () => {
+ return {
+ lazyLoading: true,
+ heading: true,
+ mentions: [],
+ unreadMentions: [],
+ filter: ''
+ }
+ }
+ })
+ it('should not be updated', async () => {
+ const result = await store.dispatch('Mentions/lazyFetchMentions', {})
+ expect(result).toEqual(null)
+ })
+ })
+
+ describe('success', () => {
+ beforeAll(() => {
+ state = () => {
+ return {
+ lazyLoading: false,
+ heading: true,
+ mentions: [
+ { id: 1, type: 'mention' },
+ { id: 2, type: 'favourite' },
+ { id: 3, type: 'reblog' },
+ { id: 4, type: 'follow' }
+ ],
+ unreadMentions: [],
+ filter: ''
+ }
+ }
+ })
+ it('should be updated', async () => {
+ const mockClient = {
+ get: () => {
+ return new Promise((resolve, reject) => {
+ resolve({
+ data: [
+ { id: 5, type: 'mention' },
+ { id: 6, type: 'favourite' }
+ ]
+ })
+ })
+ }
+ }
+
+ Mastodon.mockImplementation(() => mockClient)
+ const mentions = await store.dispatch('Mentions/lazyFetchMentions', { id: 1 })
+ expect(store.state.Mentions.mentions).toEqual([
+ { id: 1, type: 'mention' },
+ { id: 2, type: 'favourite' },
+ { id: 3, type: 'reblog' },
+ { id: 4, type: 'follow' },
+ { id: 5, type: 'mention' },
+ { id: 6, type: 'favourite' }
+ ])
+ expect(store.state.Mentions.lazyLoading).toEqual(false)
+ })
+ })
+ })
+})
From 68114b86f3056d76cb5641584f6faf48684c909d Mon Sep 17 00:00:00 2001
From: AkiraFukushima
Date: Tue, 19 Mar 2019 09:24:07 +0900
Subject: [PATCH 6/8] refs #843 Add unit spec for mentions
---
.../TimelineSpace/Contents/Mentions.spec.js | 114 ++++++++++++++++++
.../store/TimelineSpace/Contents/Mentions.js | 1 -
2 files changed, 114 insertions(+), 1 deletion(-)
create mode 100644 spec/renderer/unit/store/TimelineSpace/Contents/Mentions.spec.js
diff --git a/spec/renderer/unit/store/TimelineSpace/Contents/Mentions.spec.js b/spec/renderer/unit/store/TimelineSpace/Contents/Mentions.spec.js
new file mode 100644
index 00000000..f791c518
--- /dev/null
+++ b/spec/renderer/unit/store/TimelineSpace/Contents/Mentions.spec.js
@@ -0,0 +1,114 @@
+import Mentions from '@/store/TimelineSpace/Contents/Mentions'
+
+describe('TimelineSpace/Contents/Mentions', () => {
+ describe('mutations', () => {
+ let state
+ beforeEach(() => {
+ state = {
+ lazyLoading: false,
+ heading: true,
+ mentions: [],
+ unreadMentions: [],
+ filter: ''
+ }
+ })
+
+ describe('appendMentions', () => {
+ describe('heading', () => {
+ beforeEach(() => {
+ state = {
+ lazyLoading: false,
+ heading: true,
+ mentions: [5, 4, 3, 2, 1],
+ unreadMentions: [],
+ filter: ''
+ }
+ })
+ it('should update mentions', () => {
+ Mentions.mutations.appendMentions(state, 6)
+ expect(state.mentions).toEqual([6, 5, 4, 3, 2, 1])
+ expect(state.unreadMentions).toEqual([])
+ })
+ })
+ describe('not heading', () => {
+ beforeEach(() => {
+ state = {
+ lazyLoading: false,
+ heading: false,
+ mentions: [5, 4, 3, 2, 1],
+ unreadMentions: [],
+ filter: ''
+ }
+ })
+ it('should update mentions', () => {
+ Mentions.mutations.appendMentions(state, 6)
+ expect(state.mentions).toEqual([5, 4, 3, 2, 1])
+ expect(state.unreadMentions).toEqual([6])
+ })
+ })
+ })
+
+ describe('mergeMentions', () => {
+ beforeEach(() => {
+ state = {
+ lazyLoading: false,
+ heading: false,
+ mentions: [5, 4, 3, 2, 1],
+ unreadMentions: [8, 7, 6],
+ filter: ''
+ }
+ })
+ it('should be merged', () => {
+ Mentions.mutations.mergeMentions(state)
+ expect(state.mentions).toEqual([8, 7, 6, 5, 4, 3, 2, 1])
+ expect(state.unreadMentions).toEqual([])
+ })
+ })
+
+ describe('insertMentions', () => {
+ beforeEach(() => {
+ state = {
+ lazyLoading: false,
+ heading: false,
+ mentions: [5, 4, 3, 2, 1],
+ unreadMentions: [],
+ filter: ''
+ }
+ })
+ it('should be inserted', () => {
+ Mentions.mutations.insertMentions(state, [ -1, -2, -3, -4])
+ expect(state.mentions).toEqual([5, 4, 3, 2, 1, -1, -2, -3, -4])
+ })
+ })
+
+ describe('updateToot', () => {
+ beforeEach(() => {
+ state = {
+ lazyLoading: false,
+ heading: false,
+ mentions: [
+ { type: 'mention', status: { id: 20, favourited: false } },
+ { type: 'favourite', status: { id: 19, favourited: false } },
+ { type: 'reblog', status: { id: 18, favourited: false } },
+ { type: 'follow', status: { id: 17, favourited: false } },
+ { type: 'mention', status: { id: 16, favourited: false } }
+ ],
+ unreadMentions: [],
+ filter: ''
+ }
+ })
+ it('should be updated', () => {
+ Mentions.mutations.updateToot(state, { id: 20, favourited: true })
+ expect(state.mentions).toEqual(
+ [
+ { type: 'mention', status: { id: 20, favourited: true } },
+ { type: 'favourite', status: { id: 19, favourited: false } },
+ { type: 'reblog', status: { id: 18, favourited: false } },
+ { type: 'follow', status: { id: 17, favourited: false } },
+ { type: 'mention', status: { id: 16, favourited: false } }
+ ]
+ )
+ })
+ })
+ })
+})
diff --git a/src/renderer/store/TimelineSpace/Contents/Mentions.js b/src/renderer/store/TimelineSpace/Contents/Mentions.js
index 9adac1a0..b945928f 100644
--- a/src/renderer/store/TimelineSpace/Contents/Mentions.js
+++ b/src/renderer/store/TimelineSpace/Contents/Mentions.js
@@ -41,7 +41,6 @@ const Mentions = {
state.unreadMentions = []
},
updateToot (state, message) {
- console.log(message)
state.mentions = state.mentions.map((mention) => {
if (mention.type === 'mention' && mention.status.id === message.id) {
const status = {
From efc41b283bbd351b3798ffeab8e341429e06a625 Mon Sep 17 00:00:00 2001
From: AkiraFukushima
Date: Tue, 19 Mar 2019 09:27:01 +0900
Subject: [PATCH 7/8] refs #843 Add getters spec for mentions
---
.../TimelineSpace/Contents/Mentions.spec.js | 28 ++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/spec/renderer/integration/store/TimelineSpace/Contents/Mentions.spec.js b/spec/renderer/integration/store/TimelineSpace/Contents/Mentions.spec.js
index 905c4e31..64fd82ad 100644
--- a/spec/renderer/integration/store/TimelineSpace/Contents/Mentions.spec.js
+++ b/spec/renderer/integration/store/TimelineSpace/Contents/Mentions.spec.js
@@ -21,7 +21,8 @@ const initStore =() => {
namespaced: true,
state: state(),
actions: Mentions.actions,
- mutations: Mentions.mutations
+ mutations: Mentions.mutations,
+ getters: Mentions.getters
}
}
const timelineState = {
@@ -149,4 +150,29 @@ describe('Mentions', () => {
})
})
})
+
+ describe('mentions', () => {
+ beforeAll(() => {
+ state = () => {
+ return {
+ lazyLoading: false,
+ heading: true,
+ mentions: [
+ { id: 1, type: 'mention' },
+ { id: 2, type: 'favourite' },
+ { id: 3, type: 'reblog' },
+ { id: 4, type: 'follow' }
+ ],
+ unreadMentions: [],
+ filter: ''
+ }
+ }
+ })
+ it('should return only mentions', () => {
+ const mentions = store.getters['Mentions/mentions']
+ expect(mentions).toEqual([
+ { id: 1, type: 'mention' }
+ ])
+ })
+ })
})
From 8414e22b966a24cfe74b3c3f3b0ffd09cdcbccb4 Mon Sep 17 00:00:00 2001
From: AkiraFukushima
Date: Tue, 19 Mar 2019 09:29:25 +0900
Subject: [PATCH 8/8] refs #843 Fix code style for mentions
---
.../store/TimelineSpace/Contents/Mentions.spec.js | 8 ++++----
.../unit/store/TimelineSpace/Contents/Mentions.spec.js | 2 +-
.../components/TimelineSpace/Contents/Mentions.vue | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/spec/renderer/integration/store/TimelineSpace/Contents/Mentions.spec.js b/spec/renderer/integration/store/TimelineSpace/Contents/Mentions.spec.js
index 64fd82ad..843561d2 100644
--- a/spec/renderer/integration/store/TimelineSpace/Contents/Mentions.spec.js
+++ b/spec/renderer/integration/store/TimelineSpace/Contents/Mentions.spec.js
@@ -16,7 +16,7 @@ let state = () => {
}
}
-const initStore =() => {
+const initStore = () => {
return {
namespaced: true,
state: state(),
@@ -69,7 +69,7 @@ describe('Mentions', () => {
}
Mastodon.mockImplementation(() => mockClient)
- const mentions = await store.dispatch('Mentions/fetchMentions')
+ await store.dispatch('Mentions/fetchMentions')
expect(store.state.Mentions.mentions).toEqual([
{ id: 1, type: 'mention' },
{ id: 2, type: 'favourite' },
@@ -80,7 +80,7 @@ describe('Mentions', () => {
})
describe('lazyFetchMentions', () => {
- describe('last is null', () => {
+ describe('last is null', () => {
it('should not be updated', async () => {
const result = await store.dispatch('Mentions/lazyFetchMentions', null)
expect(result).toEqual(null)
@@ -137,7 +137,7 @@ describe('Mentions', () => {
}
Mastodon.mockImplementation(() => mockClient)
- const mentions = await store.dispatch('Mentions/lazyFetchMentions', { id: 1 })
+ await store.dispatch('Mentions/lazyFetchMentions', { id: 1 })
expect(store.state.Mentions.mentions).toEqual([
{ id: 1, type: 'mention' },
{ id: 2, type: 'favourite' },
diff --git a/spec/renderer/unit/store/TimelineSpace/Contents/Mentions.spec.js b/spec/renderer/unit/store/TimelineSpace/Contents/Mentions.spec.js
index f791c518..69ad0e56 100644
--- a/spec/renderer/unit/store/TimelineSpace/Contents/Mentions.spec.js
+++ b/spec/renderer/unit/store/TimelineSpace/Contents/Mentions.spec.js
@@ -76,7 +76,7 @@ describe('TimelineSpace/Contents/Mentions', () => {
}
})
it('should be inserted', () => {
- Mentions.mutations.insertMentions(state, [ -1, -2, -3, -4])
+ Mentions.mutations.insertMentions(state, [-1, -2, -3, -4])
expect(state.mentions).toEqual([5, 4, 3, 2, 1, -1, -2, -3, -4])
})
})
diff --git a/src/renderer/components/TimelineSpace/Contents/Mentions.vue b/src/renderer/components/TimelineSpace/Contents/Mentions.vue
index 562f19e5..3951f958 100644
--- a/src/renderer/components/TimelineSpace/Contents/Mentions.vue
+++ b/src/renderer/components/TimelineSpace/Contents/Mentions.vue
@@ -203,7 +203,7 @@ export default {
right: 24px;
top: 48px;
background-color: rgba(0, 0, 0, 0.7);
- color: #ffffff;
+ color: #fff;
padding: 4px 8px;
border-radius: 0 0 2px 2px;