diff --git a/.eslintrc.js b/.eslintrc.js index 1f04f6d1..317358cb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -29,6 +29,8 @@ module.exports = { { 'argsIgnorePattern': '^_' } - ] + ], + 'camelcase': 'off', + '@typescript-eslint/camelcase': 'off' } } diff --git a/spec/renderer/integration/store/Preferences/Account.spec.ts b/spec/renderer/integration/store/Preferences/Account.spec.ts index 665d487e..7e8cf5b4 100644 --- a/spec/renderer/integration/store/Preferences/Account.spec.ts +++ b/spec/renderer/integration/store/Preferences/Account.spec.ts @@ -1,9 +1,24 @@ import { createLocalVue } from '@vue/test-utils' import Vuex from 'vuex' import { ipcMain } from '~/spec/mock/electron' -import Account from '@/store/Preferences/Account' +import Account, { AccountState } from '@/store/Preferences/Account' +import AccountType from '~/src/types/account' -const state = () => { +const account: AccountType = { + _id: 'sample', + baseURL: 'http://example.com', + domain: 'example.com', + clientId: 'hoge', + clientSecret: 'hogehoge', + accessToken: null, + refreshToken: null, + username: null, + accountId: null, + avatar: null, + order: 1 +} + +const state = (): AccountState => { return { accounts: [], accountLoading: false @@ -35,7 +50,7 @@ describe('Account', () => { describe('loadAccounts', () => { it('error', async () => { - ipcMain.once('list-accounts', (event, _) => { + ipcMain.once('list-accounts', (event: any, _) => { event.sender.send('error-list-accounts', new Error()) }) @@ -45,86 +60,86 @@ describe('Account', () => { }) }) it('success', async () => { - ipcMain.once('list-accounts', (event, _) => { - event.sender.send('response-list-accounts', ['accounts']) + ipcMain.once('list-accounts', (event: any, _) => { + event.sender.send('response-list-accounts', [account]) }) await store.dispatch('Account/loadAccounts') - expect(store.state.Account.accounts).toEqual(['accounts']) + expect(store.state.Account.accounts).toEqual([account]) }) }) describe('removeAccount', () => { it('error', async () => { - ipcMain.once('remove-account', (event, _) => { + ipcMain.once('remove-account', (event: any, _) => { event.sender.send('error-remove-account', new Error()) }) - await store.dispatch('Account/removeAccount', 'account') + await store.dispatch('Account/removeAccount', account) .catch((err: Error) => { expect(err instanceof Error).toEqual(true) }) }) it('success', async () => { - ipcMain.once('remove-account', (event, _) => { - event.sender.send('response-remove-account', 1) + ipcMain.once('remove-account', (event: any, _) => { + event.sender.send('response-remove-account') }) - const res = await store.dispatch('Account/removeAccount', 'account') + const res = await store.dispatch('Account/removeAccount', account) expect(res).toEqual(undefined) }) }) describe('forwardAccount', () => { it('error', async () => { - ipcMain.once('forward-account', (event, _) => { + ipcMain.once('forward-account', (event: any, _) => { event.sender.send('error-forward-account', new Error()) }) - await store.dispatch('Account/forwardAccount', 'account') + await store.dispatch('Account/forwardAccount', account) .catch((err: Error) => { expect(err instanceof Error).toEqual(true) }) }) it('success', async () => { - ipcMain.once('forward-account', (event, _) => { - event.sender.send('response-forward-account', 1) + ipcMain.once('forward-account', (event: any, _) => { + event.sender.send('response-forward-account') }) - const res = await store.dispatch('Account/forwardAccount', 'account') + const res = await store.dispatch('Account/forwardAccount', account) expect(res).toEqual(undefined) }) }) describe('backwardAccount', () => { it('error', async () => { - ipcMain.once('backward-account', (event, _) => { + ipcMain.once('backward-account', (event: any, _) => { event.sender.send('error-backward-account', new Error()) }) - await store.dispatch('Account/backwardAccount', 'account') + await store.dispatch('Account/backwardAccount', account) .catch((err: Error) => { expect(err instanceof Error).toEqual(true) }) }) it('success', async () => { - ipcMain.once('backward-account', (event, _) => { - event.sender.send('response-backward-account', 1) + ipcMain.once('backward-account', (event: any, _) => { + event.sender.send('response-backward-account') }) - const res = await store.dispatch('Account/backwardAccount', 'account') + const res = await store.dispatch('Account/backwardAccount', account) expect(res).toEqual(undefined) }) }) describe('removeAllAccounts', () => { it('error', async () => { - ipcMain.once('remove-all-accounts', (event, _) => { + ipcMain.once('remove-all-accounts', (event: any, _) => { event.sender.send('error-remove-all-accounts', new Error()) }) - await store.dispatch('Account/removeAllAccounts', 'account') + await store.dispatch('Account/removeAllAccounts', account) .catch((err: Error) => { expect(err instanceof Error).toEqual(true) }) }) it('success', async () => { - ipcMain.once('remove-all-accounts', (event, _) => { - event.sender.send('response-remove-all-accounts', 1) + ipcMain.once('remove-all-accounts', (event: any, _) => { + event.sender.send('response-remove-all-accounts') }) - const res = await store.dispatch('Account/removeAllAccounts', 'account') + const res = await store.dispatch('Account/removeAllAccounts', account) expect(res).toEqual(undefined) }) }) diff --git a/spec/renderer/integration/store/Preferences/Appearance.spec.ts b/spec/renderer/integration/store/Preferences/Appearance.spec.ts index c9724aeb..1a9bc99b 100644 --- a/spec/renderer/integration/store/Preferences/Appearance.spec.ts +++ b/spec/renderer/integration/store/Preferences/Appearance.spec.ts @@ -5,10 +5,10 @@ import DisplayStyle from '~/src/constants/displayStyle' import TimeFormat from '~/src/constants/timeFormat' import { LightTheme, DarkTheme } from '~/src/renderer/utils/theme' import DefaultFonts from '@/utils/fonts' -import Appearance from '@/store/Preferences/Appearance' +import Appearance, { AppearanceState } from '@/store/Preferences/Appearance' import { ipcMain } from '~/spec/mock/electron' -const state = () => { +const state = (): AppearanceState => { return { appearance: { theme: Theme.Light.key, @@ -51,14 +51,14 @@ describe('Preferences/Appearance', () => { App: App } }) - ipcMain.once('update-preferences', (event, config) => { + ipcMain.once('update-preferences', (event: any, config: any) => { event.sender.send('response-update-preferences', config) }) }) describe('load', () => { it('loadAppearance', async () => { - ipcMain.once('get-preferences', (event, _) => { + ipcMain.once('get-preferences', (event: any, _) => { event.sender.send('response-get-preferences', { appearance: { theme: Theme.Dark.key, diff --git a/spec/renderer/integration/store/Preferences/General.spec.ts b/spec/renderer/integration/store/Preferences/General.spec.ts index 23ae4f5c..9c73abeb 100644 --- a/spec/renderer/integration/store/Preferences/General.spec.ts +++ b/spec/renderer/integration/store/Preferences/General.spec.ts @@ -1,9 +1,9 @@ import { createLocalVue } from '@vue/test-utils' import Vuex from 'vuex' import { ipcMain } from '~/spec/mock/electron' -import General from '@/store/Preferences/General' +import General, { GeneralState } from '@/store/Preferences/General' -const state = () => { +const state = (): GeneralState => { return { general: { sound: { diff --git a/spec/renderer/integration/store/Preferences/Language.spec.ts b/spec/renderer/integration/store/Preferences/Language.spec.ts index 5206d097..ac473b42 100644 --- a/spec/renderer/integration/store/Preferences/Language.spec.ts +++ b/spec/renderer/integration/store/Preferences/Language.spec.ts @@ -1,10 +1,10 @@ import { createLocalVue } from '@vue/test-utils' import Vuex from 'vuex' import { ipcMain } from '~/spec/mock/electron' -import Language from '@/store/Preferences/Language' +import Language, { LanguageState } from '@/store/Preferences/Language' import DefaultLanguage from '~/src/constants/language' -const state = () => { +const state = (): LanguageState => { return { language: { language: DefaultLanguage.en.key diff --git a/spec/renderer/integration/store/Preferences/Notification.spec.ts b/spec/renderer/integration/store/Preferences/Notification.spec.ts index 4cf2a009..a6c0b8c9 100644 --- a/spec/renderer/integration/store/Preferences/Notification.spec.ts +++ b/spec/renderer/integration/store/Preferences/Notification.spec.ts @@ -1,9 +1,9 @@ import { createLocalVue } from '@vue/test-utils' import Vuex from 'vuex' import { ipcMain } from '~/spec/mock/electron' -import Notification from '@/store/Preferences/Notification' +import Notification, { NotificationState } from '@/store/Preferences/Notification' -const state = () => { +const state = (): NotificationState => { return { notification: { notify: { diff --git a/spec/renderer/unit/store/Preferences/Account.spec.ts b/spec/renderer/unit/store/Preferences/Account.spec.ts index a3211544..e4a448d9 100644 --- a/spec/renderer/unit/store/Preferences/Account.spec.ts +++ b/spec/renderer/unit/store/Preferences/Account.spec.ts @@ -1,8 +1,23 @@ -import Account from '@/store/Preferences/Account' +import Account, { AccountState, MUTATION_TYPES } from '@/store/Preferences/Account' +import AccountType from '~/src/types/account' + +const account: AccountType = { + _id: 'sample', + baseURL: 'http://example.com', + domain: 'example.com', + clientId: 'hoge', + clientSecret: 'hogehoge', + accessToken: null, + refreshToken: null, + username: null, + accountId: null, + avatar: null, + order: 1 +} describe('Preferences/Account', () => { describe('mutations', () => { - let state + let state: AccountState beforeEach(() => { state = { accounts: [], @@ -11,13 +26,13 @@ describe('Preferences/Account', () => { }) describe('updateAccounts', () => { it('should be updated', () => { - Account.mutations.updateAccounts(state, ['account']) - expect(state.accounts).toEqual(['account']) + Account.mutations![MUTATION_TYPES.UPDATE_ACCOUNTS](state, [account]) + expect(state.accounts).toEqual([account]) }) }) describe('updateAccountLoading', () => { it('should be update', () => { - Account.mutations.updateAccountLoading(state, true) + Account.mutations![MUTATION_TYPES.UPDATE_ACCOUNT_LOADING](state, true) expect(state.accountLoading).toEqual(true) }) }) diff --git a/spec/renderer/unit/store/Preferences/Appearance.spec.ts b/spec/renderer/unit/store/Preferences/Appearance.spec.ts index 544839b5..84d8222b 100644 --- a/spec/renderer/unit/store/Preferences/Appearance.spec.ts +++ b/spec/renderer/unit/store/Preferences/Appearance.spec.ts @@ -3,10 +3,10 @@ import DisplayStyle from '~/src/constants/displayStyle' import TimeFormat from '~/src/constants/timeFormat' import { LightTheme } from '~/src/renderer/utils/theme' import DefaultFonts from '@/utils/fonts' -import Appearance from '@/store/Preferences/Appearance' +import Appearance, { AppearanceState, MUTATION_TYPES } from '@/store/Preferences/Appearance' describe('Preferences/Appearance', () => { - let state + let state: AppearanceState beforeEach(() => { state = { appearance: { @@ -23,7 +23,7 @@ describe('Preferences/Appearance', () => { describe('mutations', () => { describe('updateAppearance', () => { it('should be changed', () => { - Appearance.mutations.updateAppearance(state, { + Appearance.mutations![MUTATION_TYPES.UPDATE_APPEARANCE](state, { theme: Theme.Dark.key }) expect(state.appearance.theme).toEqual(Theme.Dark.key) @@ -31,7 +31,7 @@ describe('Preferences/Appearance', () => { }) describe('updateFonts', () => { it('should be changed', () => { - Appearance.mutations.updateFonts(state, ['font']) + Appearance.mutations![MUTATION_TYPES.UPDATE_FONTS](state, ['font']) expect(state.fonts).toEqual(['font']) }) }) diff --git a/spec/renderer/unit/store/Preferences/General.spec.ts b/spec/renderer/unit/store/Preferences/General.spec.ts index cd0bbc24..15d25632 100644 --- a/spec/renderer/unit/store/Preferences/General.spec.ts +++ b/spec/renderer/unit/store/Preferences/General.spec.ts @@ -1,13 +1,18 @@ -import General from '@/store/Preferences/General' +import General, { GeneralState, MUTATION_TYPES } from '@/store/Preferences/General' describe('Preferences/General', () => { - let state + let state: GeneralState beforeEach(() => { state = { general: { sound: { fav_rb: true, toot: true + }, + timeline: { + cw: false, + nfsw: false, + hideAllAttachments: false } }, loading: false @@ -16,7 +21,7 @@ describe('Preferences/General', () => { describe('mutations', () => { it('updateGeneral', () => { - General.mutations.updateGeneral(state, { + General.mutations![MUTATION_TYPES.UPDATE_GENERAL](state, { sound: { fav_rb: false, toot: false diff --git a/spec/renderer/unit/store/Preferences/Language.spec.ts b/spec/renderer/unit/store/Preferences/Language.spec.ts index 1527e0e1..051f6182 100644 --- a/spec/renderer/unit/store/Preferences/Language.spec.ts +++ b/spec/renderer/unit/store/Preferences/Language.spec.ts @@ -1,8 +1,8 @@ -import Language from '@/store/Preferences/Language' +import Language, { LanguageState, MUTATION_TYPES } from '@/store/Preferences/Language' import DefaultLanguage from '~/src/constants/language' describe('Preferences/Language', () => { - let state + let state: LanguageState beforeEach(() => { state = { language: { @@ -13,7 +13,7 @@ describe('Preferences/Language', () => { describe('mutations', () => { describe('updateLanguage', () => { it('should be updated', () => { - Language.mutations.updateLanguage(state, { + Language.mutations![MUTATION_TYPES.UPDATE_LANGUAGE](state, { language: DefaultLanguage.ja.key }) expect(state.language.language).toEqual(DefaultLanguage.ja.key) @@ -21,7 +21,7 @@ describe('Preferences/Language', () => { }) describe('changeLanguage', () => { it('should be changed', () => { - Language.mutations.changeLanguage(state, DefaultLanguage.ja.key) + Language.mutations![MUTATION_TYPES.CHANGE_LANGUAGE](state, DefaultLanguage.ja.key) expect(state.language.language).toEqual(DefaultLanguage.ja.key) }) }) diff --git a/spec/renderer/unit/store/Preferences/Notification.spec.ts b/spec/renderer/unit/store/Preferences/Notification.spec.ts index 49376cd2..2c05f177 100644 --- a/spec/renderer/unit/store/Preferences/Notification.spec.ts +++ b/spec/renderer/unit/store/Preferences/Notification.spec.ts @@ -1,7 +1,7 @@ -import Notification from '@/store/Preferences/Notification' +import Notification, { NotificationState, MUTATION_TYPES } from '@/store/Preferences/Notification' describe('Preferences/Notification', () => { - let state + let state: NotificationState beforeEach(() => { state = { notification: { @@ -16,7 +16,7 @@ describe('Preferences/Notification', () => { }) describe('mutations', () => { it('updateNotification', () => { - Notification.mutations.updateNotification(state, { + Notification.mutations![MUTATION_TYPES.UPDATE_NOTIFICATION](state, { notify: { reply: false, reblog: false, diff --git a/src/renderer/store/Preferences.js b/src/renderer/store/Preferences.ts similarity index 64% rename from src/renderer/store/Preferences.js rename to src/renderer/store/Preferences.ts index b1ffa9d8..db7fa6b3 100644 --- a/src/renderer/store/Preferences.js +++ b/src/renderer/store/Preferences.ts @@ -3,8 +3,14 @@ import Account from './Preferences/Account' import Language from './Preferences/Language' import Notification from './Preferences/Notification' import Appearance from './Preferences/Appearance' +import { Module } from 'vuex' -const Preferences = { +export interface PreferencesState {} + +const state = (): PreferencesState => ({}) + +// TODO: use type of rootState +const Preferences: Module = { namespaced: true, modules: { General, @@ -13,8 +19,7 @@ const Preferences = { Notification, Appearance }, - state: {}, - mutations: {} + state: state } export default Preferences diff --git a/src/renderer/store/Preferences/Account.js b/src/renderer/store/Preferences/Account.js deleted file mode 100644 index b2998f2f..00000000 --- a/src/renderer/store/Preferences/Account.js +++ /dev/null @@ -1,89 +0,0 @@ -import { ipcRenderer } from 'electron' - -const Account = { - namespaced: true, - state: { - accounts: [], - accountLoading: false - }, - mutations: { - updateAccounts (state, accounts) { - state.accounts = accounts - }, - updateAccountLoading (state, value) { - state.accountLoading = value - } - }, - actions: { - loadAccounts ({ commit }) { - return new Promise((resolve, reject) => { - ipcRenderer.send('list-accounts', 'list') - ipcRenderer.once('error-list-accounts', (event, err) => { - ipcRenderer.removeAllListeners('response-list-accounts') - reject(err) - }) - ipcRenderer.once('response-list-accounts', (event, accounts) => { - ipcRenderer.removeAllListeners('error-list-accounts') - commit('updateAccounts', accounts) - resolve(accounts) - }) - }) - }, - removeAccount (_, account) { - return new Promise((resolve, reject) => { - ipcRenderer.send('remove-account', account._id) - ipcRenderer.once('error-remove-account', (_, err) => { - ipcRenderer.removeAllListeners('response-remove-account') - reject(err) - }) - ipcRenderer.once('response-remove-account', () => { - ipcRenderer.removeAllListeners('error-remove-account') - resolve() - }) - }) - }, - forwardAccount (_, account) { - console.log(account) - return new Promise((resolve, reject) => { - ipcRenderer.send('forward-account', account) - ipcRenderer.once('error-forward-account', (_, err) => { - ipcRenderer.removeAllListeners('response-forward-account') - reject(err) - }) - ipcRenderer.once('response-forward-account', () => { - ipcRenderer.removeAllListeners('error-forward-account') - resolve() - }) - }) - }, - backwardAccount (_, account) { - console.log(account) - return new Promise((resolve, reject) => { - ipcRenderer.send('backward-account', account) - ipcRenderer.once('error-backward-account', (event, err) => { - ipcRenderer.removeAllListeners('response-forward-account') - reject(err) - }) - ipcRenderer.once('response-backward-account', () => { - ipcRenderer.removeAllListeners('error-backward-account') - resolve() - }) - }) - }, - removeAllAccounts () { - return new Promise((resolve, reject) => { - ipcRenderer.send('remove-all-accounts') - ipcRenderer.once('error-remove-all-accounts', (_, err) => { - ipcRenderer.removeAllListeners('response-remove-all-accounts') - reject(err) - }) - ipcRenderer.once('response-remove-all-accounts', () => { - ipcRenderer.removeAllListeners('error-remove-all-accounts') - resolve() - }) - }) - } - } -} - -export default Account diff --git a/src/renderer/store/Preferences/Account.ts b/src/renderer/store/Preferences/Account.ts new file mode 100644 index 00000000..b1735e28 --- /dev/null +++ b/src/renderer/store/Preferences/Account.ts @@ -0,0 +1,107 @@ +import { ipcRenderer } from 'electron' +import { Module, MutationTree, ActionTree } from 'vuex' +import Account from '~/src/types/account' + +export interface AccountState { + accounts: Array, + accountLoading: boolean +} + +const state = (): AccountState => ({ + accounts: [], + accountLoading: false +}) + +export const MUTATION_TYPES = { + UPDATE_ACCOUNTS: 'updateAccounts', + UPDATE_ACCOUNT_LOADING: 'updateAccountLoading' +} + +const mutations: MutationTree = { + [MUTATION_TYPES.UPDATE_ACCOUNTS]: (state, accounts: Array) => { + state.accounts = accounts + }, + [MUTATION_TYPES.UPDATE_ACCOUNT_LOADING]: (state, value: boolean) => { + state.accountLoading = value + } +} + +// TODO: use type of rootState +const actions: ActionTree = { + loadAccounts: ({ commit }): Promise> => { + return new Promise((resolve, reject) => { + ipcRenderer.send('list-accounts', 'list') + ipcRenderer.once('error-list-accounts', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-list-accounts') + reject(err) + }) + ipcRenderer.once('response-list-accounts', (_, accounts: Array) => { + ipcRenderer.removeAllListeners('error-list-accounts') + commit(MUTATION_TYPES.UPDATE_ACCOUNTS, accounts) + resolve(accounts) + }) + }) + }, + removeAccount: (_, account: Account) => { + return new Promise((resolve, reject) => { + ipcRenderer.send('remove-account', account._id) + ipcRenderer.once('error-remove-account', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-remove-account') + reject(err) + }) + ipcRenderer.once('response-remove-account', () => { + ipcRenderer.removeAllListeners('error-remove-account') + resolve() + }) + }) + }, + forwardAccount: (_, account: Account) => { + return new Promise((resolve, reject) => { + ipcRenderer.send('forward-account', account) + ipcRenderer.once('error-forward-account', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-forward-account') + reject(err) + }) + ipcRenderer.once('response-forward-account', () => { + ipcRenderer.removeAllListeners('error-forward-account') + resolve() + }) + }) + }, + backwardAccount: (_, account: Account) => { + return new Promise((resolve, reject) => { + ipcRenderer.send('backward-account', account) + ipcRenderer.once('error-backward-account', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-forward-account') + reject(err) + }) + ipcRenderer.once('response-backward-account', () => { + ipcRenderer.removeAllListeners('error-backward-account') + resolve() + }) + }) + }, + removeAllAccounts: () => { + return new Promise((resolve, reject) => { + ipcRenderer.send('remove-all-accounts') + ipcRenderer.once('error-remove-all-accounts', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-remove-all-accounts') + reject(err) + }) + ipcRenderer.once('response-remove-all-accounts', () => { + ipcRenderer.removeAllListeners('error-remove-all-accounts') + resolve() + }) + }) + } +} + +// TODO: use type of rootState +const account: Module = { + namespaced: true, + state: state, + mutations: mutations, + actions: actions +} + +export default account diff --git a/src/renderer/store/Preferences/Appearance.js b/src/renderer/store/Preferences/Appearance.js deleted file mode 100644 index 4866d6c1..00000000 --- a/src/renderer/store/Preferences/Appearance.js +++ /dev/null @@ -1,186 +0,0 @@ -import { ipcRenderer } from 'electron' -import DisplayStyle from '~/src/constants/displayStyle' -import Theme from '~/src/constants/theme' -import TimeFormat from '~/src/constants/timeFormat' -import { LightTheme } from '~/src/renderer/utils/theme' -import DefaultFonts from '../../utils/fonts' - -export default { - namespaced: true, - state: { - appearance: { - theme: Theme.Light.key, - fontSize: 14, - displayNameStyle: DisplayStyle.DisplayNameAndUsername.value, - timeFormat: TimeFormat.Absolute.value, - customThemeColor: LightTheme, - font: DefaultFonts[0] - }, - fonts: [] - }, - mutations: { - updateAppearance (state, conf) { - state.appearance = conf - }, - updateFonts (state, fonts) { - state.fonts = fonts - } - }, - actions: { - loadAppearance ({ commit }) { - return new Promise((resolve, reject) => { - ipcRenderer.send('get-preferences') - ipcRenderer.once('error-get-preferences', (event, err) => { - ipcRenderer.removeAllListeners('response-get-preferences') - reject(err) - }) - ipcRenderer.once('response-get-preferences', (event, conf) => { - ipcRenderer.removeAllListeners('error-get-preferences') - commit('updateAppearance', conf.appearance) - resolve(conf) - }) - }) - }, - loadFonts ({ commit }) { - return new Promise((resolve, reject) => { - ipcRenderer.send('list-fonts') - ipcRenderer.once('error-list-fonts', (event, err) => { - ipcRenderer.removeAllListeners('response-list-fonts') - reject(err) - }) - ipcRenderer.once('response-list-fonts', (event, fonts) => { - ipcRenderer.removeAllListeners('error-list-fonts') - commit('updateFonts', [DefaultFonts[0]].concat(fonts)) - resolve(fonts) - }) - }) - }, - updateTheme ({ dispatch, commit, state }, theme) { - const newAppearance = Object.assign({}, state.appearance, { - theme: theme - }) - const config = { - appearance: newAppearance - } - return new Promise((resolve, reject) => { - ipcRenderer.send('update-preferences', config) - ipcRenderer.once('error-update-preferences', (event, err) => { - ipcRenderer.removeAllListeners('response-update-preferences', err) - reject(err) - }) - ipcRenderer.once('response-update-preferences', (event, conf) => { - ipcRenderer.removeAllListeners('error-update-preferences') - commit('updateAppearance', conf.appearance) - dispatch('App/loadPreferences', null, { root: true }) - resolve(conf.appearance) - }) - }) - }, - updateFontSize ({ dispatch, commit, state }, fontSize) { - const newAppearance = Object.assign({}, state.appearance, { - fontSize: fontSize - }) - const config = { - appearance: newAppearance - } - return new Promise((resolve, reject) => { - ipcRenderer.send('update-preferences', config) - ipcRenderer.once('error-update-preferences', (event, err) => { - ipcRenderer.removeAllListeners('response-update-preferences') - reject(err) - }) - ipcRenderer.once('response-update-preferences', (event, conf) => { - ipcRenderer.removeAllListeners('error-update-preferences') - commit('updateAppearance', conf.appearance) - dispatch('App/loadPreferences', null, { root: true }) - resolve(conf.appearance) - }) - }) - }, - updateDisplayNameStyle ({ dispatch, commit, state }, value) { - const newAppearance = Object.assign({}, state.appearance, { - displayNameStyle: value - }) - const config = { - appearance: newAppearance - } - return new Promise((resolve, reject) => { - ipcRenderer.send('update-preferences', config) - ipcRenderer.once('error-update-preferences', (event, err) => { - ipcRenderer.removeAllListeners('response-update-preferences') - reject(err) - }) - ipcRenderer.once('response-update-preferences', (event, conf) => { - ipcRenderer.removeAllListeners('error-update-preferences') - dispatch('App/loadPreferences', null, { root: true }) - commit('updateAppearance', conf.appearance) - resolve(conf.appearance) - }) - }) - }, - updateTimeFormat ({ dispatch, commit, state }, value) { - const newAppearance = Object.assign({}, state.appearance, { - timeFormat: value - }) - const config = { - appearance: newAppearance - } - return new Promise((resolve, reject) => { - ipcRenderer.send('update-preferences', config) - ipcRenderer.once('error-update-preferences', (event, err) => { - ipcRenderer.removeAllListeners('response-update-preferences') - reject(err) - }) - ipcRenderer.once('response-update-preferences', (event, conf) => { - ipcRenderer.removeAllListeners('error-update-preferences') - dispatch('App/loadPreferences', null, { root: true }) - commit('updateAppearance', conf.appearance) - resolve(conf.appearance) - }) - }) - }, - updateCustomThemeColor ({ dispatch, state, commit }, value) { - const newCustom = Object.assign({}, state.appearance.customThemeColor, value) - const newAppearance = Object.assign({}, state.appearance, { - customThemeColor: newCustom - }) - const config = { - appearance: newAppearance - } - return new Promise((resolve, reject) => { - ipcRenderer.send('update-preferences', config) - ipcRenderer.once('error-update-preferences', (event, err) => { - ipcRenderer.removeAllListeners('response-update-preferences') - reject(err) - }) - ipcRenderer.once('response-update-preferences', (event, conf) => { - ipcRenderer.removeAllListeners('error-update-preferences') - commit('updateAppearance', conf.appearance) - dispatch('App/loadPreferences', null, { root: true }) - resolve(conf.appearance) - }) - }) - }, - updateFont ({ dispatch, state, commit }, value) { - const newAppearance = Object.assign({}, state.appearance, { - font: value - }) - const config = { - appearance: newAppearance - } - return new Promise((resolve, reject) => { - ipcRenderer.send('update-preferences', config) - ipcRenderer.once('error-update-preferences', (event, err) => { - ipcRenderer.removeAllListeners('response-update-preferences') - reject(err) - }) - ipcRenderer.once('response-update-preferences', (event, conf) => { - ipcRenderer.removeAllListeners('error-update-preferences') - commit('updateAppearance', conf.appearance) - dispatch('App/loadPreferences', null, { root: true }) - resolve(conf.appearance) - }) - }) - } - } -} diff --git a/src/renderer/store/Preferences/Appearance.ts b/src/renderer/store/Preferences/Appearance.ts new file mode 100644 index 00000000..87f20cc9 --- /dev/null +++ b/src/renderer/store/Preferences/Appearance.ts @@ -0,0 +1,229 @@ +import { ipcRenderer } from 'electron' +import DisplayStyle from '~/src/constants/displayStyle' +import Theme from '~/src/constants/theme' +import TimeFormat from '~/src/constants/timeFormat' +import { LightTheme } from '@/utils/theme' +import DefaultFonts from '@/utils/fonts' +import { Module, MutationTree, ActionTree } from 'vuex' + +interface ColorThemeSet { + background_color: string, + selected_background_color: string, + global_header_color: string, + side_menu_color: string, + primary_color: string, + regular_color: string, + secondary_color: string, + border_color: string, + header_menu_color: string, + wrapper_mask_color: string +} + +interface AppearanceSet { + theme: string, + fontSize: number, + displayNameStyle: number, + timeFormat: number, + customThemeColor: ColorThemeSet, + font: string +} + +export interface AppearanceState { + appearance: AppearanceSet, + fonts: Array +} + +const state = (): AppearanceState => ({ + appearance: { + theme: Theme.Light.key, + fontSize: 14, + displayNameStyle: DisplayStyle.DisplayNameAndUsername.value, + timeFormat: TimeFormat.Absolute.value, + customThemeColor: LightTheme, + font: DefaultFonts[0] + }, + fonts: [] +}) + +export const MUTATION_TYPES = { + UPDATE_APPEARANCE: 'updateAppearance', + UPDATE_FONTS: 'updateFonts' +} + +const mutations: MutationTree = { + [MUTATION_TYPES.UPDATE_APPEARANCE]: (state, conf: AppearanceSet) => { + state.appearance = conf + }, + [MUTATION_TYPES.UPDATE_FONTS]: (state, fonts: Array) => { + state.fonts = fonts + } +} + +// TODO: use type of rootState +const actions: ActionTree = { + loadAppearance: ({ commit }) => { + return new Promise((resolve, reject) => { + ipcRenderer.send('get-preferences') + ipcRenderer.once('error-get-preferences', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-get-preferences') + reject(err) + }) + ipcRenderer.once('response-get-preferences', (_, conf: any) => { + ipcRenderer.removeAllListeners('error-get-preferences') + commit(MUTATION_TYPES.UPDATE_APPEARANCE, conf.appearance as AppearanceSet) + resolve(conf) + }) + }) + }, + loadFonts: ({ commit }) => { + return new Promise((resolve, reject) => { + ipcRenderer.send('list-fonts') + ipcRenderer.once('error-list-fonts', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-list-fonts') + reject(err) + }) + ipcRenderer.once('response-list-fonts', (_, fonts: Array) => { + ipcRenderer.removeAllListeners('error-list-fonts') + commit(MUTATION_TYPES.UPDATE_FONTS, [DefaultFonts[0]].concat(fonts)) + resolve(fonts) + }) + }) + }, + updateTheme: ({ dispatch, commit, state }, themeKey: string) => { + const newAppearance: AppearanceSet = Object.assign({}, state.appearance, { + theme: themeKey + }) + const config = { + appearance: newAppearance + } + return new Promise((resolve, reject) => { + ipcRenderer.send('update-preferences', config) + ipcRenderer.once('error-update-preferences', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-update-preferences') + reject(err) + }) + ipcRenderer.once('response-update-preferences', (_, conf: any) => { + ipcRenderer.removeAllListeners('error-update-preferences') + commit(MUTATION_TYPES.UPDATE_APPEARANCE, conf.appearance as AppearanceSet) + dispatch('App/loadPreferences', null, { root: true }) + resolve(conf.appearance) + }) + }) + }, + updateFontSize: ({ dispatch, commit, state }, fontSize: number) => { + const newAppearance: AppearanceSet = Object.assign({}, state.appearance, { + fontSize: fontSize + }) + const config = { + appearance: newAppearance + } + return new Promise((resolve, reject) => { + ipcRenderer.send('update-preferences', config) + ipcRenderer.once('error-update-preferences', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-update-preferences') + reject(err) + }) + ipcRenderer.once('response-update-preferences', (_, conf: any) => { + ipcRenderer.removeAllListeners('error-update-preferences') + commit(MUTATION_TYPES.UPDATE_APPEARANCE, conf.appearance as AppearanceSet) + dispatch('App/loadPreferences', null, { root: true }) + resolve(conf.appearance) + }) + }) + }, + updateDisplayNameStyle: ({ dispatch, commit, state }, value: number) => { + const newAppearance: AppearanceSet = Object.assign({}, state.appearance, { + displayNameStyle: value + }) + const config = { + appearance: newAppearance + } + return new Promise((resolve, reject) => { + ipcRenderer.send('update-preferences', config) + ipcRenderer.once('error-update-preferences', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-update-preferences') + reject(err) + }) + ipcRenderer.once('response-update-preferences', (_, conf: any) => { + ipcRenderer.removeAllListeners('error-update-preferences') + dispatch('App/loadPreferences', null, { root: true }) + commit(MUTATION_TYPES.UPDATE_APPEARANCE, conf.appearance as AppearanceSet) + resolve(conf.appearance) + }) + }) + }, + updateTimeFormat: ({ dispatch, commit, state }, value: number) => { + const newAppearance: AppearanceSet = Object.assign({}, state.appearance, { + timeFormat: value + }) + const config = { + appearance: newAppearance + } + return new Promise((resolve, reject) => { + ipcRenderer.send('update-preferences', config) + ipcRenderer.once('error-update-preferences', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-update-preferences') + reject(err) + }) + ipcRenderer.once('response-update-preferences', (_, conf: any) => { + ipcRenderer.removeAllListeners('error-update-preferences') + dispatch('App/loadPreferences', null, { root: true }) + commit(MUTATION_TYPES.UPDATE_APPEARANCE, conf.appearance as AppearanceSet) + resolve(conf.appearance) + }) + }) + }, + updateCustomThemeColor: ({ dispatch, state, commit }, value: object) => { + const newCustom: ColorThemeSet = Object.assign({}, state.appearance.customThemeColor, value) + const newAppearance: AppearanceSet = Object.assign({}, state.appearance, { + customThemeColor: newCustom + }) + const config = { + appearance: newAppearance + } + return new Promise((resolve, reject) => { + ipcRenderer.send('update-preferences', config) + ipcRenderer.once('error-update-preferences', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-update-preferences') + reject(err) + }) + ipcRenderer.once('response-update-preferences', (_, conf: any) => { + ipcRenderer.removeAllListeners('error-update-preferences') + commit(MUTATION_TYPES.UPDATE_APPEARANCE, conf.appearance as AppearanceSet) + dispatch('App/loadPreferences', null, { root: true }) + resolve(conf.appearance) + }) + }) + }, + updateFont: ({ dispatch, state, commit }, value: string) => { + const newAppearance: AppearanceSet = Object.assign({}, state.appearance, { + font: value + }) + const config = { + appearance: newAppearance + } + return new Promise((resolve, reject) => { + ipcRenderer.send('update-preferences', config) + ipcRenderer.once('error-update-preferences', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-update-preferences') + reject(err) + }) + ipcRenderer.once('response-update-preferences', (_, conf: any) => { + ipcRenderer.removeAllListeners('error-update-preferences') + commit(MUTATION_TYPES.UPDATE_APPEARANCE, conf.appearance as AppearanceSet) + dispatch('App/loadPreferences', null, { root: true }) + resolve(conf.appearance) + }) + }) + } +} + +// TODO: use type of rootState +const Appearance: Module = { + namespaced: true, + state: state, + mutations: mutations, + actions: actions +} + +export default Appearance diff --git a/src/renderer/store/Preferences/General.js b/src/renderer/store/Preferences/General.js deleted file mode 100644 index b18644b6..00000000 --- a/src/renderer/store/Preferences/General.js +++ /dev/null @@ -1,97 +0,0 @@ -import { ipcRenderer } from 'electron' - -const General = { - namespaced: true, - state: { - general: { - sound: { - fav_rb: true, - toot: true - }, - timeline: { - cw: false, - nfsw: false, - hideAllAttachments: false - } - }, - loading: false - }, - mutations: { - updateGeneral (state, conf) { - state.general = conf - }, - changeLoading (state, value) { - state.loading = value - } - }, - actions: { - loadGeneral ({ commit }) { - return new Promise((resolve, reject) => { - commit('changeLoading', true) - ipcRenderer.send('get-preferences') - ipcRenderer.once('error-get-preferences', (event, err) => { - ipcRenderer.removeAllListeners('response-get-preferences') - commit('changeLoading', false) - reject(err) - }) - ipcRenderer.once('response-get-preferences', (event, conf) => { - ipcRenderer.removeAllListeners('error-get-preferences') - commit('updateGeneral', conf.general) - commit('changeLoading', false) - resolve(conf) - }) - }) - }, - updateSound ({ commit, state }, sound) { - commit('changeLoading', true) - const newSound = Object.assign({}, state.general.sound, sound) - const newGeneral = Object.assign({}, state.general, { - sound: newSound - }) - const config = { - general: newGeneral - } - return new Promise((resolve, reject) => { - ipcRenderer.send('update-preferences', config) - ipcRenderer.once('error-update-preferences', (event, err) => { - ipcRenderer.removeAllListeners('response-update-preferences') - commit('changeLoading', false) - reject(err) - }) - ipcRenderer.once('response-update-preferences', (event, conf) => { - ipcRenderer.removeAllListeners('error-update-preferences') - commit('updateGeneral', conf.general) - commit('changeLoading', false) - resolve(conf) - }) - }) - }, - updateTimeline ({ commit, state, dispatch }, timeline) { - commit('changeLoading', true) - const newTimeline = Object.assign({}, state.general.timeline, timeline) - const newGeneral = Object.assign({}, state.general, { - timeline: newTimeline - }) - const config = { - general: newGeneral - } - return new Promise((resolve, reject) => { - ipcRenderer.once('error-update-preferences', (event, err) => { - ipcRenderer.removeAllListeners('response-update-preferences') - commit('changeLoading', false) - reject(err) - }) - ipcRenderer.once('response-update-preferences', (event, conf) => { - ipcRenderer.removeAllListeners('error-update-preferences') - commit('updateGeneral', conf.general) - commit('changeLoading', false) - dispatch('App/loadPreferences', null, { root: true }) - resolve(conf) - }) - ipcRenderer.send('update-preferences', config) - }) - } - } -} - -export default General diff --git a/src/renderer/store/Preferences/General.ts b/src/renderer/store/Preferences/General.ts new file mode 100644 index 00000000..82d1eec9 --- /dev/null +++ b/src/renderer/store/Preferences/General.ts @@ -0,0 +1,129 @@ +import { ipcRenderer } from 'electron' +import { Module, MutationTree, ActionTree } from 'vuex' + +interface Sound { + fav_rb: boolean, + toot: boolean +} + +interface Timeline { + cw: boolean, + nfsw: boolean, + hideAllAttachments: boolean +} + +interface GeneralSet { + sound: Sound, + timeline: Timeline +} +export interface GeneralState { + general: GeneralSet, + loading: boolean +} + +const state = (): GeneralState => ({ + general: { + sound: { + fav_rb: true, + toot: true + }, + timeline: { + cw: false, + nfsw: false, + hideAllAttachments: false + } + }, + loading: false +}) + +export const MUTATION_TYPES = { + UPDATE_GENERAL: 'updateGeneral', + CHANGE_LOADING: 'changeLoading' +} + +const mutations: MutationTree = { + [MUTATION_TYPES.UPDATE_GENERAL]: (state, conf: GeneralSet) => { + state.general = conf + }, + [MUTATION_TYPES.CHANGE_LOADING]: (state, value: boolean) => { + state.loading = value + } +} + +// TODO: use type of rootState +const actions: ActionTree = { + loadGeneral: ({ commit }) => { + return new Promise((resolve, reject) => { + commit(MUTATION_TYPES.CHANGE_LOADING, true) + ipcRenderer.send('get-preferences') + ipcRenderer.once('error-get-preferences', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-get-preferences') + commit(MUTATION_TYPES.CHANGE_LOADING, false) + reject(err) + }) + ipcRenderer.once('response-get-preferences', (_, conf: any) => { + ipcRenderer.removeAllListeners('error-get-preferences') + commit(MUTATION_TYPES.UPDATE_GENERAL, conf.general as GeneralSet) + commit(MUTATION_TYPES.CHANGE_LOADING, false) + resolve(conf) + }) + }) + }, + updateSound: ({ commit, state }, sound: object) => { + commit(MUTATION_TYPES.CHANGE_LOADING, true) + const newSound: Sound = Object.assign({}, state.general.sound, sound) + const newGeneral: GeneralSet = Object.assign({}, state.general, { + sound: newSound + }) + const config = { + general: newGeneral + } + return new Promise((resolve, reject) => { + ipcRenderer.send('update-preferences', config) + ipcRenderer.once('error-update-preferences', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-update-preferences') + commit(MUTATION_TYPES.CHANGE_LOADING, false) + reject(err) + }) + ipcRenderer.once('response-update-preferences', (_, conf: any) => { + ipcRenderer.removeAllListeners('error-update-preferences') + commit(MUTATION_TYPES.UPDATE_GENERAL, conf.general as GeneralSet) + commit(MUTATION_TYPES.CHANGE_LOADING, false) + resolve(conf) + }) + }) + }, + updateTimeline: ({ commit, state, dispatch }, timeline: object) => { + commit(MUTATION_TYPES.CHANGE_LOADING, true) + const newTimeline: Timeline = Object.assign({}, state.general.timeline, timeline) + const newGeneral: GeneralSet = Object.assign({}, state.general, { + timeline: newTimeline + }) + const config = { + general: newGeneral + } + return new Promise((resolve, reject) => { + ipcRenderer.once('error-update-preferences', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-update-preferences') + commit('changeLoading', false) + reject(err) + }) + ipcRenderer.once('response-update-preferences', (_, conf: any) => { + ipcRenderer.removeAllListeners('error-update-preferences') + commit(MUTATION_TYPES.UPDATE_GENERAL, conf.general as GeneralSet) + commit(MUTATION_TYPES.CHANGE_LOADING, false) + dispatch('App/loadPreferences', null, { root: true }) + resolve(conf) + }) + ipcRenderer.send('update-preferences', config) + }) + } +} +const General: Module = { + namespaced: true, + state: state, + mutations: mutations, + actions: actions +} + +export default General diff --git a/src/renderer/store/Preferences/Language.js b/src/renderer/store/Preferences/Language.js deleted file mode 100644 index 35049e15..00000000 --- a/src/renderer/store/Preferences/Language.js +++ /dev/null @@ -1,47 +0,0 @@ -import { ipcRenderer } from 'electron' -import Language from '~/src/constants/language' - -export default { - namespaced: true, - state: { - language: { - language: Language.en.key - } - }, - mutations: { - updateLanguage (state, conf) { - state.language = conf - }, - changeLanguage (state, key) { - state.language.language = key - } - }, - actions: { - loadLanguage ({ commit }) { - return new Promise((resolve, reject) => { - ipcRenderer.send('get-preferences') - ipcRenderer.once('error-get-preferences', (event, err) => { - ipcRenderer.removeAllListeners('response-get-preferences') - reject(err) - }) - ipcRenderer.once('response-get-preferences', (event, conf) => { - ipcRenderer.removeAllListeners('error-get-preferences') - commit('updateLanguage', conf.language) - resolve(conf) - }) - }) - }, - changeLanguage ({ commit }, key) { - return new Promise(resolve => { - ipcRenderer.send('change-language', key) - ipcRenderer.once('response-change-language', (event, value) => { - commit('changeLanguage', value) - resolve(value) - }) - }) - }, - relaunch () { - ipcRenderer.send('relaunch') - } - } -} diff --git a/src/renderer/store/Preferences/Language.ts b/src/renderer/store/Preferences/Language.ts new file mode 100644 index 00000000..f2fc86f0 --- /dev/null +++ b/src/renderer/store/Preferences/Language.ts @@ -0,0 +1,69 @@ +import { ipcRenderer } from 'electron' +import Language from '~/src/constants/language' +import { Module, MutationTree, ActionTree } from 'vuex' + +interface LanguageSet { + language: string +} + +export interface LanguageState { + language: LanguageSet +} + +const state: LanguageState = { + language: { + language: Language.en.key + } +} + +export const MUTATION_TYPES = { + UPDATE_LANGUAGE: 'updateLanguage', + CHANGE_LANGUAGE: 'changeLanguage' +} + +const mutations: MutationTree = { + [MUTATION_TYPES.UPDATE_LANGUAGE]: (state, conf: LanguageSet) => { + state.language = conf + }, + [MUTATION_TYPES.CHANGE_LANGUAGE]: (state, key: string) => { + state.language.language = key + } +} + +// TODO: use type of rootState +const actions: ActionTree = { + loadLanguage: ({ commit }) => { + return new Promise((resolve, reject) => { + ipcRenderer.send('get-preferences') + ipcRenderer.once('error-get-preferences', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-get-preferences') + reject(err) + }) + ipcRenderer.once('response-get-preferences', (_, conf: any) => { + ipcRenderer.removeAllListeners('error-get-preferences') + commit(MUTATION_TYPES.UPDATE_LANGUAGE, conf.language as LanguageSet) + resolve(conf) + }) + }) + }, + changeLanguage: ({ commit }, key: string) => { + return new Promise(resolve => { + ipcRenderer.send('change-language', key) + ipcRenderer.once('response-change-language', (_, value: string) => { + commit(MUTATION_TYPES.CHANGE_LANGUAGE, value) + resolve(value) + }) + }) + }, + relaunch: () => { + ipcRenderer.send('relaunch') + } +} + +// TODO: use type of rootState +export default { + namespaced: true, + state: state, + mutations: mutations, + actions: actions +} as Module diff --git a/src/renderer/store/Preferences/Notification.js b/src/renderer/store/Preferences/Notification.js deleted file mode 100644 index 97de7ef2..00000000 --- a/src/renderer/store/Preferences/Notification.js +++ /dev/null @@ -1,53 +0,0 @@ -import { ipcRenderer } from 'electron' - -export default { - namespaced: true, - state: { - notification: { - notify: { - reply: true, - reblog: true, - favourite: true, - follow: true - } - } - }, - mutations: { - updateNotification (state, notification) { - state.notification = notification - } - }, - actions: { - loadNotification ({ commit }) { - return new Promise((resolve, reject) => { - ipcRenderer.send('get-preferences') - ipcRenderer.once('error-get-preferences', (event, err) => { - ipcRenderer.removeAllListeners('response-get-preferences') - reject(err) - }) - ipcRenderer.once('response-get-preferences', (event, conf) => { - ipcRenderer.removeAllListeners('error-get-preferences') - commit('updateNotification', conf.notification) - resolve(conf) - }) - }) - }, - updateNotify ({ commit, state, dispatch }, notify) { - const newNotify = Object.assign({}, state.notification.notify, notify) - const newNotification = Object.assign({}, state.notification, { - notify: newNotify - }) - const config = { - notification: newNotification - } - return new Promise(resolve => { - ipcRenderer.send('update-preferences', config) - ipcRenderer.once('response-update-preferences', (event, conf) => { - commit('updateNotification', conf.notification) - dispatch('App/loadPreferences', null, { root: true }) - resolve(conf.notification) - }) - }) - } - } -} diff --git a/src/renderer/store/Preferences/Notification.ts b/src/renderer/store/Preferences/Notification.ts new file mode 100644 index 00000000..0cc58912 --- /dev/null +++ b/src/renderer/store/Preferences/Notification.ts @@ -0,0 +1,81 @@ +import { ipcRenderer } from 'electron' +import { Module, MutationTree, ActionTree } from 'vuex' + +interface Notify { + reply: boolean, + reblog: boolean, + favourite: boolean, + follow: boolean +} + +interface Notification { + notify: Notify +} + +export interface NotificationState { + notification: Notification +} + +const state: NotificationState = { + notification: { + notify: { + reply: true, + reblog: true, + favourite: true, + follow: true + } + } +} + +export const MUTATION_TYPES = { + UPDATE_NOTIFICATION: 'updateNotification' +} + +const mutations: MutationTree = { + [MUTATION_TYPES.UPDATE_NOTIFICATION]: (state, notification: Notification) => { + state.notification = notification + } +} + +// TODO: use type of rootState +const actions: ActionTree = { + loadNotification: ({ commit }) => { + return new Promise((resolve, reject) => { + ipcRenderer.send('get-preferences') + ipcRenderer.once('error-get-preferences', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-get-preferences') + reject(err) + }) + ipcRenderer.once('response-get-preferences', (_, conf: any) => { + ipcRenderer.removeAllListeners('error-get-preferences') + commit(MUTATION_TYPES.UPDATE_NOTIFICATION, conf.notification as Notification) + resolve(conf) + }) + }) + }, + updateNotify: ({ commit, state, dispatch }, notify: object) => { + const newNotify: Notify = Object.assign({}, state.notification.notify, notify) + const newNotification: Notification = Object.assign({}, state.notification, { + notify: newNotify + }) + const config = { + notification: newNotification + } + return new Promise(resolve => { + ipcRenderer.send('update-preferences', config) + ipcRenderer.once('response-update-preferences', (_, conf: any) => { + commit(MUTATION_TYPES.UPDATE_NOTIFICATION, conf.notification as Notification) + dispatch('App/loadPreferences', null, { root: true }) + resolve(conf.notification) + }) + }) + } +} + +// TODO: use type of rootState +export default { + namespaced: true, + state: state, + mutations: mutations, + actions: actions +} as Module diff --git a/src/renderer/store/Settings.js b/src/renderer/store/Settings.js deleted file mode 100644 index 32b7d4ed..00000000 --- a/src/renderer/store/Settings.js +++ /dev/null @@ -1,18 +0,0 @@ -import General from './Settings/General' -import Timeline from './Settings/Timeline' - -export default { - namespaced: true, - modules: { - General, - Timeline - }, - state: { - accountID: null - }, - mutations: { - changeAccountID (state, id) { - state.accountID = id - } - } -} diff --git a/src/renderer/store/Settings.ts b/src/renderer/store/Settings.ts new file mode 100644 index 00000000..6eb8d2b7 --- /dev/null +++ b/src/renderer/store/Settings.ts @@ -0,0 +1,34 @@ +import General from './Settings/General' +import Timeline from './Settings/Timeline' +import { Module, MutationTree } from 'vuex' + +export interface SettingsState { + accountID: number | null +} + +const state = (): SettingsState => ({ + accountID: null +}) + +export const MUTATION_TYPES = { + CHANGE_ACCOUNT_ID: 'changeAccountID' +} + +const mutations: MutationTree = { + [MUTATION_TYPES.CHANGE_ACCOUNT_ID]: (state, id: number) => { + state.accountID = id + } +} + +// TODO: use type of rootState +const Settings: Module = { + namespaced: true, + modules: { + General, + Timeline + }, + state: state, + mutations: mutations +} + +export default Settings diff --git a/src/renderer/store/Settings/General.js b/src/renderer/store/Settings/General.js deleted file mode 100644 index ddc2fa05..00000000 --- a/src/renderer/store/Settings/General.js +++ /dev/null @@ -1,68 +0,0 @@ -import Mastodon from 'megalodon' -import Visibility from '~/src/constants/visibility' - -export default { - namespaced: true, - state: { - visibility: Visibility.Public.value, - sensitive: false - }, - mutations: { - changeVisibility (state, value) { - state.visibility = value - }, - changeSensitive (state, value) { - state.sensitive = value - } - }, - actions: { - fetchSettings ({ 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('changeVisibility', visibility.value) - commit('changeSensitive', res.data.source.sensitive) - return res.data - }) - }, - setVisibility ({ commit, rootState }, value) { - const client = new Mastodon( - rootState.TimelineSpace.account.accessToken, - rootState.TimelineSpace.account.baseURL + '/api/v1' - ) - const visibility = Object.values(Visibility).find((v) => { - return v.value === value - }) - return client.patch('/accounts/update_credentials', { - source: { - privacy: visibility.key - } - }) - .then(res => { - commit('changeVisibility', visibility.value) - return res.data - }) - }, - setSensitive ({ commit, rootState }, value) { - const client = new Mastodon( - rootState.TimelineSpace.account.accessToken, - rootState.TimelineSpace.account.baseURL + '/api/v1' - ) - return client.patch('/accounts/update_credentials', { - source: { - sensitive: value - } - }) - .then(res => { - commit('changeSensitive', value) - return res.data - }) - } - } -} diff --git a/src/renderer/store/Settings/General.ts b/src/renderer/store/Settings/General.ts new file mode 100644 index 00000000..9a06d0ce --- /dev/null +++ b/src/renderer/store/Settings/General.ts @@ -0,0 +1,84 @@ +import Mastodon, { Account } from 'megalodon' +import Visibilities from '~/src/constants/visibility' +import { Module, MutationTree, ActionTree } from 'vuex' +import Visibility from '~/src/types/visibility' + +export interface GeneralState { + visibility: number, + sensitive: boolean +} + +const state = (): GeneralState => ({ + visibility: Visibilities.Public.value, + sensitive: false +}) + +export const MUTATION_TYPES = { + CHANGE_VISIBILITY: 'changeVisibility', + CHANGE_SENSITIVE: 'changeSensitive' +} + +const mutations: MutationTree = { + [MUTATION_TYPES.CHANGE_VISIBILITY]: (state, value: number) => { + state.visibility = value + }, + [MUTATION_TYPES.CHANGE_SENSITIVE]: (state, value: boolean) => { + state.sensitive = value + } +} + +// TODO: use type of rootState +const actions: ActionTree = { + fetchSettings: async ({ commit, rootState }): Promise => { + const client = new Mastodon( + rootState.TimelineSpace.account.accessToken, + rootState.TimelineSpace.account.baseURL + '/api/v1' + ) + const res = await client.get('/accounts/verify_credentials') + const visibility: Visibility | undefined = Object.values(Visibilities as Array).find((v) => { + return v.key === res.data.source!.privacy + }) + commit(MUTATION_TYPES.CHANGE_VISIBILITY, visibility!.value) + commit(MUTATION_TYPES.CHANGE_SENSITIVE, res.data.source!.sensitive) + return res.data + }, + setVisibility: async ({ commit, rootState }, value: number) => { + const client = new Mastodon( + rootState.TimelineSpace.account.accessToken, + rootState.TimelineSpace.account.baseURL + '/api/v1' + ) + const visibility = Object.values(Visibilities as Array).find((v) => { + return v.value === value + }) + const res = await client.patch('/accounts/update_credentials', { + source: { + privacy: visibility!.key + } + }) + commit(MUTATION_TYPES.CHANGE_VISIBILITY, visibility!.value) + return res.data + }, + setSensitive: async ({ commit, rootState }, value: boolean) => { + const client = new Mastodon( + rootState.TimelineSpace.account.accessToken, + rootState.TimelineSpace.account.baseURL + '/api/v1' + ) + const res = await client.patch('/accounts/update_credentials', { + source: { + sensitive: value + } + }) + commit(MUTATION_TYPES.CHANGE_SENSITIVE, value) + return res.data + } +} + +// TODO: use type of rootState +const General: Module = { + namespaced: true, + state: state, + mutations: mutations, + actions: actions +} + +export default General diff --git a/src/renderer/store/Settings/Timeline.js b/src/renderer/store/Settings/Timeline.js deleted file mode 100644 index 9ba166e8..00000000 --- a/src/renderer/store/Settings/Timeline.js +++ /dev/null @@ -1,56 +0,0 @@ -import { ipcRenderer } from 'electron' -import unreadSettings from '~/src/constants/unreadNotification' - -export default { - namespaced: true, - state: { - unreadNotification: { - direct: unreadSettings.Direct.default, - local: unreadSettings.Local.default, - public: unreadSettings.Public.default - } - }, - mutations: { - updateUnreadNotification (state, settings) { - state.unreadNotification = settings - } - }, - actions: { - loadUnreadNotification ({ commit, rootState }) { - return new Promise(resolve => { - ipcRenderer.once('response-get-unread-notification', (_, settings) => { - ipcRenderer.removeAllListeners('error-get-unread-notification') - commit('updateUnreadNotification', settings) - resolve(settings) - }) - ipcRenderer.once('error-get-unread-notification', () => { - ipcRenderer.removeAllListeners('response-get-unread-notification') - commit('updateUnreadNotification', { - direct: unreadSettings.Direct.default, - local: unreadSettings.Local.default, - public: unreadSettings.Public.default - }) - resolve(null) - }) - ipcRenderer.send('get-unread-notification', rootState.Settings.accountID) - }) - }, - changeUnreadNotification ({ dispatch, state, rootState }, timeline) { - const settings = Object.assign({}, state.unreadNotification, timeline, { - accountID: rootState.Settings.accountID - }) - return new Promise((resolve, reject) => { - ipcRenderer.once('response-update-unread-notification', () => { - ipcRenderer.removeAllListeners('error-update-unread-notification') - dispatch('loadUnreadNotification') - resolve(settings) - }) - ipcRenderer.once('error-update-unread-notification', (_, err) => { - ipcRenderer.removeAllListeners('response-update-unread-notification') - reject(err) - }) - ipcRenderer.send('update-unread-notification', settings) - }) - } - } -} diff --git a/src/renderer/store/Settings/Timeline.ts b/src/renderer/store/Settings/Timeline.ts new file mode 100644 index 00000000..9cff7707 --- /dev/null +++ b/src/renderer/store/Settings/Timeline.ts @@ -0,0 +1,82 @@ +import { ipcRenderer } from 'electron' +import unreadSettings from '~/src/constants/unreadNotification' +import { Module, MutationTree, ActionTree } from 'vuex' + +interface UnreadNotification { + direct: boolean, + local: boolean, + public: boolean +} + +export interface TimelineState { + unreadNotification: UnreadNotification +} + +const state = (): TimelineState => ({ + unreadNotification: { + direct: unreadSettings.Direct.default, + local: unreadSettings.Local.default, + public: unreadSettings.Public.default + } +}) + +export const MUTATION_TYPES = { + UPDATE_UNREAD_NOTIFICATION: 'updateUnreadNotification' +} + +const mutations: MutationTree = { + [MUTATION_TYPES.UPDATE_UNREAD_NOTIFICATION]: (state, settings: UnreadNotification) => { + state.unreadNotification = settings + } +} + +// TODO: use type of rootState +const actions: ActionTree = { + loadUnreadNotification: ({ commit, rootState }): Promise => { + return new Promise(resolve => { + ipcRenderer.once('response-get-unread-notification', (_, settings: UnreadNotification) => { + ipcRenderer.removeAllListeners('error-get-unread-notification') + commit(MUTATION_TYPES.UPDATE_UNREAD_NOTIFICATION, settings) + resolve(true) + }) + ipcRenderer.once('error-get-unread-notification', () => { + ipcRenderer.removeAllListeners('response-get-unread-notification') + const settings: UnreadNotification = { + direct: unreadSettings.Direct.default, + local: unreadSettings.Local.default, + public: unreadSettings.Public.default + } + commit(MUTATION_TYPES.UPDATE_UNREAD_NOTIFICATION, settings) + resolve(false) + }) + ipcRenderer.send('get-unread-notification', rootState.Settings.accountID) + }) + }, + changeUnreadNotification: ({ dispatch, state, rootState }, timeline: object): Promise => { + const settings = Object.assign({}, state.unreadNotification, timeline, { + accountID: rootState.Settings.accountID + }) + return new Promise((resolve, reject) => { + ipcRenderer.once('response-update-unread-notification', () => { + ipcRenderer.removeAllListeners('error-update-unread-notification') + dispatch('loadUnreadNotification') + resolve(true) + }) + ipcRenderer.once('error-update-unread-notification', (_, err: Error) => { + ipcRenderer.removeAllListeners('response-update-unread-notification') + reject(err) + }) + ipcRenderer.send('update-unread-notification', settings) + }) + } +} + +// Todo: use type of rootState +const Timeline: Module = { + namespaced: true, + state: state, + mutations: mutations, + actions: actions +} + +export default Timeline diff --git a/src/types/visibility.ts b/src/types/visibility.ts new file mode 100644 index 00000000..124ca8c6 --- /dev/null +++ b/src/types/visibility.ts @@ -0,0 +1,5 @@ +export default interface Visibility { + name: string, + value: number, + key: string +}