Merge pull request #869 from h3poteto/iss-850
refs #850 Replace TimelineSpace with typescript
This commit is contained in:
commit
4bc5f8847d
|
@ -32,7 +32,7 @@ let rendererConfig = {
|
|||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(js|vue)$/,
|
||||
test: /\.(js|vue|ts)$/,
|
||||
enforce: 'pre',
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
|
|
|
@ -13466,9 +13466,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"megalodon": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/megalodon/-/megalodon-0.6.0.tgz",
|
||||
"integrity": "sha512-SXk6DqM02NJGLppr4XpCKDX3HqsPBS1fyuxm19IPmMlHRerChVyIDoWlmxlAEq3jdcCQrMmVVC/E5QuoO5uc0Q==",
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/megalodon/-/megalodon-0.6.2.tgz",
|
||||
"integrity": "sha512-EmNs0M6e2AiX9hutoiXo0FUkghZ1HdyLpS8mVkrMMN8btBR2x1hVrAF/8WAFePeJQrEMYjRyQSEJfykJ/4rwaQ==",
|
||||
"requires": {
|
||||
"@types/oauth": "0.9.1",
|
||||
"@types/request": "2.48.1",
|
||||
|
|
|
@ -145,7 +145,7 @@
|
|||
"i18next-sync-fs-backend": "^1.1.0",
|
||||
"is-empty": "^1.2.0",
|
||||
"lodash": "^4.17.11",
|
||||
"megalodon": "0.6.0",
|
||||
"megalodon": "0.6.2",
|
||||
"moment": "^2.21.0",
|
||||
"mousetrap": "^1.6.2",
|
||||
"nedb": "^1.8.0",
|
||||
|
|
|
@ -1,19 +1,35 @@
|
|||
import Mastodon from 'megalodon'
|
||||
import Mastodon, { Emoji, Instance, Response } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { ipcMain } from '~/spec/mock/electron'
|
||||
import TimelineSpace from '~/src/renderer/store/TimelineSpace'
|
||||
import TimelineSpace, { TimelineSpaceState, blankAccount } from '~/src/renderer/store/TimelineSpace'
|
||||
import unreadSettings from '~/src/constants/unreadNotification'
|
||||
|
||||
jest.mock('megalodon')
|
||||
|
||||
const state = () => {
|
||||
const mockedInstance: Instance = {
|
||||
uri: 'http://pleroma.io',
|
||||
title: 'pleroma',
|
||||
description: '',
|
||||
email: 'test@example.com',
|
||||
version: '2.5.0 (compatible; Pleroma 0.9.0-3363-g7c5d2dc7)',
|
||||
thumbnail: null,
|
||||
urls: {
|
||||
streaming_api: 'wss://pleroma.io'
|
||||
},
|
||||
stats: {
|
||||
user_count: 10,
|
||||
status_count: 1000,
|
||||
domain_count: 100
|
||||
},
|
||||
languages: ['en'],
|
||||
contact_account: null,
|
||||
max_toot_chars: 5000
|
||||
}
|
||||
|
||||
const state = (): TimelineSpaceState => {
|
||||
return {
|
||||
account: {
|
||||
domain: '',
|
||||
_id: '',
|
||||
username: ''
|
||||
},
|
||||
account: blankAccount,
|
||||
loading: false,
|
||||
emojis: [],
|
||||
tootMax: 500,
|
||||
|
@ -110,7 +126,7 @@ describe('TimelineSpace', () => {
|
|||
describe('localAccount', () => {
|
||||
describe('account already exists', () => {
|
||||
beforeEach(() => {
|
||||
ipcMain.once('get-local-account', (event, _id) => {
|
||||
ipcMain.once('get-local-account', (event: any) => {
|
||||
event.sender.send('response-get-local-account', {
|
||||
username: 'test'
|
||||
})
|
||||
|
@ -124,10 +140,10 @@ describe('TimelineSpace', () => {
|
|||
|
||||
describe('account does not exist', () => {
|
||||
beforeEach(() => {
|
||||
ipcMain.once('get-local-account', (event, _id) => {
|
||||
ipcMain.once('get-local-account', (event: any) => {
|
||||
event.sender.send('response-get-local-account', {})
|
||||
})
|
||||
ipcMain.once('update-account', (event, _account) => {
|
||||
ipcMain.once('update-account', (event: any) => {
|
||||
event.sender.send('response-update-account', {
|
||||
username: 'fetched'
|
||||
})
|
||||
|
@ -142,23 +158,52 @@ describe('TimelineSpace', () => {
|
|||
|
||||
describe('detectPleroma', () => {
|
||||
describe('API is pleroma', () => {
|
||||
let mockedResponse: Response<Instance>
|
||||
beforeEach(() => {
|
||||
mockedResponse = {
|
||||
data: mockedInstance,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: {}
|
||||
}
|
||||
})
|
||||
it('should be detected', async () => {
|
||||
// const mockResponse = {
|
||||
// version: 'Pleroma v0.9.9'
|
||||
// }
|
||||
(Mastodon.get as any).mockResolvedValue({
|
||||
version: 'Pleroma v0.9.9'
|
||||
})
|
||||
(Mastodon.get as any).mockResolvedValue(mockedResponse)
|
||||
await store.dispatch('TimelineSpace/detectPleroma')
|
||||
expect(store.state.TimelineSpace.pleroma).toEqual(true)
|
||||
expect(store.state.TimelineSpace.useWebsocket).toEqual(true)
|
||||
})
|
||||
})
|
||||
describe('API is not pleroma', () => {
|
||||
let mockedResponse: Response<Instance>
|
||||
beforeEach(() => {
|
||||
const instance: Instance = {
|
||||
uri: 'http://mstdn.io',
|
||||
title: 'mstnd.io',
|
||||
description: '',
|
||||
email: 'test@example.com',
|
||||
version: '2.7.0',
|
||||
thumbnail: null,
|
||||
urls: {
|
||||
streaming_api: 'wss://mstdn.io'
|
||||
},
|
||||
stats: {
|
||||
user_count: 10,
|
||||
status_count: 1000,
|
||||
domain_count: 100
|
||||
},
|
||||
languages: ['en'],
|
||||
contact_account: null
|
||||
}
|
||||
mockedResponse = {
|
||||
data: instance,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: {}
|
||||
}
|
||||
})
|
||||
it('should be detected', async () => {
|
||||
(Mastodon.get as any).mockResolvedValue({
|
||||
version: '2.7.0'
|
||||
})
|
||||
(Mastodon.get as any).mockResolvedValue(mockedResponse)
|
||||
await store.dispatch('TimelineSpace/detectPleroma')
|
||||
expect(store.state.TimelineSpace.pleroma).toEqual(false)
|
||||
expect(store.state.TimelineSpace.useWebsocket).toEqual(false)
|
||||
|
@ -167,36 +212,59 @@ describe('TimelineSpace', () => {
|
|||
})
|
||||
|
||||
describe('fetchEmojis', () => {
|
||||
let emacsEmoji: Emoji
|
||||
let rubyEmoji: Emoji
|
||||
let mockedResponse: Response<Array<Emoji>>
|
||||
beforeEach(() => {
|
||||
emacsEmoji = {
|
||||
shortcode: 'emacs',
|
||||
url: 'http://example.com/emacs',
|
||||
static_url: 'http://example.com/emacs',
|
||||
visible_in_picker: true
|
||||
}
|
||||
rubyEmoji = {
|
||||
shortcode: 'ruby',
|
||||
url: 'http://example.com/ruby',
|
||||
static_url: 'http://example.com/ruby',
|
||||
visible_in_picker: true
|
||||
}
|
||||
mockedResponse = {
|
||||
data: [
|
||||
emacsEmoji,
|
||||
rubyEmoji
|
||||
],
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: {}
|
||||
}
|
||||
})
|
||||
it('should be updated', async () => {
|
||||
(Mastodon.get as any).mockResolvedValue([
|
||||
{
|
||||
shortcode: 'emacs',
|
||||
url: 'http://example.com/emacs'
|
||||
},
|
||||
{
|
||||
shortcode: 'ruby',
|
||||
url: 'http://example.com/ruby'
|
||||
}
|
||||
])
|
||||
(Mastodon.get as any).mockResolvedValue(mockedResponse)
|
||||
await store.dispatch('TimelineSpace/fetchEmojis', {})
|
||||
expect(store.state.TimelineSpace.emojis).toEqual([
|
||||
{
|
||||
name: ':emacs:',
|
||||
image: 'http://example.com/emacs'
|
||||
image: 'http://example.com/emacs',
|
||||
name: ':emacs:'
|
||||
},
|
||||
{
|
||||
name: ':ruby:',
|
||||
image: 'http://example.com/ruby'
|
||||
}
|
||||
])
|
||||
image: 'http://example.com/ruby',
|
||||
name: ':ruby:'
|
||||
}])
|
||||
})
|
||||
})
|
||||
|
||||
describe('fetchInstance', () => {
|
||||
let mockedResponse: Response<Instance>
|
||||
beforeEach(() => {
|
||||
mockedResponse = {
|
||||
data: mockedInstance,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: {}
|
||||
}
|
||||
})
|
||||
it('should be updated', async () => {
|
||||
(Mastodon.get as any).mockResolvedValue({
|
||||
max_toot_chars: 5000
|
||||
})
|
||||
(Mastodon.get as any).mockResolvedValue(mockedResponse)
|
||||
await store.dispatch('TimelineSpace/fetchInstance', {})
|
||||
expect(store.state.TimelineSpace.tootMax).toEqual(5000)
|
||||
})
|
||||
|
@ -205,7 +273,7 @@ describe('TimelineSpace', () => {
|
|||
describe('loadUnreadNotification', () => {
|
||||
describe('success', () => {
|
||||
it('should be updated', async () => {
|
||||
ipcMain.once('get-unread-notification', (event, _) => {
|
||||
ipcMain.once('get-unread-notification', (event: any) => {
|
||||
event.sender.send('response-get-unread-notification', {
|
||||
direct: false,
|
||||
local: false,
|
||||
|
@ -222,7 +290,7 @@ describe('TimelineSpace', () => {
|
|||
})
|
||||
describe('error', () => {
|
||||
it('should be set default', async () => {
|
||||
ipcMain.once('get-unread-notification', (event, _) => {
|
||||
ipcMain.once('get-unread-notification', (event: any) => {
|
||||
event.sender.send('error-get-unread-notification', new Error())
|
||||
})
|
||||
await store.dispatch('TimelineSpace/loadUnreadNotification')
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
import TimelineSpace from '~/src/renderer/store/TimelineSpace'
|
||||
import TimelineSpace, { TimelineSpaceState, blankAccount, MUTATION_TYPES } from '~/src/renderer/store/TimelineSpace'
|
||||
import { Emoji } from 'megalodon'
|
||||
import unreadSettings from '~/src/constants/unreadNotification'
|
||||
|
||||
describe('TimelineSpace', () => {
|
||||
describe('mutations', () => {
|
||||
let state
|
||||
let state: TimelineSpaceState
|
||||
beforeEach(() => {
|
||||
state = {
|
||||
account: {
|
||||
domain: '',
|
||||
_id: '',
|
||||
username: ''
|
||||
},
|
||||
account: blankAccount,
|
||||
loading: false,
|
||||
emojis: [],
|
||||
tootMax: 500,
|
||||
|
@ -26,39 +23,41 @@ describe('TimelineSpace', () => {
|
|||
|
||||
describe('updateEmojis', () => {
|
||||
it('should be updated', () => {
|
||||
TimelineSpace.mutations.updateEmojis(state, [
|
||||
{
|
||||
shortcode: 'emacs',
|
||||
url: 'http://example.com/emacs'
|
||||
},
|
||||
{
|
||||
shortcode: 'ruby',
|
||||
url: 'http://example.com/ruby'
|
||||
}
|
||||
])
|
||||
const emacsEmoji: Emoji = {
|
||||
shortcode: 'emacs',
|
||||
url: 'http://example.com/emacs',
|
||||
static_url: 'http://example.com/emacs',
|
||||
visible_in_picker: true
|
||||
}
|
||||
const rubyEmoji: Emoji = {
|
||||
shortcode: 'ruby',
|
||||
url: 'http://example.com/ruby',
|
||||
static_url: 'http://example.com/ruby',
|
||||
visible_in_picker: true
|
||||
}
|
||||
TimelineSpace.mutations![MUTATION_TYPES.UPDATE_EMOJIS](state, [emacsEmoji, rubyEmoji])
|
||||
expect(state.emojis).toEqual([
|
||||
{
|
||||
name: ':emacs:',
|
||||
image: 'http://example.com/emacs'
|
||||
image: 'http://example.com/emacs',
|
||||
name: ':emacs:'
|
||||
},
|
||||
{
|
||||
name: ':ruby:',
|
||||
image: 'http://example.com/ruby'
|
||||
}
|
||||
])
|
||||
image: 'http://example.com/ruby',
|
||||
name: ':ruby:'
|
||||
}])
|
||||
})
|
||||
})
|
||||
|
||||
describe('updateTootMax', () => {
|
||||
describe('value is null', () => {
|
||||
it('should be updated with 500', () => {
|
||||
TimelineSpace.mutations.updateTootMax(state, null)
|
||||
TimelineSpace.mutations![MUTATION_TYPES.UPDATE_TOOT_MAX](state, null)
|
||||
expect(state.tootMax).toEqual(500)
|
||||
})
|
||||
})
|
||||
describe('value is not null', () => {
|
||||
it('should be updated', () => {
|
||||
TimelineSpace.mutations.updateTootMax(state, 1200)
|
||||
TimelineSpace.mutations![MUTATION_TYPES.UPDATE_TOOT_MAX](state, 1200)
|
||||
expect(state.tootMax).toEqual(1200)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,428 +0,0 @@
|
|||
import sanitizeHtml from 'sanitize-html'
|
||||
import { ipcRenderer } from 'electron'
|
||||
import Mastodon from 'megalodon'
|
||||
import SideMenu from './TimelineSpace/SideMenu'
|
||||
import HeaderMenu from './TimelineSpace/HeaderMenu'
|
||||
import Modals from './TimelineSpace/Modals'
|
||||
import Contents from './TimelineSpace/Contents'
|
||||
import router from '@/router'
|
||||
import unreadSettings from '~/src/constants/unreadNotification'
|
||||
|
||||
const TimelineSpace = {
|
||||
namespaced: true,
|
||||
modules: {
|
||||
SideMenu,
|
||||
HeaderMenu,
|
||||
Modals,
|
||||
Contents
|
||||
},
|
||||
state: {
|
||||
account: {
|
||||
domain: '',
|
||||
_id: '',
|
||||
username: ''
|
||||
},
|
||||
loading: false,
|
||||
emojis: [],
|
||||
tootMax: 500,
|
||||
unreadNotification: {
|
||||
direct: unreadSettings.Direct.default,
|
||||
local: unreadSettings.Local.default,
|
||||
public: unreadSettings.Public.default
|
||||
},
|
||||
useWebsocket: false,
|
||||
pleroma: false
|
||||
},
|
||||
mutations: {
|
||||
updateAccount (state, account) {
|
||||
state.account = account
|
||||
},
|
||||
changeLoading (state, value) {
|
||||
state.loading = value
|
||||
},
|
||||
updateEmojis (state, emojis) {
|
||||
state.emojis = emojis.map((e) => {
|
||||
return {
|
||||
name: `:${e.shortcode}:`,
|
||||
image: e.url
|
||||
}
|
||||
})
|
||||
},
|
||||
updateTootMax (state, value) {
|
||||
if (value) {
|
||||
state.tootMax = value
|
||||
} else {
|
||||
state.tootMax = 500
|
||||
}
|
||||
},
|
||||
updateUnreadNotification (state, settings) {
|
||||
state.unreadNotification = settings
|
||||
},
|
||||
changePleroma (state, pleroma) {
|
||||
state.pleroma = pleroma
|
||||
},
|
||||
changeUseWebsocket (state, use) {
|
||||
state.useWebsocket = use
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
// -------------------------------------------------
|
||||
// Accounts
|
||||
// -------------------------------------------------
|
||||
localAccount ({ dispatch, commit }, id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
ipcRenderer.send('get-local-account', id)
|
||||
ipcRenderer.once('error-get-local-account', (event, err) => {
|
||||
ipcRenderer.removeAllListeners('response-get-local-account')
|
||||
reject(err)
|
||||
})
|
||||
ipcRenderer.once('response-get-local-account', (event, account) => {
|
||||
ipcRenderer.removeAllListeners('error-get-local-account')
|
||||
|
||||
if (account.username === undefined || account.username === null || account.username === '') {
|
||||
dispatch('fetchAccount', account)
|
||||
.then((acct) => {
|
||||
commit('updateAccount', acct)
|
||||
resolve(acct)
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
} else {
|
||||
commit('updateAccount', account)
|
||||
resolve(account)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
fetchAccount (_, account) {
|
||||
return new Promise((resolve, reject) => {
|
||||
ipcRenderer.send('update-account', account)
|
||||
ipcRenderer.once('error-update-account', (event, err) => {
|
||||
ipcRenderer.removeAllListeners('response-update-account')
|
||||
reject(err)
|
||||
})
|
||||
ipcRenderer.once('response-update-account', (event, account) => {
|
||||
ipcRenderer.removeAllListeners('error-update-account')
|
||||
resolve(account)
|
||||
})
|
||||
})
|
||||
},
|
||||
async clearAccount ({ commit }) {
|
||||
commit(
|
||||
'updateAccount',
|
||||
{
|
||||
domain: '',
|
||||
_id: '',
|
||||
username: ''
|
||||
}
|
||||
)
|
||||
return 'clearAccount'
|
||||
},
|
||||
async detectPleroma ({ commit, state }) {
|
||||
const data = await Mastodon.get('/instance', {}, state.account.baseURL + '/api/v1')
|
||||
if (data.version.includes('Pleroma')) {
|
||||
commit('changePleroma', true)
|
||||
commit('changeUseWebsocket', true)
|
||||
} else {
|
||||
commit('changePleroma', false)
|
||||
commit('changeUseWebsocket', false)
|
||||
}
|
||||
},
|
||||
// -----------------------------------------------
|
||||
// Shortcuts
|
||||
// -----------------------------------------------
|
||||
watchShortcutEvents ({ commit, dispatch }) {
|
||||
ipcRenderer.on('CmdOrCtrl+N', () => {
|
||||
dispatch('TimelineSpace/Modals/NewToot/openModal', {}, { root: true })
|
||||
})
|
||||
ipcRenderer.on('CmdOrCtrl+K', () => {
|
||||
commit('TimelineSpace/Modals/Jump/changeModal', true, { root: true })
|
||||
})
|
||||
},
|
||||
async removeShortcutEvents () {
|
||||
ipcRenderer.removeAllListeners('CmdOrCtrl+N')
|
||||
ipcRenderer.removeAllListeners('CmdOrCtrl+K')
|
||||
return 'removeShortcutEvents'
|
||||
},
|
||||
/**
|
||||
* clearUnread
|
||||
*/
|
||||
async clearUnread ({ dispatch }) {
|
||||
dispatch('TimelineSpace/SideMenu/clearUnread', {}, { root: true })
|
||||
},
|
||||
/**
|
||||
* fetchEmojis
|
||||
*/
|
||||
async fetchEmojis ({ commit }, account) {
|
||||
const data = await Mastodon.get('/custom_emojis', {}, account.baseURL + '/api/v1')
|
||||
commit('updateEmojis', data)
|
||||
return data
|
||||
},
|
||||
/**
|
||||
* fetchInstance
|
||||
*/
|
||||
async fetchInstance ({ commit }, account) {
|
||||
const data = await Mastodon.get('/instance', {}, account.baseURL + '/api/v1')
|
||||
commit('updateTootMax', data.max_toot_chars)
|
||||
return data
|
||||
},
|
||||
loadUnreadNotification ({ commit }, accountID) {
|
||||
return new Promise(resolve => {
|
||||
ipcRenderer.once('response-get-unread-notification', (event, settings) => {
|
||||
ipcRenderer.removeAllListeners('error-get-unread-notification')
|
||||
commit('updateUnreadNotification', settings)
|
||||
resolve(settings)
|
||||
})
|
||||
ipcRenderer.once('error-get-unread-notification', () => {
|
||||
ipcRenderer.removeAllListeners('response-get-unread-notification')
|
||||
commit('updateUnreadNotification', {
|
||||
direct: unreadSettings.Direct.default,
|
||||
local: unreadSettings.Local.default,
|
||||
public: unreadSettings.Public.default
|
||||
})
|
||||
resolve(null)
|
||||
})
|
||||
ipcRenderer.send('get-unread-notification', accountID)
|
||||
})
|
||||
},
|
||||
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 })
|
||||
}
|
||||
if (state.unreadNotification.local) {
|
||||
await dispatch('TimelineSpace/Contents/Local/fetchLocalTimeline', {}, { root: true })
|
||||
}
|
||||
if (state.unreadNotification.public) {
|
||||
await dispatch('TimelineSpace/Contents/Public/fetchPublicTimeline', {}, { root: true })
|
||||
}
|
||||
},
|
||||
clearContentsTimelines ({ commit }) {
|
||||
commit('TimelineSpace/Contents/Home/clearTimeline', {}, { root: true })
|
||||
commit('TimelineSpace/Contents/Local/clearTimeline', {}, { root: true })
|
||||
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)
|
||||
if (state.unreadNotification.direct) {
|
||||
dispatch('bindDirectMessagesStreaming')
|
||||
}
|
||||
if (state.unreadNotification.local) {
|
||||
dispatch('bindLocalStreaming')
|
||||
}
|
||||
if (state.unreadNotification.public) {
|
||||
dispatch('bindPublicStreaming')
|
||||
}
|
||||
},
|
||||
startStreamings ({ dispatch, state }) {
|
||||
dispatch('startUserStreaming')
|
||||
if (state.unreadNotification.direct) {
|
||||
dispatch('startDirectMessagesStreaming')
|
||||
}
|
||||
if (state.unreadNotification.local) {
|
||||
dispatch('startLocalStreaming')
|
||||
}
|
||||
if (state.unreadNotification.public) {
|
||||
dispatch('startPublicStreaming')
|
||||
}
|
||||
},
|
||||
stopStreamings ({ dispatch }) {
|
||||
dispatch('stopUserStreaming')
|
||||
dispatch('stopDirectMessagesStreaming')
|
||||
dispatch('stopLocalStreaming')
|
||||
dispatch('stopPublicStreaming')
|
||||
},
|
||||
unbindStreamings ({ dispatch }) {
|
||||
dispatch('unbindUserStreaming')
|
||||
dispatch('unbindDirectMessagesStreaming')
|
||||
dispatch('unbindLocalStreaming')
|
||||
dispatch('unbindPublicStreaming')
|
||||
},
|
||||
// ------------------------------------------------
|
||||
// Each streaming methods
|
||||
// ------------------------------------------------
|
||||
bindUserStreaming ({ commit, rootState }, account) {
|
||||
ipcRenderer.on('update-start-user-streaming', (event, update) => {
|
||||
commit('TimelineSpace/Contents/Home/appendTimeline', update, { root: true })
|
||||
// Sometimes archive old statuses
|
||||
if (rootState.TimelineSpace.Contents.Home.heading && Math.random() > 0.8) {
|
||||
commit('TimelineSpace/Contents/Home/archiveTimeline', null, { root: true })
|
||||
}
|
||||
commit('TimelineSpace/SideMenu/changeUnreadHomeTimeline', true, { root: true })
|
||||
})
|
||||
ipcRenderer.on('notification-start-user-streaming', (event, notification) => {
|
||||
let notify = createNotification(notification, rootState.App.notify)
|
||||
if (notify) {
|
||||
notify.onclick = () => {
|
||||
router.push(`/${account._id}/notifications`)
|
||||
}
|
||||
}
|
||||
commit('TimelineSpace/Contents/Notifications/appendNotifications', notification, { root: true })
|
||||
if (rootState.TimelineSpace.Contents.Notifications.heading && Math.random() > 0.8) {
|
||||
commit('TimelineSpace/Contents/Notifications/archiveNotifications', null, { root: true })
|
||||
}
|
||||
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) => {
|
||||
ipcRenderer.send('start-user-streaming', {
|
||||
account: state.account,
|
||||
useWebsocket: state.useWebsocket
|
||||
})
|
||||
ipcRenderer.once('error-start-user-streaming', (event, err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
bindLocalStreaming ({ commit, rootState }) {
|
||||
ipcRenderer.on('update-start-local-streaming', (event, update) => {
|
||||
commit('TimelineSpace/Contents/Local/appendTimeline', update, { root: true })
|
||||
if (rootState.TimelineSpace.Contents.Local.heading && Math.random() > 0.8) {
|
||||
commit('TimelineSpace/Contents/Local/archiveTimeline', {}, { root: true })
|
||||
}
|
||||
commit('TimelineSpace/SideMenu/changeUnreadLocalTimeline', true, { root: true })
|
||||
})
|
||||
},
|
||||
startLocalStreaming ({ state }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
ipcRenderer.send('start-local-streaming', {
|
||||
account: state.account,
|
||||
useWebsocket: state.useWebsocket
|
||||
})
|
||||
ipcRenderer.once('error-start-local-streaming', (event, err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
bindPublicStreaming ({ commit, rootState }) {
|
||||
ipcRenderer.on('update-start-public-streaming', (event, update) => {
|
||||
commit('TimelineSpace/Contents/Public/appendTimeline', update, { root: true })
|
||||
if (rootState.TimelineSpace.Contents.Public.heading && Math.random() > 0.8) {
|
||||
commit('TimelineSpace/Contents/Public/archiveTimeline', {}, { root: true })
|
||||
}
|
||||
commit('TimelineSpace/SideMenu/changeUnreadPublicTimeline', true, { root: true })
|
||||
})
|
||||
},
|
||||
startPublicStreaming ({ state }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
ipcRenderer.send('start-public-streaming', {
|
||||
account: state.account,
|
||||
useWebsocket: state.useWebsocket
|
||||
})
|
||||
ipcRenderer.once('error-start-public-streaming', (event, err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
bindDirectMessagesStreaming ({ commit, rootState }) {
|
||||
ipcRenderer.on('update-start-directmessages-streaming', (event, update) => {
|
||||
commit('TimelineSpace/Contents/DirectMessages/appendTimeline', update, { root: true })
|
||||
if (rootState.TimelineSpace.Contents.DirectMessages.heading && Math.random() > 0.8) {
|
||||
commit('TimelineSpace/Contents/DirectMessages/archiveTimeline', {}, { root: true })
|
||||
}
|
||||
commit('TimelineSpace/SideMenu/changeUnreadDirectMessagesTimeline', true, { root: true })
|
||||
})
|
||||
},
|
||||
startDirectMessagesStreaming ({ state }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
ipcRenderer.send('start-directmessages-streaming', {
|
||||
account: state.account,
|
||||
useWebsocket: state.useWebsocket
|
||||
})
|
||||
ipcRenderer.once('error-start-directmessages-streaming', (event, err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
unbindUserStreaming () {
|
||||
ipcRenderer.removeAllListeners('update-start-user-streaming')
|
||||
ipcRenderer.removeAllListeners('notification-start-user-streaming')
|
||||
ipcRenderer.removeAllListeners('error-start-user-streaming')
|
||||
},
|
||||
stopUserStreaming () {
|
||||
ipcRenderer.send('stop-user-streaming')
|
||||
},
|
||||
unbindLocalStreaming () {
|
||||
ipcRenderer.removeAllListeners('error-start-local-streaming')
|
||||
ipcRenderer.removeAllListeners('update-start-local-streaming')
|
||||
},
|
||||
stopLocalStreaming () {
|
||||
ipcRenderer.send('stop-local-streaming')
|
||||
},
|
||||
unbindPublicStreaming () {
|
||||
ipcRenderer.removeAllListeners('error-start-public-streaming')
|
||||
ipcRenderer.removeAllListeners('update-start-public-streaming')
|
||||
},
|
||||
stopPublicStreaming () {
|
||||
ipcRenderer.send('stop-public-streaming')
|
||||
},
|
||||
unbindDirectMessagesStreaming () {
|
||||
ipcRenderer.removeAllListeners('error-start-directmessages-streaming')
|
||||
ipcRenderer.removeAllListeners('update-start-directmessages-streaming')
|
||||
},
|
||||
stopDirectMessagesStreaming () {
|
||||
ipcRenderer.send('stop-directmessages-streaming')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default TimelineSpace
|
||||
|
||||
function createNotification (notification, notifyConfig) {
|
||||
switch (notification.type) {
|
||||
case 'favourite':
|
||||
if (notifyConfig.favourite) {
|
||||
return new Notification('Favourite', {
|
||||
body: `${username(notification.account)} favourited your status`
|
||||
})
|
||||
}
|
||||
break
|
||||
case 'follow':
|
||||
if (notifyConfig.follow) {
|
||||
return new Notification('Follow', {
|
||||
body: `${username(notification.account)} is now following you`
|
||||
})
|
||||
}
|
||||
break
|
||||
case 'mention':
|
||||
if (notifyConfig.reply) {
|
||||
// Clean html tags
|
||||
return new Notification(`${notification.status.account.display_name}`, {
|
||||
body: sanitizeHtml(notification.status.content, {
|
||||
allowedTags: [],
|
||||
allowedAttributes: []
|
||||
})
|
||||
})
|
||||
}
|
||||
break
|
||||
case 'reblog':
|
||||
if (notifyConfig.reblog) {
|
||||
return new Notification('Reblog', {
|
||||
body: `${username(notification.account)} boosted your status`
|
||||
})
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
function username (account) {
|
||||
if (account.display_name !== '') {
|
||||
return account.display_name
|
||||
} else {
|
||||
return account.username
|
||||
}
|
||||
}
|
|
@ -0,0 +1,477 @@
|
|||
import sanitizeHtml from 'sanitize-html'
|
||||
import { ipcRenderer } from 'electron'
|
||||
import Mastodon, { Account, Emoji, Instance, Status, Notification as NotificationType } from 'megalodon'
|
||||
import SideMenu from './TimelineSpace/SideMenu'
|
||||
import HeaderMenu from './TimelineSpace/HeaderMenu'
|
||||
import Modals from './TimelineSpace/Modals'
|
||||
import Contents from './TimelineSpace/Contents'
|
||||
import router from '@/router'
|
||||
import unreadSettings from '~/src/constants/unreadNotification'
|
||||
import { Module, MutationTree, ActionTree } from 'vuex'
|
||||
import AccountType from '~/src/types/account'
|
||||
import { Notify } from './App'
|
||||
|
||||
declare var Notification: any
|
||||
|
||||
interface MyEmoji {
|
||||
name: string,
|
||||
image: string
|
||||
}
|
||||
|
||||
interface UnreadNotification {
|
||||
direct: boolean,
|
||||
local: boolean,
|
||||
public: boolean
|
||||
}
|
||||
|
||||
export interface TimelineSpaceState {
|
||||
account: AccountType,
|
||||
loading: boolean,
|
||||
emojis: Array<MyEmoji>,
|
||||
tootMax: number,
|
||||
unreadNotification: UnreadNotification,
|
||||
useWebsocket: boolean,
|
||||
pleroma: boolean
|
||||
}
|
||||
|
||||
export const blankAccount: AccountType = {
|
||||
_id: '',
|
||||
baseURL: '',
|
||||
domain: '',
|
||||
username: '',
|
||||
clientId: '',
|
||||
clientSecret: '',
|
||||
accessToken: null,
|
||||
refreshToken: null,
|
||||
accountId: null,
|
||||
avatar: null,
|
||||
order: 0
|
||||
}
|
||||
|
||||
const state = (): TimelineSpaceState => ({
|
||||
account: blankAccount,
|
||||
loading: false,
|
||||
emojis: [],
|
||||
tootMax: 500,
|
||||
unreadNotification: {
|
||||
direct: unreadSettings.Direct.default,
|
||||
local: unreadSettings.Local.default,
|
||||
public: unreadSettings.Public.default
|
||||
},
|
||||
useWebsocket: false,
|
||||
pleroma: false
|
||||
})
|
||||
|
||||
export const MUTATION_TYPES = {
|
||||
UPDATE_ACCOUNT: 'updateAccount',
|
||||
CHANGE_LOADING: 'changeLoading',
|
||||
UPDATE_EMOJIS: 'updateEmojis',
|
||||
UPDATE_TOOT_MAX: 'updateTootMax',
|
||||
UPDATE_UNREAD_NOTIFICATION: 'updateUnreadNotification',
|
||||
CHANGE_PLEROMA: 'changePleroma',
|
||||
CHANGE_USE_WEBSOCKET: 'changeUseWebsocket'
|
||||
}
|
||||
|
||||
const mutations: MutationTree<TimelineSpaceState> = {
|
||||
[MUTATION_TYPES.UPDATE_ACCOUNT]: (state, account: AccountType) => {
|
||||
state.account = account
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_LOADING]: (state, value: boolean) => {
|
||||
state.loading = value
|
||||
},
|
||||
[MUTATION_TYPES.UPDATE_EMOJIS]: (state, emojis: Array<Emoji>) => {
|
||||
state.emojis = emojis.map((e) => {
|
||||
return {
|
||||
name: `:${e.shortcode}:`,
|
||||
image: e.url
|
||||
}
|
||||
})
|
||||
},
|
||||
[MUTATION_TYPES.UPDATE_TOOT_MAX]: (state, value: number | null) => {
|
||||
if (value) {
|
||||
state.tootMax = value
|
||||
} else {
|
||||
state.tootMax = 500
|
||||
}
|
||||
},
|
||||
[MUTATION_TYPES.UPDATE_UNREAD_NOTIFICATION]: (state, settings: UnreadNotification) => {
|
||||
state.unreadNotification = settings
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_PLEROMA]: (state, pleroma: boolean) => {
|
||||
state.pleroma = pleroma
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_USE_WEBSOCKET]: (state, use: boolean) => {
|
||||
state.useWebsocket = use
|
||||
}
|
||||
}
|
||||
|
||||
const actions: ActionTree<TimelineSpaceState, any> = {
|
||||
// -------------------------------------------------
|
||||
// Accounts
|
||||
// -------------------------------------------------
|
||||
localAccount: ({ dispatch, commit }, id: string): Promise<AccountType> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
ipcRenderer.send('get-local-account', id)
|
||||
ipcRenderer.once('error-get-local-account', (_, err: Error) => {
|
||||
ipcRenderer.removeAllListeners('response-get-local-account')
|
||||
reject(err)
|
||||
})
|
||||
ipcRenderer.once('response-get-local-account', (_, account: AccountType) => {
|
||||
ipcRenderer.removeAllListeners('error-get-local-account')
|
||||
|
||||
if (account.username === undefined || account.username === null || account.username === '') {
|
||||
dispatch('fetchAccount', account)
|
||||
.then((acct: AccountType) => {
|
||||
commit(MUTATION_TYPES.UPDATE_ACCOUNT, acct)
|
||||
resolve(acct)
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
} else {
|
||||
commit(MUTATION_TYPES.UPDATE_ACCOUNT, account)
|
||||
resolve(account)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
fetchAccount: (_, account: AccountType): Promise<AccountType> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
ipcRenderer.send('update-account', account)
|
||||
ipcRenderer.once('error-update-account', (_, err: Error) => {
|
||||
ipcRenderer.removeAllListeners('response-update-account')
|
||||
reject(err)
|
||||
})
|
||||
ipcRenderer.once('response-update-account', (_, account: AccountType) => {
|
||||
ipcRenderer.removeAllListeners('error-update-account')
|
||||
resolve(account)
|
||||
})
|
||||
})
|
||||
},
|
||||
clearAccount: async ({ commit }) => {
|
||||
commit(MUTATION_TYPES.UPDATE_ACCOUNT, blankAccount)
|
||||
return true
|
||||
},
|
||||
detectPleroma: async ({ commit, state }) => {
|
||||
const res = await Mastodon.get<Instance>('/instance', {}, state.account.baseURL + '/api/v1')
|
||||
if (res.data.version.includes('Pleroma')) {
|
||||
commit(MUTATION_TYPES.CHANGE_PLEROMA, true)
|
||||
commit(MUTATION_TYPES.CHANGE_USE_WEBSOCKET, true)
|
||||
} else {
|
||||
commit(MUTATION_TYPES.CHANGE_PLEROMA, false)
|
||||
commit(MUTATION_TYPES.CHANGE_USE_WEBSOCKET, false)
|
||||
}
|
||||
},
|
||||
// -----------------------------------------------
|
||||
// Shortcuts
|
||||
// -----------------------------------------------
|
||||
watchShortcutEvents: ({ commit, dispatch }) => {
|
||||
ipcRenderer.on('CmdOrCtrl+N', () => {
|
||||
dispatch('TimelineSpace/Modals/NewToot/openModal', {}, { root: true })
|
||||
})
|
||||
ipcRenderer.on('CmdOrCtrl+K', () => {
|
||||
commit('TimelineSpace/Modals/Jump/changeModal', true, { root: true })
|
||||
})
|
||||
},
|
||||
removeShortcutEvents: async () => {
|
||||
ipcRenderer.removeAllListeners('CmdOrCtrl+N')
|
||||
ipcRenderer.removeAllListeners('CmdOrCtrl+K')
|
||||
return true
|
||||
},
|
||||
/**
|
||||
* clearUnread
|
||||
*/
|
||||
clearUnread: async ({ dispatch }) => {
|
||||
dispatch('TimelineSpace/SideMenu/clearUnread', {}, { root: true })
|
||||
},
|
||||
/**
|
||||
* fetchEmojis
|
||||
*/
|
||||
fetchEmojis: async ({ commit }, account: AccountType): Promise<Array<Emoji>> => {
|
||||
const res = await Mastodon.get<Array<Emoji>>('/custom_emojis', {}, account.baseURL + '/api/v1')
|
||||
commit(MUTATION_TYPES.UPDATE_EMOJIS, res.data)
|
||||
return res.data
|
||||
},
|
||||
/**
|
||||
* fetchInstance
|
||||
*/
|
||||
fetchInstance: async ({ commit }, account: AccountType) => {
|
||||
const res = await Mastodon.get<Instance>('/instance', {}, account.baseURL + '/api/v1')
|
||||
commit(MUTATION_TYPES.UPDATE_TOOT_MAX, res.data.max_toot_chars)
|
||||
return true
|
||||
},
|
||||
loadUnreadNotification: ({ commit }, accountID: string) => {
|
||||
return new Promise(resolve => {
|
||||
ipcRenderer.once('response-get-unread-notification', (_, settings: UnreadNotification) => {
|
||||
ipcRenderer.removeAllListeners('error-get-unread-notification')
|
||||
commit(MUTATION_TYPES.UPDATE_UNREAD_NOTIFICATION, settings)
|
||||
resolve(settings)
|
||||
})
|
||||
ipcRenderer.once('error-get-unread-notification', () => {
|
||||
ipcRenderer.removeAllListeners('response-get-unread-notification')
|
||||
commit(MUTATION_TYPES.UPDATE_UNREAD_NOTIFICATION, {
|
||||
direct: unreadSettings.Direct.default,
|
||||
local: unreadSettings.Local.default,
|
||||
public: unreadSettings.Public.default
|
||||
} as UnreadNotification)
|
||||
resolve({})
|
||||
})
|
||||
ipcRenderer.send('get-unread-notification', accountID)
|
||||
})
|
||||
},
|
||||
fetchContentsTimelines: async ({ dispatch, state }) => {
|
||||
await dispatch('TimelineSpace/Contents/Home/fetchTimeline', {}, { root: true })
|
||||
await dispatch('TimelineSpace/Contents/Notifications/fetchNotifications', {}, { root: true })
|
||||
await dispatch('TimelineSpace/Contents/Mentions/fetchMentions', {}, { root: true })
|
||||
if (state.unreadNotification.direct) {
|
||||
await dispatch('TimelineSpace/Contents/DirectMessages/fetchTimeline', {}, { root: true })
|
||||
}
|
||||
if (state.unreadNotification.local) {
|
||||
await dispatch('TimelineSpace/Contents/Local/fetchLocalTimeline', {}, { root: true })
|
||||
}
|
||||
if (state.unreadNotification.public) {
|
||||
await dispatch('TimelineSpace/Contents/Public/fetchPublicTimeline', {}, { root: true })
|
||||
}
|
||||
},
|
||||
clearContentsTimelines: ({ commit }) => {
|
||||
commit('TimelineSpace/Contents/Home/clearTimeline', {}, { root: true })
|
||||
commit('TimelineSpace/Contents/Local/clearTimeline', {}, { root: true })
|
||||
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: AccountType) => {
|
||||
dispatch('bindUserStreaming', account)
|
||||
if (state.unreadNotification.direct) {
|
||||
dispatch('bindDirectMessagesStreaming')
|
||||
}
|
||||
if (state.unreadNotification.local) {
|
||||
dispatch('bindLocalStreaming')
|
||||
}
|
||||
if (state.unreadNotification.public) {
|
||||
dispatch('bindPublicStreaming')
|
||||
}
|
||||
},
|
||||
startStreamings: ({ dispatch, state }) => {
|
||||
dispatch('startUserStreaming')
|
||||
if (state.unreadNotification.direct) {
|
||||
dispatch('startDirectMessagesStreaming')
|
||||
}
|
||||
if (state.unreadNotification.local) {
|
||||
dispatch('startLocalStreaming')
|
||||
}
|
||||
if (state.unreadNotification.public) {
|
||||
dispatch('startPublicStreaming')
|
||||
}
|
||||
},
|
||||
stopStreamings: ({ dispatch }) => {
|
||||
dispatch('stopUserStreaming')
|
||||
dispatch('stopDirectMessagesStreaming')
|
||||
dispatch('stopLocalStreaming')
|
||||
dispatch('stopPublicStreaming')
|
||||
},
|
||||
unbindStreamings: ({ dispatch }) => {
|
||||
dispatch('unbindUserStreaming')
|
||||
dispatch('unbindDirectMessagesStreaming')
|
||||
dispatch('unbindLocalStreaming')
|
||||
dispatch('unbindPublicStreaming')
|
||||
},
|
||||
// ------------------------------------------------
|
||||
// Each streaming methods
|
||||
// ------------------------------------------------
|
||||
bindUserStreaming: ({ commit, rootState }, account: AccountType) => {
|
||||
ipcRenderer.on('update-start-user-streaming', (_, update: Status) => {
|
||||
commit('TimelineSpace/Contents/Home/appendTimeline', update, { root: true })
|
||||
// Sometimes archive old statuses
|
||||
if (rootState.TimelineSpace.Contents.Home.heading && Math.random() > 0.8) {
|
||||
commit('TimelineSpace/Contents/Home/archiveTimeline', null, { root: true })
|
||||
}
|
||||
commit('TimelineSpace/SideMenu/changeUnreadHomeTimeline', true, { root: true })
|
||||
})
|
||||
ipcRenderer.on('notification-start-user-streaming', (_, notification: NotificationType) => {
|
||||
let notify = createNotification(notification, rootState.App.notify as Notify)
|
||||
if (notify) {
|
||||
notify.onclick = () => {
|
||||
router.push(`/${account._id}/notifications`)
|
||||
}
|
||||
}
|
||||
commit('TimelineSpace/Contents/Notifications/appendNotifications', notification, { root: true })
|
||||
if (rootState.TimelineSpace.Contents.Notifications.heading && Math.random() > 0.8) {
|
||||
commit('TimelineSpace/Contents/Notifications/archiveNotifications', null, { root: true })
|
||||
}
|
||||
commit('TimelineSpace/SideMenu/changeUnreadNotifications', true, { root: true })
|
||||
})
|
||||
ipcRenderer.on('mention-start-user-streaming', (_, mention: NotificationType) => {
|
||||
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 }): Promise<{}> => {
|
||||
// @ts-ignore
|
||||
return new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars
|
||||
ipcRenderer.send('start-user-streaming', {
|
||||
account: state.account,
|
||||
useWebsocket: state.useWebsocket
|
||||
})
|
||||
ipcRenderer.once('error-start-user-streaming', (_, err: Error) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
bindLocalStreaming: ({ commit, rootState }) => {
|
||||
ipcRenderer.on('update-start-local-streaming', (_, update: Status) => {
|
||||
commit('TimelineSpace/Contents/Local/appendTimeline', update, { root: true })
|
||||
if (rootState.TimelineSpace.Contents.Local.heading && Math.random() > 0.8) {
|
||||
commit('TimelineSpace/Contents/Local/archiveTimeline', {}, { root: true })
|
||||
}
|
||||
commit('TimelineSpace/SideMenu/changeUnreadLocalTimeline', true, { root: true })
|
||||
})
|
||||
},
|
||||
startLocalStreaming: ({ state }) => {
|
||||
// @ts-ignore
|
||||
return new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars
|
||||
ipcRenderer.send('start-local-streaming', {
|
||||
account: state.account,
|
||||
useWebsocket: state.useWebsocket
|
||||
})
|
||||
ipcRenderer.once('error-start-local-streaming', (_, err: Error) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
bindPublicStreaming: ({ commit, rootState }) => {
|
||||
ipcRenderer.on('update-start-public-streaming', (_, update: Status) => {
|
||||
commit('TimelineSpace/Contents/Public/appendTimeline', update, { root: true })
|
||||
if (rootState.TimelineSpace.Contents.Public.heading && Math.random() > 0.8) {
|
||||
commit('TimelineSpace/Contents/Public/archiveTimeline', {}, { root: true })
|
||||
}
|
||||
commit('TimelineSpace/SideMenu/changeUnreadPublicTimeline', true, { root: true })
|
||||
})
|
||||
},
|
||||
startPublicStreaming: ({ state }) => {
|
||||
// @ts-ignore
|
||||
return new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars
|
||||
ipcRenderer.send('start-public-streaming', {
|
||||
account: state.account,
|
||||
useWebsocket: state.useWebsocket
|
||||
})
|
||||
ipcRenderer.once('error-start-public-streaming', (_, err: Error) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
bindDirectMessagesStreaming: ({ commit, rootState }) => {
|
||||
ipcRenderer.on('update-start-directmessages-streaming', (_, update: Status) => {
|
||||
commit('TimelineSpace/Contents/DirectMessages/appendTimeline', update, { root: true })
|
||||
if (rootState.TimelineSpace.Contents.DirectMessages.heading && Math.random() > 0.8) {
|
||||
commit('TimelineSpace/Contents/DirectMessages/archiveTimeline', {}, { root: true })
|
||||
}
|
||||
commit('TimelineSpace/SideMenu/changeUnreadDirectMessagesTimeline', true, { root: true })
|
||||
})
|
||||
},
|
||||
startDirectMessagesStreaming: ({ state }) => {
|
||||
// @ts-ignore
|
||||
return new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars
|
||||
ipcRenderer.send('start-directmessages-streaming', {
|
||||
account: state.account,
|
||||
useWebsocket: state.useWebsocket
|
||||
})
|
||||
ipcRenderer.once('error-start-directmessages-streaming', (_, err: Error) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
unbindUserStreaming: () => {
|
||||
ipcRenderer.removeAllListeners('update-start-user-streaming')
|
||||
ipcRenderer.removeAllListeners('notification-start-user-streaming')
|
||||
ipcRenderer.removeAllListeners('error-start-user-streaming')
|
||||
},
|
||||
stopUserStreaming: () => {
|
||||
ipcRenderer.send('stop-user-streaming')
|
||||
},
|
||||
unbindLocalStreaming: () => {
|
||||
ipcRenderer.removeAllListeners('error-start-local-streaming')
|
||||
ipcRenderer.removeAllListeners('update-start-local-streaming')
|
||||
},
|
||||
stopLocalStreaming: () => {
|
||||
ipcRenderer.send('stop-local-streaming')
|
||||
},
|
||||
unbindPublicStreaming: () => {
|
||||
ipcRenderer.removeAllListeners('error-start-public-streaming')
|
||||
ipcRenderer.removeAllListeners('update-start-public-streaming')
|
||||
},
|
||||
stopPublicStreaming: () => {
|
||||
ipcRenderer.send('stop-public-streaming')
|
||||
},
|
||||
unbindDirectMessagesStreaming: () => {
|
||||
ipcRenderer.removeAllListeners('error-start-directmessages-streaming')
|
||||
ipcRenderer.removeAllListeners('update-start-directmessages-streaming')
|
||||
},
|
||||
stopDirectMessagesStreaming: () => {
|
||||
ipcRenderer.send('stop-directmessages-streaming')
|
||||
}
|
||||
}
|
||||
|
||||
const TimelineSpace: Module<TimelineSpaceState, any> = {
|
||||
namespaced: true,
|
||||
modules: {
|
||||
SideMenu,
|
||||
HeaderMenu,
|
||||
Modals,
|
||||
Contents
|
||||
},
|
||||
state: state,
|
||||
mutations: mutations,
|
||||
actions: actions
|
||||
}
|
||||
|
||||
export default TimelineSpace
|
||||
|
||||
function createNotification (notification: NotificationType, notifyConfig: Notify) {
|
||||
switch (notification.type) {
|
||||
case 'favourite':
|
||||
if (notifyConfig.favourite) {
|
||||
return new Notification('Favourite', {
|
||||
body: `${username(notification.account)} favourited your status`
|
||||
})
|
||||
}
|
||||
break
|
||||
case 'follow':
|
||||
if (notifyConfig.follow) {
|
||||
return new Notification('Follow', {
|
||||
body: `${username(notification.account)} is now following you`
|
||||
})
|
||||
}
|
||||
break
|
||||
case 'mention':
|
||||
if (notifyConfig.reply) {
|
||||
// Clean html tags
|
||||
return new Notification(`${notification.status!.account.display_name}`, {
|
||||
body: sanitizeHtml(notification.status!.content, {
|
||||
allowedTags: [],
|
||||
allowedAttributes: []
|
||||
})
|
||||
})
|
||||
}
|
||||
break
|
||||
case 'reblog':
|
||||
if (notifyConfig.reblog) {
|
||||
return new Notification('Reblog', {
|
||||
body: `${username(notification.account)} boosted your status`
|
||||
})
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
function username (account: Account) {
|
||||
if (account.display_name !== '') {
|
||||
return account.display_name
|
||||
} else {
|
||||
return account.username
|
||||
}
|
||||
}
|
|
@ -59,10 +59,10 @@ const Notifications = {
|
|||
}
|
||||
},
|
||||
actions: {
|
||||
fetchNotifications ({ commit }, account) {
|
||||
fetchNotifications ({ commit, rootState }) {
|
||||
const client = new Mastodon(
|
||||
account.accessToken,
|
||||
account.baseURL + '/api/v1'
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
return client.get('/notifications', { limit: 30 })
|
||||
.then(res => {
|
||||
|
|
Loading…
Reference in New Issue