Fix megalodon class for 3.0.0 in renderer

This commit is contained in:
AkiraFukushima 2020-03-15 17:47:56 +09:00
parent 5ab9c28ead
commit 0200f69e1d
38 changed files with 625 additions and 604 deletions

View File

@ -1,7 +1,7 @@
export type VisibilityType = { export type VisibilityType = {
name: string name: string
value: number value: number
key: string key: 'public' | 'unlisted' | 'private' | 'direct'
} }
export type VisibilityList = { export type VisibilityList = {

View File

@ -1,4 +1,4 @@
import Mastodon, { Instance } from 'megalodon' import { detector } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
import { MyWindow } from '~/src/types/global' import { MyWindow } from '~/src/types/global'
@ -49,24 +49,8 @@ const actions: ActionTree<LoginState, RootState> = {
confirmInstance: async ({ commit, rootState }, domain: string): Promise<boolean> => { confirmInstance: async ({ commit, rootState }, domain: string): Promise<boolean> => {
commit(MUTATION_TYPES.CHANGE_SEARCHING, true) commit(MUTATION_TYPES.CHANGE_SEARCHING, true)
const cleanDomain = domain.trim() const cleanDomain = domain.trim()
try { await detector(`https://${cleanDomain}`, rootState.App.proxyConfiguration)
await Mastodon.get<Instance>('/api/v1/instance', {}, `https://${cleanDomain}`, rootState.App.proxyConfiguration) commit(MUTATION_TYPES.CHANGE_SEARCHING, false)
commit(MUTATION_TYPES.CHANGE_SEARCHING, false)
} catch (err) {
// https://gist.github.com/okapies/60d62d0df0163bbfb4ab09c1766558e8
// Check /.well-known/host-meta to confirm mastodon instance.
const res = await Mastodon.get<any>('/.well-known/host-meta', {}, `https://${cleanDomain}`, rootState.App.proxyConfiguration).finally(
() => {
commit(MUTATION_TYPES.CHANGE_SEARCHING, false)
}
)
const parser = new DOMParser()
const dom = parser.parseFromString(res.data, 'text/xml')
const link = dom.getElementsByTagName('Link')[0].outerHTML
if (!link.includes(`https://${cleanDomain}/.well-known/webfinger`)) {
throw new Error('domain is not activity pub')
}
}
commit(MUTATION_TYPES.CHANGE_INSTANCE, cleanDomain) commit(MUTATION_TYPES.CHANGE_INSTANCE, cleanDomain)
return true return true
} }

View File

@ -1,4 +1,4 @@
import Mastodon, { Account } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import Visibility, { VisibilityType } from '~/src/constants/visibility' import Visibility, { VisibilityType } from '~/src/constants/visibility'
import { RootState } from '@/store' import { RootState } from '@/store'
@ -28,14 +28,15 @@ const mutations: MutationTree<GeneralState> = {
} }
const actions: ActionTree<GeneralState, RootState> = { const actions: ActionTree<GeneralState, RootState> = {
fetchSettings: async ({ commit, rootState }): Promise<Account> => { fetchSettings: async ({ commit, rootState }): Promise<Entity.Account> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res = await client.get<Account>('/accounts/verify_credentials') const res = await client.verifyAccountCredentials()
const visibility: VisibilityType | undefined = (Object.values(Visibility) as Array<VisibilityType>).find(v => { const visibility: VisibilityType | undefined = (Object.values(Visibility) as Array<VisibilityType>).find(v => {
return v.key === res.data.source!.privacy return v.key === res.data.source!.privacy
}) })
@ -44,35 +45,29 @@ const actions: ActionTree<GeneralState, RootState> = {
return res.data return res.data
}, },
setVisibility: async ({ commit, rootState }, value: number) => { setVisibility: async ({ commit, rootState }, value: number) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const visibility: VisibilityType | undefined = (Object.values(Visibility) as Array<VisibilityType>).find(v => { const visibility: VisibilityType | undefined = (Object.values(Visibility) as Array<VisibilityType>).find(v => {
return v.value === value return v.value === value
}) })
const res = await client.patch<Account>('/accounts/update_credentials', { const res = await client.updateCredentials({ source: { privacy: visibility!.key } })
source: {
privacy: visibility!.key
}
})
commit(MUTATION_TYPES.CHANGE_VISIBILITY, visibility!.value) commit(MUTATION_TYPES.CHANGE_VISIBILITY, visibility!.value)
return res.data return res.data
}, },
setSensitive: async ({ commit, rootState }, value: boolean) => { setSensitive: async ({ commit, rootState }, value: boolean) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res = await client.patch<Account>('/accounts/update_credentials', { const res = await client.updateCredentials({ source: { sensitive: value } })
source: {
sensitive: value
}
})
commit(MUTATION_TYPES.CHANGE_SENSITIVE, value) commit(MUTATION_TYPES.CHANGE_SENSITIVE, value)
return res.data return res.data
} }

View File

@ -1,4 +1,4 @@
import Mastodon, { Account, Emoji, Instance, Status, Notification as NotificationType } from 'megalodon' import generator, { detector, Entity } from 'megalodon'
import SideMenu, { SideMenuState } from './TimelineSpace/SideMenu' import SideMenu, { SideMenuState } from './TimelineSpace/SideMenu'
import HeaderMenu, { HeaderMenuState } from './TimelineSpace/HeaderMenu' import HeaderMenu, { HeaderMenuState } from './TimelineSpace/HeaderMenu'
import Modals, { ModalsModuleState } from './TimelineSpace/Modals' import Modals, { ModalsModuleState } from './TimelineSpace/Modals'
@ -18,10 +18,10 @@ export type TimelineSpaceState = {
account: LocalAccount account: LocalAccount
bindingAccount: LocalAccount | null bindingAccount: LocalAccount | null
loading: boolean loading: boolean
emojis: Array<Emoji> emojis: Array<Entity.Emoji>
tootMax: number tootMax: number
unreadNotification: UnreadNotification unreadNotification: UnreadNotification
pleroma: boolean sns: 'mastodon' | 'pleroma' | 'misskey'
} }
export const blankAccount: LocalAccount = { export const blankAccount: LocalAccount = {
@ -49,7 +49,7 @@ const state = (): TimelineSpaceState => ({
local: unreadSettings.Local.default, local: unreadSettings.Local.default,
public: unreadSettings.Public.default public: unreadSettings.Public.default
}, },
pleroma: false sns: 'mastodon'
}) })
export const MUTATION_TYPES = { export const MUTATION_TYPES = {
@ -59,7 +59,7 @@ export const MUTATION_TYPES = {
UPDATE_EMOJIS: 'updateEmojis', UPDATE_EMOJIS: 'updateEmojis',
UPDATE_TOOT_MAX: 'updateTootMax', UPDATE_TOOT_MAX: 'updateTootMax',
UPDATE_UNREAD_NOTIFICATION: 'updateUnreadNotification', UPDATE_UNREAD_NOTIFICATION: 'updateUnreadNotification',
CHANGE_PLEROMA: 'changePleroma' CHANGE_SNS: 'changeSNS'
} }
const mutations: MutationTree<TimelineSpaceState> = { const mutations: MutationTree<TimelineSpaceState> = {
@ -72,7 +72,7 @@ const mutations: MutationTree<TimelineSpaceState> = {
[MUTATION_TYPES.CHANGE_LOADING]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_LOADING]: (state, value: boolean) => {
state.loading = value state.loading = value
}, },
[MUTATION_TYPES.UPDATE_EMOJIS]: (state, emojis: Array<Emoji>) => { [MUTATION_TYPES.UPDATE_EMOJIS]: (state, emojis: Array<Entity.Emoji>) => {
state.emojis = emojis state.emojis = emojis
}, },
[MUTATION_TYPES.UPDATE_TOOT_MAX]: (state, value: number | null) => { [MUTATION_TYPES.UPDATE_TOOT_MAX]: (state, value: number | null) => {
@ -85,8 +85,8 @@ const mutations: MutationTree<TimelineSpaceState> = {
[MUTATION_TYPES.UPDATE_UNREAD_NOTIFICATION]: (state, settings: UnreadNotification) => { [MUTATION_TYPES.UPDATE_UNREAD_NOTIFICATION]: (state, settings: UnreadNotification) => {
state.unreadNotification = settings state.unreadNotification = settings
}, },
[MUTATION_TYPES.CHANGE_PLEROMA]: (state, pleroma: boolean) => { [MUTATION_TYPES.CHANGE_SNS]: (state, sns: 'mastodon' | 'pleroma' | 'misskey') => {
state.pleroma = pleroma state.sns = sns
} }
} }
@ -99,7 +99,7 @@ const actions: ActionTree<TimelineSpaceState, RootState> = {
throw new AccountLoadError() throw new AccountLoadError()
}) })
await dispatch('detectPleroma') await dispatch('detectSNS')
dispatch('TimelineSpace/SideMenu/fetchLists', account, { root: true }) dispatch('TimelineSpace/SideMenu/fetchLists', account, { root: true })
dispatch('TimelineSpace/SideMenu/fetchFollowRequests', account, { root: true }) dispatch('TimelineSpace/SideMenu/fetchFollowRequests', account, { root: true })
await dispatch('loadUnreadNotification', accountId) await dispatch('loadUnreadNotification', accountId)
@ -163,13 +163,9 @@ const actions: ActionTree<TimelineSpaceState, RootState> = {
commit(MUTATION_TYPES.UPDATE_ACCOUNT, blankAccount) commit(MUTATION_TYPES.UPDATE_ACCOUNT, blankAccount)
return true return true
}, },
detectPleroma: async ({ commit, state, rootState }) => { detectSNS: async ({ commit, state, rootState }) => {
const res = await Mastodon.get<Instance>('/instance', {}, state.account.baseURL + '/api/v1', rootState.App.proxyConfiguration) const sns = await detector(state.account.baseURL, rootState.App.proxyConfiguration)
if (res.data.version.includes('Pleroma')) { commit(MUTATION_TYPES.CHANGE_SNS, sns)
commit(MUTATION_TYPES.CHANGE_PLEROMA, true)
} else {
commit(MUTATION_TYPES.CHANGE_PLEROMA, false)
}
}, },
// ----------------------------------------------- // -----------------------------------------------
// Shortcuts // Shortcuts
@ -196,16 +192,18 @@ const actions: ActionTree<TimelineSpaceState, RootState> = {
/** /**
* fetchEmojis * fetchEmojis
*/ */
fetchEmojis: async ({ commit, rootState }, account: LocalAccount): Promise<Array<Emoji>> => { fetchEmojis: async ({ commit, state, rootState }, account: LocalAccount): Promise<Array<Entity.Emoji>> => {
const res = await Mastodon.get<Array<Emoji>>('/custom_emojis', {}, account.baseURL + '/api/v1', rootState.App.proxyConfiguration) const client = generator(state.sns, account.baseURL, null, 'Whalebird', rootState.App.proxyConfiguration)
const res = await client.getInstanceCustomEmojis()
commit(MUTATION_TYPES.UPDATE_EMOJIS, res.data) commit(MUTATION_TYPES.UPDATE_EMOJIS, res.data)
return res.data return res.data
}, },
/** /**
* fetchInstance * fetchInstance
*/ */
fetchInstance: async ({ commit, rootState }, account: LocalAccount) => { fetchInstance: async ({ commit, state, rootState }, account: LocalAccount) => {
const res = await Mastodon.get<Instance>('/instance', {}, account.baseURL + '/api/v1', rootState.App.proxyConfiguration) const client = generator(state.sns, account.baseURL, null, 'Whalebird', rootState.App.proxyConfiguration)
const res = await client.getInstance()
commit(MUTATION_TYPES.UPDATE_TOOT_MAX, res.data.max_toot_chars) commit(MUTATION_TYPES.UPDATE_TOOT_MAX, res.data.max_toot_chars)
return true return true
}, },
@ -299,7 +297,7 @@ const actions: ActionTree<TimelineSpaceState, RootState> = {
await dispatch('waitToUnbindUserStreaming') await dispatch('waitToUnbindUserStreaming')
commit(MUTATION_TYPES.UPDATE_BINDING_ACCOUNT, state.account) commit(MUTATION_TYPES.UPDATE_BINDING_ACCOUNT, state.account)
win.ipcRenderer.on(`update-start-all-user-streamings-${state.account._id!}`, (_, update: Status) => { win.ipcRenderer.on(`update-start-all-user-streamings-${state.account._id!}`, (_, update: Entity.Status) => {
commit('TimelineSpace/Contents/Home/appendTimeline', update, { root: true }) commit('TimelineSpace/Contents/Home/appendTimeline', update, { root: true })
// Sometimes archive old statuses // Sometimes archive old statuses
if (rootState.TimelineSpace.Contents.Home.heading && Math.random() > 0.8) { if (rootState.TimelineSpace.Contents.Home.heading && Math.random() > 0.8) {
@ -307,14 +305,14 @@ const actions: ActionTree<TimelineSpaceState, RootState> = {
} }
commit('TimelineSpace/SideMenu/changeUnreadHomeTimeline', true, { root: true }) commit('TimelineSpace/SideMenu/changeUnreadHomeTimeline', true, { root: true })
}) })
win.ipcRenderer.on(`notification-start-all-user-streamings-${state.account._id!}`, (_, notification: NotificationType) => { win.ipcRenderer.on(`notification-start-all-user-streamings-${state.account._id!}`, (_, notification: Entity.Notification) => {
commit('TimelineSpace/Contents/Notifications/appendNotifications', notification, { root: true }) commit('TimelineSpace/Contents/Notifications/appendNotifications', notification, { root: true })
if (rootState.TimelineSpace.Contents.Notifications.heading && Math.random() > 0.8) { if (rootState.TimelineSpace.Contents.Notifications.heading && Math.random() > 0.8) {
commit('TimelineSpace/Contents/Notifications/archiveNotifications', null, { root: true }) commit('TimelineSpace/Contents/Notifications/archiveNotifications', null, { root: true })
} }
commit('TimelineSpace/SideMenu/changeUnreadNotifications', true, { root: true }) commit('TimelineSpace/SideMenu/changeUnreadNotifications', true, { root: true })
}) })
win.ipcRenderer.on(`mention-start-all-user-streamings-${state.account._id!}`, (_, mention: NotificationType) => { win.ipcRenderer.on(`mention-start-all-user-streamings-${state.account._id!}`, (_, mention: Entity.Notification) => {
commit('TimelineSpace/Contents/Mentions/appendMentions', mention, { root: true }) commit('TimelineSpace/Contents/Mentions/appendMentions', mention, { root: true })
if (rootState.TimelineSpace.Contents.Mentions.heading && Math.random() > 0.8) { if (rootState.TimelineSpace.Contents.Mentions.heading && Math.random() > 0.8) {
commit('TimelineSpace/Contents/Mentions/archiveMentions', null, { root: true }) commit('TimelineSpace/Contents/Mentions/archiveMentions', null, { root: true })
@ -328,7 +326,7 @@ const actions: ActionTree<TimelineSpaceState, RootState> = {
}) })
}, },
bindLocalStreaming: ({ commit, rootState }) => { bindLocalStreaming: ({ commit, rootState }) => {
win.ipcRenderer.on('update-start-local-streaming', (_, update: Status) => { win.ipcRenderer.on('update-start-local-streaming', (_, update: Entity.Status) => {
commit('TimelineSpace/Contents/Local/appendTimeline', update, { root: true }) commit('TimelineSpace/Contents/Local/appendTimeline', update, { root: true })
if (rootState.TimelineSpace.Contents.Local.heading && Math.random() > 0.8) { if (rootState.TimelineSpace.Contents.Local.heading && Math.random() > 0.8) {
commit('TimelineSpace/Contents/Local/archiveTimeline', {}, { root: true }) commit('TimelineSpace/Contents/Local/archiveTimeline', {}, { root: true })
@ -352,7 +350,7 @@ const actions: ActionTree<TimelineSpaceState, RootState> = {
}) })
}, },
bindPublicStreaming: ({ commit, rootState }) => { bindPublicStreaming: ({ commit, rootState }) => {
win.ipcRenderer.on('update-start-public-streaming', (_, update: Status) => { win.ipcRenderer.on('update-start-public-streaming', (_, update: Entity.Status) => {
commit('TimelineSpace/Contents/Public/appendTimeline', update, { root: true }) commit('TimelineSpace/Contents/Public/appendTimeline', update, { root: true })
if (rootState.TimelineSpace.Contents.Public.heading && Math.random() > 0.8) { if (rootState.TimelineSpace.Contents.Public.heading && Math.random() > 0.8) {
commit('TimelineSpace/Contents/Public/archiveTimeline', {}, { root: true }) commit('TimelineSpace/Contents/Public/archiveTimeline', {}, { root: true })
@ -376,7 +374,7 @@ const actions: ActionTree<TimelineSpaceState, RootState> = {
}) })
}, },
bindDirectMessagesStreaming: ({ commit, rootState }) => { bindDirectMessagesStreaming: ({ commit, rootState }) => {
win.ipcRenderer.on('update-start-directmessages-streaming', (_, update: Status) => { win.ipcRenderer.on('update-start-directmessages-streaming', (_, update: Entity.Status) => {
commit('TimelineSpace/Contents/DirectMessages/appendTimeline', update, { root: true }) commit('TimelineSpace/Contents/DirectMessages/appendTimeline', update, { root: true })
if (rootState.TimelineSpace.Contents.DirectMessages.heading && Math.random() > 0.8) { if (rootState.TimelineSpace.Contents.DirectMessages.heading && Math.random() > 0.8) {
commit('TimelineSpace/Contents/DirectMessages/archiveTimeline', {}, { root: true }) commit('TimelineSpace/Contents/DirectMessages/archiveTimeline', {}, { root: true })
@ -437,7 +435,7 @@ const actions: ActionTree<TimelineSpaceState, RootState> = {
stopDirectMessagesStreaming: () => { stopDirectMessagesStreaming: () => {
win.ipcRenderer.send('stop-directmessages-streaming') win.ipcRenderer.send('stop-directmessages-streaming')
}, },
updateTootForAllTimelines: ({ commit, state }, status: Status): boolean => { updateTootForAllTimelines: ({ commit, state }, status: Entity.Status): boolean => {
commit('TimelineSpace/Contents/Home/updateToot', status, { root: true }) commit('TimelineSpace/Contents/Home/updateToot', status, { root: true })
commit('TimelineSpace/Contents/Notifications/updateToot', status, { root: true }) commit('TimelineSpace/Contents/Notifications/updateToot', status, { root: true })
commit('TimelineSpace/Contents/Mentions/updateToot', status, { root: true }) commit('TimelineSpace/Contents/Mentions/updateToot', status, { root: true })

View File

@ -1,12 +1,12 @@
import Mastodon, { Status, Response, Conversation } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
export type DirectMessagesState = { export type DirectMessagesState = {
lazyLoading: boolean lazyLoading: boolean
heading: boolean heading: boolean
timeline: Array<Status> timeline: Array<Entity.Status>
unreadTimeline: Array<Status> unreadTimeline: Array<Entity.Status>
filter: string filter: string
} }
@ -39,7 +39,7 @@ const mutations: MutationTree<DirectMessagesState> = {
[MUTATION_TYPES.CHANGE_HEADING]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_HEADING]: (state, value: boolean) => {
state.heading = value state.heading = value
}, },
[MUTATION_TYPES.APPEND_TIMELINE]: (state, update: Status) => { [MUTATION_TYPES.APPEND_TIMELINE]: (state, update: Entity.Status) => {
// Reject duplicated status in timeline // Reject duplicated status in timeline
if (!state.timeline.find(item => item.id === update.id) && !state.unreadTimeline.find(item => item.id === update.id)) { if (!state.timeline.find(item => item.id === update.id) && !state.unreadTimeline.find(item => item.id === update.id)) {
if (state.heading) { if (state.heading) {
@ -49,14 +49,14 @@ const mutations: MutationTree<DirectMessagesState> = {
} }
} }
}, },
[MUTATION_TYPES.UPDATE_TIMELINE]: (state, messages: Array<Status>) => { [MUTATION_TYPES.UPDATE_TIMELINE]: (state, messages: Array<Entity.Status>) => {
state.timeline = messages state.timeline = messages
}, },
[MUTATION_TYPES.MERGE_TIMELINE]: state => { [MUTATION_TYPES.MERGE_TIMELINE]: state => {
state.timeline = state.unreadTimeline.slice(0, 80).concat(state.timeline) state.timeline = state.unreadTimeline.slice(0, 80).concat(state.timeline)
state.unreadTimeline = [] state.unreadTimeline = []
}, },
[MUTATION_TYPES.INSERT_TIMELINE]: (state, messages: Array<Status>) => { [MUTATION_TYPES.INSERT_TIMELINE]: (state, messages: Array<Entity.Status>) => {
state.timeline = state.timeline.concat(messages) state.timeline = state.timeline.concat(messages)
}, },
[MUTATION_TYPES.ARCHIVE_TIMELINE]: state => { [MUTATION_TYPES.ARCHIVE_TIMELINE]: state => {
@ -66,7 +66,7 @@ const mutations: MutationTree<DirectMessagesState> = {
state.timeline = [] state.timeline = []
state.unreadTimeline = [] state.unreadTimeline = []
}, },
[MUTATION_TYPES.UPDATE_TOOT]: (state, message: Status) => { [MUTATION_TYPES.UPDATE_TOOT]: (state, message: Entity.Status) => {
// Replace target message in DirectMessagesTimeline and notifications // Replace target message in DirectMessagesTimeline and notifications
state.timeline = state.timeline.map(toot => { state.timeline = state.timeline.map(toot => {
if (toot.id === message.id) { if (toot.id === message.id) {
@ -98,33 +98,35 @@ const mutations: MutationTree<DirectMessagesState> = {
} }
const actions: ActionTree<DirectMessagesState, RootState> = { const actions: ActionTree<DirectMessagesState, RootState> = {
fetchTimeline: async ({ commit, rootState }): Promise<Array<Status>> => { fetchTimeline: async ({ commit, rootState }): Promise<Array<Entity.Status>> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<Conversation>> = await client.get<Array<Conversation>>('/conversations', { limit: 40 }) const res = await client.getConversationTimeline({ limit: 40 })
const statuses: Array<Status> = res.data.map(con => con.last_status!) const statuses: Array<Entity.Status> = res.data.map(con => con.last_status!)
commit(MUTATION_TYPES.UPDATE_TIMELINE, statuses) commit(MUTATION_TYPES.UPDATE_TIMELINE, statuses)
return statuses return statuses
}, },
lazyFetchTimeline: ({ state, commit, rootState }, lastStatus: Status): Promise<Array<Status> | null> => { lazyFetchTimeline: ({ state, commit, rootState }, lastStatus: Entity.Status): Promise<Array<Entity.Status> | null> => {
if (state.lazyLoading) { if (state.lazyLoading) {
return Promise.resolve(null) return Promise.resolve(null)
} }
commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true) commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true)
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
return client return client
.get<Array<Conversation>>('/conversations', { max_id: lastStatus.id, limit: 40 }) .getConversationTimeline({ max_id: lastStatus.id, limit: 40 })
.then(res => { .then(res => {
const statuses: Array<Status> = res.data.map(con => con.last_status!) const statuses: Array<Entity.Status> = res.data.map(con => con.last_status!)
commit(MUTATION_TYPES.INSERT_TIMELINE, statuses) commit(MUTATION_TYPES.INSERT_TIMELINE, statuses)
return statuses return statuses
}) })

View File

@ -1,11 +1,11 @@
import Mastodon, { Status, Response } from 'megalodon' import generator, { Entity } from 'megalodon'
import parse from 'parse-link-header' import parse from 'parse-link-header'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
import { LocalAccount } from '~/src/types/localAccount' import { LocalAccount } from '~/src/types/localAccount'
export type FavouritesState = { export type FavouritesState = {
favourites: Array<Status> favourites: Array<Entity.Status>
lazyLoading: boolean lazyLoading: boolean
filter: string filter: string
maxId: string | null maxId: string | null
@ -29,13 +29,13 @@ export const MUTATION_TYPES = {
} }
const mutations: MutationTree<FavouritesState> = { const mutations: MutationTree<FavouritesState> = {
[MUTATION_TYPES.UPDATE_FAVOURITES]: (state, favourites: Array<Status>) => { [MUTATION_TYPES.UPDATE_FAVOURITES]: (state, favourites: Array<Entity.Status>) => {
state.favourites = favourites state.favourites = favourites
}, },
[MUTATION_TYPES.INSERT_FAVOURITES]: (state, favourites: Array<Status>) => { [MUTATION_TYPES.INSERT_FAVOURITES]: (state, favourites: Array<Entity.Status>) => {
state.favourites = state.favourites.concat(favourites) state.favourites = state.favourites.concat(favourites)
}, },
[MUTATION_TYPES.UPDATE_TOOT]: (state, message: Status) => { [MUTATION_TYPES.UPDATE_TOOT]: (state, message: Entity.Status) => {
state.favourites = state.favourites.map(toot => { state.favourites = state.favourites.map(toot => {
if (toot.id === message.id) { if (toot.id === message.id) {
return message return message
@ -51,7 +51,7 @@ const mutations: MutationTree<FavouritesState> = {
} }
}) })
}, },
[MUTATION_TYPES.DELETE_TOOT]: (state, message: Status) => { [MUTATION_TYPES.DELETE_TOOT]: (state, message: Entity.Status) => {
state.favourites = state.favourites.filter(toot => { state.favourites = state.favourites.filter(toot => {
if (toot.reblog !== null && toot.reblog.id === message.id) { if (toot.reblog !== null && toot.reblog.id === message.id) {
return false return false
@ -72,14 +72,15 @@ const mutations: MutationTree<FavouritesState> = {
} }
const actions: ActionTree<FavouritesState, RootState> = { const actions: ActionTree<FavouritesState, RootState> = {
fetchFavourites: async ({ commit, rootState }, account: LocalAccount): Promise<Array<Status>> => { fetchFavourites: async ({ commit, rootState }, account: LocalAccount): Promise<Array<Entity.Status>> => {
const client = new Mastodon( const client = generator(
account.accessToken!, rootState.TimelineSpace.sns,
account.baseURL + '/api/v1', account.baseURL,
account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<Status>> = await client.get<Array<Status>>('/favourites', { limit: 40 }) const res = await client.getFavourites({ limit: 40 })
commit(MUTATION_TYPES.UPDATE_FAVOURITES, res.data) commit(MUTATION_TYPES.UPDATE_FAVOURITES, res.data)
// Parse link header // Parse link header
try { try {
@ -95,7 +96,7 @@ const actions: ActionTree<FavouritesState, RootState> = {
} }
return res.data return res.data
}, },
lazyFetchFavourites: async ({ state, commit, rootState }): Promise<Array<Status> | null> => { lazyFetchFavourites: async ({ state, commit, rootState }): Promise<Array<Entity.Status> | null> => {
if (state.lazyLoading) { if (state.lazyLoading) {
return Promise.resolve(null) return Promise.resolve(null)
} }
@ -103,13 +104,14 @@ const actions: ActionTree<FavouritesState, RootState> = {
return Promise.resolve(null) return Promise.resolve(null)
} }
commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true) commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true)
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<Status>> = await client.get<Array<Status>>('/favourites', { max_id: state.maxId, limit: 40 }).finally(() => { const res = await client.getFavourites({ max_id: state.maxId, limit: 40 }).finally(() => {
commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, false) commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, false)
}) })
commit(MUTATION_TYPES.INSERT_FAVOURITES, res.data) commit(MUTATION_TYPES.INSERT_FAVOURITES, res.data)

View File

@ -1,9 +1,9 @@
import Mastodon, { Account, Response } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
export type FollowRequestsState = { export type FollowRequestsState = {
requests: Array<Account> requests: Array<Entity.Account>
} }
const state = (): FollowRequestsState => ({ const state = (): FollowRequestsState => ({
@ -15,43 +15,46 @@ export const MUTATION_TYPES = {
} }
const mutations: MutationTree<FollowRequestsState> = { const mutations: MutationTree<FollowRequestsState> = {
[MUTATION_TYPES.UPDATE_REQUESTS]: (state, accounts: Array<Account>) => { [MUTATION_TYPES.UPDATE_REQUESTS]: (state, accounts: Array<Entity.Account>) => {
state.requests = accounts state.requests = accounts
} }
} }
const actions: ActionTree<FollowRequestsState, RootState> = { const actions: ActionTree<FollowRequestsState, RootState> = {
fetchRequests: async ({ commit, rootState }): Promise<Array<Account>> => { fetchRequests: async ({ commit, rootState }): Promise<Array<Entity.Account>> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<Account>> = await client.get<Array<Account>>('/follow_requests') const res = await client.getFollowRequests()
commit(MUTATION_TYPES.UPDATE_REQUESTS, res.data) commit(MUTATION_TYPES.UPDATE_REQUESTS, res.data)
return res.data return res.data
}, },
acceptRequest: async ({ dispatch, rootState }, user: Account) => { acceptRequest: async ({ dispatch, rootState }, user: Entity.Account) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<{}> = await client.post<{}>(`/follow_requests/${user.id}/authorize`) const res = await client.acceptFollowRequest(user.id)
await dispatch('fetchRequests') await dispatch('fetchRequests')
dispatch('TimelineSpace/SideMenu/fetchFollowRequests', rootState.TimelineSpace.account, { root: true }) dispatch('TimelineSpace/SideMenu/fetchFollowRequests', rootState.TimelineSpace.account, { root: true })
return res.data return res.data
}, },
rejectRequest: async ({ dispatch, rootState }, user: Account) => { rejectRequest: async ({ dispatch, rootState }, user: Entity.Account) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<{}> = await client.post<{}>(`/follow_requests/${user.id}/reject`) const res = await client.rejectFollowRequest(user.id)
await dispatch('fetchRequests') await dispatch('fetchRequests')
dispatch('TimelineSpace/SideMenu/fetchFollowRequests', rootState.TimelineSpace.account, { root: true }) dispatch('TimelineSpace/SideMenu/fetchFollowRequests', rootState.TimelineSpace.account, { root: true })
return res.data return res.data

View File

@ -1,4 +1,4 @@
import Mastodon, { Status, Response } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
import { LoadPositionWithTag } from '@/types/loadPosition' import { LoadPositionWithTag } from '@/types/loadPosition'
@ -7,8 +7,8 @@ import { MyWindow } from '~/src/types/global'
const win = window as MyWindow const win = window as MyWindow
export type TagState = { export type TagState = {
timeline: Array<Status> timeline: Array<Entity.Status>
unreadTimeline: Array<Status> unreadTimeline: Array<Entity.Status>
lazyLoading: boolean lazyLoading: boolean
heading: boolean heading: boolean
filter: string filter: string
@ -40,7 +40,7 @@ const mutations: MutationTree<TagState> = {
[MUTATION_TYPES.CHANGE_HEADING]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_HEADING]: (state, value: boolean) => {
state.heading = value state.heading = value
}, },
[MUTATION_TYPES.APPEND_TIMELINE]: (state, update: Status) => { [MUTATION_TYPES.APPEND_TIMELINE]: (state, update: Entity.Status) => {
// Reject duplicated status in timeline // Reject duplicated status in timeline
if (!state.timeline.find(item => item.id === update.id) && !state.unreadTimeline.find(item => item.id === update.id)) { if (!state.timeline.find(item => item.id === update.id) && !state.unreadTimeline.find(item => item.id === update.id)) {
if (state.heading) { if (state.heading) {
@ -50,14 +50,14 @@ const mutations: MutationTree<TagState> = {
} }
} }
}, },
[MUTATION_TYPES.UPDATE_TIMELINE]: (state, timeline: Array<Status>) => { [MUTATION_TYPES.UPDATE_TIMELINE]: (state, timeline: Array<Entity.Status>) => {
state.timeline = timeline state.timeline = timeline
}, },
[MUTATION_TYPES.MERGE_TIMELINE]: state => { [MUTATION_TYPES.MERGE_TIMELINE]: state => {
state.timeline = state.unreadTimeline.slice(0, 80).concat(state.timeline) state.timeline = state.unreadTimeline.slice(0, 80).concat(state.timeline)
state.unreadTimeline = [] state.unreadTimeline = []
}, },
[MUTATION_TYPES.INSERT_TIMELINE]: (state, messages: Array<Status>) => { [MUTATION_TYPES.INSERT_TIMELINE]: (state, messages: Array<Entity.Status>) => {
state.timeline = state.timeline.concat(messages) state.timeline = state.timeline.concat(messages)
}, },
[MUTATION_TYPES.ARCHIVE_TIMELINE]: state => { [MUTATION_TYPES.ARCHIVE_TIMELINE]: state => {
@ -67,7 +67,7 @@ const mutations: MutationTree<TagState> = {
state.timeline = [] state.timeline = []
state.unreadTimeline = [] state.unreadTimeline = []
}, },
[MUTATION_TYPES.UPDATE_TOOT]: (state, message: Status) => { [MUTATION_TYPES.UPDATE_TOOT]: (state, message: Entity.Status) => {
state.timeline = state.timeline.map(toot => { state.timeline = state.timeline.map(toot => {
if (toot.id === message.id) { if (toot.id === message.id) {
return message return message
@ -101,19 +101,20 @@ const mutations: MutationTree<TagState> = {
} }
const actions: ActionTree<TagState, RootState> = { const actions: ActionTree<TagState, RootState> = {
fetch: async ({ commit, rootState }, tag: string): Promise<Array<Status>> => { fetch: async ({ commit, rootState }, tag: string): Promise<Array<Entity.Status>> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<Status>> = await client.get<Array<Status>>(`/timelines/tag/${encodeURIComponent(tag)}`, { limit: 40 }) const res = await client.getTagTimeline(encodeURIComponent(tag), { limit: 40 })
commit(MUTATION_TYPES.UPDATE_TIMELINE, res.data) commit(MUTATION_TYPES.UPDATE_TIMELINE, res.data)
return res.data return res.data
}, },
startStreaming: ({ state, commit, rootState }, tag: string) => { startStreaming: ({ state, commit, rootState }, tag: string) => {
win.ipcRenderer.on('update-start-tag-streaming', (_, update: Status) => { win.ipcRenderer.on('update-start-tag-streaming', (_, update: Entity.Status) => {
commit(MUTATION_TYPES.APPEND_TIMELINE, update) commit(MUTATION_TYPES.APPEND_TIMELINE, update)
if (state.heading && Math.random() > 0.8) { if (state.heading && Math.random() > 0.8) {
commit(MUTATION_TYPES.ARCHIVE_TIMELINE) commit(MUTATION_TYPES.ARCHIVE_TIMELINE)
@ -148,14 +149,15 @@ const actions: ActionTree<TagState, RootState> = {
return Promise.resolve(null) return Promise.resolve(null)
} }
commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true) commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true)
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
return client return client
.get<Array<Status>>(`/timelines/tag/${loadPosition.tag}`, { max_id: loadPosition.status.id, limit: 40 }) .getTagTimeline(loadPosition.tag, { max_id: loadPosition.status.id, limit: 40 })
.then(res => { .then(res => {
commit(MUTATION_TYPES.INSERT_TIMELINE, res.data) commit(MUTATION_TYPES.INSERT_TIMELINE, res.data)
return res.data return res.data

View File

@ -1,4 +1,4 @@
import Mastodon, { Status, Response } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
@ -7,8 +7,8 @@ export type HomeState = {
heading: boolean heading: boolean
showReblogs: boolean showReblogs: boolean
showReplies: boolean showReplies: boolean
timeline: Array<Status> timeline: Array<Entity.Status>
unreadTimeline: Array<Status> unreadTimeline: Array<Entity.Status>
filter: string filter: string
} }
@ -45,7 +45,7 @@ const mutations: MutationTree<HomeState> = {
[MUTATION_TYPES.CHANGE_HEADING]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_HEADING]: (state, value: boolean) => {
state.heading = value state.heading = value
}, },
[MUTATION_TYPES.APPEND_TIMELINE]: (state, update: Status) => { [MUTATION_TYPES.APPEND_TIMELINE]: (state, update: Entity.Status) => {
// Reject duplicated status in timeline // Reject duplicated status in timeline
if (!state.timeline.find(item => item.id === update.id) && !state.unreadTimeline.find(item => item.id === update.id)) { if (!state.timeline.find(item => item.id === update.id) && !state.unreadTimeline.find(item => item.id === update.id)) {
if (state.heading) { if (state.heading) {
@ -55,14 +55,14 @@ const mutations: MutationTree<HomeState> = {
} }
} }
}, },
[MUTATION_TYPES.UPDATE_TIMELINE]: (state, messages: Array<Status>) => { [MUTATION_TYPES.UPDATE_TIMELINE]: (state, messages: Array<Entity.Status>) => {
state.timeline = messages state.timeline = messages
}, },
[MUTATION_TYPES.MERGE_TIMELINE]: state => { [MUTATION_TYPES.MERGE_TIMELINE]: state => {
state.timeline = state.unreadTimeline.slice(0, 80).concat(state.timeline) state.timeline = state.unreadTimeline.slice(0, 80).concat(state.timeline)
state.unreadTimeline = [] state.unreadTimeline = []
}, },
[MUTATION_TYPES.INSERT_TIMELINE]: (state, messages: Array<Status>) => { [MUTATION_TYPES.INSERT_TIMELINE]: (state, messages: Array<Entity.Status>) => {
state.timeline = state.timeline.concat(messages) state.timeline = state.timeline.concat(messages)
}, },
[MUTATION_TYPES.ARCHIVE_TIMELINE]: state => { [MUTATION_TYPES.ARCHIVE_TIMELINE]: state => {
@ -72,7 +72,7 @@ const mutations: MutationTree<HomeState> = {
state.timeline = [] state.timeline = []
state.unreadTimeline = [] state.unreadTimeline = []
}, },
[MUTATION_TYPES.UPDATE_TOOT]: (state, message: Status) => { [MUTATION_TYPES.UPDATE_TOOT]: (state, message: Entity.Status) => {
// Replace target message in homeTimeline and notifications // Replace target message in homeTimeline and notifications
state.timeline = state.timeline.map(toot => { state.timeline = state.timeline.map(toot => {
if (toot.id === message.id) { if (toot.id === message.id) {
@ -111,29 +111,31 @@ const mutations: MutationTree<HomeState> = {
const actions: ActionTree<HomeState, RootState> = { const actions: ActionTree<HomeState, RootState> = {
fetchTimeline: async ({ commit, rootState }) => { fetchTimeline: async ({ commit, rootState }) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<Status>> = await client.get<Array<Status>>('/timelines/home', { limit: 40 }) const res = await client.getHomeTimeline({ limit: 40 })
commit(MUTATION_TYPES.UPDATE_TIMELINE, res.data) commit(MUTATION_TYPES.UPDATE_TIMELINE, res.data)
return res.data return res.data
}, },
lazyFetchTimeline: async ({ state, commit, rootState }, lastStatus: Status): Promise<Array<Status> | null> => { lazyFetchTimeline: async ({ state, commit, rootState }, lastStatus: Entity.Status): Promise<Array<Entity.Status> | null> => {
if (state.lazyLoading) { if (state.lazyLoading) {
return Promise.resolve(null) return Promise.resolve(null)
} }
commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true) commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true)
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
return client return client
.get<Array<Status>>('/timelines/home', { max_id: lastStatus.id, limit: 40 }) .getHomeTimeline({ max_id: lastStatus.id, limit: 40 })
.then(res => { .then(res => {
commit(MUTATION_TYPES.INSERT_TIMELINE, res.data) commit(MUTATION_TYPES.INSERT_TIMELINE, res.data)
return res.data return res.data

View File

@ -1,10 +1,10 @@
import Mastodon, { Account, Response } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
import { RemoveAccountFromList } from '@/types/removeAccountFromList' import { RemoveAccountFromList } from '@/types/removeAccountFromList'
export type EditState = { export type EditState = {
members: Array<Account> members: Array<Entity.Account>
} }
const state = (): EditState => ({ const state = (): EditState => ({
@ -16,35 +16,33 @@ export const MUTATION_TYPES = {
} }
const mutations: MutationTree<EditState> = { const mutations: MutationTree<EditState> = {
[MUTATION_TYPES.CHANGE_MEMBERS]: (state, members: Array<Account>) => { [MUTATION_TYPES.CHANGE_MEMBERS]: (state, members: Array<Entity.Account>) => {
state.members = members state.members = members
} }
} }
const actions: ActionTree<EditState, RootState> = { const actions: ActionTree<EditState, RootState> = {
fetchMembers: async ({ commit, rootState }, listId: string): Promise<Array<Account>> => { fetchMembers: async ({ commit, rootState }, listId: string): Promise<Array<Entity.Account>> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<Account>> = await client.get<Array<Account>>(`/lists/${listId}/accounts`, { const res = await client.getAccountsInList(listId, { limit: 0 })
limit: 0
})
commit(MUTATION_TYPES.CHANGE_MEMBERS, res.data) commit(MUTATION_TYPES.CHANGE_MEMBERS, res.data)
return res.data return res.data
}, },
removeAccount: async ({ rootState }, remove: RemoveAccountFromList): Promise<{}> => { removeAccount: async ({ rootState }, remove: RemoveAccountFromList): Promise<{}> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
return client.del<{}>(`/lists/${remove.listId}/accounts`, { return client.deleteAccountsFromList(remove.listId, [remove.account.id])
account_ids: [remove.account.id]
})
} }
} }

View File

@ -1,9 +1,9 @@
import Mastodon, { List, Response } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
export type IndexState = { export type IndexState = {
lists: Array<List> lists: Array<Entity.List>
} }
const state = (): IndexState => ({ const state = (): IndexState => ({
@ -15,33 +15,33 @@ export const MUTATION_TYPES = {
} }
const mutations: MutationTree<IndexState> = { const mutations: MutationTree<IndexState> = {
[MUTATION_TYPES.CHANGE_LISTS]: (state, lists: Array<List>) => { [MUTATION_TYPES.CHANGE_LISTS]: (state, lists: Array<Entity.List>) => {
state.lists = lists state.lists = lists
} }
} }
const actions: ActionTree<IndexState, RootState> = { const actions: ActionTree<IndexState, RootState> = {
fetchLists: async ({ commit, rootState }): Promise<Array<List>> => { fetchLists: async ({ commit, rootState }): Promise<Array<Entity.List>> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<List>> = await client.get<Array<List>>('/lists') const res = await client.getLists()
commit(MUTATION_TYPES.CHANGE_LISTS, res.data) commit(MUTATION_TYPES.CHANGE_LISTS, res.data)
return res.data return res.data
}, },
createList: async ({ rootState }, title: string): Promise<List> => { createList: async ({ rootState }, title: string): Promise<Entity.List> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<List> = await client.post<List>('/lists', { const res = await client.createList(title)
title: title
})
return res.data return res.data
} }
} }

View File

@ -1,4 +1,4 @@
import Mastodon, { Status, Response } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
import { LoadPositionWithList } from '@/types/loadPosition' import { LoadPositionWithList } from '@/types/loadPosition'
@ -7,8 +7,8 @@ import { MyWindow } from '~/src/types/global'
const win = window as MyWindow const win = window as MyWindow
export type ShowState = { export type ShowState = {
timeline: Array<Status> timeline: Array<Entity.Status>
unreadTimeline: Array<Status> unreadTimeline: Array<Entity.Status>
lazyLoading: boolean lazyLoading: boolean
heading: boolean heading: boolean
filter: string filter: string
@ -40,7 +40,7 @@ const mutations: MutationTree<ShowState> = {
[MUTATION_TYPES.CHANGE_HEADING]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_HEADING]: (state, value: boolean) => {
state.heading = value state.heading = value
}, },
[MUTATION_TYPES.APPEND_TIMELINE]: (state, update: Status) => { [MUTATION_TYPES.APPEND_TIMELINE]: (state, update: Entity.Status) => {
// Reject duplicated status in timeline // Reject duplicated status in timeline
if (!state.timeline.find(item => item.id === update.id) && !state.unreadTimeline.find(item => item.id === update.id)) { if (!state.timeline.find(item => item.id === update.id) && !state.unreadTimeline.find(item => item.id === update.id)) {
if (state.heading) { if (state.heading) {
@ -50,14 +50,14 @@ const mutations: MutationTree<ShowState> = {
} }
} }
}, },
[MUTATION_TYPES.UPDATE_TIMELINE]: (state, timeline: Array<Status>) => { [MUTATION_TYPES.UPDATE_TIMELINE]: (state, timeline: Array<Entity.Status>) => {
state.timeline = timeline state.timeline = timeline
}, },
[MUTATION_TYPES.MERGE_TIMELINE]: state => { [MUTATION_TYPES.MERGE_TIMELINE]: state => {
state.timeline = state.unreadTimeline.slice(0, 80).concat(state.timeline) state.timeline = state.unreadTimeline.slice(0, 80).concat(state.timeline)
state.unreadTimeline = [] state.unreadTimeline = []
}, },
[MUTATION_TYPES.INSERT_TIMELINE]: (state, messages: Array<Status>) => { [MUTATION_TYPES.INSERT_TIMELINE]: (state, messages: Array<Entity.Status>) => {
state.timeline = state.timeline.concat(messages) state.timeline = state.timeline.concat(messages)
}, },
[MUTATION_TYPES.ARCHIVE_TIMELINE]: state => { [MUTATION_TYPES.ARCHIVE_TIMELINE]: state => {
@ -67,7 +67,7 @@ const mutations: MutationTree<ShowState> = {
state.timeline = [] state.timeline = []
state.unreadTimeline = [] state.unreadTimeline = []
}, },
[MUTATION_TYPES.UPDATE_TOOT]: (state, message: Status) => { [MUTATION_TYPES.UPDATE_TOOT]: (state, message: Entity.Status) => {
state.timeline = state.timeline.map(toot => { state.timeline = state.timeline.map(toot => {
if (toot.id === message.id) { if (toot.id === message.id) {
return message return message
@ -101,19 +101,20 @@ const mutations: MutationTree<ShowState> = {
} }
const actions: ActionTree<ShowState, RootState> = { const actions: ActionTree<ShowState, RootState> = {
fetchTimeline: async ({ commit, rootState }, listID: string): Promise<Array<Status>> => { fetchTimeline: async ({ commit, rootState }, listID: string): Promise<Array<Entity.Status>> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<Status>> = await client.get<Array<Status>>(`/timelines/list/${listID}`, { limit: 40 }) const res = await client.getListTimeline(listID, { limit: 40 })
commit(MUTATION_TYPES.UPDATE_TIMELINE, res.data) commit(MUTATION_TYPES.UPDATE_TIMELINE, res.data)
return res.data return res.data
}, },
startStreaming: ({ state, commit, rootState }, listID: string) => { startStreaming: ({ state, commit, rootState }, listID: string) => {
win.ipcRenderer.on('update-start-list-streaming', (_, update: Status) => { win.ipcRenderer.on('update-start-list-streaming', (_, update: Entity.Status) => {
commit(MUTATION_TYPES.APPEND_TIMELINE, update) commit(MUTATION_TYPES.APPEND_TIMELINE, update)
if (state.heading && Math.random() > 0.8) { if (state.heading && Math.random() > 0.8) {
commit(MUTATION_TYPES.ARCHIVE_TIMELINE) commit(MUTATION_TYPES.ARCHIVE_TIMELINE)
@ -143,19 +144,20 @@ const actions: ActionTree<ShowState, RootState> = {
resolve() resolve()
}) })
}, },
lazyFetchTimeline: async ({ state, commit, rootState }, loadPosition: LoadPositionWithList): Promise<Array<Status> | null> => { lazyFetchTimeline: async ({ state, commit, rootState }, loadPosition: LoadPositionWithList): Promise<Array<Entity.Status> | null> => {
if (state.lazyLoading) { if (state.lazyLoading) {
return Promise.resolve(null) return Promise.resolve(null)
} }
commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true) commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true)
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
return client return client
.get<Array<Status>>(`/timelines/list/${loadPosition.list_id}`, { max_id: loadPosition.status.id, limit: 40 }) .getListTimeline(loadPosition.list_id, { max_id: loadPosition.status.id, limit: 40 })
.then(res => { .then(res => {
commit(MUTATION_TYPES.INSERT_TIMELINE, res.data) commit(MUTATION_TYPES.INSERT_TIMELINE, res.data)
return res.data return res.data

View File

@ -1,10 +1,10 @@
import Mastodon, { Status, Response } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
export type LocalState = { export type LocalState = {
timeline: Array<Status> timeline: Array<Entity.Status>
unreadTimeline: Array<Status> unreadTimeline: Array<Entity.Status>
lazyLoading: boolean lazyLoading: boolean
heading: boolean heading: boolean
filter: string filter: string
@ -36,7 +36,7 @@ const mutations: MutationTree<LocalState> = {
[MUTATION_TYPES.CHANGE_HEADING]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_HEADING]: (state, value: boolean) => {
state.heading = value state.heading = value
}, },
[MUTATION_TYPES.APPEND_TIMELINE]: (state, update: Status) => { [MUTATION_TYPES.APPEND_TIMELINE]: (state, update: Entity.Status) => {
// Reject duplicated status in timeline // Reject duplicated status in timeline
if (!state.timeline.find(item => item.id === update.id) && !state.unreadTimeline.find(item => item.id === update.id)) { if (!state.timeline.find(item => item.id === update.id) && !state.unreadTimeline.find(item => item.id === update.id)) {
if (state.heading) { if (state.heading) {
@ -46,14 +46,14 @@ const mutations: MutationTree<LocalState> = {
} }
} }
}, },
[MUTATION_TYPES.UPDATE_TIMELINE]: (state, messages: Array<Status>) => { [MUTATION_TYPES.UPDATE_TIMELINE]: (state, messages: Array<Entity.Status>) => {
state.timeline = messages state.timeline = messages
}, },
[MUTATION_TYPES.MERGE_TIMELINE]: state => { [MUTATION_TYPES.MERGE_TIMELINE]: state => {
state.timeline = state.unreadTimeline.slice(0, 80).concat(state.timeline) state.timeline = state.unreadTimeline.slice(0, 80).concat(state.timeline)
state.unreadTimeline = [] state.unreadTimeline = []
}, },
[MUTATION_TYPES.INSERT_TIMELINE]: (state, messages: Array<Status>) => { [MUTATION_TYPES.INSERT_TIMELINE]: (state, messages: Array<Entity.Status>) => {
state.timeline = state.timeline.concat(messages) state.timeline = state.timeline.concat(messages)
}, },
[MUTATION_TYPES.ARCHIVE_TIMELINE]: state => { [MUTATION_TYPES.ARCHIVE_TIMELINE]: state => {
@ -63,7 +63,7 @@ const mutations: MutationTree<LocalState> = {
state.timeline = [] state.timeline = []
state.unreadTimeline = [] state.unreadTimeline = []
}, },
[MUTATION_TYPES.UPDATE_TOOT]: (state, message: Status) => { [MUTATION_TYPES.UPDATE_TOOT]: (state, message: Entity.Status) => {
state.timeline = state.timeline.map(toot => { state.timeline = state.timeline.map(toot => {
if (toot.id === message.id) { if (toot.id === message.id) {
return message return message
@ -97,30 +97,32 @@ const mutations: MutationTree<LocalState> = {
} }
const actions: ActionTree<LocalState, RootState> = { const actions: ActionTree<LocalState, RootState> = {
fetchLocalTimeline: async ({ commit, rootState }): Promise<Array<Status>> => { fetchLocalTimeline: async ({ commit, rootState }): Promise<Array<Entity.Status>> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<Status>> = await client.get<Array<Status>>('/timelines/public', { limit: 40, local: true }) const res = await client.getLocalTimeline({ limit: 40 })
commit(MUTATION_TYPES.UPDATE_TIMELINE, res.data) commit(MUTATION_TYPES.UPDATE_TIMELINE, res.data)
return res.data return res.data
}, },
lazyFetchTimeline: async ({ state, commit, rootState }, lastStatus: Status): Promise<Array<Status> | null> => { lazyFetchTimeline: async ({ state, commit, rootState }, lastStatus: Entity.Status): Promise<Array<Entity.Status> | null> => {
if (state.lazyLoading) { if (state.lazyLoading) {
return Promise.resolve(null) return Promise.resolve(null)
} }
commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true) commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true)
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
return client return client
.get<Array<Status>>('/timelines/public', { max_id: lastStatus.id, limit: 40, local: true }) .getLocalTimeline({ max_id: lastStatus.id, limit: 40 })
.then(res => { .then(res => {
commit(MUTATION_TYPES.INSERT_TIMELINE, res.data) commit(MUTATION_TYPES.INSERT_TIMELINE, res.data)
return res.data return res.data

View File

@ -1,12 +1,12 @@
import Mastodon, { Notification, Response } from 'megalodon' import generator, { Entity, NotificationType } from 'megalodon'
import { Module, MutationTree, ActionTree, GetterTree } from 'vuex' import { Module, MutationTree, ActionTree, GetterTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
export type MentionsState = { export type MentionsState = {
lazyLoading: boolean lazyLoading: boolean
heading: boolean heading: boolean
mentions: Array<Notification> mentions: Array<Entity.Notification>
unreadMentions: Array<Notification> unreadMentions: Array<Entity.Notification>
filter: string filter: string
} }
@ -39,7 +39,7 @@ const mutations: MutationTree<MentionsState> = {
[MUTATION_TYPES.CHANGE_HEADING]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_HEADING]: (state, value: boolean) => {
state.heading = value state.heading = value
}, },
[MUTATION_TYPES.APPEND_MENTIONS]: (state, update: Notification) => { [MUTATION_TYPES.APPEND_MENTIONS]: (state, update: Entity.Notification) => {
// Reject duplicated status in timeline // Reject duplicated status in timeline
if (!state.mentions.find(item => item.id === update.id) && !state.unreadMentions.find(item => item.id === update.id)) { if (!state.mentions.find(item => item.id === update.id) && !state.unreadMentions.find(item => item.id === update.id)) {
if (state.heading) { if (state.heading) {
@ -49,14 +49,14 @@ const mutations: MutationTree<MentionsState> = {
} }
} }
}, },
[MUTATION_TYPES.UPDATE_MENTIONS]: (state, messages: Array<Notification>) => { [MUTATION_TYPES.UPDATE_MENTIONS]: (state, messages: Array<Entity.Notification>) => {
state.mentions = messages state.mentions = messages
}, },
[MUTATION_TYPES.MERGE_MENTIONS]: state => { [MUTATION_TYPES.MERGE_MENTIONS]: state => {
state.mentions = state.unreadMentions.slice(0, 80).concat(state.mentions) state.mentions = state.unreadMentions.slice(0, 80).concat(state.mentions)
state.unreadMentions = [] state.unreadMentions = []
}, },
[MUTATION_TYPES.INSERT_MENTIONS]: (state, messages: Array<Notification>) => { [MUTATION_TYPES.INSERT_MENTIONS]: (state, messages: Array<Entity.Notification>) => {
state.mentions = state.mentions.concat(messages) state.mentions = state.mentions.concat(messages)
}, },
[MUTATION_TYPES.ARCHIVE_MENTIONS]: state => { [MUTATION_TYPES.ARCHIVE_MENTIONS]: state => {
@ -66,9 +66,9 @@ const mutations: MutationTree<MentionsState> = {
state.mentions = [] state.mentions = []
state.unreadMentions = [] state.unreadMentions = []
}, },
[MUTATION_TYPES.UPDATE_TOOT]: (state, message: Notification) => { [MUTATION_TYPES.UPDATE_TOOT]: (state, message: Entity.Notification) => {
state.mentions = state.mentions.map(mention => { state.mentions = state.mentions.map(mention => {
if (mention.status !== null && mention.status.id === message.id) { if (mention.status !== undefined && mention.status.id === message.id) {
const status = { const status = {
status: message status: message
} }
@ -97,33 +97,39 @@ const mutations: MutationTree<MentionsState> = {
} }
const actions: ActionTree<MentionsState, RootState> = { const actions: ActionTree<MentionsState, RootState> = {
fetchMentions: async ({ commit, rootState }): Promise<Array<Notification>> => { fetchMentions: async ({ commit, rootState }): Promise<Array<Entity.Notification>> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<Notification>> = await client.get<Array<Notification>>('/notifications', { const res = await client.getNotifications({
limit: 30, limit: 30,
exclude_types: ['follow', 'favourite', 'reblog'] exclude_types: [NotificationType.Follow, NotificationType.Favourite, NotificationType.Reblog, NotificationType.Poll]
}) })
commit(MUTATION_TYPES.UPDATE_MENTIONS, res.data) commit(MUTATION_TYPES.UPDATE_MENTIONS, res.data)
return res.data return res.data
}, },
lazyFetchMentions: async ({ state, commit, rootState }, lastMention: Notification): Promise<Array<Notification> | null> => { lazyFetchMentions: async ({ state, commit, rootState }, lastMention: Entity.Notification): Promise<Array<Entity.Notification> | null> => {
if (state.lazyLoading) { if (state.lazyLoading) {
return Promise.resolve(null) return Promise.resolve(null)
} }
commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true) commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true)
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
return client return client
.get<Array<Notification>>('/notifications', { max_id: lastMention.id, limit: 30, exclude_types: ['follow', 'favourite', 'reblog'] }) .getNotifications({
max_id: lastMention.id,
limit: 30,
exclude_types: [NotificationType.Follow, NotificationType.Favourite, NotificationType.Reblog, NotificationType.Poll]
})
.then(res => { .then(res => {
commit(MUTATION_TYPES.INSERT_MENTIONS, res.data) commit(MUTATION_TYPES.INSERT_MENTIONS, res.data)
return res.data return res.data

View File

@ -1,4 +1,4 @@
import Mastodon, { Notification, Status, Response } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
import { MyWindow } from '~/src/types/global' import { MyWindow } from '~/src/types/global'
@ -8,8 +8,8 @@ const win = window as MyWindow
export type NotificationsState = { export type NotificationsState = {
lazyLoading: boolean lazyLoading: boolean
heading: boolean heading: boolean
notifications: Array<Notification> notifications: Array<Entity.Notification>
unreadNotifications: Array<Notification> unreadNotifications: Array<Entity.Notification>
filter: string filter: string
} }
@ -42,7 +42,7 @@ const mutations: MutationTree<NotificationsState> = {
[MUTATION_TYPES.CHANGE_HEADING]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_HEADING]: (state, value: boolean) => {
state.heading = value state.heading = value
}, },
[MUTATION_TYPES.APPEND_NOTIFICATIONS]: (state, notification: Notification) => { [MUTATION_TYPES.APPEND_NOTIFICATIONS]: (state, notification: Entity.Notification) => {
// Reject duplicated status in timeline // Reject duplicated status in timeline
if ( if (
!state.notifications.find(item => item.id === notification.id) && !state.notifications.find(item => item.id === notification.id) &&
@ -55,17 +55,17 @@ const mutations: MutationTree<NotificationsState> = {
} }
} }
}, },
[MUTATION_TYPES.UPDATE_NOTIFICATIONS]: (state, notifications: Array<Notification>) => { [MUTATION_TYPES.UPDATE_NOTIFICATIONS]: (state, notifications: Array<Entity.Notification>) => {
state.notifications = notifications state.notifications = notifications
}, },
[MUTATION_TYPES.MERGE_NOTIFICATIONS]: state => { [MUTATION_TYPES.MERGE_NOTIFICATIONS]: state => {
state.notifications = state.unreadNotifications.slice(0, 80).concat(state.notifications) state.notifications = state.unreadNotifications.slice(0, 80).concat(state.notifications)
state.unreadNotifications = [] state.unreadNotifications = []
}, },
[MUTATION_TYPES.INSERT_NOTIFICATIONS]: (state, notifications: Array<Notification>) => { [MUTATION_TYPES.INSERT_NOTIFICATIONS]: (state, notifications: Array<Entity.Notification>) => {
state.notifications = state.notifications.concat(notifications) state.notifications = state.notifications.concat(notifications)
}, },
[MUTATION_TYPES.UPDATE_TOOT]: (state, message: Status) => { [MUTATION_TYPES.UPDATE_TOOT]: (state, message: Entity.Status) => {
state.notifications = state.notifications.map(notification => { state.notifications = state.notifications.map(notification => {
// I want to update toot only mention. // I want to update toot only mention.
// Because Toot component don't use status information when other patterns. // Because Toot component don't use status information when other patterns.
@ -104,31 +104,35 @@ const mutations: MutationTree<NotificationsState> = {
} }
const actions: ActionTree<NotificationsState, RootState> = { const actions: ActionTree<NotificationsState, RootState> = {
fetchNotifications: async ({ commit, rootState }): Promise<Array<Notification>> => { fetchNotifications: async ({ commit, rootState }): Promise<Array<Entity.Notification>> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<Notification>> = await client.get<Array<Notification>>('/notifications', { limit: 30 }) const res = await client.getNotifications({ limit: 30 })
commit(MUTATION_TYPES.UPDATE_NOTIFICATIONS, res.data) commit(MUTATION_TYPES.UPDATE_NOTIFICATIONS, res.data)
return res.data return res.data
}, },
lazyFetchNotifications: ({ state, commit, rootState }, lastNotification: Notification): Promise<Array<Notification> | null> => { lazyFetchNotifications: (
{ state, commit, rootState },
lastNotification: Entity.Notification
): Promise<Array<Entity.Notification> | null> => {
if (state.lazyLoading) { if (state.lazyLoading) {
return Promise.resolve(null) return Promise.resolve(null)
} }
commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true) commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true)
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
return client return client
.get<Array<Notification>>('/notifications', { max_id: lastNotification.id, limit: 30 }) .getNotifications({ max_id: lastNotification.id, limit: 30 })
.then(res => { .then(res => {
commit(MUTATION_TYPES.INSERT_NOTIFICATIONS, res.data) commit(MUTATION_TYPES.INSERT_NOTIFICATIONS, res.data)
return res.data return res.data

View File

@ -1,10 +1,10 @@
import Mastodon, { Status, Response } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
export type PublicState = { export type PublicState = {
timeline: Array<Status> timeline: Array<Entity.Status>
unreadTimeline: Array<Status> unreadTimeline: Array<Entity.Status>
lazyLoading: boolean lazyLoading: boolean
heading: boolean heading: boolean
filter: string filter: string
@ -36,7 +36,7 @@ const mutations: MutationTree<PublicState> = {
[MUTATION_TYPES.CHANGE_HEADING]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_HEADING]: (state, value: boolean) => {
state.heading = value state.heading = value
}, },
[MUTATION_TYPES.APPEND_TIMELINE]: (state, update: Status) => { [MUTATION_TYPES.APPEND_TIMELINE]: (state, update: Entity.Status) => {
// Reject duplicated status in timeline // Reject duplicated status in timeline
if (!state.timeline.find(item => item.id === update.id) && !state.unreadTimeline.find(item => item.id === update.id)) { if (!state.timeline.find(item => item.id === update.id) && !state.unreadTimeline.find(item => item.id === update.id)) {
if (state.heading) { if (state.heading) {
@ -46,14 +46,14 @@ const mutations: MutationTree<PublicState> = {
} }
} }
}, },
[MUTATION_TYPES.UPDATE_TIMELINE]: (state, messages: Array<Status>) => { [MUTATION_TYPES.UPDATE_TIMELINE]: (state, messages: Array<Entity.Status>) => {
state.timeline = messages state.timeline = messages
}, },
[MUTATION_TYPES.MERGE_TIMELINE]: state => { [MUTATION_TYPES.MERGE_TIMELINE]: state => {
state.timeline = state.unreadTimeline.slice(0, 80).concat(state.timeline) state.timeline = state.unreadTimeline.slice(0, 80).concat(state.timeline)
state.unreadTimeline = [] state.unreadTimeline = []
}, },
[MUTATION_TYPES.INSERT_TIMELINE]: (state, messages: Array<Status>) => { [MUTATION_TYPES.INSERT_TIMELINE]: (state, messages: Array<Entity.Status>) => {
state.timeline = state.timeline.concat(messages) state.timeline = state.timeline.concat(messages)
}, },
[MUTATION_TYPES.ARCHIVE_TIMELINE]: state => { [MUTATION_TYPES.ARCHIVE_TIMELINE]: state => {
@ -63,7 +63,7 @@ const mutations: MutationTree<PublicState> = {
state.timeline = [] state.timeline = []
state.unreadTimeline = [] state.unreadTimeline = []
}, },
[MUTATION_TYPES.UPDATE_TOOT]: (state, message: Status) => { [MUTATION_TYPES.UPDATE_TOOT]: (state, message: Entity.Status) => {
state.timeline = state.timeline.map(toot => { state.timeline = state.timeline.map(toot => {
if (toot.id === message.id) { if (toot.id === message.id) {
return message return message
@ -97,30 +97,32 @@ const mutations: MutationTree<PublicState> = {
} }
const actions: ActionTree<PublicState, RootState> = { const actions: ActionTree<PublicState, RootState> = {
fetchPublicTimeline: async ({ commit, rootState }): Promise<Array<Status>> => { fetchPublicTimeline: async ({ commit, rootState }): Promise<Array<Entity.Status>> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<Status>> = await client.get<Array<Status>>('/timelines/public', { limit: 40 }) const res = await client.getPublicTimeline({ limit: 40 })
commit(MUTATION_TYPES.UPDATE_TIMELINE, res.data) commit(MUTATION_TYPES.UPDATE_TIMELINE, res.data)
return res.data return res.data
}, },
lazyFetchTimeline: ({ state, commit, rootState }, lastStatus: Status): Promise<Array<Status> | null> => { lazyFetchTimeline: ({ state, commit, rootState }, lastStatus: Entity.Status): Promise<Array<Entity.Status> | null> => {
if (state.lazyLoading) { if (state.lazyLoading) {
return Promise.resolve(null) return Promise.resolve(null)
} }
commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true) commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true)
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
return client return client
.get<Array<Status>>('/timelines/public', { max_id: lastStatus.id, limit: 40 }) .getPublicTimeline({ max_id: lastStatus.id, limit: 40 })
.then(res => { .then(res => {
commit(MUTATION_TYPES.INSERT_TIMELINE, res.data) commit(MUTATION_TYPES.INSERT_TIMELINE, res.data)
return res.data return res.data

View File

@ -1,4 +1,4 @@
import Mastodon, { Account } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
@ -21,16 +21,17 @@ const mutations: MutationTree<AccountState> = {
} }
const actions: ActionTree<AccountState, RootState> = { const actions: ActionTree<AccountState, RootState> = {
search: async ({ commit, rootState }, query: string): Promise<Array<Account>> => { search: async ({ commit, rootState }, query: string): Promise<Array<Entity.Account>> => {
commit('TimelineSpace/Contents/changeLoading', true, { root: true }) commit('TimelineSpace/Contents/changeLoading', true, { root: true })
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
return client return client
.get<Array<Account>>('/accounts/search', { q: query, resolve: true }) .searchAccount(query, { resolve: true })
.then(res => { .then(res => {
commit(MUTATION_TYPES.UPDATE_RESULTS, res.data) commit(MUTATION_TYPES.UPDATE_RESULTS, res.data)
return res.data return res.data

View File

@ -1,9 +1,9 @@
import Mastodon, { Tag, Results } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
export type TagState = { export type TagState = {
results: Array<Tag> results: Array<Entity.Tag>
} }
const state = (): TagState => ({ const state = (): TagState => ({
@ -15,22 +15,23 @@ export const MUTATION_TYPES = {
} }
const mutations: MutationTree<TagState> = { const mutations: MutationTree<TagState> = {
[MUTATION_TYPES.UPDATE_RESULTS]: (state, results: Array<Tag>) => { [MUTATION_TYPES.UPDATE_RESULTS]: (state, results: Array<Entity.Tag>) => {
state.results = results state.results = results
} }
} }
const actions: ActionTree<TagState, RootState> = { const actions: ActionTree<TagState, RootState> = {
search: ({ commit, rootState }, query: string): Promise<Array<Tag>> => { search: ({ commit, rootState }, query: string): Promise<Array<Entity.Tag>> => {
commit('TimelineSpace/Contents/changeLoading', true, { root: true }) commit('TimelineSpace/Contents/changeLoading', true, { root: true })
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v2', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
return client return client
.get<Results>('/search', { q: query, resolve: true }) .search(query, 'hashtags', { resolve: true })
.then(res => { .then(res => {
commit(MUTATION_TYPES.UPDATE_RESULTS, res.data.hashtags) commit(MUTATION_TYPES.UPDATE_RESULTS, res.data.hashtags)
return res.data.hashtags return res.data.hashtags

View File

@ -1,9 +1,9 @@
import Mastodon, { Status, Results } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
export type TootsState = { export type TootsState = {
results: Array<Status> results: Array<Entity.Status>
} }
const state = (): TootsState => ({ const state = (): TootsState => ({
@ -15,22 +15,23 @@ export const MUTATION_TYPES = {
} }
const mutations: MutationTree<TootsState> = { const mutations: MutationTree<TootsState> = {
[MUTATION_TYPES.UPDATE_RESULTS]: (state, results: Array<Status>) => { [MUTATION_TYPES.UPDATE_RESULTS]: (state, results: Array<Entity.Status>) => {
state.results = results state.results = results
} }
} }
const actions: ActionTree<TootsState, RootState> = { const actions: ActionTree<TootsState, RootState> = {
search: ({ commit, rootState }, query: string): Promise<Array<Status>> => { search: ({ commit, rootState }, query: string): Promise<Array<Entity.Status>> => {
commit('TimelineSpace/Contents/changeLoading', true, { root: true }) commit('TimelineSpace/Contents/changeLoading', true, { root: true })
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
return client return client
.get<Results>('/search', { q: query, resolve: true }) .search(query, 'statuses', { resolve: true })
.then(res => { .then(res => {
commit(MUTATION_TYPES.UPDATE_RESULTS, res.data.statuses) commit(MUTATION_TYPES.UPDATE_RESULTS, res.data.statuses)
return res.data.statuses return res.data.statuses

View File

@ -1,4 +1,4 @@
import Mastodon, { Account, Relationship, Response, Status, Context } from 'megalodon' import generator, { Entity } from 'megalodon'
import Timeline, { TimelineState } from './AccountProfile/Timeline' import Timeline, { TimelineState } from './AccountProfile/Timeline'
import Follows, { FollowsState } from './AccountProfile/Follows' import Follows, { FollowsState } from './AccountProfile/Follows'
import Followers, { FollowersState } from './AccountProfile/Followers' import Followers, { FollowersState } from './AccountProfile/Followers'
@ -13,12 +13,12 @@ type ParsedAccount = {
type SearchAccount = { type SearchAccount = {
parsedAccount: ParsedAccount parsedAccount: ParsedAccount
status: Status status: Entity.Status
} }
export type AccountProfileState = { export type AccountProfileState = {
account: Account | null account: Entity.Account | null
relationship: Relationship | null relationship: Entity.Relationship | null
loading: boolean loading: boolean
} }
@ -43,10 +43,10 @@ export const MUTATION_TYPES = {
} }
const mutations: MutationTree<AccountProfileState> = { const mutations: MutationTree<AccountProfileState> = {
[MUTATION_TYPES.CHANGE_ACCOUNT]: (state, account: Account | null) => { [MUTATION_TYPES.CHANGE_ACCOUNT]: (state, account: Entity.Account | null) => {
state.account = account state.account = account
}, },
[MUTATION_TYPES.CHANGE_RELATIONSHIP]: (state, relationship: Relationship | null) => { [MUTATION_TYPES.CHANGE_RELATIONSHIP]: (state, relationship: Entity.Relationship | null) => {
state.relationship = relationship state.relationship = relationship
}, },
[MUTATION_TYPES.CHANGE_LOADING]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_LOADING]: (state, value: boolean) => {
@ -55,27 +55,29 @@ const mutations: MutationTree<AccountProfileState> = {
} }
const actions: ActionTree<AccountProfileState, RootState> = { const actions: ActionTree<AccountProfileState, RootState> = {
fetchAccount: async ({ rootState }, accountID: string): Promise<Account> => { fetchAccount: async ({ rootState }, accountID: string): Promise<Entity.Account> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Account> = await client.get<Account>(`/accounts/${accountID}`) const res = await client.getAccount(accountID)
return res.data return res.data
}, },
searchAccount: async ({ rootState }, searchAccount: SearchAccount): Promise<Account> => { searchAccount: async ({ rootState }, searchAccount: SearchAccount): Promise<Entity.Account> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
// Find account in toot // Find account in toot
if (searchAccount.status.in_reply_to_account_id) { if (searchAccount.status.in_reply_to_account_id) {
const res: Response<Account> = await client.get<Account>(`/accounts/${searchAccount.status.in_reply_to_account_id}`) const res = await client.getAccount(searchAccount.status.in_reply_to_account_id)
if (res.status === 200) { if (res.status === 200) {
const user = accountMatch([res.data], searchAccount.parsedAccount, rootState.TimelineSpace.account.domain) const user = accountMatch([res.data], searchAccount.parsedAccount, rootState.TimelineSpace.account.domain)
if (user) return user if (user) return user
@ -84,37 +86,35 @@ const actions: ActionTree<AccountProfileState, RootState> = {
// Find account in context // Find account in context
if (searchAccount.status.in_reply_to_id) { if (searchAccount.status.in_reply_to_id) {
const res: Response<Context> = await client.get<Context>(`/statuses/${searchAccount.status.id}/context`) const res = await client.getStatusContext(searchAccount.status.id)
if (res.status === 200) { if (res.status === 200) {
const accounts: Array<Account> = res.data.ancestors.map(s => s.account).concat(res.data.descendants.map(s => s.account)) const accounts: Array<Entity.Account> = res.data.ancestors.map(s => s.account).concat(res.data.descendants.map(s => s.account))
const user = accountMatch(accounts, searchAccount.parsedAccount, rootState.TimelineSpace.account.domain) const user = accountMatch(accounts, searchAccount.parsedAccount, rootState.TimelineSpace.account.domain)
if (user) return user if (user) return user
} }
} }
// Search account name // Search account name
const res: Response<Array<Account>> = await client.get<Array<Account>>('/accounts/search', { const res = await client.searchAccount(searchAccount.parsedAccount.url, { resolve: true })
q: searchAccount.parsedAccount.url,
resolve: true
})
if (res.data.length <= 0) throw new AccountNotFound('empty result') if (res.data.length <= 0) throw new AccountNotFound('empty result')
const user = accountMatch(res.data, searchAccount.parsedAccount, rootState.TimelineSpace.account.domain) const user = accountMatch(res.data, searchAccount.parsedAccount, rootState.TimelineSpace.account.domain)
if (!user) throw new AccountNotFound('not found') if (!user) throw new AccountNotFound('not found')
return user return user
}, },
changeAccount: ({ commit, dispatch }, account: Account) => { changeAccount: ({ commit, dispatch }, account: Entity.Account) => {
dispatch('fetchRelationship', account) dispatch('fetchRelationship', account)
commit(MUTATION_TYPES.CHANGE_ACCOUNT, account) commit(MUTATION_TYPES.CHANGE_ACCOUNT, account)
}, },
fetchRelationship: async ({ commit, rootState }, account: Account): Promise<Relationship> => { fetchRelationship: async ({ commit, rootState }, account: Entity.Account): Promise<Entity.Relationship> => {
commit(MUTATION_TYPES.CHANGE_RELATIONSHIP, null) commit(MUTATION_TYPES.CHANGE_RELATIONSHIP, null)
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Relationship> = await client.get<Relationship>('/accounts/relationships', { id: [account.id] }) const res = await client.getRelationship([account.id])
commit(MUTATION_TYPES.CHANGE_RELATIONSHIP, res.data[0]) commit(MUTATION_TYPES.CHANGE_RELATIONSHIP, res.data[0])
return res.data return res.data
}, },
@ -129,26 +129,28 @@ const actions: ActionTree<AccountProfileState, RootState> = {
commit(MUTATION_TYPES.CHANGE_LOADING, false) commit(MUTATION_TYPES.CHANGE_LOADING, false)
}) })
}, },
follow: async ({ commit, rootState, dispatch }, account: Account) => { follow: async ({ commit, rootState, dispatch }, account: Entity.Account) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Relationship> = await client.post<Relationship>(`/accounts/${account.id}/follow`) const res = await client.followAccount(account.id)
commit(MUTATION_TYPES.CHANGE_RELATIONSHIP, res.data) commit(MUTATION_TYPES.CHANGE_RELATIONSHIP, res.data)
dispatch('fetchRelationship', account) dispatch('fetchRelationship', account)
return res.data return res.data
}, },
unfollow: async ({ commit, rootState, dispatch }, account: Account) => { unfollow: async ({ commit, rootState, dispatch }, account: Entity.Account) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Relationship> = await client.post<Relationship>(`/accounts/${account.id}/unfollow`) const res = await client.unfollowAccount(account.id)
commit(MUTATION_TYPES.CHANGE_RELATIONSHIP, res.data) commit(MUTATION_TYPES.CHANGE_RELATIONSHIP, res.data)
dispatch('fetchRelationship', account) dispatch('fetchRelationship', account)
return res.data return res.data
@ -156,38 +158,41 @@ const actions: ActionTree<AccountProfileState, RootState> = {
close: ({ commit }) => { close: ({ commit }) => {
commit(MUTATION_TYPES.CHANGE_ACCOUNT, null) commit(MUTATION_TYPES.CHANGE_ACCOUNT, null)
}, },
unmute: async ({ rootState, commit, dispatch }, account: Account) => { unmute: async ({ rootState, commit, dispatch }, account: Entity.Account) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Relationship> = await client.post<Relationship>(`/accounts/${account.id}/unmute`) const res = await client.unmuteAccount(account.id)
commit(MUTATION_TYPES.CHANGE_RELATIONSHIP, res.data) commit(MUTATION_TYPES.CHANGE_RELATIONSHIP, res.data)
dispatch('fetchRelationship', account) dispatch('fetchRelationship', account)
return res.data return res.data
}, },
block: async ({ rootState, commit, dispatch }, account: Account) => { block: async ({ rootState, commit, dispatch }, account: Entity.Account) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Relationship> = await client.post<Relationship>(`/accounts/${account.id}/block`) const res = await client.blockAccount(account.id)
commit(MUTATION_TYPES.CHANGE_RELATIONSHIP, res.data) commit(MUTATION_TYPES.CHANGE_RELATIONSHIP, res.data)
dispatch('fetchRelationship', account) dispatch('fetchRelationship', account)
return res.data return res.data
}, },
unblock: async ({ rootState, commit, dispatch }, account: Account) => { unblock: async ({ rootState, commit, dispatch }, account: Account) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Relationship> = await client.post<Relationship>(`/accounts/${account.id}/unblock`) const res = await client.unblockAccount(account.id)
commit(MUTATION_TYPES.CHANGE_RELATIONSHIP, res.data) commit(MUTATION_TYPES.CHANGE_RELATIONSHIP, res.data)
dispatch('fetchRelationship', account) dispatch('fetchRelationship', account)
return res.data return res.data
@ -226,7 +231,7 @@ class AccountNotFound extends Error {}
export default AccountProfile export default AccountProfile
const accountMatch = (findAccounts: Array<Account>, parsedAccount: ParsedAccount, domain: string): Account | false => { const accountMatch = (findAccounts: Array<Entity.Account>, parsedAccount: ParsedAccount, domain: string): Entity.Account | false => {
const account = findAccounts.find(a => `@${a.acct}` === parsedAccount.acct) const account = findAccounts.find(a => `@${a.acct}` === parsedAccount.acct)
if (account) return account if (account) return account
const pleromaUser = findAccounts.find(a => a.acct === parsedAccount.acct) const pleromaUser = findAccounts.find(a => a.acct === parsedAccount.acct)

View File

@ -1,10 +1,10 @@
import Mastodon, { Account, Relationship, Response } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
export type FollowersState = { export type FollowersState = {
followers: Array<Account> followers: Array<Entity.Account>
relationships: Array<Relationship> relationships: Array<Entity.Relationship>
} }
const state = (): FollowersState => ({ const state = (): FollowersState => ({
@ -18,37 +18,38 @@ export const MUTATION_TYPES = {
} }
const mutations: MutationTree<FollowersState> = { const mutations: MutationTree<FollowersState> = {
[MUTATION_TYPES.UPDATE_FOLLOWERS]: (state, users: Array<Account>) => { [MUTATION_TYPES.UPDATE_FOLLOWERS]: (state, users: Array<Entity.Account>) => {
state.followers = users state.followers = users
}, },
[MUTATION_TYPES.UPDATE_RELATIONSHIPS]: (state, relations: Array<Relationship>) => { [MUTATION_TYPES.UPDATE_RELATIONSHIPS]: (state, relations: Array<Entity.Relationship>) => {
state.relationships = relations state.relationships = relations
} }
} }
const actions: ActionTree<FollowersState, RootState> = { const actions: ActionTree<FollowersState, RootState> = {
fetchFollowers: async ({ commit, rootState }, account: Account) => { fetchFollowers: async ({ commit, rootState }, account: Entity.Account) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<Account>> = await client.get<Array<Account>>(`/accounts/${account.id}/followers`, { limit: 80 }) const res = await client.getAccountFollowers(account.id, { limit: 80 })
commit(MUTATION_TYPES.UPDATE_FOLLOWERS, res.data) commit(MUTATION_TYPES.UPDATE_FOLLOWERS, res.data)
return res.data return res.data
}, },
fetchRelationships: async ({ commit, rootState }, accounts: Array<Account>) => { fetchRelationships: async ({ commit, rootState }, accounts: Array<Entity.Account>) => {
const ids = accounts.map(a => a.id) const ids = accounts.map(a => a.id)
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<Relationship>> = await client.get<Array<Relationship>>(`/accounts/relationships`, { const res = await client.getRelationship(ids)
id: ids
})
commit(MUTATION_TYPES.UPDATE_RELATIONSHIPS, res.data) commit(MUTATION_TYPES.UPDATE_RELATIONSHIPS, res.data)
return res.data return res.data
} }

View File

@ -1,10 +1,10 @@
import Mastodon, { Account, Relationship, Response } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
export type FollowsState = { export type FollowsState = {
follows: Array<Account> follows: Array<Entity.Account>
relationships: Array<Relationship> relationships: Array<Entity.Relationship>
} }
const state = (): FollowsState => ({ const state = (): FollowsState => ({
@ -18,37 +18,37 @@ export const MUTATION_TYPES = {
} }
const mutations: MutationTree<FollowsState> = { const mutations: MutationTree<FollowsState> = {
[MUTATION_TYPES.UPDATE_FOLLOWS]: (state, users: Array<Account>) => { [MUTATION_TYPES.UPDATE_FOLLOWS]: (state, users: Array<Entity.Account>) => {
state.follows = users state.follows = users
}, },
[MUTATION_TYPES.UPDATE_RELATIONSHIPS]: (state, relations: Array<Relationship>) => { [MUTATION_TYPES.UPDATE_RELATIONSHIPS]: (state, relations: Array<Entity.Relationship>) => {
state.relationships = relations state.relationships = relations
} }
} }
const actions: ActionTree<FollowsState, RootState> = { const actions: ActionTree<FollowsState, RootState> = {
fetchFollows: async ({ commit, rootState }, account: Account) => { fetchFollows: async ({ commit, rootState }, account: Account) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<Account>> = await client.get<Array<Account>>(`/accounts/${account.id}/following`, { limit: 80 }) const res = await client.getAccountFollowing(account.id, { limit: 80 })
commit(MUTATION_TYPES.UPDATE_FOLLOWS, res.data) commit(MUTATION_TYPES.UPDATE_FOLLOWS, res.data)
return res.data return res.data
}, },
fetchRelationships: async ({ commit, rootState }, accounts: Array<Account>) => { fetchRelationships: async ({ commit, rootState }, accounts: Array<Entity.Account>) => {
const ids = accounts.map(a => a.id) const ids = accounts.map(a => a.id)
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<Relationship>> = await client.get<Array<Relationship>>(`/accounts/relationships`, { const res = await client.getRelationship(ids)
id: ids
})
commit(MUTATION_TYPES.UPDATE_RELATIONSHIPS, res.data) commit(MUTATION_TYPES.UPDATE_RELATIONSHIPS, res.data)
return res.data return res.data
} }

View File

@ -1,11 +1,11 @@
import Mastodon, { Status, Response } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
import { LoadPositionWithAccount } from '@/types/loadPosition' import { LoadPositionWithAccount } from '@/types/loadPosition'
export type TimelineState = { export type TimelineState = {
timeline: Array<Status> timeline: Array<Entity.Status>
pinnedToots: Array<Status> pinnedToots: Array<Entity.Status>
lazyLoading: boolean lazyLoading: boolean
} }
@ -26,19 +26,19 @@ export const MUTATION_TYPES = {
} }
const mutations: MutationTree<TimelineState> = { const mutations: MutationTree<TimelineState> = {
[MUTATION_TYPES.UPDATE_TIMELINE]: (state, timeline: Array<Status>) => { [MUTATION_TYPES.UPDATE_TIMELINE]: (state, timeline: Array<Entity.Status>) => {
state.timeline = timeline state.timeline = timeline
}, },
[MUTATION_TYPES.INSERT_TIMELINE]: (state, messages: Array<Status>) => { [MUTATION_TYPES.INSERT_TIMELINE]: (state, messages: Array<Entity.Status>) => {
state.timeline = state.timeline.concat(messages) state.timeline = state.timeline.concat(messages)
}, },
[MUTATION_TYPES.UPDATE_PINNED_TOOTS]: (state, messages: Array<Status>) => { [MUTATION_TYPES.UPDATE_PINNED_TOOTS]: (state, messages: Array<Entity.Status>) => {
state.pinnedToots = messages state.pinnedToots = messages
}, },
[MUTATION_TYPES.CHANGE_LAZY_LOADING]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_LAZY_LOADING]: (state, value: boolean) => {
state.lazyLoading = value state.lazyLoading = value
}, },
[MUTATION_TYPES.UPDATE_PINNED_TOOT]: (state, message: Status) => { [MUTATION_TYPES.UPDATE_PINNED_TOOT]: (state, message: Entity.Status) => {
state.pinnedToots = state.pinnedToots.map(toot => { state.pinnedToots = state.pinnedToots.map(toot => {
if (toot.id === message.id) { if (toot.id === message.id) {
return message return message
@ -54,7 +54,7 @@ const mutations: MutationTree<TimelineState> = {
} }
}) })
}, },
[MUTATION_TYPES.UPDATE_TOOT]: (state, message: Status) => { [MUTATION_TYPES.UPDATE_TOOT]: (state, message: Entity.Status) => {
// Replace target message in timeline // Replace target message in timeline
state.timeline = state.timeline.map(toot => { state.timeline = state.timeline.map(toot => {
if (toot.id === message.id) { if (toot.id === message.id) {
@ -71,7 +71,7 @@ const mutations: MutationTree<TimelineState> = {
} }
}) })
}, },
[MUTATION_TYPES.DELETE_TOOT]: (state, message: Status) => { [MUTATION_TYPES.DELETE_TOOT]: (state, message: Entity.Status) => {
state.timeline = state.timeline.filter(toot => { state.timeline = state.timeline.filter(toot => {
if (toot.reblog !== null && toot.reblog.id === message.id) { if (toot.reblog !== null && toot.reblog.id === message.id) {
return false return false
@ -85,15 +85,16 @@ const mutations: MutationTree<TimelineState> = {
const actions: ActionTree<TimelineState, RootState> = { const actions: ActionTree<TimelineState, RootState> = {
fetchTimeline: async ({ commit, rootState }, account: Account) => { fetchTimeline: async ({ commit, rootState }, account: Account) => {
commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', true, { root: true }) commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', true, { root: true })
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const pinned: Response<Array<Status>> = await client.get<Array<Status>>(`/accounts/${account.id}/statuses`, { limit: 10, pinned: true }) const pinned = await client.getAccountStatuses(account.id, { pinned: true, limit: 10 })
commit(MUTATION_TYPES.UPDATE_PINNED_TOOTS, pinned.data) commit(MUTATION_TYPES.UPDATE_PINNED_TOOTS, pinned.data)
const res: Response<Array<Status>> = await client.get<Array<Status>>(`/accounts/${account.id}/statuses`, { limit: 40 }) const res = await client.getAccountStatuses(account.id, { limit: 40, pinned: false })
commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', false, { root: true }) commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', false, { root: true })
commit(MUTATION_TYPES.UPDATE_TIMELINE, res.data) commit(MUTATION_TYPES.UPDATE_TIMELINE, res.data)
return res.data return res.data
@ -103,16 +104,18 @@ const actions: ActionTree<TimelineState, RootState> = {
return Promise.resolve(null) return Promise.resolve(null)
} }
commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true) commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true)
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
try { try {
const res: Response<Array<Status>> = await client.get<Array<Status>>(`/accounts/${loadPosition.account.id}/statuses`, { const res = await client.getAccountStatuses(loadPosition.account.id, {
max_id: loadPosition.status.id, max_id: loadPosition.status.id,
limit: 40 limit: 40,
pinned: false
}) })
commit(MUTATION_TYPES.INSERT_TIMELINE, res.data) commit(MUTATION_TYPES.INSERT_TIMELINE, res.data)
} finally { } finally {

View File

@ -1,11 +1,11 @@
import Mastodon, { Status, Context, Response } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
export type TootDetailState = { export type TootDetailState = {
message: Status | null message: Entity.Status | null
ancestors: Array<Status> ancestors: Array<Entity.Status>
descendants: Array<Status> descendants: Array<Entity.Status>
} }
const state = (): TootDetailState => ({ const state = (): TootDetailState => ({
@ -27,16 +27,16 @@ export const MUTATION_TYPES = {
} }
const mutations: MutationTree<TootDetailState> = { const mutations: MutationTree<TootDetailState> = {
[MUTATION_TYPES.CHANGE_TOOT]: (state, message: Status) => { [MUTATION_TYPES.CHANGE_TOOT]: (state, message: Entity.Status) => {
state.message = message state.message = message
}, },
[MUTATION_TYPES.UPDATE_ANCESTORS]: (state, ancestors: Array<Status>) => { [MUTATION_TYPES.UPDATE_ANCESTORS]: (state, ancestors: Array<Entity.Status>) => {
state.ancestors = ancestors state.ancestors = ancestors
}, },
[MUTATION_TYPES.UPDATE_DESCENDANTS]: (state, descendants: Array<Status>) => { [MUTATION_TYPES.UPDATE_DESCENDANTS]: (state, descendants: Array<Entity.Status>) => {
state.descendants = descendants state.descendants = descendants
}, },
[MUTATION_TYPES.UPDATE_ANCESTORS_TOOT]: (state, message: Status) => { [MUTATION_TYPES.UPDATE_ANCESTORS_TOOT]: (state, message: Entity.Status) => {
// Replace target message in ancestors // Replace target message in ancestors
state.ancestors = state.ancestors.map(toot => { state.ancestors = state.ancestors.map(toot => {
if (toot.id === message.id) { if (toot.id === message.id) {
@ -53,7 +53,7 @@ const mutations: MutationTree<TootDetailState> = {
} }
}) })
}, },
[MUTATION_TYPES.DELETE_ANCESTORS_TOOT]: (state, message: Status) => { [MUTATION_TYPES.DELETE_ANCESTORS_TOOT]: (state, message: Entity.Status) => {
state.ancestors = state.ancestors.filter(toot => { state.ancestors = state.ancestors.filter(toot => {
if (toot.reblog !== null && toot.reblog.id === message.id) { if (toot.reblog !== null && toot.reblog.id === message.id) {
return false return false
@ -62,7 +62,7 @@ const mutations: MutationTree<TootDetailState> = {
} }
}) })
}, },
[MUTATION_TYPES.UPDATE_TOOT]: (state, message: Status) => { [MUTATION_TYPES.UPDATE_TOOT]: (state, message: Entity.Status) => {
if (state.message === null) { if (state.message === null) {
return return
} }
@ -77,7 +77,7 @@ const mutations: MutationTree<TootDetailState> = {
state.message = Object.assign({}, state.message, reblog) state.message = Object.assign({}, state.message, reblog)
} }
}, },
[MUTATION_TYPES.DELETE_TOOT]: (state, message: Status) => { [MUTATION_TYPES.DELETE_TOOT]: (state, message: Entity.Status) => {
if (state.message === null) { if (state.message === null) {
return return
} }
@ -85,7 +85,7 @@ const mutations: MutationTree<TootDetailState> = {
state.message = null state.message = null
} }
}, },
[MUTATION_TYPES.UPDATE_DESCENDANTS_TOOT]: (state, message: Status) => { [MUTATION_TYPES.UPDATE_DESCENDANTS_TOOT]: (state, message: Entity.Status) => {
// Replace target message in descendants // Replace target message in descendants
state.descendants = state.descendants.map(toot => { state.descendants = state.descendants.map(toot => {
if (toot.id === message.id) { if (toot.id === message.id) {
@ -102,7 +102,7 @@ const mutations: MutationTree<TootDetailState> = {
} }
}) })
}, },
[MUTATION_TYPES.DELETE_DESCENDANTS_TOOT]: (state, message: Status) => { [MUTATION_TYPES.DELETE_DESCENDANTS_TOOT]: (state, message: Entity.Status) => {
state.descendants = state.descendants.filter(toot => { state.descendants = state.descendants.filter(toot => {
if (toot.reblog !== null && toot.reblog.id === message.id) { if (toot.reblog !== null && toot.reblog.id === message.id) {
return false return false
@ -114,20 +114,20 @@ const mutations: MutationTree<TootDetailState> = {
} }
const actions: ActionTree<TootDetailState, RootState> = { const actions: ActionTree<TootDetailState, RootState> = {
changeToot: ({ commit }, message: Status) => { changeToot: ({ commit }, message: Entity.Status) => {
commit(MUTATION_TYPES.UPDATE_ANCESTORS, []) commit(MUTATION_TYPES.UPDATE_ANCESTORS, [])
commit(MUTATION_TYPES.UPDATE_DESCENDANTS, []) commit(MUTATION_TYPES.UPDATE_DESCENDANTS, [])
commit(MUTATION_TYPES.CHANGE_TOOT, message) commit(MUTATION_TYPES.CHANGE_TOOT, message)
}, },
fetchToot: async ({ commit, rootState }, message: Status) => { fetchToot: async ({ commit, rootState }, message: Entity.Status) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Context> = await client.get<Context>(`/statuses/${message.id}/context`, { limit: 40 }) const res = await client.getStatusContext(message.id, { limit: 40 })
commit(MUTATION_TYPES.UPDATE_ANCESTORS, res.data.ancestors) commit(MUTATION_TYPES.UPDATE_ANCESTORS, res.data.ancestors)
commit(MUTATION_TYPES.UPDATE_DESCENDANTS, res.data.descendants) commit(MUTATION_TYPES.UPDATE_DESCENDANTS, res.data.descendants)
return res.data return res.data

View File

@ -1,4 +1,4 @@
import Mastodon, { List, Response } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
import AxiosLoading from '@/utils/axiosLoading' import AxiosLoading from '@/utils/axiosLoading'
@ -34,14 +34,15 @@ const mutations: MutationTree<HeaderMenuState> = {
} }
const actions: ActionTree<HeaderMenuState, RootState> = { const actions: ActionTree<HeaderMenuState, RootState> = {
fetchList: async ({ commit, rootState }, listID: string): Promise<List> => { fetchList: async ({ commit, rootState }, listID: string): Promise<Entity.List> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<List> = await client.get<List>(`/lists/${listID}`) const res = await client.getList(listID)
commit(MUTATION_TYPES.UPDATE_TITLE, `#${res.data.title}`) commit(MUTATION_TYPES.UPDATE_TITLE, `#${res.data.title}`)
return res.data return res.data
}, },

View File

@ -1,10 +1,10 @@
import Mastodon, { Account, Response } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
export type AddListMemberState = { export type AddListMemberState = {
modalOpen: boolean modalOpen: boolean
accounts: Array<Account> accounts: Array<Entity.Account>
targetListId: string | null targetListId: string | null
} }
@ -24,7 +24,7 @@ const mutations: MutationTree<AddListMemberState> = {
[MUTATION_TYPES.CHANGE_MODAL]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_MODAL]: (state, value: boolean) => {
state.modalOpen = value state.modalOpen = value
}, },
[MUTATION_TYPES.UPDATE_ACCOUNTS]: (state, accounts: Array<Account>) => { [MUTATION_TYPES.UPDATE_ACCOUNTS]: (state, accounts: Array<Entity.Account>) => {
state.accounts = accounts state.accounts = accounts
}, },
[MUTATION_TYPES.SET_LIST_ID]: (state, id: string) => { [MUTATION_TYPES.SET_LIST_ID]: (state, id: string) => {
@ -36,30 +36,27 @@ const actions: ActionTree<AddListMemberState, RootState> = {
changeModal: ({ commit }, value: boolean) => { changeModal: ({ commit }, value: boolean) => {
commit(MUTATION_TYPES.CHANGE_MODAL, value) commit(MUTATION_TYPES.CHANGE_MODAL, value)
}, },
search: async ({ commit, rootState }, name: string): Promise<Array<Account>> => { search: async ({ commit, rootState }, name: string): Promise<Array<Entity.Account>> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<Account>> = await client.get<Array<Account>>('/accounts/search', { const res = await client.searchAccount(name, { following: true })
q: name,
following: true
})
commit(MUTATION_TYPES.UPDATE_ACCOUNTS, res.data) commit(MUTATION_TYPES.UPDATE_ACCOUNTS, res.data)
return res.data return res.data
}, },
add: async ({ state, rootState }, account: Account): Promise<{}> => { add: async ({ state, rootState }, account: Account): Promise<{}> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<{}> = await client.post<{}>(`/lists/${state.targetListId}/accounts`, { const res = await client.addAccountsToList(state.targetListId!, [account.id])
account_ids: [account.id]
})
return res.data return res.data
} }
} }

View File

@ -1,11 +1,11 @@
import { Module, MutationTree, ActionTree, GetterTree } from 'vuex' import { Module, MutationTree, ActionTree, GetterTree } from 'vuex'
import { Attachment } from 'megalodon' import { Entity } from 'megalodon'
import { RootState } from '@/store' import { RootState } from '@/store'
export type ImageViewerState = { export type ImageViewerState = {
modalOpen: boolean modalOpen: boolean
currentIndex: number currentIndex: number
mediaList: Array<Attachment> mediaList: Array<Entity.Attachment>
loading: boolean loading: boolean
} }
@ -32,7 +32,7 @@ const mutations: MutationTree<ImageViewerState> = {
[MUTATION_TYPES.CHANGE_CURRENT_INDEX]: (state, currentIndex: number) => { [MUTATION_TYPES.CHANGE_CURRENT_INDEX]: (state, currentIndex: number) => {
state.currentIndex = currentIndex state.currentIndex = currentIndex
}, },
[MUTATION_TYPES.CHANGE_MEDIA_LIST]: (state, mediaList: Array<Attachment>) => { [MUTATION_TYPES.CHANGE_MEDIA_LIST]: (state, mediaList: Array<Entity.Attachment>) => {
state.mediaList = mediaList state.mediaList = mediaList
}, },
[MUTATION_TYPES.INCREMENT_INDEX]: state => { [MUTATION_TYPES.INCREMENT_INDEX]: state => {
@ -50,7 +50,7 @@ const actions: ActionTree<ImageViewerState, RootState> = {
openModal: ({ commit }, { currentIndex, mediaList }) => { openModal: ({ commit }, { currentIndex, mediaList }) => {
commit(MUTATION_TYPES.CHANGE_MODAL, true) commit(MUTATION_TYPES.CHANGE_MODAL, true)
commit(MUTATION_TYPES.CHANGE_CURRENT_INDEX, currentIndex as number) commit(MUTATION_TYPES.CHANGE_CURRENT_INDEX, currentIndex as number)
commit(MUTATION_TYPES.CHANGE_MEDIA_LIST, mediaList as Array<Attachment>) commit(MUTATION_TYPES.CHANGE_MEDIA_LIST, mediaList as Array<Entity.Attachment>)
commit(MUTATION_TYPES.CHANGE_LOADING, true) commit(MUTATION_TYPES.CHANGE_LOADING, true)
}, },
closeModal: ({ commit }) => { closeModal: ({ commit }) => {

View File

@ -1,7 +1,7 @@
import router from '@/router' import router from '@/router'
import i18n from '~/src/config/i18n' import i18n from '~/src/config/i18n'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { List } from 'megalodon' import { Entity } from 'megalodon'
import { LocalTag } from '~/src/types/localTag' import { LocalTag } from '~/src/types/localTag'
import { RootState } from '@/store' import { RootState } from '@/store'
@ -86,7 +86,7 @@ const mutations: MutationTree<JumpState> = {
[MUTATION_TYPES.CHANGE_SELECTED]: (state, channel: Channel) => { [MUTATION_TYPES.CHANGE_SELECTED]: (state, channel: Channel) => {
state.selectedChannel = channel state.selectedChannel = channel
}, },
[MUTATION_TYPES.UPDATE_LIST_CHANNEL]: (state, lists: Array<List>) => { [MUTATION_TYPES.UPDATE_LIST_CHANNEL]: (state, lists: Array<Entity.List>) => {
state.listChannelList = lists.map(l => { state.listChannelList = lists.map(l => {
const channel: Channel = { const channel: Channel = {
name: `#${l.title}`, name: `#${l.title}`,

View File

@ -1,13 +1,13 @@
import Mastodon, { Account, List, Response } from 'megalodon' import generator, { Entity } from 'megalodon'
import lodash from 'lodash' import lodash from 'lodash'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
export type ListMembershipState = { export type ListMembershipState = {
modalOpen: boolean modalOpen: boolean
account: Account | null account: Entity.Account | null
lists: Array<List> lists: Array<Entity.List>
belongToLists: Array<List> belongToLists: Array<Entity.List>
} }
const state = (): ListMembershipState => ({ const state = (): ListMembershipState => ({
@ -28,13 +28,13 @@ const mutations: MutationTree<ListMembershipState> = {
[MUTATION_TYPES.CHANGE_MODAL]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_MODAL]: (state, value: boolean) => {
state.modalOpen = value state.modalOpen = value
}, },
[MUTATION_TYPES.CHANGE_ACCOUNT]: (state, account: Account) => { [MUTATION_TYPES.CHANGE_ACCOUNT]: (state, account: Entity.Account) => {
state.account = account state.account = account
}, },
[MUTATION_TYPES.CHANGE_BELONG_TO_LISTS]: (state, lists: Array<List>) => { [MUTATION_TYPES.CHANGE_BELONG_TO_LISTS]: (state, lists: Array<Entity.List>) => {
state.belongToLists = lists state.belongToLists = lists
}, },
[MUTATION_TYPES.CHANGE_LISTS]: (state, lists: Array<List>) => { [MUTATION_TYPES.CHANGE_LISTS]: (state, lists: Array<Entity.List>) => {
state.lists = lists state.lists = lists
} }
} }
@ -43,51 +43,53 @@ const actions: ActionTree<ListMembershipState, RootState> = {
changeModal: ({ commit }, value: boolean) => { changeModal: ({ commit }, value: boolean) => {
commit(MUTATION_TYPES.CHANGE_MODAL, value) commit(MUTATION_TYPES.CHANGE_MODAL, value)
}, },
setAccount: ({ commit }, account: Account) => { setAccount: ({ commit }, account: Entity.Account) => {
commit(MUTATION_TYPES.CHANGE_ACCOUNT, account) commit(MUTATION_TYPES.CHANGE_ACCOUNT, account)
}, },
fetchListMembership: async ({ commit, rootState }, account: Account) => { fetchListMembership: async ({ commit, rootState }, account: Entity.Account) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<List>> = await client.get<Array<List>>(`/accounts/${account.id}/lists`) const res = await client.getAccountLists(account.id)
commit(MUTATION_TYPES.CHANGE_BELONG_TO_LISTS, res.data.map(l => l.id)) commit(
MUTATION_TYPES.CHANGE_BELONG_TO_LISTS,
res.data.map(l => l.id)
)
return res.data return res.data
}, },
fetchLists: async ({ commit, rootState }) => { fetchLists: async ({ commit, rootState }) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<List>> = await client.get<Array<List>>('/lists') const res = await client.getLists()
commit(MUTATION_TYPES.CHANGE_LISTS, res.data) commit(MUTATION_TYPES.CHANGE_LISTS, res.data)
return res.data return res.data
}, },
changeBelongToLists: async ({ rootState, commit, state }, belongToLists: Array<List>) => { changeBelongToLists: async ({ rootState, commit, state }, belongToLists: Array<Entity.List>) => {
// Calcurate diff // Calcurate diff
const removedLists = lodash.difference(state.belongToLists, belongToLists) const removedLists = lodash.difference(state.belongToLists, belongToLists)
const addedLists = lodash.difference(belongToLists, state.belongToLists) const addedLists = lodash.difference(belongToLists, state.belongToLists)
commit(MUTATION_TYPES.CHANGE_BELONG_TO_LISTS, belongToLists) commit(MUTATION_TYPES.CHANGE_BELONG_TO_LISTS, belongToLists)
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const removedPromise = removedLists.map(id => { const removedPromise = removedLists.map(list => {
return client.del<{}>(`/lists/${id}/accounts`, { return client.deleteAccountsFromList(list.id, [state.account!.id])
account_ids: [state.account!.id]
})
}) })
const addedPromise = addedLists.map(id => { const addedPromise = addedLists.map(list => {
return client.post<{}>(`/lists/${id}/accounts`, { return client.addAccountsToList(list.id, [state.account!.id])
account_ids: [state.account!.id]
})
}) })
const res = await Promise.all(removedPromise.concat(addedPromise)) const res = await Promise.all(removedPromise.concat(addedPromise))
return res return res

View File

@ -1,4 +1,4 @@
import Mastodon, { Account, Response, Relationship } from 'megalodon' import generator from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
@ -34,15 +34,14 @@ const actions: ActionTree<MuteConfirmState, RootState> = {
commit(MUTATION_TYPES.CHANGE_ACCOUNT, account) commit(MUTATION_TYPES.CHANGE_ACCOUNT, account)
}, },
submit: async ({ state, rootState, dispatch }, notify: boolean) => { submit: async ({ state, rootState, dispatch }, notify: boolean) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Relationship> = await client.post<Relationship>(`/accounts/${state.account!.id}/mute`, { const res = await client.muteAccount(state.account!.id, notify)
notifications: notify
})
// Reload relationship // Reload relationship
dispatch('TimelineSpace/Contents/SideBar/AccountProfile/fetchRelationship', state.account, { root: true }) dispatch('TimelineSpace/Contents/SideBar/AccountProfile/fetchRelationship', state.account, { root: true })
return res.data return res.data

View File

@ -1,4 +1,4 @@
import Mastodon, { Status, Attachment, Tag, Response, Account } from 'megalodon' import generator, { Entity } from 'megalodon'
import Visibility, { VisibilityType } from '~/src/constants/visibility' import Visibility, { VisibilityType } from '~/src/constants/visibility'
import TootStatus, { StatusState } from './NewToot/Status' import TootStatus, { StatusState } from './NewToot/Status'
import { Module, MutationTree, ActionTree, GetterTree } from 'vuex' import { Module, MutationTree, ActionTree, GetterTree } from 'vuex'
@ -34,15 +34,15 @@ export type NewTootState = {
modalOpen: boolean modalOpen: boolean
initialStatus: string initialStatus: string
initialSpoiler: string initialSpoiler: string
replyToMessage: Status | null replyToMessage: Entity.Status | null
blockSubmit: boolean blockSubmit: boolean
attachedMedias: Array<Attachment> attachedMedias: Array<Entity.Attachment>
mediaDescriptions: { [key: string]: string | null } mediaDescriptions: { [key: string]: string | null }
visibility: number visibility: number
sensitive: boolean sensitive: boolean
attachedMediaCount: number attachedMediaCount: number
pinedHashtag: boolean pinedHashtag: boolean
hashtags: Array<Tag> hashtags: Array<Entity.Tag>
loading: boolean loading: boolean
} }
@ -92,7 +92,7 @@ const mutations: MutationTree<NewTootState> = {
[MUTATION_TYPES.CHANGE_MODAL]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_MODAL]: (state, value: boolean) => {
state.modalOpen = value state.modalOpen = value
}, },
[MUTATION_TYPES.SET_REPLY_TO]: (state, message: Status) => { [MUTATION_TYPES.SET_REPLY_TO]: (state, message: Entity.Status) => {
state.replyToMessage = message state.replyToMessage = message
}, },
[MUTATION_TYPES.UPDATE_INITIAL_STATUS]: (state, status: string) => { [MUTATION_TYPES.UPDATE_INITIAL_STATUS]: (state, status: string) => {
@ -104,13 +104,13 @@ const mutations: MutationTree<NewTootState> = {
[MUTATION_TYPES.CHANGE_BLOCK_SUBMIT]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_BLOCK_SUBMIT]: (state, value: boolean) => {
state.blockSubmit = value state.blockSubmit = value
}, },
[MUTATION_TYPES.APPEND_ATTACHED_MEDIAS]: (state, media: Attachment) => { [MUTATION_TYPES.APPEND_ATTACHED_MEDIAS]: (state, media: Entity.Attachment) => {
state.attachedMedias = state.attachedMedias.concat([media]) state.attachedMedias = state.attachedMedias.concat([media])
}, },
[MUTATION_TYPES.CLEAR_ATTACHED_MEDIAS]: state => { [MUTATION_TYPES.CLEAR_ATTACHED_MEDIAS]: state => {
state.attachedMedias = [] state.attachedMedias = []
}, },
[MUTATION_TYPES.REMOVE_MEDIA]: (state, media: Attachment) => { [MUTATION_TYPES.REMOVE_MEDIA]: (state, media: Entity.Attachment) => {
state.attachedMedias = state.attachedMedias.filter(m => m.id !== media.id) state.attachedMedias = state.attachedMedias.filter(m => m.id !== media.id)
}, },
[MUTATION_TYPES.UPDATE_MEDIA_DESCRIPTION]: (state, value: MediaDescription) => { [MUTATION_TYPES.UPDATE_MEDIA_DESCRIPTION]: (state, value: MediaDescription) => {
@ -142,7 +142,7 @@ const mutations: MutationTree<NewTootState> = {
[MUTATION_TYPES.CHANGE_PINED_HASHTAG]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_PINED_HASHTAG]: (state, value: boolean) => {
state.pinedHashtag = value state.pinedHashtag = value
}, },
[MUTATION_TYPES.UPDATE_HASHTAGS]: (state, tags: Array<Tag>) => { [MUTATION_TYPES.UPDATE_HASHTAGS]: (state, tags: Array<Entity.Tag>) => {
state.hashtags = tags state.hashtags = tags
}, },
[MUTATION_TYPES.CHANGE_LOADING]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_LOADING]: (state, value: boolean) => {
@ -174,15 +174,16 @@ const actions: ActionTree<NewTootState, RootState> = {
if (rootState.TimelineSpace.account.accessToken === undefined || rootState.TimelineSpace.account.accessToken === null) { if (rootState.TimelineSpace.account.accessToken === undefined || rootState.TimelineSpace.account.accessToken === null) {
throw new AuthenticationError() throw new AuthenticationError()
} }
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken, rootState.TimelineSpace.account.accessToken,
rootState.TimelineSpace.account.baseURL + '/api/v1',
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const attachments = Object.keys(mediaDescription).map(async id => { const attachments = Object.keys(mediaDescription).map(async id => {
if (mediaDescription[id] !== null) { if (mediaDescription[id] !== null) {
return client.put<Attachment>(`/media/${id}`, { description: mediaDescription[id] }) return client.updateMedia(id, { description: mediaDescription[id] })
} else { } else {
return Promise.resolve({}) return Promise.resolve({})
} }
@ -192,7 +193,7 @@ const actions: ActionTree<NewTootState, RootState> = {
throw err throw err
}) })
}, },
postToot: async ({ state, commit, rootState, dispatch }, params: TootForm): Promise<Status> => { postToot: async ({ state, commit, rootState, dispatch }, params: TootForm): Promise<Entity.Status> => {
if (!state.modalOpen) { if (!state.modalOpen) {
throw new NewTootModalOpen() throw new NewTootModalOpen()
} }
@ -204,13 +205,12 @@ const actions: ActionTree<NewTootState, RootState> = {
const visibilityKey: string | undefined = Object.keys(Visibility).find(key => { const visibilityKey: string | undefined = Object.keys(Visibility).find(key => {
return Visibility[key].value === state.visibility return Visibility[key].value === state.visibility
}) })
let specifiedVisibility: string = Visibility.Public.key let specifiedVisibility: 'public' | 'unlisted' | 'private' | 'direct' = Visibility.Public.key
if (visibilityKey !== undefined) { if (visibilityKey !== undefined) {
specifiedVisibility = Visibility[visibilityKey].key specifiedVisibility = Visibility[visibilityKey].key
} }
let form = { let form = {
status: params.status,
visibility: specifiedVisibility, visibility: specifiedVisibility,
sensitive: state.sensitive, sensitive: state.sensitive,
spoiler_text: params.spoiler spoiler_text: params.spoiler
@ -260,15 +260,16 @@ const actions: ActionTree<NewTootState, RootState> = {
} }
commit(MUTATION_TYPES.CHANGE_BLOCK_SUBMIT, true) commit(MUTATION_TYPES.CHANGE_BLOCK_SUBMIT, true)
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken, rootState.TimelineSpace.account.accessToken,
rootState.TimelineSpace.account.baseURL + '/api/v1',
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
return client return client
.post<Status>('/statuses', form) .postStatus(params.status, form)
.then((res: Response<Status>) => { .then(res => {
win.ipcRenderer.send('toot-action-sound') win.ipcRenderer.send('toot-action-sound')
return res.data return res.data
}) })
@ -276,7 +277,7 @@ const actions: ActionTree<NewTootState, RootState> = {
commit(MUTATION_TYPES.CHANGE_BLOCK_SUBMIT, false) commit(MUTATION_TYPES.CHANGE_BLOCK_SUBMIT, false)
}) })
}, },
openReply: ({ commit, rootState }, message: Status) => { openReply: ({ commit, rootState }, message: Entity.Status) => {
commit(MUTATION_TYPES.SET_REPLY_TO, message) commit(MUTATION_TYPES.SET_REPLY_TO, message)
const mentionAccounts = [message.account.acct] const mentionAccounts = [message.account.acct]
.concat(message.mentions.map(a => a.acct)) .concat(message.mentions.map(a => a.acct))
@ -317,16 +318,15 @@ const actions: ActionTree<NewTootState, RootState> = {
if (rootState.TimelineSpace.account.accessToken === undefined || rootState.TimelineSpace.account.accessToken === null) { if (rootState.TimelineSpace.account.accessToken === undefined || rootState.TimelineSpace.account.accessToken === null) {
throw new AuthenticationError() throw new AuthenticationError()
} }
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken, rootState.TimelineSpace.account.accessToken,
rootState.TimelineSpace.account.baseURL + '/api/v1',
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const formData = new FormData()
formData.append('file', image)
return client return client
.post<Attachment>('/media', formData) .uploadMedia(image)
.then(res => { .then(res => {
commit(MUTATION_TYPES.CHANGE_BLOCK_SUBMIT, false) commit(MUTATION_TYPES.CHANGE_BLOCK_SUBMIT, false)
if (res.data.type === 'unknown') throw new NewTootUnknownType() if (res.data.type === 'unknown') throw new NewTootUnknownType()
@ -348,24 +348,25 @@ const actions: ActionTree<NewTootState, RootState> = {
resetMediaCount: ({ commit }) => { resetMediaCount: ({ commit }) => {
commit(MUTATION_TYPES.UPDATE_MEDIA_COUNT, 0) commit(MUTATION_TYPES.UPDATE_MEDIA_COUNT, 0)
}, },
removeMedia: ({ commit, dispatch }, media: Attachment) => { removeMedia: ({ commit, dispatch }, media: Entity.Attachment) => {
commit(MUTATION_TYPES.REMOVE_MEDIA, media) commit(MUTATION_TYPES.REMOVE_MEDIA, media)
commit(MUTATION_TYPES.REMOVE_MEDIA_DESCRIPTION, media.id) commit(MUTATION_TYPES.REMOVE_MEDIA_DESCRIPTION, media.id)
dispatch('decrementMediaCount') dispatch('decrementMediaCount')
}, },
updateHashtags: ({ commit, state }, tags: Array<Tag>) => { updateHashtags: ({ commit, state }, tags: Array<Entity.Tag>) => {
if (state.pinedHashtag && tags.length > 0) { if (state.pinedHashtag && tags.length > 0) {
commit(MUTATION_TYPES.UPDATE_HASHTAGS, tags) commit(MUTATION_TYPES.UPDATE_HASHTAGS, tags)
} }
}, },
fetchVisibility: async ({ commit, rootState }) => { fetchVisibility: async ({ commit, rootState }) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Account> = await client.get<Account>('/accounts/verify_credentials') const res = await client.verifyAccountCredentials()
const visibility: VisibilityType | undefined = (Object.values(Visibility) as Array<VisibilityType>).find(v => { const visibility: VisibilityType | undefined = (Object.values(Visibility) as Array<VisibilityType>).find(v => {
return v.key === res.data.source!.privacy return v.key === res.data.source!.privacy
}) })

View File

@ -1,5 +1,5 @@
import emojilib from 'emojilib' import emojilib from 'emojilib'
import Mastodon, { Account, Response, Results } from 'megalodon' import generator, { MegalodonInterface } from 'megalodon'
import { Module, MutationTree, ActionTree, GetterTree } from 'vuex' import { Module, MutationTree, ActionTree, GetterTree } from 'vuex'
import { RootState } from '@/store/index' import { RootState } from '@/store/index'
import { LocalTag } from '~/src/types/localTag' import { LocalTag } from '~/src/types/localTag'
@ -29,7 +29,7 @@ export type StatusState = {
openSuggest: boolean openSuggest: boolean
startIndex: number | null startIndex: number | null
matchWord: string | null matchWord: string | null
client: Mastodon | null client: MegalodonInterface | null
} }
const state = (): StatusState => ({ const state = (): StatusState => ({
@ -131,7 +131,7 @@ const mutations: MutationTree<StatusState> = {
[MUTATION_TYPES.CLEAR_FILTERED_SUGGESTION]: state => { [MUTATION_TYPES.CLEAR_FILTERED_SUGGESTION]: state => {
state.filteredSuggestion = [] state.filteredSuggestion = []
}, },
[MUTATION_TYPES.SET_CLIENT]: (state, client: Mastodon) => { [MUTATION_TYPES.SET_CLIENT]: (state, client: MegalodonInterface) => {
state.client = client state.client = client
}, },
[MUTATION_TYPES.CLEAR_CLIENT]: state => { [MUTATION_TYPES.CLEAR_CLIENT]: state => {
@ -167,14 +167,15 @@ const actions: ActionTree<StatusState, RootState> = {
}) })
} }
const searchAPI = async () => { const searchAPI = async () => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
commit(MUTATION_TYPES.SET_CLIENT, client) commit(MUTATION_TYPES.SET_CLIENT, client)
const res: Response<Array<Account>> = await client.get<Array<Account>>('/accounts/search', { q: word, resolve: false }) const res = await client.searchAccount(word)
if (res.data.length === 0) throw new Error('Empty') if (res.data.length === 0) throw new Error('Empty')
commit( commit(
MUTATION_TYPES.APPEND_FILTERED_ACCOUNTS, MUTATION_TYPES.APPEND_FILTERED_ACCOUNTS,
@ -214,14 +215,15 @@ const actions: ActionTree<StatusState, RootState> = {
}) })
} }
const searchAPI = async () => { const searchAPI = async () => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v2', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
commit(MUTATION_TYPES.SET_CLIENT, client) commit(MUTATION_TYPES.SET_CLIENT, client)
const res: Response<Results> = await client.get<Results>('/search', { q: word }) const res = await client.search(word, 'hashtags')
if (res.data.hashtags.length === 0) throw new Error('Empty') if (res.data.hashtags.length === 0) throw new Error('Empty')
commit( commit(
MUTATION_TYPES.APPEND_FILTERED_HASHTAGS, MUTATION_TYPES.APPEND_FILTERED_HASHTAGS,

View File

@ -1,10 +1,10 @@
import Mastodon, { Status } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
export type ReportState = { export type ReportState = {
modalOpen: boolean modalOpen: boolean
message: Status | null message: Entity.Status | null
} }
const state = (): ReportState => ({ const state = (): ReportState => ({
@ -21,28 +21,25 @@ const mutations: MutationTree<ReportState> = {
[MUTATION_TYPES.CHANGE_MODAL_OPEN]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_MODAL_OPEN]: (state, value: boolean) => {
state.modalOpen = value state.modalOpen = value
}, },
[MUTATION_TYPES.CHANGE_MESSAGE]: (state, message: Status) => { [MUTATION_TYPES.CHANGE_MESSAGE]: (state, message: Entity.Status) => {
state.message = message state.message = message
} }
} }
const actions: ActionTree<ReportState, RootState> = { const actions: ActionTree<ReportState, RootState> = {
openReport: ({ commit }, message: Status) => { openReport: ({ commit }, message: Entity.Status) => {
commit(MUTATION_TYPES.CHANGE_MESSAGE, message) commit(MUTATION_TYPES.CHANGE_MESSAGE, message)
commit(MUTATION_TYPES.CHANGE_MODAL_OPEN, true) commit(MUTATION_TYPES.CHANGE_MODAL_OPEN, true)
}, },
submit: async ({ rootState }, { account_id, status_id, comment }) => { submit: async ({ rootState }, { account_id, status_id, comment }) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
return client.post<{}>(`/reports`, { return client.report(account_id, comment, { status_ids: [status_id] })
account_id: account_id,
status_ids: [status_id],
comment: comment
})
} }
} }

View File

@ -1,4 +1,4 @@
import Mastodon, { List, Response, Account } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, MutationTree, ActionTree } from 'vuex' import { Module, MutationTree, ActionTree } from 'vuex'
import { LocalTag } from '~/src/types/localTag' import { LocalTag } from '~/src/types/localTag'
import { LocalAccount } from '~/src/types/localAccount' import { LocalAccount } from '~/src/types/localAccount'
@ -15,7 +15,7 @@ export type SideMenuState = {
unreadDirectMessagesTimeline: boolean unreadDirectMessagesTimeline: boolean
unreadPublicTimeline: boolean unreadPublicTimeline: boolean
unreadFollowRequests: boolean unreadFollowRequests: boolean
lists: Array<List> lists: Array<Entity.List>
tags: Array<LocalTag> tags: Array<LocalTag>
collapse: boolean collapse: boolean
} }
@ -68,7 +68,7 @@ const mutations: MutationTree<SideMenuState> = {
[MUTATION_TYPES.CHANGE_UNREAD_FOLLOW_REQUESTS]: (state, value: boolean) => { [MUTATION_TYPES.CHANGE_UNREAD_FOLLOW_REQUESTS]: (state, value: boolean) => {
state.unreadFollowRequests = value state.unreadFollowRequests = value
}, },
[MUTATION_TYPES.UPDATE_LISTS]: (state, lists: Array<List>) => { [MUTATION_TYPES.UPDATE_LISTS]: (state, lists: Array<Entity.List>) => {
state.lists = lists state.lists = lists
}, },
[MUTATION_TYPES.CHANGE_COLLAPSE]: (state, collapse: boolean) => { [MUTATION_TYPES.CHANGE_COLLAPSE]: (state, collapse: boolean) => {
@ -80,27 +80,29 @@ const mutations: MutationTree<SideMenuState> = {
} }
const actions: ActionTree<SideMenuState, RootState> = { const actions: ActionTree<SideMenuState, RootState> = {
fetchLists: async ({ commit, rootState }, account: LocalAccount | null = null): Promise<Array<List>> => { fetchLists: async ({ commit, rootState }, account: LocalAccount | null = null): Promise<Array<Entity.List>> => {
if (account === null) account = rootState.TimelineSpace.account if (account === null) account = rootState.TimelineSpace.account
const client = new Mastodon( const client = generator(
account!.accessToken!, rootState.TimelineSpace.sns,
account!.baseURL + '/api/v1', account.baseURL,
account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<List>> = await client.get<Array<List>>('/lists') const res = await client.getLists()
commit(MUTATION_TYPES.UPDATE_LISTS, res.data) commit(MUTATION_TYPES.UPDATE_LISTS, res.data)
return res.data return res.data
}, },
fetchFollowRequests: async ({ commit, rootState }, account: LocalAccount | null = null): Promise<Array<Account>> => { fetchFollowRequests: async ({ commit, rootState }, account: LocalAccount | null = null): Promise<Array<Entity.Account>> => {
if (account === null) account = rootState.TimelineSpace.account if (account === null) account = rootState.TimelineSpace.account
const client = new Mastodon( const client = generator(
account!.accessToken!, rootState.TimelineSpace.sns,
account!.baseURL + '/api/v1', account.baseURL,
account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Array<Account>> = await client.get<Array<Account>>('/follow_requests') const res = await client.getFollowRequests()
commit(MUTATION_TYPES.CHANGE_UNREAD_FOLLOW_REQUESTS, res.data.length > 0) commit(MUTATION_TYPES.CHANGE_UNREAD_FOLLOW_REQUESTS, res.data.length > 0)
return res.data return res.data
}, },

View File

@ -1,4 +1,4 @@
import Mastodon, { Response, Status, Account, Poll } from 'megalodon' import generator, { Entity } from 'megalodon'
import { Module, ActionTree } from 'vuex' import { Module, ActionTree } from 'vuex'
import { RootState } from '@/store' import { RootState } from '@/store'
import { MyWindow } from '~/src/types/global' import { MyWindow } from '~/src/types/global'
@ -7,7 +7,7 @@ const win = window as MyWindow
type VoteParam = { type VoteParam = {
id: string id: string
choices: Array<string> choices: Array<number>
} }
export type TootState = {} export type TootState = {}
@ -15,14 +15,15 @@ export type TootState = {}
const state = (): TootState => ({}) const state = (): TootState => ({})
const actions: ActionTree<TootState, RootState> = { const actions: ActionTree<TootState, RootState> = {
reblog: async ({ rootState, dispatch }, message: Status) => { reblog: async ({ rootState, dispatch }, message: Entity.Status) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Status> = await client.post<Status>(`/statuses/${message.id}/reblog`) const res = await client.reblogStatus(message.id)
// API returns new status when reblog. // API returns new status when reblog.
// Reblog target status is in the data.reblog. // Reblog target status is in the data.reblog.
// So I send data.reblog as status for update local timeline. // So I send data.reblog as status for update local timeline.
@ -30,79 +31,84 @@ const actions: ActionTree<TootState, RootState> = {
dispatch('TimelineSpace/updateTootForAllTimelines', res.data.reblog, { root: true }) dispatch('TimelineSpace/updateTootForAllTimelines', res.data.reblog, { root: true })
return res.data.reblog return res.data.reblog
}, },
unreblog: async ({ rootState, dispatch }, message: Status) => { unreblog: async ({ rootState, dispatch }, message: Entity.Status) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Status> = await client.post<Status>(`/statuses/${message.id}/unreblog`) const res = await client.unreblogStatus(message.id)
dispatch('TimelineSpace/updateTootForAllTimelines', res.data, { root: true }) dispatch('TimelineSpace/updateTootForAllTimelines', res.data, { root: true })
return res.data return res.data
}, },
addFavourite: async ({ rootState, dispatch }, message: Status) => { addFavourite: async ({ rootState, dispatch }, message: Entity.Status) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Status> = await client.post<Status>(`/statuses/${message.id}/favourite`) const res = await client.favouriteStatus(message.id)
win.ipcRenderer.send('fav-rt-action-sound') win.ipcRenderer.send('fav-rt-action-sound')
dispatch('TimelineSpace/updateTootForAllTimelines', res.data, { root: true }) dispatch('TimelineSpace/updateTootForAllTimelines', res.data, { root: true })
return res.data return res.data
}, },
removeFavourite: async ({ rootState, dispatch }, message: Status) => { removeFavourite: async ({ rootState, dispatch }, message: Entity.Status) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res: Response<Status> = await client.post<Status>(`/statuses/${message.id}/unfavourite`) const res = await client.unfavouriteStatus(message.id)
dispatch('TimelineSpace/updateTootForAllTimelines', res.data, { root: true }) dispatch('TimelineSpace/updateTootForAllTimelines', res.data, { root: true })
return res.data return res.data
}, },
deleteToot: async ({ rootState }, message: Status) => { deleteToot: async ({ rootState }, message: Entity.Status) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
await client.del(`/statuses/${message.id}`) await client.deleteStatus(message.id)
return message return message
}, },
block: async ({ rootState }, account: Account) => { block: async ({ rootState }, account: Account) => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
return client.post(`/accounts/${account.id}/block`) return client.blockAccount(account.id)
}, },
vote: async ({ rootState }, params: VoteParam): Promise<Poll> => { vote: async ({ rootState }, params: VoteParam): Promise<Entity.Poll> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res = await client.post<Poll>(`/polls/${params.id}/votes`, { const res = await client.votePoll(params.id, params.choices)
choices: params.choices
})
return res.data return res.data
}, },
refresh: async ({ rootState }, id: string): Promise<Poll> => { refresh: async ({ rootState }, id: string): Promise<Entity.Poll> => {
const client = new Mastodon( const client = generator(
rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL + '/api/v1', rootState.TimelineSpace.account.baseURL,
rootState.TimelineSpace.account.accessToken,
rootState.App.userAgent, rootState.App.userAgent,
rootState.App.proxyConfiguration rootState.App.proxyConfiguration
) )
const res = await client.get<Poll>(`/polls/${id}`) const res = await client.getPoll(id)
return res.data return res.data
} }
} }

View File

@ -1,11 +1,11 @@
import { Status, Account } from 'megalodon' import { Entity } from 'megalodon'
export type LoadPosition = { export type LoadPosition = {
status: Status status: Entity.Status
} }
export type LoadPositionWithAccount = LoadPosition & { export type LoadPositionWithAccount = LoadPosition & {
account: Account account: Entity.Account
} }
export type LoadPositionWithList = LoadPosition & { export type LoadPositionWithList = LoadPosition & {

View File

@ -1,6 +1,6 @@
import { Account } from 'megalodon' import { Entity } from 'megalodon'
export type RemoveAccountFromList = { export type RemoveAccountFromList = {
account: Account account: Entity.Account
listId: string listId: string
} }

View File

@ -1,6 +1,6 @@
import { Notification } from 'megalodon' import { Entity } from 'megalodon'
export type AccountNotification = { export type AccountNotification = {
id: string id: string
notification: Notification notification: Entity.Notification
} }