mirror of
https://github.com/h3poteto/whalebird-desktop
synced 2025-01-31 01:27:26 +01:00
Merge pull request #873 from h3poteto/iss-850
refs #850 Replace Modals with typescript
This commit is contained in:
commit
1d168268b5
12
package-lock.json
generated
12
package-lock.json
generated
@ -2003,6 +2003,12 @@
|
||||
"integrity": "sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/lodash": {
|
||||
"version": "4.14.123",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.123.tgz",
|
||||
"integrity": "sha512-pQvPkc4Nltyx7G1Ww45OjVqUsJP4UsZm+GWJpigXgkikZqJgRm4c48g027o6tdgubWHwFRF15iFd+Y4Pmqv6+Q==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "11.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.4.tgz",
|
||||
@ -13466,9 +13472,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"megalodon": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/megalodon/-/megalodon-0.6.2.tgz",
|
||||
"integrity": "sha512-EmNs0M6e2AiX9hutoiXo0FUkghZ1HdyLpS8mVkrMMN8btBR2x1hVrAF/8WAFePeJQrEMYjRyQSEJfykJ/4rwaQ==",
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/megalodon/-/megalodon-0.6.3.tgz",
|
||||
"integrity": "sha512-rxh9Kbbwm9Hnn/e8xdzH2Fw5kD/TamgyGFEzOcsnKCqF4iI2qHuojCBm7KeWohgRlwJ9oq7QYVReEVTipqI8kQ==",
|
||||
"requires": {
|
||||
"@types/oauth": "0.9.1",
|
||||
"@types/request": "2.48.1",
|
||||
|
@ -145,7 +145,7 @@
|
||||
"i18next-sync-fs-backend": "^1.1.0",
|
||||
"is-empty": "^1.2.0",
|
||||
"lodash": "^4.17.11",
|
||||
"megalodon": "0.6.2",
|
||||
"megalodon": "0.6.3",
|
||||
"moment": "^2.21.0",
|
||||
"mousetrap": "^1.6.2",
|
||||
"nedb": "^1.8.0",
|
||||
@ -173,6 +173,7 @@
|
||||
"@mapbox/stylelint-processor-arbitrary-tags": "^0.2.0",
|
||||
"@types/i18next": "^12.1.0",
|
||||
"@types/jest": "^24.0.11",
|
||||
"@types/lodash": "^4.14.123",
|
||||
"@types/node": "^11.11.4",
|
||||
"@typescript-eslint/eslint-plugin": "^1.5.0",
|
||||
"@typescript-eslint/parser": "^1.5.0",
|
||||
|
@ -2,7 +2,7 @@ import { Response, Account } from 'megalodon'
|
||||
import mockedMegalodon from '~/spec/mock/megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import AddListMember from '~/src/renderer/store/TimelineSpace/Modals/AddListMember'
|
||||
import AddListMember, { AddListMemberState } from '@/store/TimelineSpace/Modals/AddListMember'
|
||||
|
||||
jest.mock('megalodon')
|
||||
|
||||
@ -28,7 +28,7 @@ const account: Account = {
|
||||
bot: false
|
||||
}
|
||||
|
||||
const state = () => {
|
||||
const state = (): AddListMemberState => {
|
||||
return {
|
||||
modalOpen: false,
|
||||
accounts: [],
|
||||
@ -121,7 +121,7 @@ describe('AddListMember', () => {
|
||||
|
||||
mockedMegalodon.mockImplementation(() => mockClient)
|
||||
const result = await store.dispatch('AddListMember/add', 'akira')
|
||||
expect(result.data).toEqual({})
|
||||
expect(result).toEqual({})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import ImageViewer from '~/src/renderer/store/TimelineSpace/Modals/ImageViewer'
|
||||
import ImageViewer, { ImageViewerState } from '~/src/renderer/store/TimelineSpace/Modals/ImageViewer'
|
||||
|
||||
const state = () => {
|
||||
const state = (): ImageViewerState => {
|
||||
return {
|
||||
modalOpen: false,
|
||||
currentIndex: -1,
|
||||
|
@ -2,9 +2,9 @@ import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import i18n from '~/src/config/i18n'
|
||||
import router from '@/router'
|
||||
import Jump from '~/src/renderer/store/TimelineSpace/Modals/Jump'
|
||||
import Jump, { JumpState, Channel } from '~/src/renderer/store/TimelineSpace/Modals/Jump'
|
||||
|
||||
const state = () => {
|
||||
const state = (): JumpState => {
|
||||
return {
|
||||
modalOpen: true,
|
||||
channel: '',
|
||||
@ -93,10 +93,11 @@ describe('Jump', () => {
|
||||
|
||||
describe('jump', () => {
|
||||
it('should be changed', () => {
|
||||
store.dispatch('Jump/jump', {
|
||||
const channel: Channel = {
|
||||
name: 'public',
|
||||
path: 'public'
|
||||
})
|
||||
}
|
||||
store.dispatch('Jump/jump', channel)
|
||||
expect(store.state.Jump.modalOpen).toEqual(false)
|
||||
expect(router.push).toHaveBeenCalledWith({ path: '/0/public' })
|
||||
})
|
||||
|
@ -1,11 +1,33 @@
|
||||
import { Response, List } from 'megalodon'
|
||||
import { Response, List, Account } from 'megalodon'
|
||||
import mockedMegalodon from '~/spec/mock/megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import ListMembership from '~/src/renderer/store/TimelineSpace/Modals/ListMembership'
|
||||
import ListMembership, { ListMembershipState } from '@/store/TimelineSpace/Modals/ListMembership'
|
||||
|
||||
jest.mock('megalodon')
|
||||
|
||||
const account: Account = {
|
||||
id: 1,
|
||||
username: 'h3poteto',
|
||||
acct: 'h3poteto@pleroma.io',
|
||||
display_name: 'h3poteto',
|
||||
locked: false,
|
||||
created_at: '2019-03-26T21:30:32',
|
||||
followers_count: 10,
|
||||
following_count: 10,
|
||||
statuses_count: 100,
|
||||
note: 'engineer',
|
||||
url: 'https://pleroma.io',
|
||||
avatar: '',
|
||||
avatar_static: '',
|
||||
header: '',
|
||||
header_static: '',
|
||||
emojis: [],
|
||||
moved: null,
|
||||
fields: null,
|
||||
bot: false
|
||||
}
|
||||
|
||||
const list1: List = {
|
||||
id: 1,
|
||||
title: 'list1'
|
||||
@ -16,7 +38,7 @@ const list2: List = {
|
||||
title: 'list2'
|
||||
}
|
||||
|
||||
let state: any = () => {
|
||||
let state = (): ListMembershipState => {
|
||||
return {
|
||||
modalOpen: false,
|
||||
account: null,
|
||||
@ -116,9 +138,7 @@ describe('ListMembership', () => {
|
||||
state = () => {
|
||||
return {
|
||||
modalOpen: false,
|
||||
account: {
|
||||
id: 65
|
||||
},
|
||||
account: account,
|
||||
lists: [],
|
||||
belongToLists: [
|
||||
list2
|
||||
|
@ -1,9 +1,11 @@
|
||||
import i18n from '~/src/config/i18n'
|
||||
import Jump from '@/store/TimelineSpace/Modals/Jump'
|
||||
import Jump, { JumpState, MUTATION_TYPES, Channel } from '@/store/TimelineSpace/Modals/Jump'
|
||||
import Hashtag from '~/src/types/hashtag'
|
||||
import { List } from 'megalodon'
|
||||
|
||||
describe('TimelineSpace/Modals/Jump', () => {
|
||||
describe('mutations', () => {
|
||||
let state
|
||||
let state: JumpState
|
||||
beforeEach(() => {
|
||||
state = {
|
||||
modalOpen: true,
|
||||
@ -53,59 +55,55 @@ describe('TimelineSpace/Modals/Jump', () => {
|
||||
|
||||
describe('updateListChannel', () => {
|
||||
it('should be updated', () => {
|
||||
const channelList = [
|
||||
{
|
||||
id: '0',
|
||||
title: 'admin'
|
||||
},
|
||||
{
|
||||
id: '1',
|
||||
title: 'engineer'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'designer'
|
||||
}
|
||||
]
|
||||
Jump.mutations.updateListChannel(state, channelList)
|
||||
expect(state.listChannelList).toEqual([
|
||||
{
|
||||
path: 'lists/0',
|
||||
name: '#admin'
|
||||
},
|
||||
{
|
||||
path: 'lists/1',
|
||||
name: '#engineer'
|
||||
},
|
||||
{
|
||||
path: 'lists/2',
|
||||
name: '#designer'
|
||||
}
|
||||
])
|
||||
const admin: List = {
|
||||
id: 0,
|
||||
title: 'admin'
|
||||
}
|
||||
const engineer: List = {
|
||||
id: 1,
|
||||
title: 'engineer'
|
||||
}
|
||||
const designer: List = {
|
||||
id: 2,
|
||||
title: 'designer'
|
||||
}
|
||||
const channelList = [admin, engineer, designer]
|
||||
Jump.mutations![MUTATION_TYPES.UPDATE_LIST_CHANNEL](state, channelList)
|
||||
const adminChannel: Channel = {
|
||||
path: 'lists/0',
|
||||
name: '#admin'
|
||||
}
|
||||
const engineerChannel: Channel = {
|
||||
path: 'lists/1',
|
||||
name: '#engineer'
|
||||
}
|
||||
const designerChannel: Channel = {
|
||||
path: 'lists/2',
|
||||
name: '#designer'
|
||||
}
|
||||
expect(state.listChannelList).toEqual([adminChannel, engineerChannel, designerChannel])
|
||||
})
|
||||
})
|
||||
|
||||
describe('updateTagChannel', () => {
|
||||
it('should be updated', () => {
|
||||
const channelList = [
|
||||
{
|
||||
tagName: 'whalebird'
|
||||
},
|
||||
{
|
||||
tagName: 'tqrk'
|
||||
}
|
||||
]
|
||||
Jump.mutations.updateTagChannel(state, channelList)
|
||||
expect(state.tagChannelList).toEqual([
|
||||
{
|
||||
name: '#whalebird',
|
||||
path: 'hashtag/whalebird'
|
||||
},
|
||||
{
|
||||
name: '#tqrk',
|
||||
path: 'hashtag/tqrk'
|
||||
}
|
||||
])
|
||||
const whalebird: Hashtag = {
|
||||
tagName: 'whalebird'
|
||||
}
|
||||
const tqrk: Hashtag = {
|
||||
tagName: 'tqrk'
|
||||
}
|
||||
const channelList = [whalebird, tqrk]
|
||||
Jump.mutations![MUTATION_TYPES.UPDATE_TAG_CHANNEL](state, channelList)
|
||||
const whalebirdChannel: Channel = {
|
||||
name: '#whalebird',
|
||||
path: 'hashtag/whalebird'
|
||||
}
|
||||
const tqrkChannel: Channel = {
|
||||
name: '#tqrk',
|
||||
path: 'hashtag/tqrk'
|
||||
}
|
||||
expect(state.tagChannelList).toEqual([whalebirdChannel, tqrkChannel])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -1,14 +1,22 @@
|
||||
import General from './Preferences/General'
|
||||
import Account from './Preferences/Account'
|
||||
import Language from './Preferences/Language'
|
||||
import Notification from './Preferences/Notification'
|
||||
import Appearance from './Preferences/Appearance'
|
||||
import General, { GeneralState } from './Preferences/General'
|
||||
import Account, { AccountState } from './Preferences/Account'
|
||||
import Language, { LanguageState } from './Preferences/Language'
|
||||
import Appearance, { AppearanceState } from './Preferences/Appearance'
|
||||
import Notification, { NotificationState } from './Preferences/Notification'
|
||||
import { Module } from 'vuex'
|
||||
|
||||
export interface PreferencesState {}
|
||||
|
||||
const state = (): PreferencesState => ({})
|
||||
|
||||
export interface PreferencesModuleState extends PreferencesState {
|
||||
General: GeneralState,
|
||||
Account: AccountState,
|
||||
Language: LanguageState,
|
||||
Notification: NotificationState,
|
||||
Appearance: AppearanceState
|
||||
}
|
||||
|
||||
// TODO: use type of rootState
|
||||
const Preferences: Module<PreferencesState, any> = {
|
||||
namespaced: true,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import General from './Settings/General'
|
||||
import Timeline from './Settings/Timeline'
|
||||
import General, { GeneralState } from './Settings/General'
|
||||
import Timeline, { TimelineState } from './Settings/Timeline'
|
||||
import { Module, MutationTree } from 'vuex'
|
||||
|
||||
export interface SettingsState {
|
||||
@ -20,6 +20,11 @@ const mutations: MutationTree<SettingsState> = {
|
||||
}
|
||||
}
|
||||
|
||||
export interface SettingsModuleState extends SettingsState {
|
||||
General: GeneralState,
|
||||
Timeline: TimelineState,
|
||||
}
|
||||
|
||||
// TODO: use type of rootState
|
||||
const Settings: Module<SettingsState, any> = {
|
||||
namespaced: true,
|
||||
|
@ -1,9 +1,9 @@
|
||||
import sanitizeHtml from 'sanitize-html'
|
||||
import { ipcRenderer } from 'electron'
|
||||
import Mastodon, { Account, Emoji, Instance, Status, Notification as NotificationType } from 'megalodon'
|
||||
import SideMenu from './TimelineSpace/SideMenu'
|
||||
import HeaderMenu from './TimelineSpace/HeaderMenu'
|
||||
import Modals from './TimelineSpace/Modals'
|
||||
import SideMenu, { SideMenuState } from './TimelineSpace/SideMenu'
|
||||
import HeaderMenu, { HeaderMenuState } from './TimelineSpace/HeaderMenu'
|
||||
import Modals, { ModalsModuleState } from './TimelineSpace/Modals'
|
||||
import Contents from './TimelineSpace/Contents'
|
||||
import router from '@/router'
|
||||
import unreadSettings from '~/src/constants/unreadNotification'
|
||||
@ -416,6 +416,13 @@ const actions: ActionTree<TimelineSpaceState, any> = {
|
||||
}
|
||||
}
|
||||
|
||||
export interface TimelineSpaceModuleState extends TimelineSpaceState {
|
||||
SideMenu: SideMenuState,
|
||||
HeaderMenu: HeaderMenuState,
|
||||
Modals: ModalsModuleState
|
||||
// TODO: Contents: ContentsState
|
||||
}
|
||||
|
||||
const TimelineSpace: Module<TimelineSpaceState, any> = {
|
||||
namespaced: true,
|
||||
modules: {
|
||||
|
@ -1,37 +0,0 @@
|
||||
import NewToot from './Modals/NewToot'
|
||||
import ImageViewer from './Modals/ImageViewer'
|
||||
import Jump from './Modals/Jump'
|
||||
import ListMembership from './Modals/ListMembership'
|
||||
import AddListMember from './Modals/AddListMember'
|
||||
import MuteConfirm from './Modals/MuteConfirm'
|
||||
import Shortcut from './Modals/Shortcut'
|
||||
import Report from './Modals/Report'
|
||||
|
||||
const Modals = {
|
||||
namespaced: true,
|
||||
modules: {
|
||||
ImageViewer,
|
||||
NewToot,
|
||||
Jump,
|
||||
ListMembership,
|
||||
AddListMember,
|
||||
MuteConfirm,
|
||||
Shortcut,
|
||||
Report
|
||||
},
|
||||
getters: {
|
||||
modalOpened: (state, getters, rootState) => {
|
||||
const imageViewer = rootState.TimelineSpace.Modals.ImageViewer.modalOpen
|
||||
const newToot = rootState.TimelineSpace.Modals.NewToot.modalOpen
|
||||
const jump = rootState.TimelineSpace.Modals.Jump.modalOpen
|
||||
const listMembership = rootState.TimelineSpace.Modals.ListMembership.modalOpen
|
||||
const addListMember = rootState.TimelineSpace.Modals.AddListMember.modalOpen
|
||||
const shortcut = rootState.TimelineSpace.Modals.Shortcut.modalOpen
|
||||
const muteConfirm = rootState.TimelineSpace.Modals.MuteConfirm.modalOpen
|
||||
const report = rootState.TimelineSpace.Modals.Report.modalOpen
|
||||
return imageViewer || newToot || jump || listMembership || addListMember || shortcut || muteConfirm || report
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Modals
|
57
src/renderer/store/TimelineSpace/Modals.ts
Normal file
57
src/renderer/store/TimelineSpace/Modals.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import NewToot, { NewTootModuleState } from './Modals/NewToot'
|
||||
import ImageViewer, { ImageViewerState } from './Modals/ImageViewer'
|
||||
import Jump, { JumpState } from './Modals/Jump'
|
||||
import ListMembership, { ListMembershipState } from './Modals/ListMembership'
|
||||
import AddListMember, { AddListMemberState } from './Modals/AddListMember'
|
||||
import MuteConfirm, { MuteConfirmState } from './Modals/MuteConfirm'
|
||||
import Shortcut, { ShortcutState } from './Modals/Shortcut'
|
||||
import Report, { ReportState } from './Modals/Report'
|
||||
import { Module, GetterTree } from 'vuex'
|
||||
import { RootState } from '@/store/index'
|
||||
|
||||
export interface ModalsState {}
|
||||
|
||||
export interface ModalsModuleState extends ModalsState {
|
||||
Jump: JumpState,
|
||||
AddListMember: AddListMemberState,
|
||||
ImageViewer: ImageViewerState,
|
||||
ListMembership: ListMembershipState,
|
||||
MuteConfirm: MuteConfirmState,
|
||||
NewToot: NewTootModuleState,
|
||||
Report: ReportState,
|
||||
Shortcut: ShortcutState
|
||||
}
|
||||
|
||||
const state = (): ModalsState => ({})
|
||||
|
||||
const getters: GetterTree<ModalsState, RootState> = {
|
||||
modalOpened: (_state, _getters, rootState) => {
|
||||
const imageViewer = rootState.TimelineSpace.Modals.ImageViewer.modalOpen
|
||||
const newToot = rootState.TimelineSpace.Modals.NewToot.modalOpen
|
||||
const jump = rootState.TimelineSpace.Modals.Jump.modalOpen
|
||||
const listMembership = rootState.TimelineSpace.Modals.ListMembership.modalOpen
|
||||
const addListMember = rootState.TimelineSpace.Modals.AddListMember.modalOpen
|
||||
const shortcut = rootState.TimelineSpace.Modals.Shortcut.modalOpen
|
||||
const muteConfirm = rootState.TimelineSpace.Modals.MuteConfirm.modalOpen
|
||||
const report = rootState.TimelineSpace.Modals.Report.modalOpen
|
||||
return imageViewer || newToot || jump || listMembership || addListMember || shortcut || muteConfirm || report
|
||||
}
|
||||
}
|
||||
|
||||
const Modals: Module<ModalsState, RootState> = {
|
||||
namespaced: true,
|
||||
modules: {
|
||||
ImageViewer,
|
||||
NewToot,
|
||||
Jump,
|
||||
ListMembership,
|
||||
AddListMember,
|
||||
MuteConfirm,
|
||||
Shortcut,
|
||||
Report
|
||||
},
|
||||
state: state,
|
||||
getters: getters
|
||||
}
|
||||
|
||||
export default Modals
|
@ -1,49 +0,0 @@
|
||||
import Mastodon from 'megalodon'
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
modalOpen: false,
|
||||
accounts: [],
|
||||
targetListId: null
|
||||
},
|
||||
mutations: {
|
||||
changeModal (state, value) {
|
||||
state.modalOpen = value
|
||||
},
|
||||
updateAccounts (state, accounts) {
|
||||
state.accounts = accounts
|
||||
},
|
||||
setListId (state, id) {
|
||||
state.targetListId = id
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
changeModal ({ commit }, value) {
|
||||
commit('changeModal', value)
|
||||
},
|
||||
search ({ commit, rootState }, name) {
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
return client.get('/accounts/search', {
|
||||
q: name,
|
||||
following: true
|
||||
})
|
||||
.then(res => {
|
||||
commit('updateAccounts', res.data)
|
||||
return res.data
|
||||
})
|
||||
},
|
||||
add ({ state, rootState }, account) {
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
return client.post(`/lists/${state.targetListId}/accounts`, {
|
||||
account_ids: [account.id]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
70
src/renderer/store/TimelineSpace/Modals/AddListMember.ts
Normal file
70
src/renderer/store/TimelineSpace/Modals/AddListMember.ts
Normal file
@ -0,0 +1,70 @@
|
||||
import Mastodon, { Account, Response } from 'megalodon'
|
||||
import { Module, MutationTree, ActionTree } from 'vuex'
|
||||
|
||||
export interface AddListMemberState {
|
||||
modalOpen: boolean,
|
||||
accounts: Array<Account>,
|
||||
targetListId: number | null
|
||||
}
|
||||
|
||||
const state = (): AddListMemberState => ({
|
||||
modalOpen: false,
|
||||
accounts: [],
|
||||
targetListId: null
|
||||
})
|
||||
|
||||
export const MUTATION_TYPES = {
|
||||
CHANGE_MODAL: 'changeModal',
|
||||
UPDATE_ACCOUNTS: 'updateAccounts',
|
||||
SET_LIST_ID: 'setListId'
|
||||
}
|
||||
|
||||
const mutations: MutationTree<AddListMemberState> = {
|
||||
[MUTATION_TYPES.CHANGE_MODAL]: (state, value: boolean) => {
|
||||
state.modalOpen = value
|
||||
},
|
||||
[MUTATION_TYPES.UPDATE_ACCOUNTS]: (state, accounts: Array<Account>) => {
|
||||
state.accounts = accounts
|
||||
},
|
||||
[MUTATION_TYPES.SET_LIST_ID]: (state, id: number) => {
|
||||
state.targetListId = id
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: use type of rootState
|
||||
const actions: ActionTree<AddListMemberState, any> = {
|
||||
changeModal: ({ commit }, value: boolean) => {
|
||||
commit(MUTATION_TYPES.CHANGE_MODAL, value)
|
||||
},
|
||||
search: async ({ commit, rootState }, name: string): Promise<Array<Account>> => {
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
const res: Response<Array<Account>> = await client.get<Array<Account>>('/accounts/search', {
|
||||
q: name,
|
||||
following: true
|
||||
})
|
||||
commit(MUTATION_TYPES.UPDATE_ACCOUNTS, res.data)
|
||||
return res.data
|
||||
},
|
||||
add: async ({ state, rootState }, account: Account): Promise<{}> => {
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
const res: Response<{}> = await client.post<{}>(`/lists/${state.targetListId}/accounts`, {
|
||||
account_ids: [account.id]
|
||||
})
|
||||
return res.data
|
||||
}
|
||||
}
|
||||
|
||||
const AddListMember: Module<AddListMemberState, any> = {
|
||||
namespaced: true,
|
||||
state: state,
|
||||
mutations: mutations,
|
||||
actions: actions
|
||||
}
|
||||
|
||||
export default AddListMember
|
@ -1,78 +0,0 @@
|
||||
const ImageViewer = {
|
||||
namespaced: true,
|
||||
state: {
|
||||
modalOpen: false,
|
||||
currentIndex: -1,
|
||||
mediaList: [],
|
||||
loading: false
|
||||
},
|
||||
mutations: {
|
||||
changeModal (state, value) {
|
||||
state.modalOpen = value
|
||||
},
|
||||
changeCurrentIndex (state, currentIndex) {
|
||||
state.currentIndex = currentIndex
|
||||
},
|
||||
changeMedliaList (state, mediaList) {
|
||||
state.mediaList = mediaList
|
||||
},
|
||||
incrementIndex (state) {
|
||||
state.currentIndex++
|
||||
},
|
||||
decrementIndex (state) {
|
||||
state.currentIndex--
|
||||
},
|
||||
loading (state, value) {
|
||||
state.loading = value
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
openModal ({ commit }, { currentIndex, mediaList }) {
|
||||
commit('changeModal', true)
|
||||
commit('changeCurrentIndex', currentIndex)
|
||||
commit('changeMedliaList', mediaList)
|
||||
commit('loading', true)
|
||||
},
|
||||
closeModal ({ commit }) {
|
||||
commit('changeModal', false)
|
||||
commit('changeCurrentIndex', -1)
|
||||
commit('changeMedliaList', [])
|
||||
commit('loading', false)
|
||||
},
|
||||
incrementIndex ({ commit }) {
|
||||
commit('incrementIndex')
|
||||
commit('loading', true)
|
||||
},
|
||||
decrementIndex ({ commit }) {
|
||||
commit('decrementIndex')
|
||||
commit('loading', true)
|
||||
},
|
||||
async loaded ({ commit }) {
|
||||
commit('loading', false)
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
imageURL (state) {
|
||||
if (state.currentIndex >= 0) {
|
||||
return state.mediaList[state.currentIndex].url
|
||||
}
|
||||
},
|
||||
imageType (state) {
|
||||
if (state.currentIndex >= 0) {
|
||||
return state.mediaList[state.currentIndex].type
|
||||
}
|
||||
},
|
||||
showLeft (state) {
|
||||
const notFirst = (state.currentIndex > 0)
|
||||
const isManyItem = (state.mediaList.length > 1)
|
||||
return (notFirst && isManyItem)
|
||||
},
|
||||
showRight (state) {
|
||||
const notLast = (state.currentIndex < (state.mediaList.length - 1))
|
||||
const isManyItem = (state.mediaList.length > 1)
|
||||
return (notLast && isManyItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default ImageViewer
|
108
src/renderer/store/TimelineSpace/Modals/ImageViewer.ts
Normal file
108
src/renderer/store/TimelineSpace/Modals/ImageViewer.ts
Normal file
@ -0,0 +1,108 @@
|
||||
import { Module, MutationTree, ActionTree, GetterTree } from 'vuex'
|
||||
import { Attachment } from 'megalodon'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
export interface ImageViewerState {
|
||||
modalOpen: boolean,
|
||||
currentIndex: number,
|
||||
mediaList: Array<Attachment>,
|
||||
loading: boolean
|
||||
}
|
||||
|
||||
const state = (): ImageViewerState => ({
|
||||
modalOpen: false,
|
||||
currentIndex: -1,
|
||||
mediaList: [],
|
||||
loading: false
|
||||
})
|
||||
|
||||
export const MUTATION_TYPES = {
|
||||
CHANGE_MODAL: 'changeModal',
|
||||
CHANGE_CURRENT_INDEX: 'changeCurrentIndex',
|
||||
CHANGE_MEDIA_LIST: 'changeMediaList',
|
||||
INCREMENT_INDEX: 'incrementIndex',
|
||||
DECREMENT_INDEX: 'decrementIndex',
|
||||
CHANGE_LOADING: 'changeLoading'
|
||||
}
|
||||
|
||||
const mutations: MutationTree<ImageViewerState> = {
|
||||
[MUTATION_TYPES.CHANGE_MODAL]: (state, value: boolean) => {
|
||||
state.modalOpen = value
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_CURRENT_INDEX]: (state, currentIndex: number) => {
|
||||
state.currentIndex = currentIndex
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_MEDIA_LIST]: (state, mediaList: Array<Attachment>) => {
|
||||
state.mediaList = mediaList
|
||||
},
|
||||
[MUTATION_TYPES.INCREMENT_INDEX]: (state) => {
|
||||
state.currentIndex++
|
||||
},
|
||||
[MUTATION_TYPES.DECREMENT_INDEX]: (state) => {
|
||||
state.currentIndex--
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_LOADING]: (state, value: boolean) => {
|
||||
state.loading = value
|
||||
}
|
||||
}
|
||||
|
||||
const actions: ActionTree<ImageViewerState, RootState> = {
|
||||
openModal: ({ commit }, { currentIndex, mediaList }) => {
|
||||
commit(MUTATION_TYPES.CHANGE_MODAL, true)
|
||||
commit(MUTATION_TYPES.CHANGE_CURRENT_INDEX, currentIndex as number)
|
||||
commit(MUTATION_TYPES.CHANGE_MEDIA_LIST, mediaList as Array<Attachment>)
|
||||
commit(MUTATION_TYPES.CHANGE_LOADING, true)
|
||||
},
|
||||
closeModal: ({ commit }) => {
|
||||
commit(MUTATION_TYPES.CHANGE_MODAL, false)
|
||||
commit(MUTATION_TYPES.CHANGE_CURRENT_INDEX, -1)
|
||||
commit(MUTATION_TYPES.CHANGE_MEDIA_LIST, [])
|
||||
commit(MUTATION_TYPES.CHANGE_LOADING, false)
|
||||
},
|
||||
incrementIndex: ({ commit }) => {
|
||||
commit(MUTATION_TYPES.INCREMENT_INDEX)
|
||||
commit(MUTATION_TYPES.CHANGE_LOADING, true)
|
||||
},
|
||||
decrementIndex: ({ commit }) => {
|
||||
commit(MUTATION_TYPES.DECREMENT_INDEX)
|
||||
commit(MUTATION_TYPES.CHANGE_LOADING, true)
|
||||
},
|
||||
loaded: ({ commit }) => {
|
||||
commit(MUTATION_TYPES.CHANGE_LOADING, false)
|
||||
}
|
||||
}
|
||||
|
||||
const getters: GetterTree<ImageViewerState, RootState> = {
|
||||
imageURL: (state): string | null => {
|
||||
if (state.currentIndex >= 0) {
|
||||
return state.mediaList[state.currentIndex].url
|
||||
}
|
||||
return null
|
||||
},
|
||||
imageType: (state): string | null => {
|
||||
if (state.currentIndex >= 0) {
|
||||
return state.mediaList[state.currentIndex].type
|
||||
}
|
||||
return null
|
||||
},
|
||||
showLeft: (state): boolean => {
|
||||
const notFirst = (state.currentIndex > 0)
|
||||
const isManyItem = (state.mediaList.length > 1)
|
||||
return (notFirst && isManyItem)
|
||||
},
|
||||
showRight: (state): boolean => {
|
||||
const notLast = (state.currentIndex < (state.mediaList.length - 1))
|
||||
const isManyItem = (state.mediaList.length > 1)
|
||||
return (notLast && isManyItem)
|
||||
}
|
||||
}
|
||||
|
||||
const ImageViewer: Module<ImageViewerState, RootState> = {
|
||||
namespaced: true,
|
||||
state: state,
|
||||
mutations: mutations,
|
||||
actions: actions,
|
||||
getters: getters
|
||||
}
|
||||
|
||||
export default ImageViewer
|
@ -1,99 +0,0 @@
|
||||
import router from '@/router'
|
||||
import i18n from '~/src/config/i18n'
|
||||
|
||||
const Jump = {
|
||||
namespaced: true,
|
||||
state: {
|
||||
modalOpen: false,
|
||||
channel: '',
|
||||
defaultChannelList: [
|
||||
{
|
||||
name: i18n.t('side_menu.home'),
|
||||
path: 'home'
|
||||
},
|
||||
{
|
||||
name: i18n.t('side_menu.notification'),
|
||||
path: 'notifications'
|
||||
},
|
||||
{
|
||||
name: i18n.t('side_menu.mention'),
|
||||
path: 'mentions'
|
||||
},
|
||||
{
|
||||
name: i18n.t('side_menu.favourite'),
|
||||
path: 'favourites'
|
||||
},
|
||||
{
|
||||
name: i18n.t('side_menu.local'),
|
||||
path: 'local'
|
||||
},
|
||||
{
|
||||
name: i18n.t('side_menu.public'),
|
||||
path: 'public'
|
||||
},
|
||||
{
|
||||
name: i18n.t('side_menu.hashtag'),
|
||||
path: 'hashtag'
|
||||
},
|
||||
{
|
||||
name: i18n.t('side_menu.search'),
|
||||
path: 'search'
|
||||
},
|
||||
{
|
||||
name: i18n.t('side_menu.direct'),
|
||||
path: 'direct-messages'
|
||||
}
|
||||
],
|
||||
listChannelList: [],
|
||||
tagChannelList: [],
|
||||
selectedChannel: {
|
||||
name: i18n.t('side_menu.home'),
|
||||
path: 'home'
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
changeModal (state, value) {
|
||||
state.modalOpen = value
|
||||
},
|
||||
updateChannel (state, value) {
|
||||
state.channel = value
|
||||
},
|
||||
changeSelected (state, value) {
|
||||
state.selectedChannel = value
|
||||
},
|
||||
updateListChannel (state, list) {
|
||||
state.listChannelList = list.map((l) => {
|
||||
return {
|
||||
name: `#${l.title}`,
|
||||
path: `lists/${l.id}`
|
||||
}
|
||||
})
|
||||
},
|
||||
updateTagChannel (state, tags) {
|
||||
state.tagChannelList = tags.map(t => {
|
||||
return {
|
||||
name: `#${t.tagName}`,
|
||||
path: `hashtag/${t.tagName}`
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
jumpCurrentSelected ({ state, commit, rootState }) {
|
||||
commit('changeModal', false)
|
||||
router.push({ path: `/${rootState.TimelineSpace.account._id}/${state.selectedChannel.path}` })
|
||||
},
|
||||
jump ({ commit, rootState }, channel) {
|
||||
commit('changeModal', false)
|
||||
router.push({ path: `/${rootState.TimelineSpace.account._id}/${channel.path}` })
|
||||
},
|
||||
syncListChannel ({ commit, rootState }) {
|
||||
commit('updateListChannel', rootState.TimelineSpace.SideMenu.lists)
|
||||
},
|
||||
syncTagChannel ({ commit, rootState }) {
|
||||
commit('updateTagChannel', rootState.TimelineSpace.SideMenu.tags)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Jump
|
133
src/renderer/store/TimelineSpace/Modals/Jump.ts
Normal file
133
src/renderer/store/TimelineSpace/Modals/Jump.ts
Normal file
@ -0,0 +1,133 @@
|
||||
import router from '@/router'
|
||||
import i18n from '~/src/config/i18n'
|
||||
import { Module, MutationTree, ActionTree } from 'vuex'
|
||||
import { List } from 'megalodon'
|
||||
import Hashtag from '~/src/types/hashtag'
|
||||
|
||||
export interface Channel {
|
||||
name: string,
|
||||
path: string
|
||||
}
|
||||
|
||||
export interface JumpState {
|
||||
modalOpen: boolean,
|
||||
channel: string,
|
||||
defaultChannelList: Array<Channel>,
|
||||
listChannelList: Array<Channel>,
|
||||
tagChannelList: Array<Channel>,
|
||||
selectedChannel: Channel
|
||||
}
|
||||
|
||||
const state = (): JumpState => ({
|
||||
modalOpen: false,
|
||||
channel: '',
|
||||
defaultChannelList: [
|
||||
{
|
||||
name: i18n.t('side_menu.home'),
|
||||
path: 'home'
|
||||
},
|
||||
{
|
||||
name: i18n.t('side_menu.notification'),
|
||||
path: 'notifications'
|
||||
},
|
||||
{
|
||||
name: i18n.t('side_menu.mention'),
|
||||
path: 'mentions'
|
||||
},
|
||||
{
|
||||
name: i18n.t('side_menu.favourite'),
|
||||
path: 'favourites'
|
||||
},
|
||||
{
|
||||
name: i18n.t('side_menu.local'),
|
||||
path: 'local'
|
||||
},
|
||||
{
|
||||
name: i18n.t('side_menu.public'),
|
||||
path: 'public'
|
||||
},
|
||||
{
|
||||
name: i18n.t('side_menu.hashtag'),
|
||||
path: 'hashtag'
|
||||
},
|
||||
{
|
||||
name: i18n.t('side_menu.search'),
|
||||
path: 'search'
|
||||
},
|
||||
{
|
||||
name: i18n.t('side_menu.direct'),
|
||||
path: 'direct-messages'
|
||||
}
|
||||
],
|
||||
listChannelList: [],
|
||||
tagChannelList: [],
|
||||
selectedChannel: {
|
||||
name: i18n.t('side_menu.home'),
|
||||
path: 'home'
|
||||
}
|
||||
})
|
||||
|
||||
export const MUTATION_TYPES = {
|
||||
CHANGE_MODAL: 'changeModal',
|
||||
UPDATE_CHANNEL: 'updateChannel',
|
||||
CHANGE_SELECTED: 'changeSelected',
|
||||
UPDATE_LIST_CHANNEL: 'updateListChannel',
|
||||
UPDATE_TAG_CHANNEL: 'updateTagChannel'
|
||||
}
|
||||
|
||||
const mutations: MutationTree<JumpState> = {
|
||||
[MUTATION_TYPES.CHANGE_MODAL]: (state, value: boolean) => {
|
||||
state.modalOpen = value
|
||||
},
|
||||
[MUTATION_TYPES.UPDATE_CHANNEL]: (state, channel: string) => {
|
||||
state.channel = channel
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_SELECTED]: (state, channel: Channel) => {
|
||||
state.selectedChannel = channel
|
||||
},
|
||||
[MUTATION_TYPES.UPDATE_LIST_CHANNEL]: (state, lists: Array<List>) => {
|
||||
state.listChannelList = lists.map((l) => {
|
||||
const channel: Channel = {
|
||||
name: `#${l.title}`,
|
||||
path: `lists/${l.id}`
|
||||
}
|
||||
return channel
|
||||
})
|
||||
},
|
||||
[MUTATION_TYPES.UPDATE_TAG_CHANNEL]: (state, tags: Array<Hashtag>) => {
|
||||
state.tagChannelList = tags.map(t => {
|
||||
const channel: Channel = {
|
||||
name: `#${t.tagName}`,
|
||||
path: `hashtag/${t.tagName}`
|
||||
}
|
||||
return channel
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: use type of rootState
|
||||
const actions: ActionTree<JumpState, any> = {
|
||||
jumpCurrentSelected: ({ state, commit, rootState }) => {
|
||||
commit(MUTATION_TYPES.CHANGE_MODAL, false)
|
||||
router.push({ path: `/${rootState.TimelineSpace.account._id}/${state.selectedChannel.path}` })
|
||||
},
|
||||
jump: ({ commit, rootState }, channel: Channel) => {
|
||||
commit(MUTATION_TYPES.CHANGE_MODAL, false)
|
||||
router.push({ path: `/${rootState.TimelineSpace.account._id}/${channel.path}` })
|
||||
},
|
||||
syncListChannel: ({ commit, rootState }) => {
|
||||
commit(MUTATION_TYPES.UPDATE_LIST_CHANNEL, rootState.TimelineSpace.SideMenu.lists)
|
||||
},
|
||||
syncTagChannel: ({ commit, rootState }) => {
|
||||
commit(MUTATION_TYPES.UPDATE_TAG_CHANNEL, rootState.TimelineSpace.SideMenu.tags)
|
||||
}
|
||||
}
|
||||
|
||||
const Jump: Module<JumpState, any> = {
|
||||
namespaced: true,
|
||||
state: state,
|
||||
mutations: mutations,
|
||||
actions: actions
|
||||
}
|
||||
|
||||
export default Jump
|
@ -1,80 +0,0 @@
|
||||
import Mastodon from 'megalodon'
|
||||
import _ from 'lodash'
|
||||
|
||||
const ListMembership = {
|
||||
namespaced: true,
|
||||
state: {
|
||||
modalOpen: false,
|
||||
account: null,
|
||||
lists: [],
|
||||
belongToLists: []
|
||||
},
|
||||
mutations: {
|
||||
changeModal (state, value) {
|
||||
state.modalOpen = value
|
||||
},
|
||||
changeAccount (state, account) {
|
||||
state.account = account
|
||||
},
|
||||
changeBelongToLists (state, lists) {
|
||||
state.belongToLists = lists
|
||||
},
|
||||
changeLists (state, lists) {
|
||||
state.lists = lists
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
changeModal ({ commit }, value) {
|
||||
commit('changeModal', value)
|
||||
},
|
||||
setAccount ({ commit }, account) {
|
||||
commit('changeAccount', account)
|
||||
},
|
||||
fetchListMembership ({ commit, rootState }, account) {
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
return client.get(`/accounts/${account.id}/lists`)
|
||||
.then(res => {
|
||||
commit('changeBelongToLists', res.data.map(l => l.id))
|
||||
return res.data
|
||||
})
|
||||
},
|
||||
fetchLists ({ commit, rootState }) {
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
return client.get('/lists')
|
||||
.then(res => {
|
||||
commit('changeLists', res.data)
|
||||
return res.data
|
||||
})
|
||||
},
|
||||
async changeBelongToLists ({ rootState, commit, state }, belongToLists) {
|
||||
// Calcurate diff
|
||||
const removedLists = _.difference(state.belongToLists, belongToLists)
|
||||
const addedLists = _.difference(belongToLists, state.belongToLists)
|
||||
commit('changeBelongToLists', belongToLists)
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
const removedPromise = removedLists.map(id => {
|
||||
return client.del(`/lists/${id}/accounts`, {
|
||||
account_ids: [state.account.id]
|
||||
})
|
||||
})
|
||||
const addedPromise = addedLists.map(id => {
|
||||
return client.post(`/lists/${id}/accounts`, {
|
||||
account_ids: [state.account.id]
|
||||
})
|
||||
})
|
||||
const res = await Promise.all(removedPromise.concat(addedPromise))
|
||||
return res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default ListMembership
|
98
src/renderer/store/TimelineSpace/Modals/ListMembership.ts
Normal file
98
src/renderer/store/TimelineSpace/Modals/ListMembership.ts
Normal file
@ -0,0 +1,98 @@
|
||||
import Mastodon, { Account, List, Response } from 'megalodon'
|
||||
import lodash from 'lodash'
|
||||
import { Module, MutationTree, ActionTree } from 'vuex'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
export interface ListMembershipState {
|
||||
modalOpen: boolean,
|
||||
account: Account | null,
|
||||
lists: Array<List>,
|
||||
belongToLists: Array<List>
|
||||
}
|
||||
|
||||
const state = (): ListMembershipState => ({
|
||||
modalOpen: false,
|
||||
account: null,
|
||||
lists: [],
|
||||
belongToLists: []
|
||||
})
|
||||
|
||||
export const MUTATION_TYPES = {
|
||||
CHANGE_MODAL: 'changeModal',
|
||||
CHANGE_ACCOUNT: 'changeAccount',
|
||||
CHANGE_BELONG_TO_LISTS: 'changeBelongToLists',
|
||||
CHANGE_LISTS: 'changeLists'
|
||||
}
|
||||
|
||||
const mutations: MutationTree<ListMembershipState> = {
|
||||
[MUTATION_TYPES.CHANGE_MODAL]: (state, value: boolean) => {
|
||||
state.modalOpen = value
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_ACCOUNT]: (state, account: Account) => {
|
||||
state.account = account
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_BELONG_TO_LISTS]: (state, lists: Array<List>) => {
|
||||
state.belongToLists = lists
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_LISTS]: (state, lists: Array<List>) => {
|
||||
state.lists = lists
|
||||
}
|
||||
}
|
||||
|
||||
const actions: ActionTree<ListMembershipState, RootState> = {
|
||||
changeModal: ({ commit }, value: boolean) => {
|
||||
commit(MUTATION_TYPES.CHANGE_MODAL, value)
|
||||
},
|
||||
setAccount: ({ commit }, account: Account) => {
|
||||
commit(MUTATION_TYPES.CHANGE_ACCOUNT, account)
|
||||
},
|
||||
fetchListMembership: async ({ commit, rootState }, account: Account) => {
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken!,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
const res: Response<Array<List>> = await client.get<Array<List>>(`/accounts/${account.id}/lists`)
|
||||
commit(MUTATION_TYPES.CHANGE_BELONG_TO_LISTS, res.data.map(l => l.id))
|
||||
return res.data
|
||||
},
|
||||
fetchLists: async ({ commit, rootState }) => {
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken!,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
const res: Response<Array<List>> = await client.get<Array<List>>('/lists')
|
||||
commit(MUTATION_TYPES.CHANGE_LISTS, res.data)
|
||||
return res.data
|
||||
},
|
||||
changeBelongToLists: async ({ rootState, commit, state }, belongToLists: Array<List>) => {
|
||||
// Calcurate diff
|
||||
const removedLists = lodash.difference(state.belongToLists, belongToLists)
|
||||
const addedLists = lodash.difference(belongToLists, state.belongToLists)
|
||||
commit(MUTATION_TYPES.CHANGE_BELONG_TO_LISTS, belongToLists)
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken!,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
const removedPromise = removedLists.map(id => {
|
||||
return client.del<{}>(`/lists/${id}/accounts`, {
|
||||
account_ids: [state.account!.id]
|
||||
})
|
||||
})
|
||||
const addedPromise = addedLists.map(id => {
|
||||
return client.post<{}>(`/lists/${id}/accounts`, {
|
||||
account_ids: [state.account!.id]
|
||||
})
|
||||
})
|
||||
const res = await Promise.all(removedPromise.concat(addedPromise))
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
const ListMembership: Module<ListMembershipState, RootState> = {
|
||||
namespaced: true,
|
||||
state: state,
|
||||
mutations: mutations,
|
||||
actions: actions
|
||||
}
|
||||
|
||||
export default ListMembership
|
@ -1,39 +0,0 @@
|
||||
import Mastodon from 'megalodon'
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
modalOpen: false,
|
||||
account: {}
|
||||
},
|
||||
mutations: {
|
||||
changeModal (state, value) {
|
||||
state.modalOpen = value
|
||||
},
|
||||
changeAccount (state, account) {
|
||||
state.account = account
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
changeModal ({ commit }, value) {
|
||||
commit('changeModal', value)
|
||||
},
|
||||
changeAccount ({ commit }, account) {
|
||||
commit('changeAccount', account)
|
||||
},
|
||||
async submit ({ state, rootState, dispatch }, notify) {
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
return client.post(`/accounts/${state.account.id}/mute`, {
|
||||
notifications: notify
|
||||
})
|
||||
.then(res => {
|
||||
// Reload relationship
|
||||
dispatch('TimelineSpace/Contents/SideBar/AccountProfile/fetchRelationship', state.account, { root: true })
|
||||
return res.data
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
57
src/renderer/store/TimelineSpace/Modals/MuteConfirm.ts
Normal file
57
src/renderer/store/TimelineSpace/Modals/MuteConfirm.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import Mastodon, { Account, Response, Relationship } from 'megalodon'
|
||||
import { Module, MutationTree, ActionTree } from 'vuex'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
export interface MuteConfirmState {
|
||||
modalOpen: boolean,
|
||||
account: Account | null
|
||||
}
|
||||
|
||||
const state = (): MuteConfirmState => ({
|
||||
modalOpen: false,
|
||||
account: null
|
||||
})
|
||||
|
||||
export const MUTATION_TYPES = {
|
||||
CHANGE_MODAL: 'changeModal',
|
||||
CHANGE_ACCOUNT: 'changeAccount'
|
||||
}
|
||||
|
||||
const mutations: MutationTree<MuteConfirmState> = {
|
||||
[MUTATION_TYPES.CHANGE_MODAL]: (state, value: boolean) => {
|
||||
state.modalOpen = value
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_ACCOUNT]: (state, account: Account) => {
|
||||
state.account = account
|
||||
}
|
||||
}
|
||||
|
||||
const actions: ActionTree<MuteConfirmState, RootState> = {
|
||||
changeModal: ({ commit }, value: boolean) => {
|
||||
commit(MUTATION_TYPES.CHANGE_MODAL, value)
|
||||
},
|
||||
changeAccount: ({ commit }, account: Account) => {
|
||||
commit(MUTATION_TYPES.CHANGE_ACCOUNT, account)
|
||||
},
|
||||
submit: async ({ state, rootState, dispatch }, notify: boolean) => {
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken!,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
const res: Response<Relationship> = await client.post<Relationship>(`/accounts/${state.account!.id}/mute`, {
|
||||
notifications: notify
|
||||
})
|
||||
// Reload relationship
|
||||
dispatch('TimelineSpace/Contents/SideBar/AccountProfile/fetchRelationship', state.account, { root: true })
|
||||
return res.data
|
||||
}
|
||||
}
|
||||
|
||||
const MuteConfirm: Module<MuteConfirmState, RootState> = {
|
||||
namespaced: true,
|
||||
state: state,
|
||||
mutations: mutations,
|
||||
actions: actions
|
||||
}
|
||||
|
||||
export default MuteConfirm
|
@ -1,204 +0,0 @@
|
||||
import Mastodon from 'megalodon'
|
||||
import { ipcRenderer } from 'electron'
|
||||
import Visibility from '~/src/constants/visibility'
|
||||
import Status from './NewToot/Status'
|
||||
|
||||
const NewToot = {
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Status
|
||||
},
|
||||
state: {
|
||||
modalOpen: false,
|
||||
initialStatus: '',
|
||||
initialSpoiler: '',
|
||||
replyToMessage: null,
|
||||
blockSubmit: false,
|
||||
attachedMedias: [],
|
||||
visibility: Visibility.Public.value,
|
||||
sensitive: false,
|
||||
attachedMediaId: 0,
|
||||
pinedHashtag: false,
|
||||
hashtags: []
|
||||
},
|
||||
mutations: {
|
||||
changeModal (state, value) {
|
||||
state.modalOpen = value
|
||||
},
|
||||
setReplyTo (state, message) {
|
||||
state.replyToMessage = message
|
||||
},
|
||||
updateInitialStatus (state, status) {
|
||||
state.initialStatus = status
|
||||
},
|
||||
updateInitialSpoiler (state, cw) {
|
||||
state.initialSpoiler = cw
|
||||
},
|
||||
changeBlockSubmit (state, value) {
|
||||
state.blockSubmit = value
|
||||
},
|
||||
appendAttachedMedias (state, media) {
|
||||
state.attachedMedias = state.attachedMedias.concat([media])
|
||||
},
|
||||
clearAttachedMedias (state) {
|
||||
state.attachedMedias = []
|
||||
},
|
||||
removeMedia (state, media) {
|
||||
state.attachedMedias = state.attachedMedias.filter(m => m.id !== media.id)
|
||||
},
|
||||
/**
|
||||
* changeVisibilityValue
|
||||
* Update visibility using direct value
|
||||
* @param state vuex state object
|
||||
* @param value visibility value
|
||||
*/
|
||||
changeVisibilityValue (state, value) {
|
||||
state.visibility = value
|
||||
},
|
||||
changeSensitive (state, value) {
|
||||
state.sensitive = value
|
||||
},
|
||||
updateMediaId (state, value) {
|
||||
state.attachedMediaId = value
|
||||
},
|
||||
changePinedHashtag (state, value) {
|
||||
state.pinedHashtag = value
|
||||
},
|
||||
updateHashtags (state, tags) {
|
||||
state.hashtags = tags
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
hashtagInserting (state) {
|
||||
return !state.replyToMessage && state.pinedHashtag
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
async updateMedia ({ rootState }, media) {
|
||||
if (rootState.TimelineSpace.account.accessToken === undefined || rootState.TimelineSpace.account.accessToken === null) {
|
||||
throw new AuthenticationError()
|
||||
}
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
return Promise.all(
|
||||
Object.keys(media).map(async id => {
|
||||
return client.put(`/media/${id}`, { description: media[id] })
|
||||
}
|
||||
)).catch(err => {
|
||||
console.error(err)
|
||||
throw err
|
||||
})
|
||||
},
|
||||
async postToot ({ state, commit, rootState }, form) {
|
||||
if (rootState.TimelineSpace.account.accessToken === undefined || rootState.TimelineSpace.account.accessToken === null) {
|
||||
throw new AuthenticationError()
|
||||
}
|
||||
if (state.blockSubmit) {
|
||||
return
|
||||
}
|
||||
commit('changeBlockSubmit', true)
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
return client.post('/statuses', form)
|
||||
.then(res => {
|
||||
ipcRenderer.send('toot-action-sound')
|
||||
return res.data
|
||||
})
|
||||
.finally(() => {
|
||||
commit('changeBlockSubmit', false)
|
||||
})
|
||||
},
|
||||
openReply ({ commit, rootState }, message) {
|
||||
commit('setReplyTo', message)
|
||||
const mentionAccounts = [message.account.acct].concat(message.mentions.map(a => a.acct))
|
||||
.filter((a, i, self) => self.indexOf(a) === i)
|
||||
.filter((a) => a !== rootState.TimelineSpace.account.username)
|
||||
commit('updateInitialStatus', `${mentionAccounts.map(m => `@${m}`).join(' ')} `)
|
||||
commit('updateInitialSpoiler', message.spoiler_text)
|
||||
commit('changeModal', true)
|
||||
let value = Visibility.Public.value
|
||||
Object.keys(Visibility).map(key => {
|
||||
const target = Visibility[key]
|
||||
if (target.key === message.visibility) {
|
||||
value = target.value
|
||||
}
|
||||
})
|
||||
commit('changeVisibilityValue', value)
|
||||
},
|
||||
openModal ({ dispatch, commit, state }) {
|
||||
if (!state.replyToMessage && state.pinedHashtag) {
|
||||
commit('updateInitialStatus', state.hashtags.map(t => ` #${t.name}`).join())
|
||||
}
|
||||
commit('changeModal', true)
|
||||
dispatch('fetchVisibility')
|
||||
},
|
||||
closeModal ({ commit }) {
|
||||
commit('changeModal', false)
|
||||
commit('updateInitialStatus', '')
|
||||
commit('updateInitialSpoiler', '')
|
||||
commit('setReplyTo', null)
|
||||
commit('changeBlockSubmit', false)
|
||||
commit('clearAttachedMedias')
|
||||
commit('changeSensitive', false)
|
||||
commit('changeVisibilityValue', Visibility.Public.value)
|
||||
},
|
||||
uploadImage ({ commit, rootState }, image) {
|
||||
commit('changeBlockSubmit', true)
|
||||
if (rootState.TimelineSpace.account.accessToken === undefined || rootState.TimelineSpace.account.accessToken === null) {
|
||||
throw new AuthenticationError()
|
||||
}
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
const formData = new FormData()
|
||||
formData.append('file', image)
|
||||
return client.post('/media', formData)
|
||||
.then(res => {
|
||||
commit('changeBlockSubmit', false)
|
||||
if (res.data.type === 'unknown') throw new UnknownTypeError()
|
||||
commit('appendAttachedMedias', res.data)
|
||||
return res.data
|
||||
})
|
||||
.catch(err => {
|
||||
commit('changeBlockSubmit', false)
|
||||
console.error(err)
|
||||
throw err
|
||||
})
|
||||
},
|
||||
incrementMediaId ({ commit, state }) {
|
||||
commit('updateMediaId', state.attachedMediaId + 1)
|
||||
},
|
||||
resetMediaId ({ commit }) {
|
||||
commit('updateMediaId', 0)
|
||||
},
|
||||
updateHashtags ({ commit, state }, tags) {
|
||||
if (state.pinedHashtag) {
|
||||
commit('updateHashtags', tags)
|
||||
}
|
||||
},
|
||||
fetchVisibility ({ commit, rootState }) {
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
return client.get('/accounts/verify_credentials')
|
||||
.then(res => {
|
||||
const visibility = Object.values(Visibility).find((v) => {
|
||||
return v.key === res.data.source.privacy
|
||||
})
|
||||
commit('changeVisibilityValue', visibility.value)
|
||||
return res.data
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default NewToot
|
||||
|
||||
class AuthenticationError {}
|
||||
class UnknownTypeError {}
|
250
src/renderer/store/TimelineSpace/Modals/NewToot.ts
Normal file
250
src/renderer/store/TimelineSpace/Modals/NewToot.ts
Normal file
@ -0,0 +1,250 @@
|
||||
import Mastodon, { Status, Attachment, Tag, Response, Account } from 'megalodon'
|
||||
import { ipcRenderer } from 'electron'
|
||||
import Visibility from '~/src/constants/visibility'
|
||||
import TootStatus, { StatusState } from './NewToot/Status'
|
||||
import { Module, MutationTree, ActionTree, GetterTree } from 'vuex'
|
||||
import { RootState } from '@/store'
|
||||
import VisibilityType from '~/src/types/visibility'
|
||||
|
||||
export interface NewTootState {
|
||||
modalOpen: boolean,
|
||||
initialStatus: string,
|
||||
initialSpoiler: string,
|
||||
replyToMessage: Status | null,
|
||||
blockSubmit: boolean,
|
||||
attachedMedias: Array<Attachment>,
|
||||
visibility: number,
|
||||
sensitive: boolean,
|
||||
attachedMediaId: number,
|
||||
pinedHashtag: boolean,
|
||||
hashtags: Array<Tag>
|
||||
}
|
||||
|
||||
export interface NewTootModuleState extends NewTootState {
|
||||
Status: StatusState
|
||||
}
|
||||
|
||||
const state = (): NewTootState => ({
|
||||
modalOpen: false,
|
||||
initialStatus: '',
|
||||
initialSpoiler: '',
|
||||
replyToMessage: null,
|
||||
blockSubmit: false,
|
||||
attachedMedias: [],
|
||||
visibility: Visibility.Public.value,
|
||||
sensitive: false,
|
||||
attachedMediaId: 0,
|
||||
pinedHashtag: false,
|
||||
hashtags: []
|
||||
})
|
||||
|
||||
export const MUTATION_TYPES = {
|
||||
CHANGE_MODAL: 'changeModal',
|
||||
SET_REPLY_TO: 'setReplyTo',
|
||||
UPDATE_INITIAL_STATUS: 'updateInitialStatus',
|
||||
UPDATE_INITIAL_SPOILER: 'updateInitialSpoiler',
|
||||
CHANGE_BLOCK_SUBMIT: 'changeBlockSubmit',
|
||||
APPEND_ATTACHED_MEDIAS: 'appendAttachedMedias',
|
||||
CLEAR_ATTACHED_MEDIAS: 'clearAttachedMedias',
|
||||
REMOVE_MEDIA: 'removeMedia',
|
||||
CHANGE_VISIBILITY_VALUE: 'changeVisibilityValue',
|
||||
CHANGE_SENSITIVE: 'changeSensitive',
|
||||
UPDATE_MEDIA_ID: 'updateMediaId',
|
||||
CHANGE_PINED_HASHTAG: 'changePinedHashtag',
|
||||
UPDATE_HASHTAGS: 'updateHashtags'
|
||||
}
|
||||
|
||||
const mutations: MutationTree<NewTootState> = {
|
||||
[MUTATION_TYPES.CHANGE_MODAL]: (state, value: boolean) => {
|
||||
state.modalOpen = value
|
||||
},
|
||||
[MUTATION_TYPES.SET_REPLY_TO]: (state, message: Status) => {
|
||||
state.replyToMessage = message
|
||||
},
|
||||
[MUTATION_TYPES.UPDATE_INITIAL_STATUS]: (state, status: string) => {
|
||||
state.initialStatus = status
|
||||
},
|
||||
[MUTATION_TYPES.UPDATE_INITIAL_SPOILER]: (state, cw: string) => {
|
||||
state.initialSpoiler = cw
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_BLOCK_SUBMIT]: (state, value: boolean) => {
|
||||
state.blockSubmit = value
|
||||
},
|
||||
[MUTATION_TYPES.APPEND_ATTACHED_MEDIAS]: (state, media: Attachment) => {
|
||||
state.attachedMedias = state.attachedMedias.concat([media])
|
||||
},
|
||||
[MUTATION_TYPES.CLEAR_ATTACHED_MEDIAS]: (state) => {
|
||||
state.attachedMedias = []
|
||||
},
|
||||
[MUTATION_TYPES.REMOVE_MEDIA]: (state, media: Attachment) => {
|
||||
state.attachedMedias = state.attachedMedias.filter(m => m.id !== media.id)
|
||||
},
|
||||
/**
|
||||
* changeVisibilityValue
|
||||
* Update visibility using direct value
|
||||
* @param state vuex state object
|
||||
* @param value visibility value
|
||||
*/
|
||||
[MUTATION_TYPES.CHANGE_VISIBILITY_VALUE]: (state, value: number) => {
|
||||
state.visibility = value
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_SENSITIVE]: (state, value: boolean) => {
|
||||
state.sensitive = value
|
||||
},
|
||||
[MUTATION_TYPES.UPDATE_MEDIA_ID]: (state, value: number) => {
|
||||
state.attachedMediaId = value
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_PINED_HASHTAG]: (state, value: boolean) => {
|
||||
state.pinedHashtag = value
|
||||
},
|
||||
[MUTATION_TYPES.UPDATE_HASHTAGS]: (state, tags: Array<Tag>) => {
|
||||
state.hashtags = tags
|
||||
}
|
||||
}
|
||||
|
||||
const actions: ActionTree<NewTootState, RootState> = {
|
||||
updateMedia: async ({ rootState }, media: Attachment) => {
|
||||
if (rootState.TimelineSpace.account.accessToken === undefined || rootState.TimelineSpace.account.accessToken === null) {
|
||||
throw new AuthenticationError()
|
||||
}
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
const attachments = Object.keys(media).map(async id => {
|
||||
return client.put<Attachment>(`/media/${id}`, { description: media[id] })
|
||||
})
|
||||
return Promise.all(attachments)
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
throw err
|
||||
})
|
||||
},
|
||||
postToot: async ({ state, commit, rootState }, form) => {
|
||||
if (rootState.TimelineSpace.account.accessToken === undefined || rootState.TimelineSpace.account.accessToken === null) {
|
||||
throw new AuthenticationError()
|
||||
}
|
||||
if (state.blockSubmit) {
|
||||
return
|
||||
}
|
||||
commit(MUTATION_TYPES.CHANGE_BLOCK_SUBMIT, true)
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
return client.post<Status>('/statuses', form)
|
||||
.then((res: Response<Status>) => {
|
||||
ipcRenderer.send('toot-action-sound')
|
||||
return res.data
|
||||
})
|
||||
.finally(() => {
|
||||
commit(MUTATION_TYPES.CHANGE_BLOCK_SUBMIT, false)
|
||||
})
|
||||
},
|
||||
openReply: ({ commit, rootState }, message: Status) => {
|
||||
commit(MUTATION_TYPES.SET_REPLY_TO, message)
|
||||
const mentionAccounts = [message.account.acct].concat(message.mentions.map(a => a.acct))
|
||||
.filter((a, i, self) => self.indexOf(a) === i)
|
||||
.filter((a) => a !== rootState.TimelineSpace.account.username)
|
||||
commit(MUTATION_TYPES.UPDATE_INITIAL_STATUS, `${mentionAccounts.map(m => `@${m}`).join(' ')} `)
|
||||
commit(MUTATION_TYPES.UPDATE_INITIAL_SPOILER, message.spoiler_text)
|
||||
commit(MUTATION_TYPES.CHANGE_MODAL, true)
|
||||
let value: number = Visibility.Public.value
|
||||
Object.keys(Visibility).map(key => {
|
||||
const target = Visibility[key]
|
||||
if (target.key === message.visibility) {
|
||||
value = target.value
|
||||
}
|
||||
})
|
||||
commit(MUTATION_TYPES.CHANGE_VISIBILITY_VALUE, value)
|
||||
},
|
||||
openModal: ({ dispatch, commit, state }) => {
|
||||
if (!state.replyToMessage && state.pinedHashtag) {
|
||||
commit(MUTATION_TYPES.UPDATE_INITIAL_STATUS, state.hashtags.map(t => ` #${t.name}`).join())
|
||||
}
|
||||
commit(MUTATION_TYPES.CHANGE_MODAL, true)
|
||||
dispatch('fetchVisibility')
|
||||
},
|
||||
closeModal: ({ commit }) => {
|
||||
commit(MUTATION_TYPES.CHANGE_MODAL, false)
|
||||
commit(MUTATION_TYPES.UPDATE_INITIAL_STATUS, '')
|
||||
commit(MUTATION_TYPES.UPDATE_INITIAL_SPOILER, '')
|
||||
commit(MUTATION_TYPES.SET_REPLY_TO, null)
|
||||
commit(MUTATION_TYPES.CHANGE_BLOCK_SUBMIT, false)
|
||||
commit(MUTATION_TYPES.CLEAR_ATTACHED_MEDIAS)
|
||||
commit(MUTATION_TYPES.CHANGE_SENSITIVE, false)
|
||||
commit(MUTATION_TYPES.CHANGE_VISIBILITY_VALUE, Visibility.Public.value)
|
||||
},
|
||||
uploadImage: async ({ commit, rootState }, image: any) => {
|
||||
commit(MUTATION_TYPES.CHANGE_BLOCK_SUBMIT, true)
|
||||
if (rootState.TimelineSpace.account.accessToken === undefined || rootState.TimelineSpace.account.accessToken === null) {
|
||||
throw new AuthenticationError()
|
||||
}
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
const formData = new FormData()
|
||||
formData.append('file', image)
|
||||
return client.post<Attachment>('/media', formData)
|
||||
.then(res => {
|
||||
commit(MUTATION_TYPES.CHANGE_BLOCK_SUBMIT, false)
|
||||
if (res.data.type === 'unknown') throw new UnknownTypeError()
|
||||
commit(MUTATION_TYPES.APPEND_ATTACHED_MEDIAS, res.data)
|
||||
return res.data
|
||||
})
|
||||
.catch(err => {
|
||||
commit(MUTATION_TYPES.CHANGE_BLOCK_SUBMIT, false)
|
||||
console.error(err)
|
||||
throw err
|
||||
})
|
||||
},
|
||||
incrementMediaId: ({ commit, state }) => {
|
||||
commit(MUTATION_TYPES.UPDATE_MEDIA_ID, state.attachedMediaId + 1)
|
||||
},
|
||||
resetMediaId: ({ commit }) => {
|
||||
commit(MUTATION_TYPES.UPDATE_MEDIA_ID, 0)
|
||||
},
|
||||
updateHashtags: ({ commit, state }, tags: Array<Tag>) => {
|
||||
if (state.pinedHashtag) {
|
||||
commit(MUTATION_TYPES.UPDATE_HASHTAGS, tags)
|
||||
}
|
||||
},
|
||||
fetchVisibility: async ({ commit, rootState }) => {
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken!,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
const res: Response<Account> = await client.get<Account>('/accounts/verify_credentials')
|
||||
const visibility: VisibilityType = Object.values(Visibility as Array<Visibility>).find((v) => {
|
||||
return v.key === res.data.source!.privacy
|
||||
})
|
||||
if (visibility === undefined) {
|
||||
throw new Error('Visibility value is invalid')
|
||||
}
|
||||
commit(MUTATION_TYPES.CHANGE_VISIBILITY_VALUE, visibility.value)
|
||||
return res.data
|
||||
}
|
||||
}
|
||||
|
||||
const getters: GetterTree<NewTootState, RootState> = {
|
||||
hashtagInserting: (state) => {
|
||||
return !state.replyToMessage && state.pinedHashtag
|
||||
}
|
||||
}
|
||||
|
||||
const NewToot: Module<NewTootState, RootState> = {
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Status: TootStatus
|
||||
},
|
||||
state: state,
|
||||
mutations: mutations,
|
||||
getters: getters,
|
||||
actions: actions
|
||||
}
|
||||
|
||||
export default NewToot
|
||||
|
||||
class AuthenticationError {}
|
||||
class UnknownTypeError {}
|
@ -1,73 +0,0 @@
|
||||
import Mastodon from 'megalodon'
|
||||
|
||||
const Status = {
|
||||
namespaced: true,
|
||||
state: {
|
||||
filteredAccounts: [],
|
||||
filteredHashtags: []
|
||||
},
|
||||
mutations: {
|
||||
updateFilteredAccounts (state, accounts) {
|
||||
state.filteredAccounts = accounts.map((a) => {
|
||||
return {
|
||||
name: `@${a.acct}`,
|
||||
image: null
|
||||
}
|
||||
})
|
||||
},
|
||||
clearFilteredAccounts (state) {
|
||||
state.filteredAccounts = []
|
||||
},
|
||||
updateFilteredHashtags (state, tags) {
|
||||
state.filteredHashtags = tags.map((t) => {
|
||||
return {
|
||||
name: `#${t}`,
|
||||
image: null
|
||||
}
|
||||
})
|
||||
},
|
||||
clearFilteredHashtags (state) {
|
||||
state.filteredHashtags = []
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
async searchAccount ({ commit, rootState }, word) {
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
const res = await client.get('/search', { q: word, resolve: false })
|
||||
commit('updateFilteredAccounts', res.data.accounts)
|
||||
if (res.data.accounts.length === 0) throw new Error('Empty')
|
||||
return res.data.accounts
|
||||
},
|
||||
async searchHashtag ({ commit, rootState }, word) {
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
const res = await client.get('/search', { q: word })
|
||||
commit('updateFilteredHashtags', res.data.hashtags)
|
||||
if (res.data.hashtags.length === 0) throw new Error('Empty')
|
||||
return res.data.hashtags
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
pickerEmojis: (state, getters, rootState) => {
|
||||
return rootState.TimelineSpace.emojis.filter((e, i, array) => {
|
||||
return (array.findIndex(ar => e.name === ar.name) === i)
|
||||
}).map(e => {
|
||||
return {
|
||||
name: e.name,
|
||||
short_names: [e.name],
|
||||
text: e.name,
|
||||
emoticons: [],
|
||||
keywords: [e.name],
|
||||
imageUrl: e.image
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Status
|
100
src/renderer/store/TimelineSpace/Modals/NewToot/Status.ts
Normal file
100
src/renderer/store/TimelineSpace/Modals/NewToot/Status.ts
Normal file
@ -0,0 +1,100 @@
|
||||
import Mastodon, { Account, Tag, Response, Results } from 'megalodon'
|
||||
import { Module, MutationTree, ActionTree, GetterTree } from 'vuex'
|
||||
import { RootState } from '@/store/index'
|
||||
|
||||
interface Suggest {
|
||||
name: string,
|
||||
image: string | null
|
||||
}
|
||||
|
||||
interface SuggestAccount extends Suggest {}
|
||||
|
||||
interface SuggestHashtag extends Suggest {}
|
||||
|
||||
export interface StatusState {
|
||||
filteredAccounts: Array<SuggestAccount>,
|
||||
filteredHashtags: Array<SuggestHashtag>
|
||||
}
|
||||
|
||||
const state = (): StatusState => ({
|
||||
filteredAccounts: [],
|
||||
filteredHashtags: []
|
||||
})
|
||||
|
||||
export const MUTATION_TYPES = {
|
||||
UPDATE_FILTERED_ACCOUNTS: 'updateFilteredAccounts',
|
||||
CLEAR_FILTERED_ACCOUNTS: 'clearFilteredAccounts',
|
||||
UPDATE_FILTERED_HASHTAGS: 'updateFilteredHashtags',
|
||||
CLAER_FILTERED_HASHTAGS: 'clearFilteredHashtags'
|
||||
}
|
||||
|
||||
const mutations: MutationTree<StatusState> = {
|
||||
[MUTATION_TYPES.UPDATE_FILTERED_ACCOUNTS]: (state, accounts: Array<Account>) => {
|
||||
state.filteredAccounts = accounts.map(a => ({
|
||||
name: `@${a.acct}`,
|
||||
image: null
|
||||
}))
|
||||
},
|
||||
[MUTATION_TYPES.CLEAR_FILTERED_ACCOUNTS]: (state) => {
|
||||
state.filteredAccounts = []
|
||||
},
|
||||
[MUTATION_TYPES.UPDATE_FILTERED_HASHTAGS]: (state, tags: Array<Tag>) => {
|
||||
state.filteredHashtags = tags.map(t => ({
|
||||
name: `#${t}`,
|
||||
image: null
|
||||
}))
|
||||
},
|
||||
[MUTATION_TYPES.CLEAR_FILTERED_ACCOUNTS]: (state) => {
|
||||
state.filteredHashtags = []
|
||||
}
|
||||
}
|
||||
|
||||
const actions: ActionTree<StatusState, RootState> = {
|
||||
searchAccount: async ({ commit, rootState }, word: string) => {
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken!,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
const res: Response<Results> = await client.get<Results>('/search', { q: word, resolve: false })
|
||||
commit(MUTATION_TYPES.UPDATE_FILTERED_ACCOUNTS, res.data.accounts)
|
||||
if (res.data.accounts.length === 0) throw new Error('Empty')
|
||||
return res.data.accounts
|
||||
},
|
||||
searchHashtag: async ({ commit, rootState }, word: string) => {
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken!,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
const res: Response<Results> = await client.get<Results>('/search', { q: word })
|
||||
commit(MUTATION_TYPES.UPDATE_FILTERED_HASHTAGS, res.data.hashtags)
|
||||
if (res.data.hashtags.length === 0) throw new Error('Empty')
|
||||
return res.data.hashtags
|
||||
}
|
||||
}
|
||||
|
||||
const getters: GetterTree<StatusState, RootState> = {
|
||||
pickerEmojis: (_state, _getters, rootState) => {
|
||||
return rootState.TimelineSpace.emojis.filter((e, i, array) => {
|
||||
return (array.findIndex(ar => e.name === ar.name) === i)
|
||||
}).map(e => {
|
||||
return {
|
||||
name: e.name,
|
||||
short_names: [e.name],
|
||||
text: e.name,
|
||||
emoticons: [],
|
||||
keywords: [e.name],
|
||||
imageUrl: e.image
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const Status: Module<StatusState, RootState> = {
|
||||
namespaced: true,
|
||||
state: state,
|
||||
mutations: mutations,
|
||||
actions: actions,
|
||||
getters: getters
|
||||
}
|
||||
|
||||
export default Status
|
@ -1,34 +0,0 @@
|
||||
import Mastodon from 'megalodon'
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
modalOpen: false,
|
||||
message: {}
|
||||
},
|
||||
mutations: {
|
||||
changeModalOpen (state, value) {
|
||||
state.modalOpen = value
|
||||
},
|
||||
changeMessage (state, value) {
|
||||
state.message = value
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
openReport ({ commit }, message) {
|
||||
commit('changeMessage', message)
|
||||
commit('changeModalOpen', true)
|
||||
},
|
||||
submit ({ rootState }, payload) {
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
return client.post(`/reports`, {
|
||||
account_id: payload.account_id,
|
||||
status_ids: [payload.status_id],
|
||||
comment: payload.comment
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
52
src/renderer/store/TimelineSpace/Modals/Report.ts
Normal file
52
src/renderer/store/TimelineSpace/Modals/Report.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import Mastodon, { Status } from 'megalodon'
|
||||
import { Module, MutationTree, ActionTree } from 'vuex'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
export interface ReportState {
|
||||
modalOpen: boolean,
|
||||
message: Status | null
|
||||
}
|
||||
|
||||
const state = (): ReportState => ({
|
||||
modalOpen: false,
|
||||
message: null
|
||||
})
|
||||
|
||||
export const MUTATION_TYPES = {
|
||||
CHANGE_MODAL_OPEN: 'changeModalOpen',
|
||||
CHANGE_MESSAGE: 'changeMessage'
|
||||
}
|
||||
|
||||
const mutations: MutationTree<ReportState> = {
|
||||
[MUTATION_TYPES.CHANGE_MODAL_OPEN]: (state, value: boolean) => {
|
||||
state.modalOpen = value
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_MESSAGE]: (state, message: Status) => {
|
||||
state.message = message
|
||||
}
|
||||
}
|
||||
|
||||
const actions: ActionTree<ReportState, RootState> = {
|
||||
openReport: ({ commit }, message: Status) => {
|
||||
commit(MUTATION_TYPES.CHANGE_MESSAGE, message)
|
||||
commit(MUTATION_TYPES.CHANGE_MODAL_OPEN, true)
|
||||
},
|
||||
submit: async ({ rootState }, { account_id, status_id, comment }) => {
|
||||
const client = new Mastodon(
|
||||
rootState.TimelineSpace.account.accessToken!,
|
||||
rootState.TimelineSpace.account.baseURL + '/api/v1'
|
||||
)
|
||||
return client.post<{}>(`/reports`, {
|
||||
account_id: account_id,
|
||||
status_ids: [status_id],
|
||||
comment: comment
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: state,
|
||||
mutations: mutations,
|
||||
actions: actions
|
||||
} as Module<ReportState, RootState>
|
@ -1,11 +0,0 @@
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
modalOpen: false
|
||||
},
|
||||
mutations: {
|
||||
changeModal (state, value) {
|
||||
state.modalOpen = value
|
||||
}
|
||||
}
|
||||
}
|
26
src/renderer/store/TimelineSpace/Modals/Shortcut.ts
Normal file
26
src/renderer/store/TimelineSpace/Modals/Shortcut.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { Module, MutationTree } from 'vuex'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
export interface ShortcutState {
|
||||
modalOpen: boolean
|
||||
}
|
||||
|
||||
const state = (): ShortcutState => ({
|
||||
modalOpen: false
|
||||
})
|
||||
|
||||
export const MUTATION_TYPES = {
|
||||
CHANGE_MODAL: 'changeModal'
|
||||
}
|
||||
|
||||
const mutations: MutationTree<ShortcutState> = {
|
||||
[MUTATION_TYPES.CHANGE_MODAL]: (state, value: boolean) => {
|
||||
state.modalOpen = value
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: state,
|
||||
mutations: mutations
|
||||
} as Module<ShortcutState, RootState>
|
@ -2,17 +2,28 @@ import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import createLogger from 'vuex/dist/logger'
|
||||
|
||||
import App from './App'
|
||||
import GlobalHeader from './GlobalHeader'
|
||||
import Login from './Login'
|
||||
import Authorize from './Authorize'
|
||||
import TimelineSpace from './TimelineSpace'
|
||||
import Preferences from './Preferences'
|
||||
import Settings from './Settings'
|
||||
import molecules from './molecules'
|
||||
import App, { AppState } from './App'
|
||||
import GlobalHeader, { GlobalHeaderState } from './GlobalHeader'
|
||||
import Login, { LoginState } from './Login'
|
||||
import Authorize, { AuthorizeState } from './Authorize'
|
||||
import TimelineSpace, { TimelineSpaceModuleState } from './TimelineSpace'
|
||||
import Preferences, { PreferencesModuleState } from './Preferences'
|
||||
import Settings, { SettingsModuleState } from './Settings'
|
||||
import molecules, { MoleculesModuleState } from './molecules'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
export interface RootState {
|
||||
App: AppState,
|
||||
GlobalHeader: GlobalHeaderState,
|
||||
Login: LoginState,
|
||||
Authorize: AuthorizeState,
|
||||
TimelineSpace: TimelineSpaceModuleState,
|
||||
Preferences: PreferencesModuleState,
|
||||
Settings: SettingsModuleState,
|
||||
molecules: MoleculesModuleState
|
||||
}
|
||||
|
||||
export default new Vuex.Store({
|
||||
strict: process.env.NODE_ENV !== 'production',
|
||||
plugins: process.env.NODE_ENV !== 'production'
|
||||
|
@ -1,5 +1,8 @@
|
||||
import Toot from './molecules/Toot'
|
||||
|
||||
export interface MoleculesModuleState {
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
modules: {
|
||||
|
@ -2,7 +2,11 @@
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "es2015",
|
||||
"lib": ["es6"],
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"es6"
|
||||
],
|
||||
"sourceMap": true,
|
||||
"downlevelIteration": true,
|
||||
"strict": true,
|
||||
|
Loading…
x
Reference in New Issue
Block a user