commit
c57b0ee273
|
@ -13,7 +13,7 @@ const { VueLoaderPlugin } = require('vue-loader')
|
|||
|
||||
let rendererConfig = {
|
||||
entry: {
|
||||
renderer: path.join(__dirname, '../src/renderer/main.ts')
|
||||
renderer: path.join(__dirname, '../src/renderer/main.js')
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
|
@ -205,8 +205,7 @@ let rendererConfig = {
|
|||
alias: {
|
||||
// Same as tsconfig.json
|
||||
'@': path.join(__dirname, '../src/renderer'),
|
||||
'~': path.join(__dirname, '../'),
|
||||
vue$: 'vue/dist/vue.esm.js'
|
||||
'~': path.join(__dirname, '../')
|
||||
},
|
||||
extensions: ['.ts', '.js', '.vue', '.json', '.css', '.node'],
|
||||
fallback: {
|
||||
|
|
28
package.json
28
package.json
|
@ -72,8 +72,8 @@
|
|||
"@fortawesome/fontawesome-svg-core": "^6.1.0",
|
||||
"@fortawesome/free-regular-svg-icons": "^6.1.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.1.0",
|
||||
"@fortawesome/vue-fontawesome": "^2.0.6",
|
||||
"@panter/vue-i18next": "^0.15.2",
|
||||
"@fortawesome/vue-fontawesome": "^3.0.0-5",
|
||||
"vue-virtual-scroller": "2.0.0-alpha.1",
|
||||
"@trodi/electron-splashscreen": "^1.0.2",
|
||||
"about-window": "^1.15.2",
|
||||
"animate.css": "^4.1.0",
|
||||
|
@ -85,13 +85,14 @@
|
|||
"electron-json-storage": "^4.5.0",
|
||||
"electron-log": "^4.4.6",
|
||||
"electron-window-state": "^5.0.3",
|
||||
"element-ui": "2.15.8",
|
||||
"emoji-mart-vue": "^2.6.6",
|
||||
"element-plus": "^2.1.9",
|
||||
"emoji-mart-vue-fast": "^10.2.1",
|
||||
"i18next": "^21.6.16",
|
||||
"lodash": "^4.17.21",
|
||||
"lokijs": "^1.5.12",
|
||||
"megalodon": "4.0.1",
|
||||
"minimist": "^1.2.6",
|
||||
"mitt": "^3.0.0",
|
||||
"moment": "^2.29.2",
|
||||
"mousetrap": "^1.6.5",
|
||||
"nedb": "^1.8.0",
|
||||
|
@ -103,15 +104,13 @@
|
|||
"system-font-families": "^0.6.0",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"unicode-emoji-json": "^0.3.1",
|
||||
"vue": "^2.6.14",
|
||||
"vue-click-outside": "^1.1.0",
|
||||
"vue": "^3.2.31",
|
||||
"vue-popperjs": "^2.3.0",
|
||||
"vue-resize": "^1.0.1",
|
||||
"vue-router": "^3.5.3",
|
||||
"vue-shortkey": "^3.1.7",
|
||||
"vue-virtual-scroller": "^1.0.10",
|
||||
"vuex": "^3.6.2",
|
||||
"vuex-router-sync": "^5.0.0"
|
||||
"vue-resize": "^2.0.0-alpha.1",
|
||||
"vue-router": "^4.0.14",
|
||||
"vue3-i18next": "^0.1.0",
|
||||
"vuex": "^4.0.2",
|
||||
"vuex-router-sync": "^6.0.0-rc.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.17.9",
|
||||
|
@ -134,7 +133,7 @@
|
|||
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
||||
"@typescript-eslint/parser": "^4.33.0",
|
||||
"@typescript-eslint/typescript-estree": "^5.19.0",
|
||||
"@vue/test-utils": "^1.3.0",
|
||||
"@vue/compiler-sfc": "^3.2.31",
|
||||
"ajv": "^8.11.0",
|
||||
"all-object-keys": "^2.2.0",
|
||||
"assert": "^2.0.0",
|
||||
|
@ -211,9 +210,8 @@
|
|||
"url-loader": "^4.1.1",
|
||||
"utf-8-validate": "^5.0.9",
|
||||
"vue-html-loader": "^1.2.4",
|
||||
"vue-loader": "^15.9.8",
|
||||
"vue-loader": "^17.0.0",
|
||||
"vue-style-loader": "^4.1.3",
|
||||
"vue-template-compiler": "^2.6.14",
|
||||
"webpack": "^5.72.0",
|
||||
"webpack-cli": "^4.9.2",
|
||||
"webpack-dev-server": "^4.8.1",
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import { ipcMain, ipcRenderer } from '~/spec/mock/electron'
|
||||
import App from '@/store/App'
|
||||
import DisplayStyle from '~/src/constants/displayStyle'
|
||||
|
@ -9,7 +8,8 @@ import TimeFormat from '~/src/constants/timeFormat'
|
|||
import Language from '~/src/constants/language'
|
||||
import DefaultFonts from '@/utils/fonts'
|
||||
import { MyWindow } from '~/src/types/global'
|
||||
;((window as any) as MyWindow).ipcRenderer = ipcRenderer
|
||||
import { RootState } from '@/store'
|
||||
;(window as any as MyWindow).ipcRenderer = ipcRenderer
|
||||
|
||||
const state = () => {
|
||||
return {
|
||||
|
@ -41,13 +41,10 @@ const initStore = () => {
|
|||
}
|
||||
|
||||
describe('App', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
App: initStore()
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { RootState } from '@/store'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import { ipcMain, ipcRenderer } from '~/spec/mock/electron'
|
||||
import GlobalHeader, { GlobalHeaderState } from '~/src/renderer/store/GlobalHeader'
|
||||
import { MyWindow } from '~/src/types/global'
|
||||
;((window as any) as MyWindow).ipcRenderer = ipcRenderer
|
||||
;(window as any as MyWindow).ipcRenderer = ipcRenderer
|
||||
|
||||
const state = (): GlobalHeaderState => {
|
||||
return {
|
||||
|
@ -32,13 +32,10 @@ const routerState = {
|
|||
}
|
||||
|
||||
describe('GlobalHeader', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
GlobalHeader: initStore(),
|
||||
route: routerState
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import { ipcMain, ipcRenderer } from '~/spec/mock/electron'
|
||||
import Login, { LoginState } from '@/store/Login'
|
||||
import { MyWindow } from '~/src/types/global'
|
||||
;((window as any) as MyWindow).ipcRenderer = ipcRenderer
|
||||
import { RootState } from '@/store'
|
||||
;(window as any as MyWindow).ipcRenderer = ipcRenderer
|
||||
|
||||
jest.mock('megalodon', () => ({
|
||||
...jest.requireActual<object>('megalodon'),
|
||||
|
@ -36,13 +36,10 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('Login', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Login: initStore(),
|
||||
App: appState
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import { ipcMain, ipcRenderer } from '~/spec/mock/electron'
|
||||
import Account, { AccountState } from '@/store/Preferences/Account'
|
||||
import { LocalAccount } from '~/src/types/localAccount'
|
||||
import { MyWindow } from '~/src/types/global'
|
||||
;((window as any) as MyWindow).ipcRenderer = ipcRenderer
|
||||
import { RootState } from '@/store'
|
||||
;(window as any as MyWindow).ipcRenderer = ipcRenderer
|
||||
|
||||
const account: LocalAccount = {
|
||||
_id: 'sample',
|
||||
|
@ -36,16 +36,20 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const preferencesStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Account: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
describe('Account', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Account: initStore()
|
||||
Preferences: preferencesStore()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -56,7 +60,7 @@ describe('Account', () => {
|
|||
throw new Error()
|
||||
})
|
||||
|
||||
await store.dispatch('Account/loadAccounts').catch((err: Error) => {
|
||||
await store.dispatch('Preferences/Account/loadAccounts').catch((err: Error) => {
|
||||
expect(err instanceof Error).toEqual(true)
|
||||
})
|
||||
ipcMain.removeHandler('list-accounts')
|
||||
|
@ -65,8 +69,8 @@ describe('Account', () => {
|
|||
ipcMain.handle('list-accounts', () => {
|
||||
return [account]
|
||||
})
|
||||
await store.dispatch('Account/loadAccounts')
|
||||
expect(store.state.Account.accounts).toEqual([account])
|
||||
await store.dispatch('Preferences/Account/loadAccounts')
|
||||
expect(store.state.Preferences.Account.accounts).toEqual([account])
|
||||
ipcMain.removeHandler('list-accounts')
|
||||
})
|
||||
})
|
||||
|
@ -76,7 +80,7 @@ describe('Account', () => {
|
|||
ipcMain.handle('remove-account', async () => {
|
||||
throw new Error()
|
||||
})
|
||||
await store.dispatch('Account/removeAccount', account).catch((err: Error) => {
|
||||
await store.dispatch('Preferences/Account/removeAccount', account).catch((err: Error) => {
|
||||
expect(err instanceof Error).toEqual(true)
|
||||
})
|
||||
ipcMain.removeHandler('remove-account')
|
||||
|
@ -85,7 +89,7 @@ describe('Account', () => {
|
|||
ipcMain.handle('remove-account', () => {
|
||||
return true
|
||||
})
|
||||
const res = await store.dispatch('Account/removeAccount', account)
|
||||
const res = await store.dispatch('Preferences/Account/removeAccount', account)
|
||||
expect(res).toEqual(undefined)
|
||||
ipcMain.removeHandler('remove-account')
|
||||
})
|
||||
|
@ -96,7 +100,7 @@ describe('Account', () => {
|
|||
ipcMain.handle('forward-account', async () => {
|
||||
throw new Error()
|
||||
})
|
||||
await store.dispatch('Account/forwardAccount', account).catch((err: Error) => {
|
||||
await store.dispatch('Preferences/Account/forwardAccount', account).catch((err: Error) => {
|
||||
expect(err instanceof Error).toEqual(true)
|
||||
})
|
||||
ipcMain.removeHandler('forward-account')
|
||||
|
@ -105,7 +109,7 @@ describe('Account', () => {
|
|||
ipcMain.handle('forward-account', () => {
|
||||
return {}
|
||||
})
|
||||
const res = await store.dispatch('Account/forwardAccount', account)
|
||||
const res = await store.dispatch('Preferences/Account/forwardAccount', account)
|
||||
expect(res).toEqual(undefined)
|
||||
ipcMain.removeHandler('forward-account')
|
||||
})
|
||||
|
@ -116,7 +120,7 @@ describe('Account', () => {
|
|||
ipcMain.handle('backward-account', () => {
|
||||
throw new Error()
|
||||
})
|
||||
await store.dispatch('Account/backwardAccount', account).catch((err: Error) => {
|
||||
await store.dispatch('Preferences/Account/backwardAccount', account).catch((err: Error) => {
|
||||
expect(err instanceof Error).toEqual(true)
|
||||
})
|
||||
ipcMain.removeHandler('backward-account')
|
||||
|
@ -125,7 +129,7 @@ describe('Account', () => {
|
|||
ipcMain.handle('backward-account', () => {
|
||||
return {}
|
||||
})
|
||||
const res = await store.dispatch('Account/backwardAccount', account)
|
||||
const res = await store.dispatch('Preferences/Account/backwardAccount', account)
|
||||
expect(res).toEqual(undefined)
|
||||
ipcMain.removeHandler('backward-account')
|
||||
})
|
||||
|
@ -136,7 +140,7 @@ describe('Account', () => {
|
|||
ipcMain.handle('remove-all-accounts', () => {
|
||||
throw new Error()
|
||||
})
|
||||
await store.dispatch('Account/removeAllAccounts', account).catch((err: Error) => {
|
||||
await store.dispatch('Preferences/Account/removeAllAccounts', account).catch((err: Error) => {
|
||||
expect(err instanceof Error).toEqual(true)
|
||||
})
|
||||
ipcMain.removeHandler('remove-all-accounts')
|
||||
|
@ -145,7 +149,7 @@ describe('Account', () => {
|
|||
ipcMain.handle('remove-all-accounts', () => {
|
||||
return {}
|
||||
})
|
||||
const res = await store.dispatch('Account/removeAllAccounts', account)
|
||||
const res = await store.dispatch('Preferences/Account/removeAllAccounts', account)
|
||||
expect(res).toEqual(undefined)
|
||||
ipcMain.removeHandler('remove-all-accounts')
|
||||
})
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { IpcMainInvokeEvent } from 'electron'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import Theme from '~/src/constants/theme'
|
||||
import DisplayStyle from '~/src/constants/displayStyle'
|
||||
import TimeFormat from '~/src/constants/timeFormat'
|
||||
|
@ -9,7 +8,8 @@ import DefaultFonts from '@/utils/fonts'
|
|||
import Appearance, { AppearanceState } from '@/store/Preferences/Appearance'
|
||||
import { ipcMain, ipcRenderer } from '~/spec/mock/electron'
|
||||
import { MyWindow } from '~/src/types/global'
|
||||
;((window as any) as MyWindow).ipcRenderer = ipcRenderer
|
||||
import { RootState } from '@/store'
|
||||
;(window as any as MyWindow).ipcRenderer = ipcRenderer
|
||||
|
||||
const state = (): AppearanceState => {
|
||||
return {
|
||||
|
@ -35,6 +35,13 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const preferencesStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Appearance: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const App = {
|
||||
namespaced: true,
|
||||
actions: {
|
||||
|
@ -43,15 +50,12 @@ const App = {
|
|||
}
|
||||
|
||||
describe('Preferences/Appearance', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Preferences: initStore(),
|
||||
Preferences: preferencesStore(),
|
||||
App: App
|
||||
}
|
||||
})
|
||||
|
@ -73,9 +77,9 @@ describe('Preferences/Appearance', () => {
|
|||
ipcMain.removeHandler('get-preferences')
|
||||
})
|
||||
it('should be loaded', async () => {
|
||||
await store.dispatch('Preferences/loadAppearance')
|
||||
expect(store.state.Preferences.appearance.theme).toEqual(Theme.Dark.key)
|
||||
expect(store.state.Preferences.appearance.fontSize).toEqual(15)
|
||||
await store.dispatch('Preferences/Appearance/loadAppearance')
|
||||
expect(store.state.Preferences.Appearance.appearance.theme).toEqual(Theme.Dark.key)
|
||||
expect(store.state.Preferences.Appearance.appearance.fontSize).toEqual(15)
|
||||
})
|
||||
})
|
||||
describe('loadFonts', () => {
|
||||
|
@ -88,8 +92,8 @@ describe('Preferences/Appearance', () => {
|
|||
ipcMain.removeHandler('list-fonts')
|
||||
})
|
||||
it('should be loaded', async () => {
|
||||
await store.dispatch('Preferences/loadFonts')
|
||||
expect(store.state.Preferences.fonts).toEqual([DefaultFonts[0], 'my-font'])
|
||||
await store.dispatch('Preferences/Appearance/loadFonts')
|
||||
expect(store.state.Preferences.Appearance.fonts).toEqual([DefaultFonts[0], 'my-font'])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -104,38 +108,38 @@ describe('Preferences/Appearance', () => {
|
|||
ipcMain.removeHandler('update-preferences')
|
||||
})
|
||||
it('updateTheme', async () => {
|
||||
await store.dispatch('Preferences/updateTheme', Theme.Dark.key)
|
||||
expect(store.state.Preferences.appearance.theme).toEqual(Theme.Dark.key)
|
||||
await store.dispatch('Preferences/Appearance/updateTheme', Theme.Dark.key)
|
||||
expect(store.state.Preferences.Appearance.appearance.theme).toEqual(Theme.Dark.key)
|
||||
expect(App.actions.loadPreferences).toBeCalled()
|
||||
})
|
||||
|
||||
it('updateFontSize', async () => {
|
||||
await store.dispatch('Preferences/updateFontSize', 15)
|
||||
expect(store.state.Preferences.appearance.fontSize).toEqual(15)
|
||||
await store.dispatch('Preferences/Appearance/updateFontSize', 15)
|
||||
expect(store.state.Preferences.Appearance.appearance.fontSize).toEqual(15)
|
||||
expect(App.actions.loadPreferences).toBeCalled()
|
||||
})
|
||||
|
||||
it('updateDisplayNameStyle', async () => {
|
||||
await store.dispatch('Preferences/updateDisplayNameStyle', DisplayStyle.DisplayName.value)
|
||||
expect(store.state.Preferences.appearance.displayNameStyle).toEqual(DisplayStyle.DisplayName.value)
|
||||
await store.dispatch('Preferences/Appearance/updateDisplayNameStyle', DisplayStyle.DisplayName.value)
|
||||
expect(store.state.Preferences.Appearance.appearance.displayNameStyle).toEqual(DisplayStyle.DisplayName.value)
|
||||
expect(App.actions.loadPreferences).toBeCalled()
|
||||
})
|
||||
|
||||
it('updateTimeFormat', async () => {
|
||||
await store.dispatch('Preferences/updateTimeFormat', TimeFormat.Relative.value)
|
||||
expect(store.state.Preferences.appearance.timeFormat).toEqual(TimeFormat.Relative.value)
|
||||
await store.dispatch('Preferences/Appearance/updateTimeFormat', TimeFormat.Relative.value)
|
||||
expect(store.state.Preferences.Appearance.appearance.timeFormat).toEqual(TimeFormat.Relative.value)
|
||||
expect(App.actions.loadPreferences).toBeCalled()
|
||||
})
|
||||
|
||||
it('updateCustomThemeColor', async () => {
|
||||
await store.dispatch('Preferences/updateCustomThemeColor', DarkTheme)
|
||||
expect(store.state.Preferences.appearance.customThemeColor).toEqual(DarkTheme)
|
||||
await store.dispatch('Preferences/Appearance/updateCustomThemeColor', DarkTheme)
|
||||
expect(store.state.Preferences.Appearance.appearance.customThemeColor).toEqual(DarkTheme)
|
||||
expect(App.actions.loadPreferences).toBeCalled()
|
||||
})
|
||||
|
||||
it('updateFont', async () => {
|
||||
await store.dispatch('Preferences/updateFont', DefaultFonts[1])
|
||||
expect(store.state.Preferences.appearance.font).toEqual(DefaultFonts[1])
|
||||
await store.dispatch('Preferences/Appearance/updateFont', DefaultFonts[1])
|
||||
expect(store.state.Preferences.Appearance.appearance.font).toEqual(DefaultFonts[1])
|
||||
expect(App.actions.loadPreferences).toBeCalled()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import { ipcMain, ipcRenderer } from '~/spec/mock/electron'
|
||||
import General, { GeneralState } from '@/store/Preferences/General'
|
||||
import { MyWindow } from '~/src/types/global'
|
||||
import { IpcMainInvokeEvent } from 'electron'
|
||||
;((window as any) as MyWindow).ipcRenderer = ipcRenderer
|
||||
import { RootState } from '@/store'
|
||||
;(window as any as MyWindow).ipcRenderer = ipcRenderer
|
||||
|
||||
const state = (): GeneralState => {
|
||||
return {
|
||||
|
@ -34,6 +34,13 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const preferencesStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
General: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const app = {
|
||||
namespaced: true,
|
||||
actions: {
|
||||
|
@ -44,15 +51,12 @@ const app = {
|
|||
}
|
||||
|
||||
describe('Preferences/General', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Preferences: initStore(),
|
||||
Preferences: preferencesStore(),
|
||||
App: app
|
||||
}
|
||||
})
|
||||
|
@ -75,10 +79,10 @@ describe('Preferences/General', () => {
|
|||
ipcMain.removeHandler('get-preferences')
|
||||
})
|
||||
it('should be updated', async () => {
|
||||
await store.dispatch('Preferences/loadGeneral')
|
||||
expect(store.state.Preferences.general.sound.fav_rb).toEqual(false)
|
||||
expect(store.state.Preferences.general.sound.toot).toEqual(false)
|
||||
expect(store.state.Preferences.loading).toEqual(false)
|
||||
await store.dispatch('Preferences/General/loadGeneral')
|
||||
expect(store.state.Preferences.General.general.sound.fav_rb).toEqual(false)
|
||||
expect(store.state.Preferences.General.general.sound.toot).toEqual(false)
|
||||
expect(store.state.Preferences.General.loading).toEqual(false)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -92,13 +96,13 @@ describe('Preferences/General', () => {
|
|||
ipcMain.removeHandler('update-preferences')
|
||||
})
|
||||
it('should be updated', async () => {
|
||||
await store.dispatch('Preferences/updateSound', {
|
||||
await store.dispatch('Preferences/General/updateSound', {
|
||||
fav_rb: false,
|
||||
toot: false
|
||||
})
|
||||
expect(store.state.Preferences.general.sound.fav_rb).toEqual(false)
|
||||
expect(store.state.Preferences.general.sound.toot).toEqual(false)
|
||||
expect(store.state.Preferences.loading).toEqual(false)
|
||||
expect(store.state.Preferences.General.general.sound.fav_rb).toEqual(false)
|
||||
expect(store.state.Preferences.General.general.sound.toot).toEqual(false)
|
||||
expect(store.state.Preferences.General.loading).toEqual(false)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -112,15 +116,15 @@ describe('Preferences/General', () => {
|
|||
ipcMain.removeHandler('update-preferences')
|
||||
})
|
||||
it('should be updated', async () => {
|
||||
await store.dispatch('Preferences/updateTimeline', {
|
||||
await store.dispatch('Preferences/General/updateTimeline', {
|
||||
cw: true,
|
||||
nsfw: true,
|
||||
hideAllAttachments: true
|
||||
})
|
||||
expect(store.state.Preferences.general.timeline.cw).toEqual(true)
|
||||
expect(store.state.Preferences.general.timeline.nsfw).toEqual(true)
|
||||
expect(store.state.Preferences.general.timeline.hideAllAttachments).toEqual(true)
|
||||
expect(store.state.Preferences.loading).toEqual(false)
|
||||
expect(store.state.Preferences.General.general.timeline.cw).toEqual(true)
|
||||
expect(store.state.Preferences.General.general.timeline.nsfw).toEqual(true)
|
||||
expect(store.state.Preferences.General.general.timeline.hideAllAttachments).toEqual(true)
|
||||
expect(store.state.Preferences.General.loading).toEqual(false)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import { ipcMain, ipcRenderer } from '~/spec/mock/electron'
|
||||
import Language, { LanguageState } from '@/store/Preferences/Language'
|
||||
import DefaultLanguage from '~/src/constants/language'
|
||||
import { MyWindow } from '~/src/types/global'
|
||||
;((window as any) as MyWindow).ipcRenderer = ipcRenderer
|
||||
import { RootState } from '@/store'
|
||||
;(window as any as MyWindow).ipcRenderer = ipcRenderer
|
||||
|
||||
const state = (): LanguageState => {
|
||||
return {
|
||||
|
@ -27,16 +27,20 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const preferencesStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Language: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
describe('Preferences/Language', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Language: initStore()
|
||||
Preferences: preferencesStore()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -59,8 +63,8 @@ describe('Preferences/Language', () => {
|
|||
ipcMain.removeHandler('get-preferences')
|
||||
})
|
||||
it('should be updated', async () => {
|
||||
await store.dispatch('Language/loadLanguage')
|
||||
expect(store.state.Language.language.language).toEqual(DefaultLanguage.ja.key)
|
||||
await store.dispatch('Preferences/Language/loadLanguage')
|
||||
expect(store.state.Preferences.Language.language.language).toEqual(DefaultLanguage.ja.key)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -74,8 +78,8 @@ describe('Preferences/Language', () => {
|
|||
ipcMain.removeHandler('change-language')
|
||||
})
|
||||
it('should be changed', async () => {
|
||||
await store.dispatch('Language/changeLanguage', DefaultLanguage.ja.key)
|
||||
expect(store.state.Language.language.language).toEqual(DefaultLanguage.ja.key)
|
||||
await store.dispatch('Preferences/Language/changeLanguage', DefaultLanguage.ja.key)
|
||||
expect(store.state.Preferences.Language.language.language).toEqual(DefaultLanguage.ja.key)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import { ipcMain, ipcRenderer } from '~/spec/mock/electron'
|
||||
import Notification, { NotificationState } from '@/store/Preferences/Notification'
|
||||
import { MyWindow } from '~/src/types/global'
|
||||
;((window as any) as MyWindow).ipcRenderer = ipcRenderer
|
||||
import { RootState } from '@/store'
|
||||
;(window as any as MyWindow).ipcRenderer = ipcRenderer
|
||||
|
||||
const state = (): NotificationState => {
|
||||
return {
|
||||
|
@ -32,6 +32,13 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const preferencesStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Notification: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const App = {
|
||||
namespaced: true,
|
||||
actions: {
|
||||
|
@ -40,15 +47,12 @@ const App = {
|
|||
}
|
||||
|
||||
describe('Preferences/Notification', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Notification: initStore(),
|
||||
Preferences: preferencesStore(),
|
||||
App: App
|
||||
}
|
||||
})
|
||||
|
@ -77,8 +81,8 @@ describe('Preferences/Notification', () => {
|
|||
ipcMain.removeHandler('get-preferences')
|
||||
})
|
||||
it('should be updated', async () => {
|
||||
await store.dispatch('Notification/loadNotification')
|
||||
expect(store.state.Notification.notification).toEqual({
|
||||
await store.dispatch('Preferences/Notification/loadNotification')
|
||||
expect(store.state.Preferences.Notification.notification).toEqual({
|
||||
notify: {
|
||||
reply: false,
|
||||
reblog: false,
|
||||
|
@ -105,11 +109,11 @@ describe('Preferences/Notification', () => {
|
|||
ipcMain.removeHandler('update-preferences')
|
||||
})
|
||||
it('should be updated', async () => {
|
||||
await store.dispatch('Notification/updateNotify', {
|
||||
await store.dispatch('Preferences/Notification/updateNotify', {
|
||||
reply: false,
|
||||
reblog: false
|
||||
})
|
||||
expect(store.state.Notification.notification).toEqual({
|
||||
expect(store.state.Preferences.Notification.notification).toEqual({
|
||||
notify: {
|
||||
reply: false,
|
||||
reblog: false,
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { RootState } from '@/store'
|
||||
import { Entity, Response } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import { ipcMain, ipcRenderer } from '~/spec/mock/electron'
|
||||
import TimelineSpace, { TimelineSpaceState, blankAccount } from '~/src/renderer/store/TimelineSpace'
|
||||
import { MyWindow } from '~/src/types/global'
|
||||
;((window as any) as MyWindow).ipcRenderer = ipcRenderer
|
||||
;(window as any as MyWindow).ipcRenderer = ipcRenderer
|
||||
|
||||
const emacsEmoji: Entity.Emoji = {
|
||||
shortcode: 'emacs',
|
||||
|
@ -172,13 +172,10 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('TimelineSpace', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
TimelineSpace: initStore(),
|
||||
App: appState
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Response, Entity } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import DirectMessages, { DirectMessagesState } from '@/store/TimelineSpace/Contents/DirectMessages'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
const mockClient = {
|
||||
getConversationTimeline: () => {
|
||||
|
@ -149,7 +149,14 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const timelineState = {
|
||||
const contentsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
DirectMessages: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
state: {
|
||||
account: {
|
||||
|
@ -157,8 +164,11 @@ const timelineState = {
|
|||
baseURL: 'http://localhost'
|
||||
},
|
||||
sns: 'mastodon'
|
||||
},
|
||||
modules: {
|
||||
Contents: contentsStore()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const appState = {
|
||||
namespaced: true,
|
||||
|
@ -168,16 +178,12 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('Home', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
DirectMessages: initStore(),
|
||||
TimelineSpace: timelineState,
|
||||
TimelineSpace: timelineStore(),
|
||||
App: appState
|
||||
}
|
||||
})
|
||||
|
@ -185,9 +191,9 @@ describe('Home', () => {
|
|||
|
||||
describe('fetchTimeline', () => {
|
||||
it('should be updated', async () => {
|
||||
const statuses = await store.dispatch('DirectMessages/fetchTimeline')
|
||||
const statuses = await store.dispatch('TimelineSpace/Contents/DirectMessages/fetchTimeline')
|
||||
expect(statuses).toEqual([status1])
|
||||
expect(store.state.DirectMessages.timeline).toEqual([status1])
|
||||
expect(store.state.TimelineSpace.Contents.DirectMessages.timeline).toEqual([status1])
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -215,9 +221,9 @@ describe('Home', () => {
|
|||
resolve(res)
|
||||
})
|
||||
}
|
||||
await store.dispatch('DirectMessages/lazyFetchTimeline', status1)
|
||||
expect(store.state.DirectMessages.lazyLoading).toEqual(false)
|
||||
expect(store.state.DirectMessages.timeline).toEqual([status1, status2])
|
||||
await store.dispatch('TimelineSpace/Contents/DirectMessages/lazyFetchTimeline', status1)
|
||||
expect(store.state.TimelineSpace.Contents.DirectMessages.lazyLoading).toEqual(false)
|
||||
expect(store.state.TimelineSpace.Contents.DirectMessages.timeline).toEqual([status1, status2])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Response, Entity } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import Favourites, { FavouritesState } from '@/store/TimelineSpace/Contents/Favourites'
|
||||
import { LocalAccount } from '~/src/types/localAccount'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
const mockClient = {
|
||||
getFavourites: () => {
|
||||
|
@ -147,7 +147,14 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const timelineState = {
|
||||
const contentsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Favourites: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
state: {
|
||||
account: {
|
||||
|
@ -155,8 +162,11 @@ const timelineState = {
|
|||
baseURL: 'http://localhost'
|
||||
},
|
||||
sns: 'mastodon'
|
||||
},
|
||||
modules: {
|
||||
Contents: contentsStore()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const appState = {
|
||||
namespaced: true,
|
||||
|
@ -166,16 +176,12 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('Favourites', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Favourites: initStore(),
|
||||
TimelineSpace: timelineState,
|
||||
TimelineSpace: timelineStore(),
|
||||
App: appState
|
||||
}
|
||||
})
|
||||
|
@ -183,9 +189,9 @@ describe('Favourites', () => {
|
|||
|
||||
describe('fetchFavourites', () => {
|
||||
it('does not exist header', async () => {
|
||||
await store.dispatch('Favourites/fetchFavourites', localAccount)
|
||||
expect(store.state.Favourites.favourites).toEqual([status1])
|
||||
expect(store.state.Favourites.maxId).toEqual(null)
|
||||
await store.dispatch('TimelineSpace/Contents/Favourites/fetchFavourites', localAccount)
|
||||
expect(store.state.TimelineSpace.Contents.Favourites.favourites).toEqual([status1])
|
||||
expect(store.state.TimelineSpace.Contents.Favourites.maxId).toEqual(null)
|
||||
})
|
||||
|
||||
it('link is null', async () => {
|
||||
|
@ -202,9 +208,9 @@ describe('Favourites', () => {
|
|||
resolve(res)
|
||||
})
|
||||
}
|
||||
await store.dispatch('Favourites/fetchFavourites', localAccount)
|
||||
expect(store.state.Favourites.favourites).toEqual([status1])
|
||||
expect(store.state.Favourites.maxId).toEqual(null)
|
||||
await store.dispatch('TimelineSpace/Contents/Favourites/fetchFavourites', localAccount)
|
||||
expect(store.state.TimelineSpace.Contents.Favourites.favourites).toEqual([status1])
|
||||
expect(store.state.TimelineSpace.Contents.Favourites.maxId).toEqual(null)
|
||||
})
|
||||
|
||||
it('link exists in header', async () => {
|
||||
|
@ -222,9 +228,9 @@ describe('Favourites', () => {
|
|||
})
|
||||
}
|
||||
|
||||
await store.dispatch('Favourites/fetchFavourites', localAccount)
|
||||
expect(store.state.Favourites.favourites).toEqual([status1])
|
||||
expect(store.state.Favourites.maxId).toEqual('2')
|
||||
await store.dispatch('TimelineSpace/Contents/Favourites/fetchFavourites', localAccount)
|
||||
expect(store.state.TimelineSpace.Contents.Favourites.favourites).toEqual([status1])
|
||||
expect(store.state.TimelineSpace.Contents.Favourites.maxId).toEqual('2')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -240,7 +246,7 @@ describe('Favourites', () => {
|
|||
}
|
||||
})
|
||||
it('should not be updated', async () => {
|
||||
const res = await store.dispatch('Favourites/lazyFetchFavourites')
|
||||
const res = await store.dispatch('TimelineSpace/Contents/Favourites/lazyFetchFavourites')
|
||||
expect(res).toEqual(null)
|
||||
})
|
||||
})
|
||||
|
@ -256,7 +262,7 @@ describe('Favourites', () => {
|
|||
}
|
||||
})
|
||||
it('should not be updated', async () => {
|
||||
const res = await store.dispatch('Favourites/lazyFetchFavourites')
|
||||
const res = await store.dispatch('TimelineSpace/Contents/Favourites/lazyFetchFavourites')
|
||||
expect(res).toEqual(null)
|
||||
})
|
||||
})
|
||||
|
@ -286,9 +292,9 @@ describe('Favourites', () => {
|
|||
})
|
||||
}
|
||||
|
||||
await store.dispatch('Favourites/lazyFetchFavourites')
|
||||
expect(store.state.Favourites.favourites).toEqual([status1, status2])
|
||||
expect(store.state.Favourites.maxId).toEqual(null)
|
||||
await store.dispatch('TimelineSpace/Contents/Favourites/lazyFetchFavourites')
|
||||
expect(store.state.TimelineSpace.Contents.Favourites.favourites).toEqual([status1, status2])
|
||||
expect(store.state.TimelineSpace.Contents.Favourites.maxId).toEqual(null)
|
||||
})
|
||||
|
||||
it('link exists in header', async () => {
|
||||
|
@ -306,9 +312,9 @@ describe('Favourites', () => {
|
|||
})
|
||||
}
|
||||
|
||||
await store.dispatch('Favourites/lazyFetchFavourites')
|
||||
expect(store.state.Favourites.favourites).toEqual([status1, status2])
|
||||
expect(store.state.Favourites.maxId).toEqual('3')
|
||||
await store.dispatch('TimelineSpace/Contents/Favourites/lazyFetchFavourites')
|
||||
expect(store.state.TimelineSpace.Contents.Favourites.favourites).toEqual([status1, status2])
|
||||
expect(store.state.TimelineSpace.Contents.Favourites.maxId).toEqual('3')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Entity, Response } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import FollowRequests, { FollowRequestsState } from '@/store/TimelineSpace/Contents/FollowRequests'
|
||||
import { SideMenuState } from '@/store/TimelineSpace/SideMenu'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
const mockClient = {
|
||||
getFollowRequests: () => {
|
||||
|
@ -110,19 +110,27 @@ const sideMenuState = (): SideMenuState => {
|
|||
}
|
||||
}
|
||||
|
||||
const sideMenuStore = {
|
||||
const sideMenuStore = () => ({
|
||||
namespaced: true,
|
||||
state: sideMenuState(),
|
||||
actions: {
|
||||
fetchFollowRequests: jest.fn()
|
||||
},
|
||||
mutations: {}
|
||||
}
|
||||
})
|
||||
|
||||
const timelineState = {
|
||||
const contentsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
SideMenu: sideMenuStore
|
||||
FollowRequests: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
SideMenu: sideMenuStore(),
|
||||
Contents: contentsStore()
|
||||
},
|
||||
state: {
|
||||
account: {
|
||||
|
@ -131,7 +139,7 @@ const timelineState = {
|
|||
},
|
||||
sns: 'mastodon'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const appState = {
|
||||
namespaced: true,
|
||||
|
@ -141,16 +149,12 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('Home', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
FollowRequests: initStore(),
|
||||
TimelineSpace: timelineState,
|
||||
TimelineSpace: timelineStore(),
|
||||
App: appState
|
||||
}
|
||||
})
|
||||
|
@ -158,8 +162,8 @@ describe('Home', () => {
|
|||
|
||||
describe('fetchRequests', () => {
|
||||
it('should be updated', async () => {
|
||||
await store.dispatch('FollowRequests/fetchRequests')
|
||||
expect(store.state.FollowRequests.requests).toEqual([account])
|
||||
await store.dispatch('TimelineSpace/Contents/FollowRequests/fetchRequests')
|
||||
expect(store.state.TimelineSpace.Contents.FollowRequests.requests).toEqual([account])
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -184,8 +188,8 @@ describe('Home', () => {
|
|||
})
|
||||
}
|
||||
|
||||
await store.dispatch('FollowRequests/acceptRequest', account)
|
||||
expect(store.state.FollowRequests.requests).toEqual([])
|
||||
await store.dispatch('TimelineSpace/Contents/FollowRequests/acceptRequest', account)
|
||||
expect(store.state.TimelineSpace.Contents.FollowRequests.requests).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -210,8 +214,8 @@ describe('Home', () => {
|
|||
})
|
||||
}
|
||||
|
||||
await store.dispatch('FollowRequests/rejectRequest', account)
|
||||
expect(store.state.FollowRequests.requests).toEqual([])
|
||||
await store.dispatch('TimelineSpace/Contents/FollowRequests/rejectRequest', account)
|
||||
expect(store.state.TimelineSpace.Contents.FollowRequests.requests).toEqual([])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { IpcMainInvokeEvent } from 'electron'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import { ipcMain, ipcRenderer } from '~/spec/mock/electron'
|
||||
import Vuex from 'vuex'
|
||||
import { LocalTag } from '~/src/types/localTag'
|
||||
import List, { ListState } from '@/store/TimelineSpace/Contents/Hashtag/List'
|
||||
import { MyWindow } from '~/src/types/global'
|
||||
;((window as any) as MyWindow).ipcRenderer = ipcRenderer
|
||||
import { RootState } from '@/store'
|
||||
;(window as any as MyWindow).ipcRenderer = ipcRenderer
|
||||
|
||||
const tag1: LocalTag = {
|
||||
tagName: 'tag1',
|
||||
|
@ -32,6 +32,20 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const hashtagStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
List: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const contentsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Hashtag: hashtagStore()
|
||||
}
|
||||
})
|
||||
|
||||
const sideMenuStore = {
|
||||
namespaced: true,
|
||||
actions: {
|
||||
|
@ -39,24 +53,21 @@ const sideMenuStore = {
|
|||
}
|
||||
}
|
||||
|
||||
const timelineState = {
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
SideMenu: sideMenuStore
|
||||
SideMenu: sideMenuStore,
|
||||
Contents: contentsStore()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
describe('Hashtag/List', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
List: initStore(),
|
||||
TimelineSpace: timelineState
|
||||
TimelineSpace: timelineStore()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -69,8 +80,8 @@ describe('Hashtag/List', () => {
|
|||
afterEach(() => {
|
||||
ipcMain.removeHandler('list-hashtags')
|
||||
})
|
||||
await store.dispatch('List/listTags')
|
||||
expect(store.state.List.tags).toEqual([tag1, tag2])
|
||||
await store.dispatch('TimelineSpace/Contents/Hashtag/List/listTags')
|
||||
expect(store.state.TimelineSpace.Contents.Hashtag.List.tags).toEqual([tag1, tag2])
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -79,7 +90,7 @@ describe('Hashtag/List', () => {
|
|||
ipcMain.handle('remove-hashtag', (_: IpcMainInvokeEvent, tag: LocalTag) => {
|
||||
expect(tag).toEqual(tag1)
|
||||
})
|
||||
await store.dispatch('List/removeTag', tag1)
|
||||
await store.dispatch('TimelineSpace/Contents/Hashtag/List/removeTag', tag1)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Response, Entity } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import Tag, { TagState } from '@/store/TimelineSpace/Contents/Hashtag/Tag'
|
||||
import { LoadPositionWithTag } from '@/types/loadPosition'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
const mockClient = {
|
||||
getTagTimeline: () => {
|
||||
|
@ -134,15 +134,32 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const timelineState = {
|
||||
const hashtagStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Tag: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const contentsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Hashtag: hashtagStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
state: {
|
||||
account: {
|
||||
accessToken: 'token',
|
||||
baseURL: 'http://localhost'
|
||||
}
|
||||
},
|
||||
modules: {
|
||||
Contents: contentsStore()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const appState = {
|
||||
namespaced: true,
|
||||
|
@ -152,16 +169,12 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('Home', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Tag: initStore(),
|
||||
TimelineSpace: timelineState,
|
||||
TimelineSpace: timelineStore(),
|
||||
App: appState
|
||||
}
|
||||
})
|
||||
|
@ -169,9 +182,9 @@ describe('Home', () => {
|
|||
|
||||
describe('fetch', () => {
|
||||
it('should be updated', async () => {
|
||||
const statuses = await store.dispatch('Tag/fetch', 'tag')
|
||||
const statuses = await store.dispatch('TimelineSpace/Contents/Hashtag/Tag/fetch', 'tag')
|
||||
expect(statuses).toEqual([status1])
|
||||
expect(store.state.Tag.timeline).toEqual([status1])
|
||||
expect(store.state.TimelineSpace.Contents.Hashtag.Tag.timeline).toEqual([status1])
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -203,9 +216,9 @@ describe('Home', () => {
|
|||
status: status1,
|
||||
tag: 'tag'
|
||||
}
|
||||
await store.dispatch('Tag/lazyFetchTimeline', loadPositionWithTag)
|
||||
expect(store.state.Tag.lazyLoading).toEqual(false)
|
||||
expect(store.state.Tag.timeline).toEqual([status1, status2])
|
||||
await store.dispatch('TimelineSpace/Contents/Hashtag/Tag/lazyFetchTimeline', loadPositionWithTag)
|
||||
expect(store.state.TimelineSpace.Contents.Hashtag.Tag.lazyLoading).toEqual(false)
|
||||
expect(store.state.TimelineSpace.Contents.Hashtag.Tag.timeline).toEqual([status1, status2])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Response, Entity } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import Home, { HomeState } from '@/store/TimelineSpace/Contents/Home'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
const mockClient = {
|
||||
getHomeTimeline: () => {
|
||||
|
@ -126,7 +126,7 @@ let state = (): HomeState => {
|
|||
}
|
||||
}
|
||||
|
||||
const initStore = () => {
|
||||
const homeStore = () => {
|
||||
return {
|
||||
namespaced: true,
|
||||
state: state(),
|
||||
|
@ -135,7 +135,14 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const timelineState = {
|
||||
const contentsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Home: homeStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
state: {
|
||||
account: {
|
||||
|
@ -148,8 +155,11 @@ const timelineState = {
|
|||
notifications: false
|
||||
}
|
||||
}
|
||||
},
|
||||
modules: {
|
||||
Contents: contentsStore()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const appState = {
|
||||
namespaced: true,
|
||||
|
@ -159,16 +169,12 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('Home', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Home: initStore(),
|
||||
TimelineSpace: timelineState,
|
||||
TimelineSpace: timelineStore(),
|
||||
App: appState
|
||||
}
|
||||
})
|
||||
|
@ -176,9 +182,9 @@ describe('Home', () => {
|
|||
|
||||
describe('fetchTimeline', () => {
|
||||
it('should be updated', async () => {
|
||||
const statuses = await store.dispatch('Home/fetchTimeline')
|
||||
const statuses = await store.dispatch('TimelineSpace/Contents/Home/fetchTimeline')
|
||||
expect(statuses).toEqual([status1])
|
||||
expect(store.state.Home.timeline).toEqual([status1])
|
||||
expect(store.state.TimelineSpace.Contents.Home.timeline).toEqual([status1])
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -210,9 +216,9 @@ describe('Home', () => {
|
|||
})
|
||||
}
|
||||
|
||||
await store.dispatch('Home/lazyFetchTimeline', status1)
|
||||
expect(store.state.Home.lazyLoading).toEqual(false)
|
||||
expect(store.state.Home.timeline).toEqual([status1, status2])
|
||||
await store.dispatch('TimelineSpace/Contents/Home/lazyFetchTimeline', status1)
|
||||
expect(store.state.TimelineSpace.Contents.Home.lazyLoading).toEqual(false)
|
||||
expect(store.state.TimelineSpace.Contents.Home.timeline).toEqual([status1, status2])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Response, Entity } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import Edit, { EditState } from '@/store/TimelineSpace/Contents/Lists/Edit'
|
||||
import { RemoveAccountFromList } from '@/types/removeAccountFromList'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
const mockClient = {
|
||||
getAccountsInList: () => {
|
||||
|
@ -72,7 +72,21 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const timelineState = {
|
||||
const listsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Edit: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const contentsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Lists: listsStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
state: {
|
||||
account: {
|
||||
|
@ -80,8 +94,11 @@ const timelineState = {
|
|||
baseURL: 'http://localhost'
|
||||
},
|
||||
sns: 'mastodon'
|
||||
},
|
||||
modules: {
|
||||
Contents: contentsStore()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const appState = {
|
||||
namespaced: true,
|
||||
|
@ -91,16 +108,12 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('Lists/Edit', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Edit: initStore(),
|
||||
TimelineSpace: timelineState,
|
||||
TimelineSpace: timelineStore(),
|
||||
App: appState
|
||||
}
|
||||
})
|
||||
|
@ -108,8 +121,8 @@ describe('Lists/Edit', () => {
|
|||
|
||||
describe('fetchMembers', () => {
|
||||
it('should get', async () => {
|
||||
await store.dispatch('Edit/fetchMembers', 'id')
|
||||
expect(store.state.Edit.members).toEqual([account])
|
||||
await store.dispatch('TimelineSpace/Contents/Lists/Edit/fetchMembers', 'id')
|
||||
expect(store.state.TimelineSpace.Contents.Lists.Edit.members).toEqual([account])
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -119,7 +132,7 @@ describe('Lists/Edit', () => {
|
|||
account: account,
|
||||
listId: 'id'
|
||||
}
|
||||
const res = await store.dispatch('Edit/removeAccount', removeFromList)
|
||||
const res = await store.dispatch('TimelineSpace/Contents/Lists/Edit/removeAccount', removeFromList)
|
||||
expect(res.data).toEqual({})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Response, Entity } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import Index, { IndexState } from '@/store/TimelineSpace/Contents/Lists/Index'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
const mockClient = {
|
||||
getLists: () => {
|
||||
|
@ -54,7 +54,21 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const timelineState = {
|
||||
const listsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Index: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const contentsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Lists: listsStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
state: {
|
||||
account: {
|
||||
|
@ -62,8 +76,11 @@ const timelineState = {
|
|||
baseURL: 'http://localhost'
|
||||
},
|
||||
sns: 'mastodon'
|
||||
},
|
||||
modules: {
|
||||
Contents: contentsStore()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const appState = {
|
||||
namespaced: true,
|
||||
|
@ -73,16 +90,12 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('Lists/Index', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Index: initStore(),
|
||||
TimelineSpace: timelineState,
|
||||
TimelineSpace: timelineStore(),
|
||||
App: appState
|
||||
}
|
||||
})
|
||||
|
@ -90,14 +103,14 @@ describe('Lists/Index', () => {
|
|||
|
||||
describe('fetchLists', () => {
|
||||
it('should be updated', async () => {
|
||||
await store.dispatch('Index/fetchLists')
|
||||
expect(store.state.Index.lists).toEqual([list])
|
||||
await store.dispatch('TimelineSpace/Contents/Lists/Index/fetchLists')
|
||||
expect(store.state.TimelineSpace.Contents.Lists.Index.lists).toEqual([list])
|
||||
})
|
||||
})
|
||||
|
||||
describe('createList', () => {
|
||||
it('should be created', async () => {
|
||||
const res: Entity.List = await store.dispatch('Index/createList', 'list1')
|
||||
const res: Entity.List = await store.dispatch('TimelineSpace/Contents/Lists/Index/createList', 'list1')
|
||||
expect(res.title).toEqual('list1')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Response, Entity } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import Show, { ShowState } from '@/store/TimelineSpace/Contents/Lists/Show'
|
||||
import { LoadPositionWithList } from '@/types/loadPosition'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
const mockClient = {
|
||||
getListTimeline: () => {
|
||||
|
@ -136,15 +136,32 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const timelineState = {
|
||||
const listsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Show: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const contentsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Lists: listsStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
state: {
|
||||
account: {
|
||||
accessToken: 'token',
|
||||
baseURL: 'http://localhost'
|
||||
}
|
||||
},
|
||||
modules: {
|
||||
Contents: contentsStore()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const appState = {
|
||||
namespaced: true,
|
||||
|
@ -154,16 +171,12 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('Lists/Show', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Show: initStore(),
|
||||
TimelineSpace: timelineState,
|
||||
TimelineSpace: timelineStore(),
|
||||
App: appState
|
||||
}
|
||||
})
|
||||
|
@ -171,8 +184,8 @@ describe('Lists/Show', () => {
|
|||
|
||||
describe('fetchTimeline', () => {
|
||||
it('should be updated', async () => {
|
||||
await store.dispatch('Show/fetchTimeline', '1')
|
||||
expect(store.state.Show.timeline).toEqual([status1])
|
||||
await store.dispatch('TimelineSpace/Contents/Lists/Show/fetchTimeline', '1')
|
||||
expect(store.state.TimelineSpace.Contents.Lists.Show.timeline).toEqual([status1])
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -204,9 +217,9 @@ describe('Lists/Show', () => {
|
|||
status: status1,
|
||||
list_id: '1'
|
||||
}
|
||||
await store.dispatch('Show/lazyFetchTimeline', loadPosition)
|
||||
expect(store.state.Show.timeline).toEqual([status1, status2])
|
||||
expect(store.state.Show.lazyLoading).toEqual(false)
|
||||
await store.dispatch('TimelineSpace/Contents/Lists/Show/lazyFetchTimeline', loadPosition)
|
||||
expect(store.state.TimelineSpace.Contents.Lists.Show.timeline).toEqual([status1, status2])
|
||||
expect(store.state.TimelineSpace.Contents.Lists.Show.lazyLoading).toEqual(false)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Response, Entity } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import Local, { LocalState } from '@/store/TimelineSpace/Contents/Local'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
const mockClient = {
|
||||
getLocalTimeline: () => {
|
||||
|
@ -133,15 +133,25 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const timelineState = {
|
||||
const contentsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Local: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
state: {
|
||||
account: {
|
||||
accessToken: 'token',
|
||||
baseURL: 'http://localhost'
|
||||
}
|
||||
},
|
||||
modules: {
|
||||
Contents: contentsStore()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const appState = {
|
||||
namespaced: true,
|
||||
|
@ -151,16 +161,12 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('Home', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Local: initStore(),
|
||||
TimelineSpace: timelineState,
|
||||
TimelineSpace: timelineStore(),
|
||||
App: appState
|
||||
}
|
||||
})
|
||||
|
@ -168,9 +174,9 @@ describe('Home', () => {
|
|||
|
||||
describe('fetchLocalTimeline', () => {
|
||||
it('should be updated', async () => {
|
||||
const statuses = await store.dispatch('Local/fetchLocalTimeline')
|
||||
const statuses = await store.dispatch('TimelineSpace/Contents/Local/fetchLocalTimeline')
|
||||
expect(statuses).toEqual([status1])
|
||||
expect(store.state.Local.timeline).toEqual([status1])
|
||||
expect(store.state.TimelineSpace.Contents.Local.timeline).toEqual([status1])
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -199,9 +205,9 @@ describe('Home', () => {
|
|||
})
|
||||
}
|
||||
|
||||
await store.dispatch('Local/lazyFetchTimeline', status1)
|
||||
expect(store.state.Local.lazyLoading).toEqual(false)
|
||||
expect(store.state.Local.timeline).toEqual([status1, status2])
|
||||
await store.dispatch('TimelineSpace/Contents/Local/lazyFetchTimeline', status1)
|
||||
expect(store.state.TimelineSpace.Contents.Local.lazyLoading).toEqual(false)
|
||||
expect(store.state.TimelineSpace.Contents.Local.timeline).toEqual([status1, status2])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { RootState } from '@/store'
|
||||
import { Response, Entity } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import Mentions from '~/src/renderer/store/TimelineSpace/Contents/Mentions'
|
||||
|
||||
const mockClient = {
|
||||
|
@ -129,7 +129,15 @@ const initStore = () => {
|
|||
getters: Mentions.getters
|
||||
}
|
||||
}
|
||||
const timelineState = {
|
||||
|
||||
const contentsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Mentions: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
state: {
|
||||
account: {
|
||||
|
@ -143,8 +151,11 @@ const timelineState = {
|
|||
mentions: false
|
||||
}
|
||||
}
|
||||
},
|
||||
modules: {
|
||||
Contents: contentsStore()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const appState = {
|
||||
namespaced: true,
|
||||
|
@ -154,16 +165,12 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('Mentions', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Mentions: initStore(),
|
||||
TimelineSpace: timelineState,
|
||||
TimelineSpace: timelineStore(),
|
||||
App: appState
|
||||
}
|
||||
})
|
||||
|
@ -171,8 +178,8 @@ describe('Mentions', () => {
|
|||
|
||||
describe('fetchMentions', () => {
|
||||
it('should be updated', async () => {
|
||||
await store.dispatch('Mentions/fetchMentions')
|
||||
expect(store.state.Mentions.mentions).toEqual([mention, reblog, favourite, follow])
|
||||
await store.dispatch('TimelineSpace/Contents/Mentions/fetchMentions')
|
||||
expect(store.state.TimelineSpace.Contents.Mentions.mentions).toEqual([mention, reblog, favourite, follow])
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -189,7 +196,7 @@ describe('Mentions', () => {
|
|||
}
|
||||
})
|
||||
it('should not be updated', async () => {
|
||||
const result = await store.dispatch('Mentions/lazyFetchMentions', {})
|
||||
const result = await store.dispatch('TimelineSpace/Contents/Mentions/lazyFetchMentions', {})
|
||||
expect(result).toEqual(null)
|
||||
})
|
||||
})
|
||||
|
@ -218,9 +225,9 @@ describe('Mentions', () => {
|
|||
})
|
||||
}
|
||||
|
||||
await store.dispatch('Mentions/lazyFetchMentions', { id: 1 })
|
||||
expect(store.state.Mentions.mentions).toEqual([mention, reblog, favourite, follow])
|
||||
expect(store.state.Mentions.lazyLoading).toEqual(false)
|
||||
await store.dispatch('TimelineSpace/Contents/Mentions/lazyFetchMentions', { id: 1 })
|
||||
expect(store.state.TimelineSpace.Contents.Mentions.mentions).toEqual([mention, reblog, favourite, follow])
|
||||
expect(store.state.TimelineSpace.Contents.Mentions.lazyLoading).toEqual(false)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -237,7 +244,7 @@ describe('Mentions', () => {
|
|||
}
|
||||
})
|
||||
it('should return only mentions', () => {
|
||||
const mentions = store.getters['Mentions/mentions']
|
||||
const mentions = store.getters['TimelineSpace/Contents/Mentions/mentions']
|
||||
expect(mentions).toEqual([mention])
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Response, Entity } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import Notifications, { NotificationsState } from '@/store/TimelineSpace/Contents/Notifications'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
const mockClient = {
|
||||
getNotifications: () => {
|
||||
|
@ -209,7 +209,14 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const timelineState = {
|
||||
const contentsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Notifications: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
state: {
|
||||
account: {
|
||||
|
@ -223,8 +230,11 @@ const timelineState = {
|
|||
mentions: false
|
||||
}
|
||||
}
|
||||
},
|
||||
modules: {
|
||||
Contents: contentsStore()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const appState = {
|
||||
namespaced: true,
|
||||
|
@ -235,16 +245,12 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('Notifications', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Notifications: initStore(),
|
||||
TimelineSpace: timelineState,
|
||||
TimelineSpace: timelineStore(),
|
||||
App: appState
|
||||
}
|
||||
})
|
||||
|
@ -252,9 +258,9 @@ describe('Notifications', () => {
|
|||
|
||||
describe('fetchNotifications', () => {
|
||||
it('should be updated', async () => {
|
||||
const response = await store.dispatch('Notifications/fetchNotifications')
|
||||
const response = await store.dispatch('TimelineSpace/Contents/Notifications/fetchNotifications')
|
||||
expect(response).toEqual([notification1])
|
||||
expect(store.state.Notifications.notifications).toEqual([notification1])
|
||||
expect(store.state.TimelineSpace.Contents.Notifications.notifications).toEqual([notification1])
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -281,9 +287,9 @@ describe('Notifications', () => {
|
|||
resolve(res)
|
||||
})
|
||||
}
|
||||
await store.dispatch('Notifications/lazyFetchNotifications', notification1)
|
||||
expect(store.state.Notifications.lazyLoading).toEqual(false)
|
||||
expect(store.state.Notifications.notifications).toEqual([notification1, notification2])
|
||||
await store.dispatch('TimelineSpace/Contents/Notifications/lazyFetchNotifications', notification1)
|
||||
expect(store.state.TimelineSpace.Contents.Notifications.lazyLoading).toEqual(false)
|
||||
expect(store.state.TimelineSpace.Contents.Notifications.notifications).toEqual([notification1, notification2])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Response, Entity } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import Public, { PublicState } from '@/store/TimelineSpace/Contents/Public'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
const mockClient = {
|
||||
getPublicTimeline: () => {
|
||||
|
@ -133,15 +133,25 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const timelineState = {
|
||||
const contentsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Public: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
state: {
|
||||
account: {
|
||||
accessToken: 'token',
|
||||
baseURL: 'http://localhost'
|
||||
}
|
||||
},
|
||||
modules: {
|
||||
Contents: contentsStore()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const appState = {
|
||||
namespaced: true,
|
||||
|
@ -151,16 +161,12 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('Home', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Public: initStore(),
|
||||
TimelineSpace: timelineState,
|
||||
TimelineSpace: timelineStore(),
|
||||
App: appState
|
||||
}
|
||||
})
|
||||
|
@ -168,9 +174,9 @@ describe('Home', () => {
|
|||
|
||||
describe('fetchPublicTimeline', () => {
|
||||
it('should be updated', async () => {
|
||||
const statuses = await store.dispatch('Public/fetchPublicTimeline')
|
||||
const statuses = await store.dispatch('TimelineSpace/Contents/Public/fetchPublicTimeline')
|
||||
expect(statuses).toEqual([status1])
|
||||
expect(store.state.Public.timeline).toEqual([status1])
|
||||
expect(store.state.TimelineSpace.Contents.Public.timeline).toEqual([status1])
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -198,9 +204,9 @@ describe('Home', () => {
|
|||
resolve(res)
|
||||
})
|
||||
}
|
||||
await store.dispatch('Public/lazyFetchTimeline', status1)
|
||||
expect(store.state.Public.lazyLoading).toEqual(false)
|
||||
expect(store.state.Public.timeline).toEqual([status1, status2])
|
||||
await store.dispatch('TimelineSpace/Contents/Public/lazyFetchTimeline', status1)
|
||||
expect(store.state.TimelineSpace.Contents.Public.lazyLoading).toEqual(false)
|
||||
expect(store.state.TimelineSpace.Contents.Public.timeline).toEqual([status1, status2])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Response, Entity } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import AccountStore, { AccountState } from '@/store/TimelineSpace/Contents/Search/Account'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
const account: Entity.Account = {
|
||||
id: '1',
|
||||
|
@ -60,19 +60,29 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const contentsStore = {
|
||||
const searchStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Account: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const contentsStore = () => ({
|
||||
namespaced: true,
|
||||
state: {},
|
||||
mutations: {
|
||||
changeLoading: jest.fn()
|
||||
},
|
||||
actions: {}
|
||||
}
|
||||
actions: {},
|
||||
modules: {
|
||||
Search: searchStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineState = {
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Contents: contentsStore
|
||||
Contents: contentsStore()
|
||||
},
|
||||
state: {
|
||||
account: {
|
||||
|
@ -81,7 +91,7 @@ const timelineState = {
|
|||
},
|
||||
sns: 'mastodon'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const appState = {
|
||||
namespaced: true,
|
||||
|
@ -91,16 +101,12 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('Search/Account', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Account: initStore(),
|
||||
TimelineSpace: timelineState,
|
||||
TimelineSpace: timelineStore(),
|
||||
App: appState
|
||||
}
|
||||
})
|
||||
|
@ -108,8 +114,8 @@ describe('Search/Account', () => {
|
|||
|
||||
describe('search', () => {
|
||||
it('should be updated', async () => {
|
||||
await store.dispatch('Account/search', 'query')
|
||||
expect(store.state.Account.results).toEqual([account])
|
||||
await store.dispatch('TimelineSpace/Contents/Search/Account/search', 'query')
|
||||
expect(store.state.TimelineSpace.Contents.Search.Account.results).toEqual([account])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Response, Entity } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import TagStore, { TagState } from '@/store/TimelineSpace/Contents/Search/Tag'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
const tag1: Entity.Tag = {
|
||||
name: 'tag1',
|
||||
|
@ -48,19 +48,29 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const contentsStore = {
|
||||
const searchStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Tag: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const contentsStore = () => ({
|
||||
namespaced: true,
|
||||
state: {},
|
||||
mutations: {
|
||||
changeLoading: jest.fn()
|
||||
},
|
||||
actions: {}
|
||||
}
|
||||
actions: {},
|
||||
modules: {
|
||||
Search: searchStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineState = {
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Contents: contentsStore
|
||||
Contents: contentsStore()
|
||||
},
|
||||
state: {
|
||||
account: {
|
||||
|
@ -69,7 +79,8 @@ const timelineState = {
|
|||
},
|
||||
sns: 'mastodon'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const appState = {
|
||||
namespaced: true,
|
||||
state: {
|
||||
|
@ -78,16 +89,12 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('Search/Tag', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Tag: initStore(),
|
||||
TimelineSpace: timelineState,
|
||||
TimelineSpace: timelineStore(),
|
||||
App: appState
|
||||
}
|
||||
})
|
||||
|
@ -95,8 +102,8 @@ describe('Search/Tag', () => {
|
|||
|
||||
describe('search', () => {
|
||||
it('should be updated', async () => {
|
||||
await store.dispatch('Tag/search', 'query')
|
||||
expect(store.state.Tag.results).toEqual([tag1])
|
||||
await store.dispatch('TimelineSpace/Contents/Search/Tag/search', 'query')
|
||||
expect(store.state.TimelineSpace.Contents.Search.Tag.results).toEqual([tag1])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Response, Entity } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import Toots, { TootsState } from '@/store/TimelineSpace/Contents/Search/Toots'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
const mockClient = {
|
||||
search: () => {
|
||||
|
@ -100,19 +100,29 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const contentsStore = {
|
||||
const searchStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Toots: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const contentsStore = () => ({
|
||||
namespaced: true,
|
||||
state: {},
|
||||
mutations: {
|
||||
changeLoading: jest.fn()
|
||||
},
|
||||
actions: {}
|
||||
}
|
||||
actions: {},
|
||||
modules: {
|
||||
Search: searchStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineState = {
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Contents: contentsStore
|
||||
Contents: contentsStore()
|
||||
},
|
||||
state: {
|
||||
account: {
|
||||
|
@ -121,7 +131,7 @@ const timelineState = {
|
|||
},
|
||||
sns: 'mastodon'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const appState = {
|
||||
namespaced: true,
|
||||
|
@ -131,16 +141,12 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('Search/Account', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Toots: initStore(),
|
||||
TimelineSpace: timelineState,
|
||||
TimelineSpace: timelineStore(),
|
||||
App: appState
|
||||
}
|
||||
})
|
||||
|
@ -148,8 +154,8 @@ describe('Search/Account', () => {
|
|||
|
||||
describe('search', () => {
|
||||
it('should be updated', async () => {
|
||||
await store.dispatch('Toots/search', 'query')
|
||||
expect(store.state.Toots.results).toEqual([status])
|
||||
await store.dispatch('TimelineSpace/Contents/Search/Toots/search', 'query')
|
||||
expect(store.state.TimelineSpace.Contents.Search.Toots.results).toEqual([status])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { RootState } from '@/store'
|
||||
import { Entity } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import AccountProfile, { AccountProfileState } from '~/src/renderer/store/TimelineSpace/Contents/SideBar/AccountProfile'
|
||||
|
||||
const state = (account: Entity.Account | null): AccountProfileState => {
|
||||
|
@ -12,7 +12,31 @@ const state = (account: Entity.Account | null): AccountProfileState => {
|
|||
}
|
||||
}
|
||||
|
||||
const timelineSpace = {
|
||||
const initStore = (account: Entity.Account | null) => {
|
||||
return {
|
||||
namespaced: true,
|
||||
state: state(account),
|
||||
actions: AccountProfile.actions,
|
||||
mutations: AccountProfile.mutations,
|
||||
getters: AccountProfile.getters
|
||||
}
|
||||
}
|
||||
|
||||
const sidebarStore = (account: Entity.Account | null) => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
AccountProfile: initStore(account)
|
||||
}
|
||||
})
|
||||
|
||||
const contentsStore = (account: Entity.Account | null) => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
SideBar: sidebarStore(account)
|
||||
}
|
||||
})
|
||||
|
||||
const timelineStore = (account: Entity.Account | null) => ({
|
||||
namespaced: true,
|
||||
state: {
|
||||
account: {
|
||||
|
@ -27,30 +51,19 @@ const timelineSpace = {
|
|||
avatar: null,
|
||||
order: 1
|
||||
}
|
||||
},
|
||||
modules: {
|
||||
Contents: contentsStore(account)
|
||||
}
|
||||
}
|
||||
|
||||
const initStore = (account: Entity.Account | null) => {
|
||||
return {
|
||||
namespaced: true,
|
||||
state: state(account),
|
||||
actions: AccountProfile.actions,
|
||||
mutations: AccountProfile.mutations,
|
||||
getters: AccountProfile.getters
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
describe('AccountProfile', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
AccountProfile: initStore(null),
|
||||
TimelineSpace: timelineSpace
|
||||
TimelineSpace: timelineStore(null)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -79,15 +92,14 @@ describe('AccountProfile', () => {
|
|||
bot: false
|
||||
}
|
||||
beforeEach(() => {
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
AccountProfile: initStore(account),
|
||||
TimelineSpace: timelineSpace
|
||||
TimelineSpace: timelineStore(account)
|
||||
}
|
||||
})
|
||||
})
|
||||
it('should be matched', () => {
|
||||
expect(store.getters['AccountProfile/isOwnProfile']).toBeTruthy()
|
||||
expect(store.getters['TimelineSpace/Contents/SideBar/AccountProfile/isOwnProfile']).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -114,15 +126,14 @@ describe('AccountProfile', () => {
|
|||
bot: false
|
||||
}
|
||||
beforeEach(() => {
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
AccountProfile: initStore(account),
|
||||
TimelineSpace: timelineSpace
|
||||
TimelineSpace: timelineStore(account)
|
||||
}
|
||||
})
|
||||
})
|
||||
it('should be matched', () => {
|
||||
expect(store.getters['AccountProfile/isOwnProfile']).toBeFalsy()
|
||||
expect(store.getters['TimelineSpace/Contents/SideBar/AccountProfile/isOwnProfile']).toBeFalsy()
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -149,15 +160,14 @@ describe('AccountProfile', () => {
|
|||
bot: false
|
||||
}
|
||||
beforeEach(() => {
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
AccountProfile: initStore(account),
|
||||
TimelineSpace: timelineSpace
|
||||
TimelineSpace: timelineStore(account)
|
||||
}
|
||||
})
|
||||
})
|
||||
it('should be matched', () => {
|
||||
expect(store.getters['AccountProfile/isOwnProfile']).toBeTruthy()
|
||||
expect(store.getters['TimelineSpace/Contents/SideBar/AccountProfile/isOwnProfile']).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -184,15 +194,14 @@ describe('AccountProfile', () => {
|
|||
bot: false
|
||||
}
|
||||
beforeEach(() => {
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
AccountProfile: initStore(account),
|
||||
TimelineSpace: timelineSpace
|
||||
TimelineSpace: timelineStore(account)
|
||||
}
|
||||
})
|
||||
})
|
||||
it('should be matched', () => {
|
||||
expect(store.getters['AccountProfile/isOwnProfile']).toBeFalsy()
|
||||
expect(store.getters['TimelineSpace/Contents/SideBar/AccountProfile/isOwnProfile']).toBeFalsy()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { RootState } from '@/store'
|
||||
import { Response, Entity } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import HeaderMenu, { HeaderMenuState } from '~/src/renderer/store/TimelineSpace/HeaderMenu'
|
||||
|
||||
const list: Entity.List = {
|
||||
|
@ -45,7 +45,7 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const timelineState = {
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
state: {
|
||||
account: {
|
||||
|
@ -53,8 +53,11 @@ const timelineState = {
|
|||
baseURL: 'http://localhost'
|
||||
},
|
||||
sns: 'mastodon'
|
||||
},
|
||||
modules: {
|
||||
HeaderMenu: initStore()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const appState = {
|
||||
namespaced: true,
|
||||
|
@ -64,16 +67,12 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('HeaderMenu', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
HeaderMenu: initStore(),
|
||||
TimelineSpace: timelineState,
|
||||
TimelineSpace: timelineStore(),
|
||||
App: appState
|
||||
}
|
||||
})
|
||||
|
@ -81,9 +80,9 @@ describe('HeaderMenu', () => {
|
|||
|
||||
describe('fetchLists', () => {
|
||||
it('should be updated', async () => {
|
||||
const l = await store.dispatch('HeaderMenu/fetchList', list.id)
|
||||
const l = await store.dispatch('TimelineSpace/HeaderMenu/fetchList', list.id)
|
||||
expect(l).toEqual(list)
|
||||
expect(store.state.HeaderMenu.title).toEqual(`#${list.title}`)
|
||||
expect(store.state.TimelineSpace.HeaderMenu.title).toEqual(`#${list.title}`)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Response, Entity } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import AddListMember, { AddListMemberState } from '@/store/TimelineSpace/Modals/AddListMember'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
const mockClient = {
|
||||
searchAccount: () => {
|
||||
|
@ -73,15 +73,25 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const timelineState = {
|
||||
const modalsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
AddListMember: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
state: {
|
||||
account: {
|
||||
_id: '0'
|
||||
},
|
||||
sns: 'mastodon'
|
||||
},
|
||||
modules: {
|
||||
Modals: modalsStore()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const appState = {
|
||||
namespaced: true,
|
||||
|
@ -91,16 +101,13 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('AddListMember', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
AddListMember: initStore(),
|
||||
TimelineSpace: timelineState,
|
||||
TimelineSpace: timelineStore(),
|
||||
App: appState
|
||||
}
|
||||
})
|
||||
|
@ -108,21 +115,21 @@ describe('AddListMember', () => {
|
|||
|
||||
describe('changeModal', () => {
|
||||
it('should change modal', () => {
|
||||
store.dispatch('AddListMember/changeModal', true)
|
||||
expect(store.state.AddListMember.modalOpen).toEqual(true)
|
||||
store.dispatch('TimelineSpace/Modals/AddListMember/changeModal', true)
|
||||
expect(store.state.TimelineSpace.Modals.AddListMember.modalOpen).toEqual(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('search', () => {
|
||||
it('should be searched', async () => {
|
||||
await store.dispatch('AddListMember/search', 'akira')
|
||||
expect(store.state.AddListMember.accounts).toEqual([account])
|
||||
await store.dispatch('TimelineSpace/Modals/AddListMember/search', 'akira')
|
||||
expect(store.state.TimelineSpace.Modals.AddListMember.accounts).toEqual([account])
|
||||
})
|
||||
})
|
||||
|
||||
describe('add', () => {
|
||||
it('should be added a member to the list', async () => {
|
||||
const result = await store.dispatch('AddListMember/add', 'akira')
|
||||
const result = await store.dispatch('TimelineSpace/Modals/AddListMember/add', 'akira')
|
||||
expect(result).toEqual({})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { RootState } from '@/store'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import ImageViewer, { ImageViewerState } from '~/src/renderer/store/TimelineSpace/Modals/ImageViewer'
|
||||
|
||||
const state = (): ImageViewerState => {
|
||||
|
@ -21,16 +21,27 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const modalsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
ImageViewer: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Modals: modalsStore()
|
||||
}
|
||||
})
|
||||
|
||||
describe('ImageViewer', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
ImageViewer: initStore()
|
||||
TimelineSpace: timelineStore()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -38,46 +49,46 @@ describe('ImageViewer', () => {
|
|||
// Actions
|
||||
describe('openModal', () => {
|
||||
it('should be changed', () => {
|
||||
store.dispatch('ImageViewer/openModal', {
|
||||
store.dispatch('TimelineSpace/Modals/ImageViewer/openModal', {
|
||||
currentIndex: 1,
|
||||
mediaList: ['media1', 'media2']
|
||||
})
|
||||
expect(store.state.ImageViewer.modalOpen).toEqual(true)
|
||||
expect(store.state.ImageViewer.currentIndex).toEqual(1)
|
||||
expect(store.state.ImageViewer.mediaList).toEqual(['media1', 'media2'])
|
||||
expect(store.state.ImageViewer.loading).toEqual(true)
|
||||
expect(store.state.TimelineSpace.Modals.ImageViewer.modalOpen).toEqual(true)
|
||||
expect(store.state.TimelineSpace.Modals.ImageViewer.currentIndex).toEqual(1)
|
||||
expect(store.state.TimelineSpace.Modals.ImageViewer.mediaList).toEqual(['media1', 'media2'])
|
||||
expect(store.state.TimelineSpace.Modals.ImageViewer.loading).toEqual(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('closeModal', () => {
|
||||
beforeEach(() => {
|
||||
store.dispatch('ImageViewer/openModal', {
|
||||
store.dispatch('TimelineSpace/Modals/ImageViewer/openModal', {
|
||||
currentIndex: 1,
|
||||
mediaList: ['media1', 'media2']
|
||||
})
|
||||
})
|
||||
it('should be changed', () => {
|
||||
store.dispatch('ImageViewer/closeModal')
|
||||
expect(store.state.ImageViewer.modalOpen).toEqual(false)
|
||||
expect(store.state.ImageViewer.currentIndex).toEqual(-1)
|
||||
expect(store.state.ImageViewer.mediaList).toEqual([])
|
||||
expect(store.state.ImageViewer.loading).toEqual(false)
|
||||
store.dispatch('TimelineSpace/Modals/ImageViewer/closeModal')
|
||||
expect(store.state.TimelineSpace.Modals.ImageViewer.modalOpen).toEqual(false)
|
||||
expect(store.state.TimelineSpace.Modals.ImageViewer.currentIndex).toEqual(-1)
|
||||
expect(store.state.TimelineSpace.Modals.ImageViewer.mediaList).toEqual([])
|
||||
expect(store.state.TimelineSpace.Modals.ImageViewer.loading).toEqual(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('incrementIndex', () => {
|
||||
it('should be changed', () => {
|
||||
store.dispatch('ImageViewer/incrementIndex')
|
||||
expect(store.state.ImageViewer.currentIndex).toEqual(0)
|
||||
expect(store.state.ImageViewer.loading).toEqual(true)
|
||||
store.dispatch('TimelineSpace/Modals/ImageViewer/incrementIndex')
|
||||
expect(store.state.TimelineSpace.Modals.ImageViewer.currentIndex).toEqual(0)
|
||||
expect(store.state.TimelineSpace.Modals.ImageViewer.loading).toEqual(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('decrementIndex', () => {
|
||||
it('should be changed', () => {
|
||||
store.dispatch('ImageViewer/decrementIndex')
|
||||
expect(store.state.ImageViewer.currentIndex).toEqual(-2)
|
||||
expect(store.state.ImageViewer.loading).toEqual(true)
|
||||
store.dispatch('TimelineSpace/Modals/ImageViewer/decrementIndex')
|
||||
expect(store.state.TimelineSpace.Modals.ImageViewer.currentIndex).toEqual(-2)
|
||||
expect(store.state.TimelineSpace.Modals.ImageViewer.loading).toEqual(true)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -85,7 +96,7 @@ describe('ImageViewer', () => {
|
|||
describe('imageURL', () => {
|
||||
describe('currentIndex exists', () => {
|
||||
beforeEach(() => {
|
||||
store.dispatch('ImageViewer/openModal', {
|
||||
store.dispatch('TimelineSpace/Modals/ImageViewer/openModal', {
|
||||
currentIndex: 0,
|
||||
mediaList: [
|
||||
{
|
||||
|
@ -98,7 +109,7 @@ describe('ImageViewer', () => {
|
|||
})
|
||||
})
|
||||
it('should return url', () => {
|
||||
const url = store.getters['ImageViewer/imageURL']
|
||||
const url = store.getters['TimelineSpace/Modals/ImageViewer/imageURL']
|
||||
expect(url).toEqual('http://joinmastodon.org')
|
||||
})
|
||||
})
|
||||
|
@ -107,7 +118,7 @@ describe('ImageViewer', () => {
|
|||
describe('imageType', () => {
|
||||
describe('currentIndex exists', () => {
|
||||
beforeEach(() => {
|
||||
store.dispatch('ImageViewer/openModal', {
|
||||
store.dispatch('TimelineSpace/Modals/ImageViewer/openModal', {
|
||||
currentIndex: 0,
|
||||
mediaList: [
|
||||
{
|
||||
|
@ -120,7 +131,7 @@ describe('ImageViewer', () => {
|
|||
})
|
||||
})
|
||||
it('should return type', () => {
|
||||
const type = store.getters['ImageViewer/imageType']
|
||||
const type = store.getters['TimelineSpace/Modals/ImageViewer/imageType']
|
||||
expect(type).toEqual('image/png')
|
||||
})
|
||||
})
|
||||
|
@ -130,7 +141,7 @@ describe('ImageViewer', () => {
|
|||
describe('currentIndex > 0', () => {
|
||||
describe('mediaList > 1', () => {
|
||||
beforeEach(() => {
|
||||
store.dispatch('ImageViewer/openModal', {
|
||||
store.dispatch('TimelineSpace/Modals/ImageViewer/openModal', {
|
||||
currentIndex: 1,
|
||||
mediaList: [
|
||||
{
|
||||
|
@ -143,13 +154,13 @@ describe('ImageViewer', () => {
|
|||
})
|
||||
})
|
||||
it('should return true', () => {
|
||||
const left = store.getters['ImageViewer/showLeft']
|
||||
const left = store.getters['TimelineSpace/Modals/ImageViewer/showLeft']
|
||||
expect(left).toEqual(true)
|
||||
})
|
||||
})
|
||||
describe('mediaList < 1', () => {
|
||||
beforeEach(() => {
|
||||
store.dispatch('ImageViewer/openModal', {
|
||||
store.dispatch('TimelineSpace/Modals/ImageViewer/openModal', {
|
||||
currentIndex: 0,
|
||||
mediaList: [
|
||||
{
|
||||
|
@ -159,7 +170,7 @@ describe('ImageViewer', () => {
|
|||
})
|
||||
})
|
||||
it('should not return true', () => {
|
||||
const left = store.getters['ImageViewer/showLeft']
|
||||
const left = store.getters['TimelineSpace/Modals/ImageViewer/showLeft']
|
||||
expect(left).toEqual(false)
|
||||
})
|
||||
})
|
||||
|
@ -170,7 +181,7 @@ describe('ImageViewer', () => {
|
|||
describe('current index is lower than media list length', () => {
|
||||
describe('media list length > 1', () => {
|
||||
beforeEach(() => {
|
||||
store.dispatch('ImageViewer/openModal', {
|
||||
store.dispatch('TimelineSpace/Modals/ImageViewer/openModal', {
|
||||
currentIndex: 0,
|
||||
mediaList: [
|
||||
{
|
||||
|
@ -183,13 +194,13 @@ describe('ImageViewer', () => {
|
|||
})
|
||||
})
|
||||
it('should return true', () => {
|
||||
const right = store.getters['ImageViewer/showRight']
|
||||
const right = store.getters['TimelineSpace/Modals/ImageViewer/showRight']
|
||||
expect(right).toEqual(true)
|
||||
})
|
||||
})
|
||||
describe('media list length <= 1', () => {
|
||||
beforeEach(() => {
|
||||
store.dispatch('ImageViewer/openModal', {
|
||||
store.dispatch('TimelineSpace/Modals/ImageViewer/openModal', {
|
||||
currentIndex: 0,
|
||||
mediaList: [
|
||||
{
|
||||
|
@ -199,7 +210,7 @@ describe('ImageViewer', () => {
|
|||
})
|
||||
})
|
||||
it('should not return true', () => {
|
||||
const right = store.getters['ImageViewer/showRight']
|
||||
const right = store.getters['TimelineSpace/Modals/ImageViewer/showRight']
|
||||
expect(right).toEqual(false)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import i18n from '~/src/config/i18n'
|
||||
import router from '@/router'
|
||||
import Jump, { JumpState, Channel } from '~/src/renderer/store/TimelineSpace/Modals/Jump'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
const state = (): JumpState => {
|
||||
return {
|
||||
|
@ -59,34 +59,40 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const timelineState = {
|
||||
const modalsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
Jump: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
state: {
|
||||
account: {
|
||||
_id: '0'
|
||||
}
|
||||
},
|
||||
modules: {
|
||||
Modals: modalsStore()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
describe('Jump', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
Jump: initStore(),
|
||||
TimelineSpace: timelineState
|
||||
TimelineSpace: timelineStore()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('jumpCurrentSelected', () => {
|
||||
it('should be changed', () => {
|
||||
store.dispatch('Jump/jumpCurrentSelected')
|
||||
expect(store.state.Jump.modalOpen).toEqual(false)
|
||||
store.dispatch('TimelineSpace/Modals/Jump/jumpCurrentSelected')
|
||||
expect(store.state.TimelineSpace.Modals.Jump.modalOpen).toEqual(false)
|
||||
expect(router.push).toHaveBeenCalledWith({ path: '/0/home' })
|
||||
})
|
||||
})
|
||||
|
@ -97,8 +103,8 @@ describe('Jump', () => {
|
|||
name: 'public',
|
||||
path: 'public'
|
||||
}
|
||||
store.dispatch('Jump/jump', channel)
|
||||
expect(store.state.Jump.modalOpen).toEqual(false)
|
||||
store.dispatch('TimelineSpace/Modals/Jump/jump', channel)
|
||||
expect(store.state.TimelineSpace.Modals.Jump.modalOpen).toEqual(false)
|
||||
expect(router.push).toHaveBeenCalledWith({ path: '/0/public' })
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Response, Entity } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import ListMembership, { ListMembershipState } from '@/store/TimelineSpace/Modals/ListMembership'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
const mockClient = {
|
||||
getAccountLists: () => {
|
||||
|
@ -119,14 +119,24 @@ const initStore = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const timelineState = {
|
||||
const modalsStore = () => ({
|
||||
namespaced: true,
|
||||
modules: {
|
||||
ListMembership: initStore()
|
||||
}
|
||||
})
|
||||
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
state: {
|
||||
account: {
|
||||
_id: '0'
|
||||
}
|
||||
},
|
||||
modules: {
|
||||
Modals: modalsStore()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const appState = {
|
||||
namespaced: true,
|
||||
|
@ -136,16 +146,12 @@ const appState = {
|
|||
}
|
||||
|
||||
describe('ListMembership', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
ListMembership: initStore(),
|
||||
TimelineSpace: timelineState,
|
||||
TimelineSpace: timelineStore(),
|
||||
App: appState
|
||||
}
|
||||
})
|
||||
|
@ -153,17 +159,17 @@ describe('ListMembership', () => {
|
|||
|
||||
describe('fetchListMembership', () => {
|
||||
it('should get', async () => {
|
||||
await store.dispatch('ListMembership/fetchListMembership', {
|
||||
await store.dispatch('TimelineSpace/Modals/ListMembership/fetchListMembership', {
|
||||
id: '5'
|
||||
})
|
||||
expect(store.state.ListMembership.belongToLists).toEqual([list1, list2])
|
||||
expect(store.state.TimelineSpace.Modals.ListMembership.belongToLists).toEqual([list1, list2])
|
||||
})
|
||||
})
|
||||
|
||||
describe('fetchLists', () => {
|
||||
it('should be changed', async () => {
|
||||
await store.dispatch('ListMembership/fetchLists')
|
||||
expect(store.state.ListMembership.lists).toEqual([list1, list2])
|
||||
await store.dispatch('TimelineSpace/Modals/ListMembership/fetchLists')
|
||||
expect(store.state.TimelineSpace.Modals.ListMembership.lists).toEqual([list1, list2])
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -179,8 +185,8 @@ describe('ListMembership', () => {
|
|||
}
|
||||
})
|
||||
it('should be changed', async () => {
|
||||
await store.dispatch('ListMembership/changeBelongToLists', [list1.id, list2.id])
|
||||
expect(store.state.ListMembership.belongToLists).toEqual([list1, list2])
|
||||
await store.dispatch('TimelineSpace/Modals/ListMembership/changeBelongToLists', [list1.id, list2.id])
|
||||
expect(store.state.TimelineSpace.Modals.ListMembership.belongToLists).toEqual([list1, list2])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { Entity, Response } from 'megalodon'
|
||||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore, Store } from 'vuex'
|
||||
import { ipcMain, ipcRenderer } from '~/spec/mock/electron'
|
||||
import SideMenu, { SideMenuState } from '~/src/renderer/store/TimelineSpace/SideMenu'
|
||||
import { LocalTag } from '~/src/types/localTag'
|
||||
import { MyWindow } from '~/src/types/global'
|
||||
;((window as any) as MyWindow).ipcRenderer = ipcRenderer
|
||||
import { RootState } from '@/store'
|
||||
;(window as any as MyWindow).ipcRenderer = ipcRenderer
|
||||
|
||||
const mockClient = {
|
||||
getLists: () => {
|
||||
|
@ -82,25 +82,24 @@ const appStore = {
|
|||
}
|
||||
}
|
||||
|
||||
const timelineStore = {
|
||||
const timelineStore = () => ({
|
||||
namespaced: true,
|
||||
state: {
|
||||
sns: 'mastodon'
|
||||
},
|
||||
modules: {
|
||||
SideMenu: initStore()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
describe('SideMenu', () => {
|
||||
let store
|
||||
let localVue
|
||||
let store: Store<RootState>
|
||||
|
||||
beforeEach(() => {
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
store = createStore({
|
||||
modules: {
|
||||
SideMenu: initStore(),
|
||||
App: appStore,
|
||||
TimelineSpace: timelineStore
|
||||
TimelineSpace: timelineStore()
|
||||
}
|
||||
})
|
||||
// mockedMegalodon.mockClear()
|
||||
|
@ -113,27 +112,27 @@ describe('SideMenu', () => {
|
|||
accessToken: 'token',
|
||||
baseURL: 'http://localhost'
|
||||
}
|
||||
const lists = await store.dispatch('SideMenu/fetchLists', account)
|
||||
expect(store.state.SideMenu.lists).toEqual([list1, list2])
|
||||
const lists = await store.dispatch('TimelineSpace/SideMenu/fetchLists', account)
|
||||
expect(store.state.TimelineSpace.SideMenu.lists).toEqual([list1, list2])
|
||||
expect(lists).toEqual([list1, list2])
|
||||
})
|
||||
})
|
||||
|
||||
describe('clearUnread', () => {
|
||||
it('should be resetted', () => {
|
||||
store.dispatch('SideMenu/clearUnread')
|
||||
expect(store.state.SideMenu.unreadHomeTimeline).toEqual(false)
|
||||
expect(store.state.SideMenu.unreadNotifications).toEqual(false)
|
||||
expect(store.state.SideMenu.unreadLocalTimeline).toEqual(false)
|
||||
expect(store.state.SideMenu.unreadDirectMessagesTimeline).toEqual(false)
|
||||
expect(store.state.SideMenu.unreadPublicTimeline).toEqual(false)
|
||||
store.dispatch('TimelineSpace/SideMenu/clearUnread')
|
||||
expect(store.state.TimelineSpace.SideMenu.unreadHomeTimeline).toEqual(false)
|
||||
expect(store.state.TimelineSpace.SideMenu.unreadNotifications).toEqual(false)
|
||||
expect(store.state.TimelineSpace.SideMenu.unreadLocalTimeline).toEqual(false)
|
||||
expect(store.state.TimelineSpace.SideMenu.unreadDirectMessagesTimeline).toEqual(false)
|
||||
expect(store.state.TimelineSpace.SideMenu.unreadPublicTimeline).toEqual(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('changeCollapse', () => {
|
||||
it('should be changed', () => {
|
||||
store.dispatch('SideMenu/changeCollapse', true)
|
||||
expect(store.state.SideMenu.collapse).toEqual(true)
|
||||
store.dispatch('TimelineSpace/SideMenu/changeCollapse', true)
|
||||
expect(store.state.TimelineSpace.SideMenu.collapse).toEqual(true)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -142,8 +141,8 @@ describe('SideMenu', () => {
|
|||
ipcMain.handle('get-collapse', () => {
|
||||
return true
|
||||
})
|
||||
await store.dispatch('SideMenu/readCollapse')
|
||||
expect(store.state.SideMenu.collapse).toEqual(true)
|
||||
await store.dispatch('TimelineSpace/SideMenu/readCollapse')
|
||||
expect(store.state.TimelineSpace.SideMenu.collapse).toEqual(true)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -158,8 +157,8 @@ describe('SideMenu', () => {
|
|||
ipcMain.handle('list-hashtags', () => {
|
||||
return [tag1, tag2]
|
||||
})
|
||||
await store.dispatch('SideMenu/listTags')
|
||||
expect(store.state.SideMenu.tags).toEqual([tag1, tag2])
|
||||
await store.dispatch('TimelineSpace/SideMenu/listTags')
|
||||
expect(store.state.TimelineSpace.SideMenu.tags).toEqual([tag1, tag2])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -608,11 +608,10 @@ ipcMain.handle('confirm-timelines', async (_event: IpcMainInvokeEvent, account:
|
|||
// user streaming
|
||||
const userStreamings: { [key: string]: UserStreaming | null } = {}
|
||||
|
||||
ipcMain.on('start-all-user-streamings', (event: IpcMainEvent, accounts: Array<LocalAccount>) => {
|
||||
accounts.map(async account => {
|
||||
const id: string = account._id!
|
||||
ipcMain.on('start-all-user-streamings', (event: IpcMainEvent, accounts: Array<string>) => {
|
||||
accounts.map(async id => {
|
||||
const acct = await accountRepo.getAccount(id)
|
||||
try {
|
||||
const acct = await accountRepo.getAccount(id)
|
||||
// Stop old user streaming
|
||||
if (userStreamings[id]) {
|
||||
userStreamings[id]!.stop()
|
||||
|
@ -678,7 +677,7 @@ ipcMain.on('start-all-user-streamings', (event: IpcMainEvent, accounts: Array<Lo
|
|||
}
|
||||
} catch (err: any) {
|
||||
log.error(err)
|
||||
const streamingError = new StreamingError(err.message, account.domain)
|
||||
const streamingError = new StreamingError(err.message, acct.domain)
|
||||
if (!event.sender.isDestroyed()) {
|
||||
event.sender.send('error-start-all-user-streamings', streamingError)
|
||||
}
|
||||
|
@ -708,16 +707,11 @@ const stopUserStreaming = (id: string) => {
|
|||
})
|
||||
}
|
||||
|
||||
type StreamingSetting = {
|
||||
account: LocalAccount
|
||||
}
|
||||
|
||||
let directMessagesStreaming: DirectStreaming | null = null
|
||||
|
||||
ipcMain.on('start-directmessages-streaming', async (event: IpcMainEvent, obj: StreamingSetting) => {
|
||||
const { account } = obj
|
||||
ipcMain.on('start-directmessages-streaming', async (event: IpcMainEvent, id: string) => {
|
||||
try {
|
||||
const acct = await accountRepo.getAccount(account._id!)
|
||||
const acct = await accountRepo.getAccount(id)
|
||||
|
||||
// Stop old directmessages streaming
|
||||
if (directMessagesStreaming !== null) {
|
||||
|
@ -763,10 +757,9 @@ ipcMain.on('stop-directmessages-streaming', () => {
|
|||
|
||||
let localStreaming: LocalStreaming | null = null
|
||||
|
||||
ipcMain.on('start-local-streaming', async (event: IpcMainEvent, obj: StreamingSetting) => {
|
||||
const { account } = obj
|
||||
ipcMain.on('start-local-streaming', async (event: IpcMainEvent, id: string) => {
|
||||
try {
|
||||
const acct = await accountRepo.getAccount(account._id!)
|
||||
const acct = await accountRepo.getAccount(id)
|
||||
|
||||
// Stop old local streaming
|
||||
if (localStreaming !== null) {
|
||||
|
@ -812,10 +805,9 @@ ipcMain.on('stop-local-streaming', () => {
|
|||
|
||||
let publicStreaming: PublicStreaming | null = null
|
||||
|
||||
ipcMain.on('start-public-streaming', async (event: IpcMainEvent, obj: StreamingSetting) => {
|
||||
const { account } = obj
|
||||
ipcMain.on('start-public-streaming', async (event: IpcMainEvent, id: string) => {
|
||||
try {
|
||||
const acct = await accountRepo.getAccount(account._id!)
|
||||
const acct = await accountRepo.getAccount(id)
|
||||
|
||||
// Stop old public streaming
|
||||
if (publicStreaming !== null) {
|
||||
|
@ -861,14 +853,15 @@ ipcMain.on('stop-public-streaming', () => {
|
|||
|
||||
let listStreaming: ListStreaming | null = null
|
||||
|
||||
type ListID = {
|
||||
type ListStreamingOpts = {
|
||||
listID: string
|
||||
accountID: string
|
||||
}
|
||||
|
||||
ipcMain.on('start-list-streaming', async (event: IpcMainEvent, obj: ListID & StreamingSetting) => {
|
||||
const { listID, account } = obj
|
||||
ipcMain.on('start-list-streaming', async (event: IpcMainEvent, obj: ListStreamingOpts) => {
|
||||
const { listID, accountID } = obj
|
||||
try {
|
||||
const acct = await accountRepo.getAccount(account._id!)
|
||||
const acct = await accountRepo.getAccount(accountID)
|
||||
|
||||
// Stop old list streaming
|
||||
if (listStreaming !== null) {
|
||||
|
@ -915,14 +908,15 @@ ipcMain.on('stop-list-streaming', () => {
|
|||
|
||||
let tagStreaming: TagStreaming | null = null
|
||||
|
||||
type Tag = {
|
||||
type TagStreamingOpts = {
|
||||
tag: string
|
||||
accountID: string
|
||||
}
|
||||
|
||||
ipcMain.on('start-tag-streaming', async (event: IpcMainEvent, obj: Tag & StreamingSetting) => {
|
||||
const { tag, account } = obj
|
||||
ipcMain.on('start-tag-streaming', async (event: IpcMainEvent, obj: TagStreamingOpts) => {
|
||||
const { tag, accountID } = obj
|
||||
try {
|
||||
const acct = await accountRepo.getAccount(account._id!)
|
||||
const acct = await accountRepo.getAccount(accountID)
|
||||
|
||||
// Stop old tag streaming
|
||||
if (tagStreaming !== null) {
|
||||
|
|
|
@ -34,10 +34,10 @@ export default {
|
|||
created() {
|
||||
this.$store.dispatch('App/watchShortcutsEvents')
|
||||
this.$store.dispatch('App/loadPreferences').then(conf => {
|
||||
this.$i18n.i18next.changeLanguage(conf.language.language)
|
||||
this.$i18n.locale = conf.language.language
|
||||
})
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.$store.dispatch('App/removeShortcutsEvents')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
<el-header>
|
||||
<el-row>
|
||||
<el-col :span="24" class="close">
|
||||
<el-button type="text" icon="el-icon-close" @click="close" class="close-button"> </el-button>
|
||||
<el-button type="text" @click="close" class="close-button">
|
||||
<font-awesome-icon icon="x-mark"></font-awesome-icon>
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
|
@ -43,6 +45,14 @@
|
|||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
authorizeForm: {
|
||||
code: null
|
||||
},
|
||||
submitting: false
|
||||
}
|
||||
},
|
||||
name: 'authorize',
|
||||
props: {
|
||||
url: {
|
||||
|
@ -54,14 +64,6 @@ export default {
|
|||
default: 'mastodon'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
authorizeForm: {
|
||||
code: null
|
||||
},
|
||||
submitting: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.url)
|
||||
},
|
||||
|
@ -101,7 +103,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
#authorize /deep/ {
|
||||
#authorize {
|
||||
background-color: #292f3f;
|
||||
color: #ffffff;
|
||||
text-align: center;
|
||||
|
@ -130,14 +132,16 @@ export default {
|
|||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.el-form-item__label {
|
||||
color: #f0f3f9;
|
||||
}
|
||||
.authorize-form :deep() {
|
||||
.el-form-item__label {
|
||||
color: #f0f3f9;
|
||||
}
|
||||
|
||||
.el-input__inner {
|
||||
background-color: #373d48;
|
||||
color: #ffffff;
|
||||
border: 0;
|
||||
.el-input__inner {
|
||||
background-color: #373d48;
|
||||
color: #ffffff;
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.hidden {
|
||||
|
|
|
@ -18,13 +18,13 @@
|
|||
v-bind:key="account._id"
|
||||
role="menuitem"
|
||||
>
|
||||
<i v-if="account.avatar === undefined || account.avatar === null || account.avatar === ''" class="el-icon-menu"></i>
|
||||
<font-awesome-icon icon="circle-user" v-if="account.avatar === undefined || account.avatar === null || account.avatar === ''" />
|
||||
<FailoverImg v-else :src="account.avatar" class="avatar" :title="account.username + '@' + account.domain" />
|
||||
<FailoverImg :src="`${account.baseURL}/favicon.ico`" :failoverSrc="`${account.baseURL}/favicon.png`" class="instance-icon" />
|
||||
<span slot="title">{{ account.domain }}</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/login" :title="$t('global_header.add_new_account')" role="menuitem">
|
||||
<i class="el-icon-plus"></i>
|
||||
<el-menu-item index="/login" :title="$t('global_header.add_new_account')" role="menuitem" class="add-new-account">
|
||||
<font-awesome-icon icon="plus" />
|
||||
<span slot="new">New</span>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
|
@ -40,10 +40,10 @@ import FailoverImg from '~/src/renderer/components/atoms/FailoverImg'
|
|||
import { StreamingError } from '~/src/errors/streamingError'
|
||||
|
||||
export default {
|
||||
name: 'global-header',
|
||||
components: {
|
||||
FailoverImg
|
||||
},
|
||||
name: 'global-header',
|
||||
computed: {
|
||||
...mapState('GlobalHeader', {
|
||||
accounts: state => state.accounts,
|
||||
|
@ -67,7 +67,9 @@ export default {
|
|||
this.$store.dispatch('GlobalHeader/startStreamings').catch(err => {
|
||||
if (err instanceof StreamingError) {
|
||||
this.$message({
|
||||
message: this.$t('message.start_all_streamings_error', { domain: err.domain }),
|
||||
message: this.$t('message.start_all_streamings_error', {
|
||||
domain: err.domain
|
||||
}),
|
||||
type: 'error'
|
||||
})
|
||||
}
|
||||
|
@ -85,7 +87,14 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
#global_header /deep/ {
|
||||
.account-menu :deep(.el-menu-item) {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-end;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
#global_header {
|
||||
.account-menu {
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
|
@ -95,12 +104,6 @@ export default {
|
|||
padding-top: 24px;
|
||||
border: 0;
|
||||
|
||||
.el-tooltip {
|
||||
outline: 0;
|
||||
text-align: center;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
|
@ -138,5 +141,9 @@ export default {
|
|||
.with-global-header {
|
||||
margin-left: 65px;
|
||||
}
|
||||
|
||||
.add-new-account {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -3,12 +3,14 @@
|
|||
<el-header>
|
||||
<el-row>
|
||||
<el-col :span="24" class="close">
|
||||
<el-button type="text" icon="el-icon-close" @click="close" class="close-button"> </el-button>
|
||||
<el-button type="text" @click="close" class="close-button">
|
||||
<font-awesome-icon icon="xmark" />
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-container>
|
||||
<div v-shortkey="['esc']" @shortkey="close"></div>
|
||||
<div></div>
|
||||
<login-form></login-form>
|
||||
</el-container>
|
||||
</el-container>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
:model="form"
|
||||
>
|
||||
<el-form-item :label="$t('login.domain_name_label')" prop="domainName">
|
||||
<el-input v-model="form.domainName" placeholder="mastodon.social" v-shortkey="['enter']" @shortkey.native="handleKey"></el-input>
|
||||
<el-input v-model="form.domainName" placeholder="mastodon.social"></el-input>
|
||||
</el-form-item>
|
||||
<p class="proxy-info">
|
||||
{{ $t('login.proxy_info') }}<router-link to="/preferences/network">{{ $t('login.proxy_here') }}</router-link>
|
||||
|
@ -22,7 +22,14 @@
|
|||
<el-button type="primary" class="login" @click="login" v-if="allowLogin">
|
||||
{{ $t('login.login') }}
|
||||
</el-button>
|
||||
<el-button type="primary" v-else @click="confirm('loginForm')" v-loading="searching" element-loading-background="rgba(0, 0, 0, 0.8)">
|
||||
<el-button
|
||||
type="primary"
|
||||
class="search"
|
||||
v-else
|
||||
@click="confirm('loginForm')"
|
||||
v-loading="searching"
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)"
|
||||
>
|
||||
{{ $t('login.search') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
|
@ -48,7 +55,7 @@ export default {
|
|||
searching: state => state.Login.searching,
|
||||
sns: state => state.Login.sns
|
||||
}),
|
||||
allowLogin: function() {
|
||||
allowLogin: function () {
|
||||
return this.selectedInstance && this.form.domainName === this.selectedInstance
|
||||
},
|
||||
rules: {
|
||||
|
@ -83,7 +90,10 @@ export default {
|
|||
.then(url => {
|
||||
loading.close()
|
||||
this.$store.dispatch('Login/pageBack')
|
||||
this.$router.push({ path: '/authorize', query: { url: url, sns: this.sns } })
|
||||
this.$router.push({
|
||||
path: '/authorize',
|
||||
query: { url: url, sns: this.sns }
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
loading.close()
|
||||
|
@ -100,13 +110,17 @@ export default {
|
|||
.dispatch('Login/confirmInstance', this.form.domainName)
|
||||
.then(() => {
|
||||
this.$message({
|
||||
message: this.$t('message.domain_confirmed', { domain: this.form.domainName }),
|
||||
message: this.$t('message.domain_confirmed', {
|
||||
domain: this.form.domainName
|
||||
}),
|
||||
type: 'success'
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
this.$message({
|
||||
message: this.$t('message.domain_doesnt_exist', { domain: this.form.domainName }),
|
||||
message: this.$t('message.domain_doesnt_exist', {
|
||||
domain: this.form.domainName
|
||||
}),
|
||||
type: 'error'
|
||||
})
|
||||
})
|
||||
|
@ -131,20 +145,10 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.login-form /deep/ {
|
||||
.login-form {
|
||||
margin: 0 auto;
|
||||
width: 300px;
|
||||
|
||||
.el-form-item__label {
|
||||
color: #f0f3f9;
|
||||
}
|
||||
|
||||
.el-input__inner {
|
||||
background-color: #373d48;
|
||||
color: #fff;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.instance-group {
|
||||
text-align: left;
|
||||
margin: 0 auto;
|
||||
|
@ -158,12 +162,12 @@ export default {
|
|||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.submit {
|
||||
margin: 0;
|
||||
.search {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.back {
|
||||
margin-right: 20px;
|
||||
.login {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
|
@ -175,4 +179,16 @@ export default {
|
|||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.login-form :deep() {
|
||||
.el-form-item__label {
|
||||
color: #f0f3f9;
|
||||
}
|
||||
|
||||
.el-input__inner {
|
||||
background-color: #373d48;
|
||||
color: #fff;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -5,13 +5,15 @@
|
|||
<el-col :span="23">
|
||||
<h1>{{ $t('preferences.title') }}</h1>
|
||||
</el-col>
|
||||
<el-col :span="1">
|
||||
<el-button type="text" icon="el-icon-close" @click="close" class="close-button" role="button"></el-button>
|
||||
<el-col :span="1" class="close-area">
|
||||
<el-button type="text" @click="close" class="close-button" role="button">
|
||||
<font-awesome-icon icon="xmark" />
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-container>
|
||||
<div v-shortkey="['esc']" @shortkey="close"></div>
|
||||
<div></div>
|
||||
<el-aside width="240px" class="menu">
|
||||
<el-menu
|
||||
:default-active="activeRoute()"
|
||||
|
@ -85,8 +87,13 @@ export default {
|
|||
border-bottom: 1px solid var(--theme-border-color);
|
||||
user-select: none;
|
||||
|
||||
.close-button {
|
||||
font-size: 28px;
|
||||
.close-area {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.close-button {
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,13 +105,13 @@ export default {
|
|||
border-right: solid 1px var(--theme-border-color);
|
||||
}
|
||||
|
||||
.setting-menu /deep/ {
|
||||
.setting-menu {
|
||||
height: 100%;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-right: 9px;
|
||||
}
|
||||
.setting-menu :deep(.icon) {
|
||||
margin-right: 9px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div id="account">
|
||||
<h2>{{ $t('preferences.account.title') }}</h2>
|
||||
<el-form class="connected-account section" size="small">
|
||||
<el-form class="connected-account section">
|
||||
<h3>{{ $t('preferences.account.connected') }}</h3>
|
||||
<el-form-item>
|
||||
<el-table
|
||||
|
@ -15,29 +15,24 @@
|
|||
<el-table-column prop="username" :label="$t('preferences.account.username')"> </el-table-column>
|
||||
<el-table-column prop="domain" :label="$t('preferences.account.domain')"> </el-table-column>
|
||||
<el-table-column :label="$t('preferences.account.association')">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click.native.prevent="removeAccount(scope.$index, accounts)" type="text" class="action">
|
||||
<i class="el-icon-close"></i> {{ $t('preferences.account.remove_association') }}
|
||||
<template #default="scope">
|
||||
<el-button @click.prevent="removeAccount(scope.$index, accounts)" type="text" class="action">
|
||||
<font-awesome-icon icon="xmark" />
|
||||
{{ $t('preferences.account.remove_association') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('preferences.account.order')" width="60">
|
||||
<template slot-scope="scope">
|
||||
<template #default="scope">
|
||||
<div class="allow-up">
|
||||
<el-button
|
||||
class="arrow-up action"
|
||||
type="text"
|
||||
icon="el-icon-arrow-up"
|
||||
@click.native.prevent="forward(scope.$index, accounts)"
|
||||
></el-button>
|
||||
<el-button class="arrow-up action" type="text" @click.prevent="forward(scope.$index, accounts)">
|
||||
<font-awesome-icon icon="arrow-up" />
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="allow-down">
|
||||
<el-button
|
||||
class="arrow-down action"
|
||||
type="text"
|
||||
icon="el-icon-arrow-down"
|
||||
@click.native.prevent="backward(scope.$index, accounts)"
|
||||
></el-button>
|
||||
<el-button class="arrow-down action" type="text" @click.prevent="backward(scope.$index, accounts)">
|
||||
<font-awesome-icon icon="arrow-down" />
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
@ -47,10 +42,12 @@
|
|||
<el-popover placement="top" width="160" v-model="deletePopoverVisible">
|
||||
<p>{{ $t('preferences.account.confirm_message') }}</p>
|
||||
<div style="text-align: right; margin: 0">
|
||||
<el-button size="mini" type="text" @click="deletePopoverVisible = false">{{ $t('preferences.account.cancel') }}</el-button>
|
||||
<el-button type="danger" size="mini" @click="removeAllAssociations">{{ $t('preferences.account.confirm') }}</el-button>
|
||||
<el-button size="small" type="text" @click="deletePopoverVisible = false">{{ $t('preferences.account.cancel') }}</el-button>
|
||||
<el-button type="danger" size="small" @click="removeAllAssociations">{{ $t('preferences.account.confirm') }}</el-button>
|
||||
</div>
|
||||
<el-button slot="reference" type="danger">{{ $t('preferences.account.remove_all_associations') }}</el-button>
|
||||
<template #reference>
|
||||
<el-button type="danger">{{ $t('preferences.account.remove_all_associations') }}</el-button>
|
||||
</template>
|
||||
</el-popover>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
@ -61,13 +58,13 @@
|
|||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'account',
|
||||
data() {
|
||||
return {
|
||||
openRemoveDialog: false,
|
||||
deletePopoverVisible: false
|
||||
}
|
||||
},
|
||||
name: 'account',
|
||||
computed: {
|
||||
...mapState({
|
||||
accounts: state => state.Preferences.Account.accounts,
|
||||
|
@ -129,16 +126,16 @@ export default {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
#account {
|
||||
.section /deep/ {
|
||||
.section {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.el-form-item__label {
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
.section :deep(.el-form-item__label) {
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
|
||||
.connected-account {
|
||||
.el-table /deep/ {
|
||||
.el-table :deep() {
|
||||
tr,
|
||||
th,
|
||||
td {
|
||||
|
@ -161,5 +158,9 @@ export default {
|
|||
font-size: var(--base-font-size);
|
||||
}
|
||||
}
|
||||
|
||||
.action :deep(.svg-inline--fa) {
|
||||
padding-right: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div id="appearance">
|
||||
<h2>{{ $t('preferences.appearance.title') }}</h2>
|
||||
<el-form class="theme section" size="small" label-position="top">
|
||||
<el-form class="theme section" label-position="top">
|
||||
<div class="left">
|
||||
<el-form-item for="theme" :label="$t('preferences.appearance.theme_color')">
|
||||
<el-select id="theme" v-model="theme" placeholder="theme">
|
||||
|
@ -16,29 +16,29 @@
|
|||
<div class="color-pallet section" v-if="customizeThemeColor">
|
||||
<color-pallet></color-pallet>
|
||||
</div>
|
||||
<el-form class="font section" size="small" label-position="top">
|
||||
<el-form class="font section" label-position="top">
|
||||
<el-form-item for="font-family" :label="$t('preferences.appearance.font_family')">
|
||||
<el-select id="font-family" v-model="font" placeholder="fonts">
|
||||
<el-option v-for="f in fontList" :key="f" :label="f" :value="f" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item for="font-size" :label="$t('preferences.appearance.font_size')">
|
||||
<el-input-number id="font-size" :value="fontSize" :min="9" :max="72" @change="updateFontSize"></el-input-number>
|
||||
<el-input-number id="font-size" :model-value="fontSize" :min="9" :max="72" @change="updateFontSize"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form class="toot-padding section" size="small" label-position="top">
|
||||
<el-form class="toot-padding section" label-position="top">
|
||||
<el-form-item for="toot-padding" :label="$t('preferences.appearance.toot_padding')">
|
||||
<el-input-number id="toot-padding" :value="tootPadding" :min="0" :max="24" @change="updateTootPadding"></el-input-number>
|
||||
<el-input-number id="toot-padding" :model-value="tootPadding" :min="0" :max="24" @change="updateTootPadding"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form class="display-style section" size="small" label-position="top">
|
||||
<el-form class="display-style section" label-position="top">
|
||||
<el-form-item for="display-style" :label="$t('preferences.appearance.display_style.title')">
|
||||
<el-select id="display-style" v-model="displayNameStyle" placeholder="style">
|
||||
<el-option v-for="style in nameStyles" :key="style.value" :label="$t(style.name)" :value="style.value"> </el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form class="time-format section" size="small" label-position="top">
|
||||
<el-form class="time-format section" label-position="top">
|
||||
<el-form-item for="time-format" :label="$t('preferences.appearance.time_format.title')">
|
||||
<el-select id="time-format" v-model="timeFormat" placeholder="format">
|
||||
<el-option v-for="format in timeFormats" :key="format.value" :label="$t(format.name)" :value="format.value"> </el-option>
|
||||
|
@ -140,12 +140,12 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.section /deep/ {
|
||||
.section {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.el-form-item__label {
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
.section :deep(.el-form-item__label) {
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,46 +1,71 @@
|
|||
<template>
|
||||
<el-form class="pallet" label-position="top" size="small">
|
||||
<div class="item">
|
||||
<el-form-item :label="$t('preferences.appearance.custom_theme.background_color') ">
|
||||
<el-color-picker v-model="background"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('preferences.appearance.custom_theme.selected_background_color')">
|
||||
<el-color-picker v-model="selectedBackground"></el-color-picker>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="item">
|
||||
<el-form-item :label="$t('preferences.appearance.custom_theme.global_header_color')">
|
||||
<el-color-picker v-model="globalHeader"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('preferences.appearance.custom_theme.side_menu_color')">
|
||||
<el-color-picker v-model="sideMenu"></el-color-picker>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="item">
|
||||
<el-form-item :label="$t('preferences.appearance.custom_theme.primary_color')">
|
||||
<el-color-picker v-model="primary"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('preferences.appearance.custom_theme.regular_color')">
|
||||
<el-color-picker v-model="regular"></el-color-picker>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="item">
|
||||
<el-form-item :label="$t('preferences.appearance.custom_theme.secondary_color')">
|
||||
<el-color-picker v-model="secondary"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('preferences.appearance.custom_theme.border_color')">
|
||||
<el-color-picker v-model="border"></el-color-picker>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="item">
|
||||
<el-form-item :label="$t('preferences.appearance.custom_theme.header_menu_color')">
|
||||
<el-color-picker v-model="headerMenu"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('preferences.appearance.custom_theme.wrapper_mask_color')">
|
||||
<el-color-picker v-model="wrapperMask" :show-alpha="true"></el-color-picker>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
<el-form class="pallet" label-position="top" size="small">
|
||||
<div class="item">
|
||||
<el-form-item
|
||||
:label="$t('preferences.appearance.custom_theme.background_color')"
|
||||
>
|
||||
<el-color-picker v-model="background"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="
|
||||
$t('preferences.appearance.custom_theme.selected_background_color')
|
||||
"
|
||||
>
|
||||
<el-color-picker v-model="selectedBackground"></el-color-picker>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="item">
|
||||
<el-form-item
|
||||
:label="$t('preferences.appearance.custom_theme.global_header_color')"
|
||||
>
|
||||
<el-color-picker v-model="globalHeader"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('preferences.appearance.custom_theme.side_menu_color')"
|
||||
>
|
||||
<el-color-picker v-model="sideMenu"></el-color-picker>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="item">
|
||||
<el-form-item
|
||||
:label="$t('preferences.appearance.custom_theme.primary_color')"
|
||||
>
|
||||
<el-color-picker v-model="primary"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('preferences.appearance.custom_theme.regular_color')"
|
||||
>
|
||||
<el-color-picker v-model="regular"></el-color-picker>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="item">
|
||||
<el-form-item
|
||||
:label="$t('preferences.appearance.custom_theme.secondary_color')"
|
||||
>
|
||||
<el-color-picker v-model="secondary"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('preferences.appearance.custom_theme.border_color')"
|
||||
>
|
||||
<el-color-picker v-model="border"></el-color-picker>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="item">
|
||||
<el-form-item
|
||||
:label="$t('preferences.appearance.custom_theme.header_menu_color')"
|
||||
>
|
||||
<el-color-picker v-model="headerMenu"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('preferences.appearance.custom_theme.wrapper_mask_color')"
|
||||
>
|
||||
<el-color-picker
|
||||
v-model="wrapperMask"
|
||||
:show-alpha="true"
|
||||
></el-color-picker>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -48,106 +73,116 @@ export default {
|
|||
name: 'color-pallet',
|
||||
computed: {
|
||||
background: {
|
||||
get () {
|
||||
return this.$store.state.Preferences.Appearance.appearance.customThemeColor.background_color
|
||||
get() {
|
||||
return this.$store.state.Preferences.Appearance.appearance
|
||||
.customThemeColor.background_color
|
||||
},
|
||||
set (value) {
|
||||
set(value) {
|
||||
this.$store.dispatch('Preferences/Appearance/updateCustomThemeColor', {
|
||||
background_color: value
|
||||
background_color: value,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
selectedBackground: {
|
||||
get () {
|
||||
return this.$store.state.Preferences.Appearance.appearance.customThemeColor.selected_background_color
|
||||
get() {
|
||||
return this.$store.state.Preferences.Appearance.appearance
|
||||
.customThemeColor.selected_background_color
|
||||
},
|
||||
set (value) {
|
||||
set(value) {
|
||||
this.$store.dispatch('Preferences/Appearance/updateCustomThemeColor', {
|
||||
selected_background_color: value
|
||||
selected_background_color: value,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
globalHeader: {
|
||||
get () {
|
||||
return this.$store.state.Preferences.Appearance.appearance.customThemeColor.global_header_color
|
||||
get() {
|
||||
return this.$store.state.Preferences.Appearance.appearance
|
||||
.customThemeColor.global_header_color
|
||||
},
|
||||
set (value) {
|
||||
set(value) {
|
||||
this.$store.dispatch('Preferences/Appearance/updateCustomThemeColor', {
|
||||
global_header_color: value
|
||||
global_header_color: value,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
sideMenu: {
|
||||
get () {
|
||||
return this.$store.state.Preferences.Appearance.appearance.customThemeColor.side_menu_color
|
||||
get() {
|
||||
return this.$store.state.Preferences.Appearance.appearance
|
||||
.customThemeColor.side_menu_color
|
||||
},
|
||||
set (value) {
|
||||
set(value) {
|
||||
this.$store.dispatch('Preferences/Appearance/updateCustomThemeColor', {
|
||||
side_menu_color: value
|
||||
side_menu_color: value,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
primary: {
|
||||
get () {
|
||||
return this.$store.state.Preferences.Appearance.appearance.customThemeColor.primary_color
|
||||
get() {
|
||||
return this.$store.state.Preferences.Appearance.appearance
|
||||
.customThemeColor.primary_color
|
||||
},
|
||||
set (value) {
|
||||
set(value) {
|
||||
this.$store.dispatch('Preferences/Appearance/updateCustomThemeColor', {
|
||||
primary_color: value
|
||||
primary_color: value,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
regular: {
|
||||
get () {
|
||||
return this.$store.state.Preferences.Appearance.appearance.customThemeColor.regular_color
|
||||
get() {
|
||||
return this.$store.state.Preferences.Appearance.appearance
|
||||
.customThemeColor.regular_color
|
||||
},
|
||||
set (value) {
|
||||
set(value) {
|
||||
this.$store.dispatch('Preferences/Appearance/updateCustomThemeColor', {
|
||||
regular_color: value
|
||||
regular_color: value,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
secondary: {
|
||||
get () {
|
||||
return this.$store.state.Preferences.Appearance.appearance.customThemeColor.secondary_color
|
||||
get() {
|
||||
return this.$store.state.Preferences.Appearance.appearance
|
||||
.customThemeColor.secondary_color
|
||||
},
|
||||
set (value) {
|
||||
set(value) {
|
||||
this.$store.dispatch('Preferences/Appearance/updateCustomThemeColor', {
|
||||
secondary_color: value
|
||||
secondary_color: value,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
border: {
|
||||
get () {
|
||||
return this.$store.state.Preferences.Appearance.appearance.customThemeColor.border_color
|
||||
get() {
|
||||
return this.$store.state.Preferences.Appearance.appearance
|
||||
.customThemeColor.border_color
|
||||
},
|
||||
set (value) {
|
||||
set(value) {
|
||||
this.$store.dispatch('Preferences/Appearance/updateCustomThemeColor', {
|
||||
border_color: value
|
||||
border_color: value,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
headerMenu: {
|
||||
get () {
|
||||
return this.$store.state.Preferences.Appearance.appearance.customThemeColor.header_menu_color
|
||||
get() {
|
||||
return this.$store.state.Preferences.Appearance.appearance
|
||||
.customThemeColor.header_menu_color
|
||||
},
|
||||
set (value) {
|
||||
set(value) {
|
||||
this.$store.dispatch('Preferences/Appearance/updateCustomThemeColor', {
|
||||
header_menu_color: value
|
||||
header_menu_color: value,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
wrapperMask: {
|
||||
get () {
|
||||
return this.$store.state.Preferences.Appearance.appearance.customThemeColor.wrapper_mask_color
|
||||
get() {
|
||||
return this.$store.state.Preferences.Appearance.appearance
|
||||
.customThemeColor.wrapper_mask_color
|
||||
},
|
||||
set (value) {
|
||||
set(value) {
|
||||
this.$store.dispatch('Preferences/Appearance/updateCustomThemeColor', {
|
||||
wrapper_mask_color: value
|
||||
wrapper_mask_color: value,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -34,27 +34,6 @@
|
|||
<span class="count">
|
||||
{{ favouritesCount }}
|
||||
</span>
|
||||
<popper trigger="click" :options="{ placement: 'bottom' }" ref="popper">
|
||||
<div class="popper toot-menu">
|
||||
<ul class="menu-list">
|
||||
<li role="button">
|
||||
{{ $t('cards.toot.view_toot_detail') }}
|
||||
</li>
|
||||
<li role="button">
|
||||
{{ $t('cards.toot.open_in_browser') }}
|
||||
</li>
|
||||
<li role="button">
|
||||
{{ $t('cards.toot.copy_link_to_toot') }}
|
||||
</li>
|
||||
<li role="button" class="separate">
|
||||
{{ $t('cards.toot.delete') }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<el-button slot="reference" type="text" :title="$t('cards.toot.detail')">
|
||||
<font-awesome-icon icon="ellipsis" size="sm" />
|
||||
</el-button>
|
||||
</popper>
|
||||
</div>
|
||||
<div class="application">
|
||||
{{ $t('cards.toot.via', { application: 'Whalebird' }) }}
|
||||
|
@ -174,7 +153,7 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.content-wrapper /deep/ {
|
||||
.content-wrapper {
|
||||
font-size: var(--base-font-size);
|
||||
color: var(--theme-primary-color);
|
||||
|
||||
|
@ -182,11 +161,6 @@ export default {
|
|||
margin: var(--toot-padding) 0;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.emojione {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.tool-box {
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<template>
|
||||
<div id="general" v-loading="loading" :element-loading-background="backgroundColor">
|
||||
<h2>{{ $t('preferences.general.title') }}</h2>
|
||||
<el-form class="sounds section" label-position="right" label-width="250px" size="small">
|
||||
<el-form class="sounds section" label-position="right" label-width="250px">
|
||||
<h3>{{ $t('preferences.general.sounds.title') }}</h3>
|
||||
<p class="description">{{ $t('preferences.general.sounds.description') }}</p>
|
||||
<p class="description">
|
||||
{{ $t('preferences.general.sounds.description') }}
|
||||
</p>
|
||||
<el-form-item for="fav_rb" :label="$t('preferences.general.sounds.fav_rb')">
|
||||
<el-switch id="fav_rb" v-model="sound_fav_rb" active-color="#13ce66"> </el-switch>
|
||||
</el-form-item>
|
||||
|
@ -11,9 +13,11 @@
|
|||
<el-switch id="sound_toot" v-model="sound_toot" active-color="#13ce66"> </el-switch>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form class="timeline section" label-potision="right" label-width="302px" size="samll">
|
||||
<el-form class="timeline section" label-potision="right" label-width="302px">
|
||||
<h3>{{ $t('preferences.general.timeline.title') }}</h3>
|
||||
<p class="description">{{ $t('preferences.general.timeline.description') }}</p>
|
||||
<p class="description">
|
||||
{{ $t('preferences.general.timeline.description') }}
|
||||
</p>
|
||||
<el-form-item for="cw" :label="$t('preferences.general.timeline.cw')">
|
||||
<el-switch id="cw" v-model="timeline_cw" active-color="#13ce66"> </el-switch>
|
||||
</el-form-item>
|
||||
|
@ -24,7 +28,7 @@
|
|||
<el-switch id="hideAllAttachments" v-model="timeline_hide_attachments" active-color="#13ce66"> </el-switch>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form class="other section" label-position="right" label-width="250px" size="small" v-if="notDarwin">
|
||||
<el-form class="other section" label-position="right" label-width="250px" v-if="notDarwin">
|
||||
<h3>{{ $t('preferences.general.other.title') }}</h3>
|
||||
<el-form-item for="launch" :label="$t('preferences.general.other.launch')">
|
||||
<el-switch id="launch" v-model="other_launch" active-color="#13ce66"> </el-switch>
|
||||
|
@ -123,7 +127,7 @@ export default {
|
|||
this.$store
|
||||
.dispatch('Preferences/General/reset')
|
||||
.then(language => {
|
||||
this.$i18n.i18next.changeLanguage(language)
|
||||
this.$i18n.locale = language
|
||||
})
|
||||
.catch(() => {
|
||||
this.$message({
|
||||
|
@ -142,12 +146,12 @@ export default {
|
|||
margin: 24px 0 20px;
|
||||
}
|
||||
|
||||
.section /deep/ {
|
||||
.section {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.el-form-item__label {
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
.section :deep(.el-form-item__label) {
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
|
||||
.selection {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div id="language">
|
||||
<h2>{{ $t('preferences.language.title') }}</h2>
|
||||
<el-form class="display-language section" label-position="top" size="small">
|
||||
<el-form class="display-language section" label-position="top">
|
||||
<h3>{{ $t('preferences.language.language.title') }}</h3>
|
||||
<el-form-item for="language" :label="$t('preferences.language.language.description')">
|
||||
<el-select id="language" v-model="displayLanguage" placeholder="style">
|
||||
|
@ -9,7 +9,7 @@
|
|||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form class="spellchecker section" label-position="top" size="small">
|
||||
<el-form class="spellchecker section" label-position="top">
|
||||
<h3>{{ $t('preferences.language.spellchecker.title') }}</h3>
|
||||
<el-form-item for="spellcheck" :label="$t('preferences.language.spellchecker.enabled')">
|
||||
<el-switch id="spellcheck" v-model="spellcheck" active-color="#13ce66"> </el-switch>
|
||||
|
@ -67,7 +67,7 @@ export default {
|
|||
},
|
||||
set(value) {
|
||||
this.$store.dispatch('Preferences/Language/changeLanguage', value).then(key => {
|
||||
this.$i18n.i18next.changeLanguage(key)
|
||||
this.$i18n.locale = key
|
||||
})
|
||||
}
|
||||
},
|
||||
|
@ -105,12 +105,12 @@ export default {
|
|||
margin: 24px 0 20px;
|
||||
}
|
||||
|
||||
.section /deep/ {
|
||||
.section {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.el-form-item__label {
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
.section :deep(.el-form-item__label) {
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
|
||||
.selection {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div id="network">
|
||||
<h2>{{ $t('preferences.network.proxy.title') }}</h2>
|
||||
<el-form class="network section" size="small" label-width="120px">
|
||||
<el-form class="network section" label-width="120px">
|
||||
<div class="proxy-source">
|
||||
<el-radio v-model="source" label="no">{{ $t('preferences.network.proxy.no') }}</el-radio>
|
||||
</div>
|
||||
|
@ -113,21 +113,21 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.network /deep/ {
|
||||
.network {
|
||||
max-width: 720px;
|
||||
|
||||
.proxy-source {
|
||||
line-height: 32px;
|
||||
margin: 12px 8px;
|
||||
font-size: 14px;
|
||||
|
||||
.el-radio {
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
}
|
||||
|
||||
.el-form-item__label {
|
||||
.proxy-source :deep(.el-radio) {
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
}
|
||||
|
||||
.network :deep(.el-form-item__label) {
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
<template>
|
||||
<div id="notification">
|
||||
<h2>{{ $t('preferences.notification.title') }}</h2>
|
||||
<el-form class="section" label-position="right" label-width="360px" size="small">
|
||||
<p class="description">{{ $t('preferences.notification.enable.description') }}</p>
|
||||
<el-form class="section" label-position="right" label-width="360px">
|
||||
<p class="description">
|
||||
{{ $t('preferences.notification.enable.description') }}
|
||||
</p>
|
||||
<el-form-item for="notifyReply" :label="$t('preferences.notification.enable.reply')">
|
||||
<el-switch id="notifyReply" v-model="notifyReply" active-color="#13ce66"> </el-switch>
|
||||
</el-form-item>
|
||||
|
@ -146,12 +148,12 @@ export default {
|
|||
margin: 24px 0 20px;
|
||||
}
|
||||
|
||||
.section /deep/ {
|
||||
.section {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.el-form-item__label {
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
.section :deep(.el-form-item__label) {
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -5,13 +5,15 @@
|
|||
<el-col :span="23">
|
||||
<h1>{{ $t('settings.title') }}</h1>
|
||||
</el-col>
|
||||
<el-col :span="1">
|
||||
<el-button type="text" icon="el-icon-close" @click="close" class="close-button" role="button"></el-button>
|
||||
<el-col :span="1" class="close-area">
|
||||
<el-button type="text" @click="close" class="close-button" role="button">
|
||||
<font-awesome-icon icon="xmark" />
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-container>
|
||||
<div v-shortkey="['esc']" @shortkey="close"></div>
|
||||
<div></div>
|
||||
<el-aside width="240px" class="menu">
|
||||
<el-menu
|
||||
:default-active="activeRoute()"
|
||||
|
@ -81,8 +83,13 @@ export default {
|
|||
user-select: none;
|
||||
}
|
||||
|
||||
.close-button {
|
||||
font-size: 28px;
|
||||
.close-area {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.close-button {
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.menu {
|
||||
|
@ -93,13 +100,12 @@ export default {
|
|||
border-right: solid 1px var(--theme-border-color);
|
||||
}
|
||||
|
||||
.setting-menu /deep/ {
|
||||
.setting-menu {
|
||||
height: 100%;
|
||||
user-select: none;
|
||||
|
||||
.icon {
|
||||
margin-right: 9px;
|
||||
}
|
||||
}
|
||||
.setting-menu :deep(.icon) {
|
||||
margin-right: 9px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,45 +3,43 @@
|
|||
<h2>{{ $t('settings.filters.title') }}</h2>
|
||||
<div class="new-filter">
|
||||
<el-button type="primary" :disabled="sns === 'misskey'">
|
||||
<router-link tag="span" :to="`/${id()}/settings/filters/new`">
|
||||
<router-link :to="`/${id()}/settings/filters/new`">
|
||||
{{ $t('settings.filters.new.title') }}
|
||||
</router-link>
|
||||
</el-button>
|
||||
</div>
|
||||
<template>
|
||||
<el-table
|
||||
:data="filters"
|
||||
tooltip-effect="dark"
|
||||
empty-text="No filters"
|
||||
style="width: 100%"
|
||||
v-loading="filtersLoading"
|
||||
:element-loading-background="backgroundColor"
|
||||
>
|
||||
<el-table-column prop="phrase" label="Keyword" width="180"> </el-table-column>
|
||||
<el-table-column label="Context">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ filters[scope.$index].context.join(',') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="expires_at" label="Expires" width="180"> </el-table-column>
|
||||
<el-table-column width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text">
|
||||
<router-link tag="span" :to="`/${id()}/settings/filters/${filters[scope.$index].id}/edit`">
|
||||
{{ $t('settings.filters.edit.title') }}
|
||||
</router-link>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" @click="deleteFilter(filters[scope.$index].id)">
|
||||
{{ $t('settings.filters.delete.title') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
<el-table
|
||||
:data="filters"
|
||||
tooltip-effect="dark"
|
||||
empty-text="No filters"
|
||||
style="width: 100%"
|
||||
v-loading="filtersLoading"
|
||||
:element-loading-background="backgroundColor"
|
||||
>
|
||||
<el-table-column prop="phrase" label="Keyword" width="180"> </el-table-column>
|
||||
<el-table-column label="Context">
|
||||
<template #default="scope">
|
||||
<span>{{ filters[scope.$index].context.join(',') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="expires_at" label="Expires" width="180"> </el-table-column>
|
||||
<el-table-column width="80">
|
||||
<template #default="scope">
|
||||
<el-button type="text">
|
||||
<router-link tag="span" :to="`/${id()}/settings/filters/${filters[scope.$index].id}/edit`">
|
||||
{{ $t('settings.filters.edit.title') }}
|
||||
</router-link>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="80">
|
||||
<template #default="scope">
|
||||
<el-button type="text" @click="deleteFilter(filters[scope.$index].id)">
|
||||
{{ $t('settings.filters.delete.title') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -87,9 +85,14 @@ export default {
|
|||
.new-filter {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
a {
|
||||
color: var(--theme-primary-color);
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.el-table /deep/ {
|
||||
.el-table :deep() {
|
||||
tr,
|
||||
th,
|
||||
td,
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
<template>
|
||||
<div id="edit_filter">
|
||||
<h2>{{ $t('settings.filters.edit.title') }}</h2>
|
||||
<FilterForm v-model="filter" @cancel="cancel" @onSubmit="onSubmit" :loading="loading" :sns="sns"> </FilterForm>
|
||||
<FilterForm
|
||||
v-model="filter"
|
||||
@cancel="cancel"
|
||||
@onSubmit="onSubmit"
|
||||
:loading="loading"
|
||||
:sns="sns"
|
||||
>
|
||||
</FilterForm>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -15,10 +22,10 @@ export default {
|
|||
components: { FilterForm },
|
||||
computed: {
|
||||
...mapState('Settings/Filters/Edit', {
|
||||
loading: state => state.loading
|
||||
loading: (state) => state.loading,
|
||||
}),
|
||||
...mapState('TimelineSpace', {
|
||||
sns: state => state.sns
|
||||
sns: (state) => state.sns,
|
||||
}),
|
||||
filter: {
|
||||
get() {
|
||||
|
@ -26,11 +33,14 @@ export default {
|
|||
},
|
||||
set(value) {
|
||||
this.$store.dispatch('Settings/Filters/Edit/editFilter', value)
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
await this.$store.dispatch('Settings/Filters/Edit/fetchFilter', this.filter_id)
|
||||
await this.$store.dispatch(
|
||||
'Settings/Filters/Edit/fetchFilter',
|
||||
this.filter_id
|
||||
)
|
||||
},
|
||||
methods: {
|
||||
cancel() {
|
||||
|
@ -42,14 +52,14 @@ export default {
|
|||
.then(() => {
|
||||
this.$router.go(-1)
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
this.$message({
|
||||
message: this.$t('message.update_filter_error'),
|
||||
type: 'error'
|
||||
type: 'error',
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
<template>
|
||||
<div id="new_filter">
|
||||
<h2>{{ $t('settings.filters.new.title') }}</h2>
|
||||
<FilterForm v-model="filter" @cancel="cancel" @onSubmit="onSubmit" :loading="loading" :sns="sns"> </FilterForm>
|
||||
<FilterForm
|
||||
v-model="filter"
|
||||
@cancel="cancel"
|
||||
@onSubmit="onSubmit"
|
||||
:loading="loading"
|
||||
:sns="sns"
|
||||
>
|
||||
</FilterForm>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -14,10 +21,10 @@ export default {
|
|||
components: { FilterForm },
|
||||
computed: {
|
||||
...mapState('Settings/Filters/New', {
|
||||
loading: state => state.loading
|
||||
loading: (state) => state.loading,
|
||||
}),
|
||||
...mapState('TimelineSpace', {
|
||||
sns: state => state.sns
|
||||
sns: (state) => state.sns,
|
||||
}),
|
||||
filter: {
|
||||
get() {
|
||||
|
@ -25,8 +32,8 @@ export default {
|
|||
},
|
||||
set(value) {
|
||||
this.$store.dispatch('Settings/Filters/New/editFilter', value)
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
cancel() {
|
||||
|
@ -38,14 +45,14 @@ export default {
|
|||
.then(() => {
|
||||
this.$router.go(-1)
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
this.$message({
|
||||
message: this.$t('message.create_filter_error'),
|
||||
type: 'error'
|
||||
type: 'error',
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<el-form ref="form" class="section" label-width="200px" label-position="right" size="medium">
|
||||
<el-form ref="form" class="section" label-width="200px" label-position="right" size="default">
|
||||
<el-form-item :label="$t('settings.filters.form.phrase')">
|
||||
<el-input v-model="filterPhrase"></el-input>
|
||||
</el-form-item>
|
||||
|
@ -9,15 +9,13 @@
|
|||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('settings.filters.form.context')">
|
||||
<template>
|
||||
<el-checkbox-group v-model="filterContext">
|
||||
<el-checkbox label="home"></el-checkbox>
|
||||
<el-checkbox label="notifications"></el-checkbox>
|
||||
<el-checkbox label="public"></el-checkbox>
|
||||
<el-checkbox label="thread"></el-checkbox>
|
||||
<el-checkbox label="account" :disabled="accountDisabled()"></el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</template>
|
||||
<el-checkbox-group v-model="filterContext">
|
||||
<el-checkbox label="home"></el-checkbox>
|
||||
<el-checkbox label="notifications"></el-checkbox>
|
||||
<el-checkbox label="public"></el-checkbox>
|
||||
<el-checkbox label="thread"></el-checkbox>
|
||||
<el-checkbox label="account" :disabled="accountDisabled()"></el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="filterIrreversible">{{ $t('settings.filters.form.irreversible') }}</el-checkbox>
|
||||
|
@ -157,9 +155,11 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.section /deep/ {
|
||||
.section {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.section :deep() {
|
||||
.el-form-item__label {
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
<template>
|
||||
<div id="general">
|
||||
<h2>{{ $t('settings.general.title') }}</h2>
|
||||
<el-form class="toot section" label-width="250px" label-position="right" size="medium">
|
||||
<el-form class="toot section" label-width="250px" label-position="right" size="default">
|
||||
<h3>{{ $t('settings.general.toot.title') }}</h3>
|
||||
<el-form-item for="visibility" :label="$t('settings.general.toot.visibility.description')">
|
||||
<el-select id="visibility" v-model="tootVisibility" placeholder="visibility">
|
||||
<el-select id="visibility" :model-value="tootVisibility" placeholder="visibility" @change="changeVisibility">
|
||||
<el-option v-for="v in visibilities" :key="v.value" :label="$t(v.name)" :value="v.value"> </el-option>
|
||||
</el-select>
|
||||
<p class="notice">{{ $t('settings.general.toot.visibility.notice') }}</p>
|
||||
<p class="notice">
|
||||
{{ $t('settings.general.toot.visibility.notice') }}
|
||||
</p>
|
||||
</el-form-item>
|
||||
<el-form-item for="sensitive" :label="$t('settings.general.toot.sensitive.description')">
|
||||
<el-switch id="sensitive" v-model="tootSensitive"></el-switch>
|
||||
<el-switch id="sensitive" :model-value="tootSensitive" @change="changeSensitive"></el-switch>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
@ -46,18 +48,26 @@ export default {
|
|||
},
|
||||
created() {
|
||||
this.$store.dispatch('Settings/General/fetchSettings')
|
||||
},
|
||||
methods: {
|
||||
changeVisibility(value) {
|
||||
this.tootVisibility = value
|
||||
},
|
||||
changeSensitive(value) {
|
||||
this.tootSensitive = value
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
#general {
|
||||
.section /deep/ {
|
||||
.section {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.el-form-item__label {
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
.section :deep(.el-form-item__label) {
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
|
||||
.notice {
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<template>
|
||||
<div id="timeline">
|
||||
<h2>{{ $t('settings.timeline.title') }}</h2>
|
||||
<el-form class="unread-notification section" size="medium" label-position="right" label-width="250px">
|
||||
<el-form class="unread-notification section" size="default" label-position="right" label-width="250px">
|
||||
<h3>{{ $t('settings.timeline.unread_notification.title') }}</h3>
|
||||
<p class="description">{{ $t('settings.timeline.unread_notification.description') }}</p>
|
||||
<p class="description">
|
||||
{{ $t('settings.timeline.unread_notification.description') }}
|
||||
</p>
|
||||
|
||||
<el-form-item for="direct" :label="$t('settings.timeline.unread_notification.direct')">
|
||||
<el-switch v-model="direct" id="direct" />
|
||||
|
@ -16,7 +18,7 @@
|
|||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-form class="use-marker section" size="medium" label-position="right" label-width="250px">
|
||||
<el-form class="use-marker section" size="default" label-position="right" label-width="250px">
|
||||
<h3>{{ $t('settings.timeline.use_marker.title') }}</h3>
|
||||
<el-form-item for="marker_home" :label="$t('settings.timeline.use_marker.home')">
|
||||
<el-switch v-model="marker_home" id="marker_home" />
|
||||
|
@ -108,12 +110,12 @@ export default {
|
|||
margin: 32px 0 20px;
|
||||
}
|
||||
|
||||
.section /deep/ {
|
||||
.section {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.el-form-item__label {
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
.section :deep(.el-form-item__label) {
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
:element-loading-text="$t('message.loading')"
|
||||
element-loading-spinner="el-icon-loading"
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)"
|
||||
v-shortkey="shortcutEnabled ? { help: ['shift', '?'] } : {}"
|
||||
@shortkey="handleKey"
|
||||
>
|
||||
<side-menu></side-menu>
|
||||
<div :class="collapse ? 'page-narrow' : 'page'">
|
||||
|
@ -31,7 +29,7 @@ import ReceiveDrop from './TimelineSpace/ReceiveDrop'
|
|||
import { AccountLoadError } from '@/errors/load'
|
||||
import { TimelineFetchError } from '@/errors/fetch'
|
||||
import { NewTootAttachLength } from '@/errors/validations'
|
||||
import { Event } from '~/src/renderer/components/event'
|
||||
import { EventEmitter } from '~/src/renderer/components/event'
|
||||
|
||||
export default {
|
||||
name: 'timeline-space',
|
||||
|
@ -67,7 +65,7 @@ export default {
|
|||
this.$store.commit('TimelineSpace/Modals/Jump/changeModal', true)
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
window.removeEventListener('dragenter', this.onDragEnter)
|
||||
window.removeEventListener('dragleave', this.onDragLeave)
|
||||
window.removeEventListener('dragover', this.onDragOver)
|
||||
|
@ -125,7 +123,7 @@ export default {
|
|||
this.$store
|
||||
.dispatch('TimelineSpace/Modals/NewToot/uploadImage', file)
|
||||
.then(() => {
|
||||
Event.$emit('image-uploaded')
|
||||
EventEmitter.emit('image-uploaded')
|
||||
})
|
||||
.catch(err => {
|
||||
if (err instanceof NewTootAttachLength) {
|
||||
|
@ -180,7 +178,6 @@ export default {
|
|||
width: calc(100% - 180px);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
height: 48px;
|
||||
border-bottom: solid 1px var(--theme-border-color);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ export default {
|
|||
#contents {
|
||||
--current-sidebar-width: 360px;
|
||||
|
||||
padding-top: 49px;
|
||||
padding-top: 53px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
user-select: text;
|
||||
|
@ -97,7 +97,7 @@ export default {
|
|||
background-color: var(--theme-border-color);
|
||||
height: calc(100% - 48px);
|
||||
position: fixed;
|
||||
top: 48px;
|
||||
top: 53px;
|
||||
right: var(--current-sidebar-width);
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,7 @@ export default {
|
|||
|
||||
#side_bar {
|
||||
position: fixed;
|
||||
top: 48px;
|
||||
top: 52px;
|
||||
right: 0;
|
||||
width: var(--current-sidebar-width);
|
||||
height: calc(100% - 48px);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div id="bookmarks" v-shortkey="shortcutEnabled ? { next: ['j'] } : {}" @shortkey="handleKey">
|
||||
<div v-shortkey="{ linux: ['ctrl', 'r'], mac: ['meta', 'r'] }" @shortkey="reload()"></div>
|
||||
<div id="bookmarks">
|
||||
<div></div>
|
||||
<DynamicScroller :items="bookmarks" :min-item-size="60" id="scroller" class="scroller" ref="scroller">
|
||||
<template v-slot="{ item, index, active }">
|
||||
<DynamicScrollerItem :item="item" :active="active" :size-dependencies="[item.uri]" :data-index="index" :watchData="true">
|
||||
|
@ -20,7 +20,9 @@
|
|||
</template>
|
||||
</DynamicScroller>
|
||||
<div :class="openSideBar ? 'upper-with-side-bar' : 'upper'" v-show="!heading">
|
||||
<el-button type="primary" icon="el-icon-arrow-up" @click="upper" circle> </el-button>
|
||||
<el-button type="primary" @click="upper" circle>
|
||||
<font-awesome-icon icon="angle-up" class="upper-icon" />
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -29,18 +31,18 @@
|
|||
import { mapState, mapGetters } from 'vuex'
|
||||
import Toot from '@/components/organisms/Toot'
|
||||
import reloadable from '~/src/renderer/components/mixins/reloadable'
|
||||
import { Event } from '~/src/renderer/components/event'
|
||||
import { EventEmitter } from '~/src/renderer/components/event'
|
||||
|
||||
export default {
|
||||
name: 'bookmarks',
|
||||
components: { Toot },
|
||||
mixins: [reloadable],
|
||||
data() {
|
||||
return {
|
||||
heading: true,
|
||||
focusedId: null
|
||||
}
|
||||
},
|
||||
name: 'bookmarks',
|
||||
components: { Toot },
|
||||
mixins: [reloadable],
|
||||
computed: {
|
||||
...mapState('TimelineSpace', {
|
||||
account: state => state.account
|
||||
|
@ -79,7 +81,7 @@ export default {
|
|||
},
|
||||
mounted() {
|
||||
document.getElementById('scroller').addEventListener('scroll', this.onScroll)
|
||||
Event.$on('focus-timeline', () => {
|
||||
EventEmitter.on('focus-timeline', () => {
|
||||
// If focusedId does not change, we have to refresh focusedId because Toot component watch change events.
|
||||
const previousFocusedId = this.focusedId
|
||||
this.focusedId = 0
|
||||
|
@ -88,10 +90,10 @@ export default {
|
|||
})
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
Event.$off('focus-timeline')
|
||||
beforeUnmount() {
|
||||
EventEmitter.off('focus-timeline')
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.$store.commit('TimelineSpace/Contents/Bookmarks/updateBookmarks', [])
|
||||
if (document.getElementById('scroller') !== undefined && document.getElementById('scroller') !== null) {
|
||||
document.getElementById('scroller').removeEventListener('scroll', this.onScroll)
|
||||
|
@ -178,7 +180,7 @@ export default {
|
|||
this.focusedId = message.id
|
||||
},
|
||||
focusSidebar() {
|
||||
Event.$emit('focus-sidebar')
|
||||
EventEmitter.emit('focus-sidebar')
|
||||
},
|
||||
handleKey(event) {
|
||||
switch (event.srcKey) {
|
||||
|
@ -213,5 +215,9 @@ export default {
|
|||
right: calc(20px + var(--current-sidebar-width));
|
||||
transition: all 0.5s;
|
||||
}
|
||||
|
||||
.upper-icon {
|
||||
padding: 3px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div id="directmessages" v-shortkey="shortcutEnabled ? { next: ['j'] } : {}" @shortkey="handleKey">
|
||||
<div v-shortkey="{ linux: ['ctrl', 'r'], mac: ['meta', 'r'] }" @shortkey="reload()"></div>
|
||||
<div id="directmessages">
|
||||
<div></div>
|
||||
<DynamicScroller :items="timeline" :min-item-size="86" id="scroller" class="scroller" ref="scroller">
|
||||
<template v-slot="{ item, index, active }">
|
||||
<DynamicScrollerItem :item="item" :active="active" :size-dependencies="[item.uri]" :data-index="index" :watchData="true">
|
||||
|
@ -22,7 +22,9 @@
|
|||
</template>
|
||||
</DynamicScroller>
|
||||
<div :class="openSideBar ? 'upper-with-side-bar' : 'upper'" v-show="!heading">
|
||||
<el-button type="primary" icon="el-icon-arrow-up" @click="upper" circle> </el-button>
|
||||
<el-button type="primary" @click="upper" circle>
|
||||
<font-awesome-icon icon="angle-up" class="upper-icon" />
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -32,13 +34,10 @@ import { mapState, mapGetters } from 'vuex'
|
|||
import moment from 'moment'
|
||||
import Toot from '~/src/renderer/components/organisms/Toot'
|
||||
import reloadable from '~/src/renderer/components/mixins/reloadable'
|
||||
import { Event } from '~/src/renderer/components/event'
|
||||
import { EventEmitter } from '~/src/renderer/components/event'
|
||||
import { ScrollPosition } from '~/src/renderer/components/utils/scroll'
|
||||
|
||||
export default {
|
||||
name: 'directmessages',
|
||||
components: { Toot },
|
||||
mixins: [reloadable],
|
||||
data() {
|
||||
return {
|
||||
focusedId: null,
|
||||
|
@ -48,6 +47,9 @@ export default {
|
|||
resizeTime: null
|
||||
}
|
||||
},
|
||||
name: 'directmessages',
|
||||
components: { Toot },
|
||||
mixins: [reloadable],
|
||||
computed: {
|
||||
...mapState('TimelineSpace/Contents/DirectMessages', {
|
||||
timeline: state => state.timeline,
|
||||
|
@ -84,7 +86,7 @@ export default {
|
|||
})
|
||||
}
|
||||
|
||||
Event.$on('focus-timeline', () => {
|
||||
EventEmitter.on('focus-timeline', () => {
|
||||
// If focusedId does not change, we have to refresh focusedId because Toot component watch change events.
|
||||
const previousFocusedId = this.focusedId
|
||||
this.focusedId = 0
|
||||
|
@ -114,15 +116,15 @@ export default {
|
|||
this.scrollPosition.prepare()
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
if (!this.unreadNotification.direct) {
|
||||
this.$store.dispatch('TimelineSpace/stopDirectMessagesStreaming')
|
||||
this.$store.dispatch('TimelineSpace/unbindDirectMessagesStreaming')
|
||||
}
|
||||
Event.$off('focus-timeline')
|
||||
EventEmitter.off('focus-timeline')
|
||||
this.observer.disconnect()
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.$store.commit('TimelineSpace/Contents/DirectMessages/changeHeading', true)
|
||||
this.$store.commit('TimelineSpace/Contents/DirectMessages/archiveTimeline')
|
||||
if (!this.unreadNotification.direct) {
|
||||
|
@ -247,7 +249,7 @@ export default {
|
|||
this.focusedId = message.uri + message.id
|
||||
},
|
||||
focusSidebar() {
|
||||
Event.$emit('focus-sidebar')
|
||||
EventEmitter.emit('focus-sidebar')
|
||||
},
|
||||
handleKey(event) {
|
||||
switch (event.srcKey) {
|
||||
|
@ -297,6 +299,11 @@ export default {
|
|||
right: calc(20px + var(--current-sidebar-width));
|
||||
transition: all 0.5s;
|
||||
}
|
||||
|
||||
.upper-icon {
|
||||
padding: 3px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" src="@/assets/timeline-transition.scss"></style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div id="favourites" v-shortkey="shortcutEnabled ? { next: ['j'] } : {}" @shortkey="handleKey">
|
||||
<div v-shortkey="{ linux: ['ctrl', 'r'], mac: ['meta', 'r'] }" @shortkey="reload()"></div>
|
||||
<div id="favourites">
|
||||
<div></div>
|
||||
<DynamicScroller :items="favourites" :min-item-size="60" id="scroller" class="scroller" ref="scroller">
|
||||
<template v-slot="{ item, index, active }">
|
||||
<DynamicScrollerItem :item="item" :active="active" :size-dependencies="[item.uri]" :data-index="index" :watchData="true">
|
||||
|
@ -21,7 +21,9 @@
|
|||
</template>
|
||||
</DynamicScroller>
|
||||
<div :class="openSideBar ? 'upper-with-side-bar' : 'upper'" v-show="!heading">
|
||||
<el-button type="primary" icon="el-icon-arrow-up" @click="upper" circle> </el-button>
|
||||
<el-button type="primary" @click="upper" circle>
|
||||
<font-awesome-icon icon="angle-up" class="upper-icon" />
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -30,18 +32,18 @@
|
|||
import { mapState, mapGetters } from 'vuex'
|
||||
import Toot from '~/src/renderer/components/organisms/Toot'
|
||||
import reloadable from '~/src/renderer/components/mixins/reloadable'
|
||||
import { Event } from '~/src/renderer/components/event'
|
||||
import { EventEmitter } from '~/src/renderer/components/event'
|
||||
|
||||
export default {
|
||||
name: 'favourites',
|
||||
components: { Toot },
|
||||
mixins: [reloadable],
|
||||
data() {
|
||||
return {
|
||||
heading: true,
|
||||
focusedId: null
|
||||
}
|
||||
},
|
||||
name: 'favourites',
|
||||
components: { Toot },
|
||||
mixins: [reloadable],
|
||||
computed: {
|
||||
...mapState({
|
||||
openSideBar: state => state.TimelineSpace.Contents.SideBar.openSideBar,
|
||||
|
@ -72,7 +74,7 @@ export default {
|
|||
},
|
||||
mounted() {
|
||||
document.getElementById('scroller').addEventListener('scroll', this.onScroll)
|
||||
Event.$on('focus-timeline', () => {
|
||||
EventEmitter.on('focus-timeline', () => {
|
||||
// If focusedId does not change, we have to refresh focusedId because Toot component watch change events.
|
||||
const previousFocusedId = this.focusedId
|
||||
this.focusedId = 0
|
||||
|
@ -81,10 +83,10 @@ export default {
|
|||
})
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
Event.$off('focus-timeline')
|
||||
beforeUnmount() {
|
||||
EventEmitter.off('focus-timeline')
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.$store.commit('TimelineSpace/Contents/Favourites/updateFavourites', [])
|
||||
if (document.getElementById('scroller') !== undefined && document.getElementById('scroller') !== null) {
|
||||
document.getElementById('scroller').removeEventListener('scroll', this.onScroll)
|
||||
|
@ -173,7 +175,7 @@ export default {
|
|||
this.focusedId = message.id
|
||||
},
|
||||
focusSidebar() {
|
||||
Event.$emit('focus-sidebar')
|
||||
EventEmitter.emit('focus-sidebar')
|
||||
},
|
||||
handleKey(event) {
|
||||
switch (event.srcKey) {
|
||||
|
@ -208,5 +210,9 @@ export default {
|
|||
right: calc(20px + var(--current-sidebar-width));
|
||||
transition: all 0.5s;
|
||||
}
|
||||
|
||||
.upper-icon {
|
||||
padding: 3px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
<template>
|
||||
<div id="follow-requests">
|
||||
<template v-for="account in requests">
|
||||
<user :user="account" :request="true" @acceptRequest="accept" @rejectRequest="reject"></user>
|
||||
<user
|
||||
:user="account"
|
||||
:request="true"
|
||||
@acceptRequest="accept"
|
||||
@rejectRequest="reject"
|
||||
></user>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -15,39 +20,49 @@ export default {
|
|||
components: { User },
|
||||
computed: {
|
||||
...mapState('TimelineSpace/Contents/FollowRequests', {
|
||||
requests: state => state.requests
|
||||
})
|
||||
requests: (state) => state.requests,
|
||||
}),
|
||||
},
|
||||
async mounted() {
|
||||
await this.initialize()
|
||||
},
|
||||
methods: {
|
||||
async initialize() {
|
||||
await this.$store.dispatch('TimelineSpace/Contents/FollowRequests/fetchRequests').catch(_ => {
|
||||
this.$message({
|
||||
message: this.$t('message.timeline_fetch_error'),
|
||||
type: 'error'
|
||||
await this.$store
|
||||
.dispatch('TimelineSpace/Contents/FollowRequests/fetchRequests')
|
||||
.catch((_) => {
|
||||
this.$message({
|
||||
message: this.$t('message.timeline_fetch_error'),
|
||||
type: 'error',
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
accept(account) {
|
||||
this.$store.dispatch('TimelineSpace/Contents/FollowRequests/acceptRequest', account).catch(_ => {
|
||||
this.$message({
|
||||
message: this.$t('message.follow_request_accept_error'),
|
||||
type: 'error'
|
||||
this.$store
|
||||
.dispatch(
|
||||
'TimelineSpace/Contents/FollowRequests/acceptRequest',
|
||||
account
|
||||
)
|
||||
.catch((_) => {
|
||||
this.$message({
|
||||
message: this.$t('message.follow_request_accept_error'),
|
||||
type: 'error',
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
reject(account) {
|
||||
this.$store.dispatch('TimelineSpace/Contents/FollowRequests/rejectRequest', account).catch(_ => {
|
||||
this.$message({
|
||||
message: this.$t('message.follow_request_reject_error'),
|
||||
type: 'error'
|
||||
this.$store
|
||||
.dispatch(
|
||||
'TimelineSpace/Contents/FollowRequests/rejectRequest',
|
||||
account
|
||||
)
|
||||
.catch((_) => {
|
||||
this.$message({
|
||||
message: this.$t('message.follow_request_reject_error'),
|
||||
type: 'error',
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scorped></style>
|
||||
|
|
|
@ -9,14 +9,7 @@
|
|||
</el-button>
|
||||
</div>
|
||||
<div class="form-item input">
|
||||
<input
|
||||
v-model="tag"
|
||||
:placeholder="$t('hashtag.tag_name')"
|
||||
class="search-keyword"
|
||||
v-shortkey.avoid
|
||||
v-on:keyup.enter="search"
|
||||
autofocus
|
||||
/>
|
||||
<input v-model="tag" :placeholder="$t('hashtag.tag_name')" class="search-keyword" v-on:keyup.enter="search" autofocus />
|
||||
</div>
|
||||
<div class="form-item" v-show="tagPage()">
|
||||
<el-button type="text" @click="save" :title="$t('hashtag.save_tag')">
|
||||
|
@ -72,7 +65,6 @@ export default {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
#hashtag {
|
||||
border-top: 1px solid var(--theme-border-color);
|
||||
height: calc(100% - 1px);
|
||||
overflow: hidden;
|
||||
|
||||
|
|
|
@ -32,7 +32,9 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
openTimeline(tagName) {
|
||||
this.$router.push({ path: `/${this.$route.params.id}/hashtag/${tagName}` })
|
||||
this.$router.push({
|
||||
path: `/${this.$route.params.id}/hashtag/${tagName}`
|
||||
})
|
||||
},
|
||||
deleteTag(tag) {
|
||||
this.$store.dispatch('TimelineSpace/Contents/Hashtag/List/removeTag', tag)
|
||||
|
@ -63,7 +65,7 @@ export default {
|
|||
.action {
|
||||
width: 20px;
|
||||
|
||||
.el-button /deep/ {
|
||||
.el-button {
|
||||
padding: 0;
|
||||
color: var(--theme-secondary-color);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div name="tag" class="tag-timeline" v-shortkey="shortcutEnabled ? { next: ['j'] } : {}" @shortkey="handleKey">
|
||||
<div v-shortkey="{ linux: ['ctrl', 'r'], mac: ['meta', 'r'] }" @shortkey="reload()"></div>
|
||||
<div name="tag" class="tag-timeline">
|
||||
<div></div>
|
||||
<DynamicScroller :items="timeline" :min-item-size="86" id="scroller" class="scroller" ref="scroller">
|
||||
<template v-slot="{ item, index, active }">
|
||||
<DynamicScrollerItem :item="item" :active="active" :size-dependencies="[item.uri]" :data-index="index" :watchData="true">
|
||||
|
@ -22,7 +22,9 @@
|
|||
</template>
|
||||
</DynamicScroller>
|
||||
<div :class="openSideBar ? 'upper-with-side-bar' : 'upper'" v-show="!heading">
|
||||
<el-button type="primary" icon="el-icon-arrow-up" @click="upper" circle> </el-button>
|
||||
<el-button type="primary" @click="upper" circle>
|
||||
<font-awesome-icon icon="angle-up" class="upper-icon" />
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -32,14 +34,10 @@ import { mapState, mapGetters } from 'vuex'
|
|||
import moment from 'moment'
|
||||
import Toot from '~/src/renderer/components/organisms/Toot'
|
||||
import reloadable from '~/src/renderer/components/mixins/reloadable'
|
||||
import { Event } from '~/src/renderer/components/event'
|
||||
import { EventEmitter } from '~/src/renderer/components/event'
|
||||
import { ScrollPosition } from '~/src/renderer/components/utils/scroll'
|
||||
|
||||
export default {
|
||||
name: 'tag',
|
||||
components: { Toot },
|
||||
mixins: [reloadable],
|
||||
props: ['tag'],
|
||||
data() {
|
||||
return {
|
||||
focusedId: null,
|
||||
|
@ -49,6 +47,10 @@ export default {
|
|||
resizeTime: null
|
||||
}
|
||||
},
|
||||
name: 'tag',
|
||||
components: { Toot },
|
||||
mixins: [reloadable],
|
||||
props: ['tag'],
|
||||
computed: {
|
||||
...mapState({
|
||||
openSideBar: state => state.TimelineSpace.Contents.SideBar.openSideBar,
|
||||
|
@ -79,7 +81,7 @@ export default {
|
|||
})
|
||||
document.getElementById('scroller').addEventListener('scroll', this.onScroll)
|
||||
|
||||
Event.$on('focus-timeline', () => {
|
||||
EventEmitter.on('focus-timeline', () => {
|
||||
// If focusedId does not change, we have to refresh focusedId because Toot component watch change events.
|
||||
const previousFocusedId = this.focusedId
|
||||
this.focusedId = 0
|
||||
|
@ -129,10 +131,10 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
this.$store.dispatch('TimelineSpace/Contents/Hashtag/Tag/stopStreaming')
|
||||
this.reset()
|
||||
Event.$off('focus-timeline')
|
||||
EventEmitter.off('focus-timeline')
|
||||
this.observer.disconnect()
|
||||
},
|
||||
methods: {
|
||||
|
@ -263,7 +265,7 @@ export default {
|
|||
this.focusedId = message.uri + message.id
|
||||
},
|
||||
focusSidebar() {
|
||||
Event.$emit('focus-sidebar')
|
||||
EventEmitter.emit('focus-sidebar')
|
||||
},
|
||||
handleKey(event) {
|
||||
switch (event.srcKey) {
|
||||
|
@ -304,6 +306,11 @@ export default {
|
|||
right: calc(20px + var(--current-sidebar-width));
|
||||
transition: all 0.5s;
|
||||
}
|
||||
|
||||
.upper-icon {
|
||||
padding: 3px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" src="@/assets/timeline-transition.scss"></style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div id="home" v-shortkey="shortcutEnabled ? { next: ['j'] } : {}" @shortkey="handleKey">
|
||||
<div v-shortkey="{ linux: ['ctrl', 'r'], mac: ['meta', 'r'] }" @shortkey="reload()"></div>
|
||||
<div id="home">
|
||||
<div></div>
|
||||
<DynamicScroller :items="filteredTimeline" :min-item-size="86" id="scroller" class="scroller" ref="scroller">
|
||||
<template v-slot="{ item, index, active }">
|
||||
<template v-if="item.id === 'loading-card'">
|
||||
|
@ -30,7 +30,9 @@
|
|||
</DynamicScroller>
|
||||
|
||||
<div :class="openSideBar ? 'upper-with-side-bar' : 'upper'" v-show="!heading">
|
||||
<el-button type="primary" icon="el-icon-arrow-up" @click="upper" circle> </el-button>
|
||||
<el-button type="primary" @click="upper" circle>
|
||||
<font-awesome-icon icon="angle-up" class="upper-icon" />
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -41,13 +43,10 @@ import moment from 'moment'
|
|||
import Toot from '~/src/renderer/components/organisms/Toot'
|
||||
import StatusLoading from '~/src/renderer/components/organisms/StatusLoading'
|
||||
import reloadable from '~/src/renderer/components/mixins/reloadable'
|
||||
import { Event } from '~/src/renderer/components/event'
|
||||
import { EventEmitter } from '~/src/renderer/components/event'
|
||||
import { ScrollPosition } from '~/src/renderer/components/utils/scroll'
|
||||
|
||||
export default {
|
||||
name: 'home',
|
||||
components: { Toot, StatusLoading },
|
||||
mixins: [reloadable],
|
||||
data() {
|
||||
return {
|
||||
focusedId: null,
|
||||
|
@ -58,6 +57,9 @@ export default {
|
|||
loadingMore: false
|
||||
}
|
||||
},
|
||||
name: 'home',
|
||||
components: { Toot, StatusLoading },
|
||||
mixins: [reloadable],
|
||||
computed: {
|
||||
...mapState('TimelineSpace/Contents/Home', {
|
||||
timeline: state => state.timeline,
|
||||
|
@ -100,7 +102,7 @@ export default {
|
|||
mounted() {
|
||||
this.$store.commit('TimelineSpace/SideMenu/changeUnreadHomeTimeline', false)
|
||||
document.getElementById('scroller').addEventListener('scroll', this.onScroll)
|
||||
Event.$on('focus-timeline', () => {
|
||||
EventEmitter.on('focus-timeline', () => {
|
||||
// If focusedId does not change, we have to refresh focusedId because Toot component watch change events.
|
||||
const previousFocusedId = this.focusedId
|
||||
this.focusedId = 0
|
||||
|
@ -134,11 +136,11 @@ export default {
|
|||
this.scrollPosition.prepare()
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
Event.$off('focus-timeline')
|
||||
beforeUnmount() {
|
||||
EventEmitter.off('focus-timeline')
|
||||
this.observer.disconnect()
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.$store.commit('TimelineSpace/Contents/Home/changeHeading', true)
|
||||
this.$store.commit('TimelineSpace/Contents/Home/archiveTimeline')
|
||||
if (document.getElementById('scroller') !== undefined && document.getElementById('scroller') !== null) {
|
||||
|
@ -161,10 +163,13 @@ export default {
|
|||
this.$store.commit('TimelineSpace/Contents/Home/changeHeading', true)
|
||||
}
|
||||
},
|
||||
timeline: function (newState, _oldState) {
|
||||
if (this.heading && newState.length > 0) {
|
||||
this.$store.dispatch('TimelineSpace/Contents/Home/saveMarker')
|
||||
}
|
||||
timeline: {
|
||||
handler(newState, _oldState) {
|
||||
if (this.heading && newState.length > 0) {
|
||||
this.$store.dispatch('TimelineSpace/Contents/Home/saveMarker')
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -263,7 +268,7 @@ export default {
|
|||
this.focusedId = message.uri + message.id
|
||||
},
|
||||
focusSidebar() {
|
||||
Event.$emit('focus-sidebar')
|
||||
EventEmitter.emit('focus-sidebar')
|
||||
},
|
||||
handleKey(event) {
|
||||
switch (event.srcKey) {
|
||||
|
@ -313,6 +318,11 @@ export default {
|
|||
right: calc(20px + var(--current-sidebar-width));
|
||||
transition: all 0.5s;
|
||||
}
|
||||
|
||||
.upper-icon {
|
||||
padding: 3px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" src="@/assets/timeline-transition.scss"></style>
|
||||
|
|
|
@ -6,7 +6,11 @@
|
|||
</el-button>
|
||||
</div>
|
||||
<template v-for="account in members">
|
||||
<user :user="account" :remove="true" @removeAccount="removeAccount"></user>
|
||||
<user
|
||||
:user="account"
|
||||
:remove="true"
|
||||
@removeAccount="removeAccount"
|
||||
></user>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -21,8 +25,8 @@ export default {
|
|||
components: { User },
|
||||
computed: {
|
||||
...mapState({
|
||||
members: state => state.TimelineSpace.Contents.Lists.Edit.members
|
||||
})
|
||||
members: (state) => state.TimelineSpace.Contents.Lists.Edit.members,
|
||||
}),
|
||||
},
|
||||
created() {
|
||||
this.init()
|
||||
|
@ -31,11 +35,14 @@ export default {
|
|||
async init() {
|
||||
this.$store.commit('TimelineSpace/Contents/changeLoading', true)
|
||||
try {
|
||||
await this.$store.dispatch('TimelineSpace/Contents/Lists/Edit/fetchMembers', this.list_id)
|
||||
await this.$store.dispatch(
|
||||
'TimelineSpace/Contents/Lists/Edit/fetchMembers',
|
||||
this.list_id
|
||||
)
|
||||
} catch (err) {
|
||||
this.$message({
|
||||
message: this.$t('message.members_fetch_error'),
|
||||
type: 'error'
|
||||
type: 'error',
|
||||
})
|
||||
} finally {
|
||||
this.$store.commit('TimelineSpace/Contents/changeLoading', false)
|
||||
|
@ -44,25 +51,37 @@ export default {
|
|||
async removeAccount(account) {
|
||||
this.$store.commit('TimelineSpace/Contents/changeLoading', true)
|
||||
try {
|
||||
await this.$store.dispatch('TimelineSpace/Contents/Lists/Edit/removeAccount', {
|
||||
account: account,
|
||||
listId: this.list_id
|
||||
})
|
||||
await this.$store.dispatch('TimelineSpace/Contents/Lists/Edit/fetchMembers', this.list_id)
|
||||
await this.$store.dispatch(
|
||||
'TimelineSpace/Contents/Lists/Edit/removeAccount',
|
||||
{
|
||||
account: account,
|
||||
listId: this.list_id,
|
||||
}
|
||||
)
|
||||
await this.$store.dispatch(
|
||||
'TimelineSpace/Contents/Lists/Edit/fetchMembers',
|
||||
this.list_id
|
||||
)
|
||||
} catch (err) {
|
||||
this.$message({
|
||||
message: this.$t('message.remove_user_error'),
|
||||
type: 'error'
|
||||
type: 'error',
|
||||
})
|
||||
} finally {
|
||||
this.$store.commit('TimelineSpace/Contents/changeLoading', false)
|
||||
}
|
||||
},
|
||||
addAccount() {
|
||||
this.$store.commit('TimelineSpace/Modals/AddListMember/setListId', this.list_id)
|
||||
this.$store.dispatch('TimelineSpace/Modals/AddListMember/changeModal', true)
|
||||
}
|
||||
}
|
||||
this.$store.commit(
|
||||
'TimelineSpace/Modals/AddListMember/setListId',
|
||||
this.list_id
|
||||
)
|
||||
this.$store.dispatch(
|
||||
'TimelineSpace/Modals/AddListMember/changeModal',
|
||||
true
|
||||
)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ export default {
|
|||
.list {
|
||||
padding: 4px 24px;
|
||||
display: flex;
|
||||
flex-dirrection: row;
|
||||
flex-direction: row;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid var(--theme-border-color);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div name="list" class="list-timeline" v-shortkey="shortcutEnabled ? { next: ['j'] } : {}" @shortkey="handleKey">
|
||||
<div v-shortkey="{ linux: ['ctrl', 'r'], mac: ['meta', 'r'] }" @shortkey="reload()"></div>
|
||||
<div name="list" class="list-timeline">
|
||||
<div></div>
|
||||
<DynamicScroller :items="timeline" :min-item-size="86" id="scroller" class="scroller" ref="scroller">
|
||||
<template v-slot="{ item, index, active }">
|
||||
<DynamicScrollerItem :item="item" :active="active" :size-dependencies="[item.uri]" :data-index="index" :watchData="true">
|
||||
|
@ -22,7 +22,9 @@
|
|||
</template>
|
||||
</DynamicScroller>
|
||||
<div :class="openSideBar ? 'upper-with-side-bar' : 'upper'" v-show="!heading">
|
||||
<el-button type="primary" icon="el-icon-arrow-up" @click="upper" circle> </el-button>
|
||||
<el-button type="primary" @click="upper" circle>
|
||||
<font-awesome-icon icon="angle-up" class="upper-icon" />
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -32,14 +34,10 @@ import { mapState, mapGetters } from 'vuex'
|
|||
import moment from 'moment'
|
||||
import Toot from '~/src/renderer/components/organisms/Toot'
|
||||
import reloadable from '~/src/renderer/components/mixins/reloadable'
|
||||
import { Event } from '~/src/renderer/components/event'
|
||||
import { EventEmitter } from '~/src/renderer/components/event'
|
||||
import { ScrollPosition } from '~/src/renderer/components/utils/scroll'
|
||||
|
||||
export default {
|
||||
name: 'list',
|
||||
props: ['list_id'],
|
||||
components: { Toot },
|
||||
mixins: [reloadable],
|
||||
data() {
|
||||
return {
|
||||
focusedId: null,
|
||||
|
@ -49,6 +47,10 @@ export default {
|
|||
resizeTime: null
|
||||
}
|
||||
},
|
||||
name: 'list',
|
||||
props: ['list_id'],
|
||||
components: { Toot },
|
||||
mixins: [reloadable],
|
||||
computed: {
|
||||
...mapState({
|
||||
openSideBar: state => state.TimelineSpace.Contents.SideBar.openSideBar,
|
||||
|
@ -80,7 +82,7 @@ export default {
|
|||
},
|
||||
mounted() {
|
||||
document.getElementById('scroller').addEventListener('scroll', this.onScroll)
|
||||
Event.$on('focus-timeline', () => {
|
||||
EventEmitter.on('focus-timeline', () => {
|
||||
// If focusedId does not change, we have to refresh focusedId because Toot component watch change events.
|
||||
const previousFocusedId = this.focusedId
|
||||
this.focusedId = 0
|
||||
|
@ -129,11 +131,11 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
this.$store.dispatch('TimelineSpace/Contents/Lists/Show/stopStreaming')
|
||||
this.observer.disconnect()
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.$store.commit('TimelineSpace/Contents/Lists/Show/changeHeading', true)
|
||||
this.$store.commit('TimelineSpace/Contents/Lists/Show/archiveTimeline')
|
||||
this.$store.commit('TimelineSpace/Contents/Lists/Show/clearTimeline')
|
||||
|
@ -263,7 +265,7 @@ export default {
|
|||
this.focusedId = message.uri + message.id
|
||||
},
|
||||
focusSidebar() {
|
||||
Event.$emit('focus-sidebar')
|
||||
EventEmitter.emit('focus-sidebar')
|
||||
},
|
||||
handleKey(event) {
|
||||
switch (event.srcKey) {
|
||||
|
@ -304,6 +306,11 @@ export default {
|
|||
right: calc(20px + var(--current-sidebar-width));
|
||||
transition: all 0.5s;
|
||||
}
|
||||
|
||||
.upper-icon {
|
||||
padding: 3px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" src="@/assets/timeline-transition.scss"></style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div id="local" v-shortkey="shortcutEnabled ? { next: ['j'] } : {}" @shortkey="handleKey">
|
||||
<div v-shortkey="{ linux: ['ctrl', 'r'], mac: ['meta', 'r'] }" @shortkey="reload()"></div>
|
||||
<div id="local">
|
||||
<div></div>
|
||||
<DynamicScroller :items="timeline" :min-item-size="86" id="scroller" class="scroller" ref="scroller">
|
||||
<template v-slot="{ item, index, active }">
|
||||
<DynamicScrollerItem :item="item" :active="active" :size-dependencies="[item.uri]" :data-index="index" :watchData="true">
|
||||
|
@ -22,7 +22,9 @@
|
|||
</template>
|
||||
</DynamicScroller>
|
||||
<div :class="openSideBar ? 'upper-with-side-bar' : 'upper'" v-show="!heading">
|
||||
<el-button type="primary" icon="el-icon-arrow-up" @click="upper" circle> </el-button>
|
||||
<el-button type="primary" @click="upper" circle>
|
||||
<font-awesome-icon icon="angle-up" class="upper-icon" />
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -32,13 +34,10 @@ import { mapState, mapGetters } from 'vuex'
|
|||
import moment from 'moment'
|
||||
import Toot from '~/src/renderer/components/organisms/Toot'
|
||||
import reloadable from '~/src/renderer/components/mixins/reloadable'
|
||||
import { Event } from '~/src/renderer/components/event'
|
||||
import { EventEmitter } from '~/src/renderer/components/event'
|
||||
import { ScrollPosition } from '~/src/renderer/components/utils/scroll'
|
||||
|
||||
export default {
|
||||
name: 'local',
|
||||
components: { Toot },
|
||||
mixins: [reloadable],
|
||||
data() {
|
||||
return {
|
||||
focusedId: null,
|
||||
|
@ -48,6 +47,9 @@ export default {
|
|||
resizeTime: null
|
||||
}
|
||||
},
|
||||
name: 'local',
|
||||
components: { Toot },
|
||||
mixins: [reloadable],
|
||||
computed: {
|
||||
...mapState('TimelineSpace/Contents/Local', {
|
||||
timeline: state => state.timeline,
|
||||
|
@ -59,7 +61,7 @@ export default {
|
|||
openSideBar: state => state.TimelineSpace.Contents.SideBar.openSideBar,
|
||||
backgroundColor: state => state.App.theme.background_color,
|
||||
startReload: state => state.TimelineSpace.HeaderMenu.reload,
|
||||
unreadNotification: state => state.TimelineSpace.unreadNotification
|
||||
unreadNotification: state => state.TimelineSpace.timelineSetting.unreadNotification
|
||||
}),
|
||||
...mapGetters('TimelineSpace/Modals', ['modalOpened']),
|
||||
shortcutEnabled: function () {
|
||||
|
@ -75,6 +77,7 @@ export default {
|
|||
}
|
||||
},
|
||||
async mounted() {
|
||||
console.log(this.unreadNotification)
|
||||
this.$store.commit('TimelineSpace/SideMenu/changeUnreadLocalTimeline', false)
|
||||
document.getElementById('scroller').addEventListener('scroll', this.onScroll)
|
||||
if (!this.unreadNotification.local) {
|
||||
|
@ -84,7 +87,7 @@ export default {
|
|||
})
|
||||
}
|
||||
|
||||
Event.$on('focus-timeline', () => {
|
||||
EventEmitter.on('focus-timeline', () => {
|
||||
// If focusedId does not change, we have to refresh focusedId because Toot component watch change events.
|
||||
const previousFocusedId = this.focusedId
|
||||
this.focusedId = 0
|
||||
|
@ -114,15 +117,15 @@ export default {
|
|||
this.scrollPosition.prepare()
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
if (!this.unreadNotification.local) {
|
||||
this.$store.dispatch('TimelineSpace/stopLocalStreaming')
|
||||
this.$store.dispatch('TimelineSpace/unbindLocalStreaming')
|
||||
}
|
||||
Event.$off('focus-timeline')
|
||||
EventEmitter.off('focus-timeline')
|
||||
this.observer.disconnect()
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.$store.commit('TimelineSpace/Contents/Local/changeHeading', true)
|
||||
this.$store.commit('TimelineSpace/Contents/Local/archiveTimeline')
|
||||
if (!this.unreadNotification.local) {
|
||||
|
@ -245,7 +248,7 @@ export default {
|
|||
this.focusedId = message.uri + message.id
|
||||
},
|
||||
focusSidebar() {
|
||||
Event.$emit('focus-sidebar')
|
||||
EventEmitter.emit('focus-sidebar')
|
||||
},
|
||||
handleKey(event) {
|
||||
switch (event.srcKey) {
|
||||
|
@ -294,6 +297,11 @@ export default {
|
|||
right: calc(20px + var(--current-sidebar-width));
|
||||
transition: all 0.5s;
|
||||
}
|
||||
|
||||
.upper-icon {
|
||||
padding: 3px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" src="@/assets/timeline-transition.scss"></style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div id="mentions" v-shortkey="shortcutEnabled ? { next: ['j'] } : {}" @shortkey="handleKey">
|
||||
<div v-shortkey="{ linux: ['ctrl', 'r'], mac: ['meta', 'r'] }" @shortkey="reload()"></div>
|
||||
<div id="mentions">
|
||||
<div></div>
|
||||
<DynamicScroller :items="mentions" :min-item-size="86" id="scroller" class="scroller" ref="scroller">
|
||||
<template v-slot="{ item, index, active }">
|
||||
<template v-if="item.id === 'loading-card'">
|
||||
|
@ -28,7 +28,9 @@
|
|||
</template>
|
||||
</DynamicScroller>
|
||||
<div :class="openSideBar ? 'upper-with-side-bar' : 'upper'" v-show="!heading">
|
||||
<el-button type="primary" icon="el-icon-arrow-up" @click="upper" circle> </el-button>
|
||||
<el-button type="primary" @click="upper" circle>
|
||||
<font-awesome-icon icon="angle-up" class="upper-icon" />
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -39,13 +41,10 @@ import moment from 'moment'
|
|||
import Notification from '~/src/renderer/components/organisms/Notification'
|
||||
import StatusLoading from '~/src/renderer/components/organisms/StatusLoading'
|
||||
import reloadable from '~/src/renderer/components/mixins/reloadable'
|
||||
import { Event } from '~/src/renderer/components/event'
|
||||
import { EventEmitter } from '~/src/renderer/components/event'
|
||||
import { ScrollPosition } from '~/src/renderer/components/utils/scroll'
|
||||
|
||||
export default {
|
||||
name: 'mentions',
|
||||
components: { Notification, StatusLoading },
|
||||
mixins: [reloadable],
|
||||
data() {
|
||||
return {
|
||||
focusedId: null,
|
||||
|
@ -56,6 +55,9 @@ export default {
|
|||
loadingMore: false
|
||||
}
|
||||
},
|
||||
name: 'mentions',
|
||||
components: { Notification, StatusLoading },
|
||||
mixins: [reloadable],
|
||||
computed: {
|
||||
...mapState('App', {
|
||||
backgroundColor: state => state.theme.background_color
|
||||
|
@ -88,7 +90,7 @@ export default {
|
|||
mounted() {
|
||||
this.$store.commit('TimelineSpace/SideMenu/changeUnreadMentions', false)
|
||||
document.getElementById('scroller').addEventListener('scroll', this.onScroll)
|
||||
Event.$on('focus-timeline', () => {
|
||||
EventEmitter.on('focus-timeline', () => {
|
||||
// If focusedId does not change, we have to refresh focusedId because Toot component watch change events.
|
||||
const previousFocusedId = this.focusedId
|
||||
this.focusedId = 0
|
||||
|
@ -122,11 +124,11 @@ export default {
|
|||
this.scrollPosition.prepare()
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
Event.$off('focus-timeline')
|
||||
beforeUnmount() {
|
||||
EventEmitter.off('focus-timeline')
|
||||
this.observer.disconnect()
|
||||
},
|
||||
destroyed() {
|
||||
unounted() {
|
||||
this.$store.commit('TimelineSpace/Contents/Mentions/changeHeading', true)
|
||||
this.$store.commit('TimelineSpace/Contents/Mentions/archiveMentions')
|
||||
if (document.getElementById('scroller') !== undefined && document.getElementById('scroller') !== null) {
|
||||
|
@ -149,10 +151,13 @@ export default {
|
|||
this.$store.commit('TimelineSpace/Contents/Mentions/changeHeading', true)
|
||||
}
|
||||
},
|
||||
mentions: function (newState, _oldState) {
|
||||
if (this.heading && newState.length > 0) {
|
||||
this.$store.dispatch('TimelineSpace/Contents/Mentions/saveMarker')
|
||||
}
|
||||
mentions: {
|
||||
handler(newState, _oldState) {
|
||||
if (this.heading && newState.length > 0) {
|
||||
this.$store.dispatch('TimelineSpace/Contents/Mentions/saveMarker')
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -249,7 +254,7 @@ export default {
|
|||
this.focusedId = message.id
|
||||
},
|
||||
focusSidebar() {
|
||||
Event.$emit('focus-sidebar')
|
||||
EventEmitter.emit('focus-sidebar')
|
||||
},
|
||||
handleKey(event) {
|
||||
switch (event.srcKey) {
|
||||
|
@ -298,6 +303,11 @@ export default {
|
|||
right: calc(20px + var(--current-sidebar-width));
|
||||
transition: all 0.5s;
|
||||
}
|
||||
|
||||
.upper-icon {
|
||||
padding: 3px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" src="@/assets/timeline-transition.scss"></style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div id="notifications" v-shortkey="shortcutEnabled ? { next: ['j'] } : {}" @shortkey="handleKey">
|
||||
<div v-shortkey="{ linux: ['ctrl', 'r'], mac: ['meta', 'r'] }" @shortkey="reload()"></div>
|
||||
<div id="notifications">
|
||||
<div></div>
|
||||
<DynamicScroller :items="handledNotifications" :min-item-size="20" id="scroller" class="scroller" ref="scroller">
|
||||
<template v-slot="{ item, index, active }">
|
||||
<template v-if="item.id === 'loading-card'">
|
||||
|
@ -27,7 +27,9 @@
|
|||
</template>
|
||||
</DynamicScroller>
|
||||
<div :class="openSideBar ? 'upper-with-side-bar' : 'upper'" v-show="!heading">
|
||||
<el-button type="primary" icon="el-icon-arrow-up" @click="upper" circle> </el-button>
|
||||
<el-button type="primary" @click="upper" circle>
|
||||
<font-awesome-icon icon="angle-up" class="upper-icon" />
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -38,13 +40,10 @@ import moment from 'moment'
|
|||
import Notification from '~/src/renderer/components/organisms/Notification'
|
||||
import StatusLoading from '~/src/renderer/components/organisms/StatusLoading'
|
||||
import reloadable from '~/src/renderer/components/mixins/reloadable'
|
||||
import { Event } from '~/src/renderer/components/event'
|
||||
import { EventEmitter } from '~/src/renderer/components/event'
|
||||
import { ScrollPosition } from '~/src/renderer/components/utils/scroll'
|
||||
|
||||
export default {
|
||||
name: 'notifications',
|
||||
components: { Notification, StatusLoading },
|
||||
mixins: [reloadable],
|
||||
data() {
|
||||
return {
|
||||
focusedId: null,
|
||||
|
@ -55,6 +54,9 @@ export default {
|
|||
loadingMore: false
|
||||
}
|
||||
},
|
||||
name: 'notifications',
|
||||
components: { Notification, StatusLoading },
|
||||
mixins: [reloadable],
|
||||
computed: {
|
||||
...mapState({
|
||||
openSideBar: state => state.TimelineSpace.Contents.SideBar.openSideBar,
|
||||
|
@ -86,7 +88,7 @@ export default {
|
|||
this.$store.dispatch('TimelineSpace/Contents/Notifications/resetBadge')
|
||||
document.getElementById('scroller').addEventListener('scroll', this.onScroll)
|
||||
|
||||
Event.$on('focus-timeline', () => {
|
||||
EventEmitter.on('focus-timeline', () => {
|
||||
// If focusedId does not change, we have to refresh focusedId because Toot component watch change events.
|
||||
const previousFocusedId = this.focusedId
|
||||
this.focusedId = 0
|
||||
|
@ -120,11 +122,11 @@ export default {
|
|||
this.scrollPosition.prepare()
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
Event.$off('focus-timeline')
|
||||
beforeUnmount() {
|
||||
EventEmitter.off('focus-timeline')
|
||||
this.observer.disconnect()
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.$store.commit('TimelineSpace/Contents/Notifications/changeHeading', true)
|
||||
this.$store.commit('TimelineSpace/Contents/Notifications/archiveNotifications')
|
||||
if (document.getElementById('scroller') !== undefined && document.getElementById('scroller') !== null) {
|
||||
|
@ -148,10 +150,13 @@ export default {
|
|||
this.$store.dispatch('TimelineSpace/Contents/Notifications/resetBadge')
|
||||
}
|
||||
},
|
||||
notifications: function (newState, _oldState) {
|
||||
if (this.heading && newState.length > 0) {
|
||||
this.$store.dispatch('TimelineSpace/Contents/Notifications/saveMarker')
|
||||
}
|
||||
notifications: {
|
||||
handler(newState, _oldState) {
|
||||
if (this.heading && newState.length > 0) {
|
||||
this.$store.dispatch('TimelineSpace/Contents/Notifications/saveMarker')
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -252,7 +257,7 @@ export default {
|
|||
this.focusedId = notification.id
|
||||
},
|
||||
focusSidebar() {
|
||||
Event.$emit('focus-sidebar')
|
||||
EventEmitter.emit('focus-sidebar')
|
||||
},
|
||||
handleKey(event) {
|
||||
switch (event.srcKey) {
|
||||
|
@ -295,6 +300,11 @@ export default {
|
|||
right: calc(20px + var(--current-sidebar-width));
|
||||
transition: all 0.5s;
|
||||
}
|
||||
|
||||
.upper-icon {
|
||||
padding: 3px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" src="@/assets/timeline-transition.scss"></style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div id="public" v-shortkey="shortcutEnabled ? { next: ['j'] } : {}" @shortkey="handleKey">
|
||||
<div v-shortkey="{ linux: ['ctrl', 'r'], mac: ['meta', 'r'] }" @shortkey="reload()"></div>
|
||||
<div id="public">
|
||||
<div></div>
|
||||
<DynamicScroller :items="timeline" :min-item-size="86" id="scroller" class="scroller" ref="scroller">
|
||||
<template v-slot="{ item, index, active }">
|
||||
<DynamicScrollerItem :item="item" :active="active" :size-dependencies="[item.uri]" :data-index="index" :watchData="true">
|
||||
|
@ -22,7 +22,9 @@
|
|||
</template>
|
||||
</DynamicScroller>
|
||||
<div :class="openSideBar ? 'upper-with-side-bar' : 'upper'" v-show="!heading">
|
||||
<el-button type="primary" icon="el-icon-arrow-up" @click="upper" circle> </el-button>
|
||||
<el-button type="primary" @click="upper" circle>
|
||||
<font-awesome-icon icon="angle-up" class="upper-icon" />
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -32,13 +34,10 @@ import { mapState, mapGetters } from 'vuex'
|
|||
import moment from 'moment'
|
||||
import Toot from '~/src/renderer/components/organisms/Toot'
|
||||
import reloadable from '~/src/renderer/components/mixins/reloadable'
|
||||
import { Event } from '~/src/renderer/components/event'
|
||||
import { EventEmitter } from '~/src/renderer/components/event'
|
||||
import { ScrollPosition } from '~/src/renderer/components/utils/scroll'
|
||||
|
||||
export default {
|
||||
name: 'public',
|
||||
components: { Toot },
|
||||
mixins: [reloadable],
|
||||
data() {
|
||||
return {
|
||||
focusedId: null,
|
||||
|
@ -48,6 +47,9 @@ export default {
|
|||
resizeTime: null
|
||||
}
|
||||
},
|
||||
name: 'public',
|
||||
components: { Toot },
|
||||
mixins: [reloadable],
|
||||
computed: {
|
||||
...mapState('TimelineSpace/Contents/Public', {
|
||||
timeline: state => state.timeline,
|
||||
|
@ -85,7 +87,7 @@ export default {
|
|||
})
|
||||
}
|
||||
|
||||
Event.$on('focus-timeline', () => {
|
||||
EventEmitter.on('focus-timeline', () => {
|
||||
// If focusedId does not change, we have to refresh focusedId because Toot component watch change events.
|
||||
const previousFocusedId = this.focusedId
|
||||
this.focusedId = 0
|
||||
|
@ -115,15 +117,15 @@ export default {
|
|||
this.scrollPosition.prepare()
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
if (!this.unreadNotification.public) {
|
||||
this.$store.dispatch('TimelineSpace/stopPublicStreaming')
|
||||
this.$store.dispatch('TimelineSpace/unbindPublicStreaming')
|
||||
}
|
||||
Event.$off('focus-timeline')
|
||||
EventEmitter.off('focus-timeline')
|
||||
this.observer.disconnect()
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.$store.commit('TimelineSpace/Contents/Public/changeHeading', true)
|
||||
this.$store.commit('TimelineSpace/Contents/Public/archiveTimeline')
|
||||
if (!this.unreadNotification.public) {
|
||||
|
@ -248,7 +250,7 @@ export default {
|
|||
this.focusedId = message.uri + message.id
|
||||
},
|
||||
focusSidebar() {
|
||||
Event.$emit('focus-sidebar')
|
||||
EventEmitter.emit('focus-sidebar')
|
||||
},
|
||||
handleKey(event) {
|
||||
switch (event.srcKey) {
|
||||
|
@ -297,6 +299,11 @@ export default {
|
|||
right: calc(20px + var(--current-sidebar-width));
|
||||
transition: all 0.5s;
|
||||
}
|
||||
|
||||
.upper-icon {
|
||||
padding: 3px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" src="@/assets/timeline-transition.scss"></style>
|
||||
|
|
|
@ -2,17 +2,10 @@
|
|||
<div id="search">
|
||||
<div class="search-header">
|
||||
<el-form :inline="true">
|
||||
<el-select v-model="target" :placeholder="$t('search.search')" class="search-target">
|
||||
<el-select v-model="target" :placeholder="$t('search.search')" class="search-target" size="large">
|
||||
<el-option v-for="item in searchTargets" :key="item.target" :label="item.label" :value="item.target"> </el-option>
|
||||
</el-select>
|
||||
<input
|
||||
v-model="query"
|
||||
:placeholder="$t('search.keyword')"
|
||||
class="search-keyword"
|
||||
v-shortkey.avoid
|
||||
v-on:keyup.enter="search"
|
||||
autofocus
|
||||
/>
|
||||
<input v-model="query" :placeholder="$t('search.keyword')" class="search-keyword" v-on:keyup.enter="search" autofocus />
|
||||
<div class="clearfix"></div>
|
||||
</el-form>
|
||||
</div>
|
||||
|
@ -25,6 +18,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { ref } from 'vue'
|
||||
import SearchAccount from './Search/Account'
|
||||
import SearchTag from './Search/Tag'
|
||||
import SearchToots from './Search/Toots'
|
||||
|
@ -34,28 +28,22 @@ export default {
|
|||
components: { SearchAccount, SearchTag, SearchToots },
|
||||
data() {
|
||||
return {
|
||||
target: 'account',
|
||||
query: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
searchTargets: {
|
||||
get() {
|
||||
return [
|
||||
{
|
||||
target: 'account',
|
||||
label: this.$t('search.account')
|
||||
},
|
||||
{
|
||||
target: 'tag',
|
||||
label: this.$t('search.tag')
|
||||
},
|
||||
{
|
||||
target: 'toot',
|
||||
label: this.$t('search.toot')
|
||||
}
|
||||
]
|
||||
}
|
||||
target: ref('account'),
|
||||
query: '',
|
||||
searchTargets: [
|
||||
{
|
||||
target: 'account',
|
||||
label: this.$t('search.account')
|
||||
},
|
||||
{
|
||||
target: 'tag',
|
||||
label: this.$t('search.tag')
|
||||
},
|
||||
{
|
||||
target: 'toot',
|
||||
label: this.$t('search.toot')
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -95,22 +83,21 @@ export default {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
#search {
|
||||
border-top: 1px solid var(--theme-border-color);
|
||||
|
||||
.search-header {
|
||||
background-color: var(--theme-selected-background-color);
|
||||
padding: 8px 12px;
|
||||
|
||||
.search-target /deep/ {
|
||||
.search-target {
|
||||
float: left;
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.el-input__inner {
|
||||
background-color: var(--theme-background-color);
|
||||
border: none;
|
||||
border-radius: 4px 0 0 4px;
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
.search-target :deep(.el-input__inner) {
|
||||
background-color: var(--theme-background-color);
|
||||
border: none;
|
||||
border-radius: 4px 0 0 4px;
|
||||
color: var(--theme-primary-color);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.search-keyword {
|
||||
|
|
|
@ -22,10 +22,8 @@ export default {
|
|||
results: state => state.TimelineSpace.Contents.Search.Account.results
|
||||
})
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.$store.commit('TimelineSpace/Contents/Search/Account/updateResults', [])
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
|
@ -22,7 +22,7 @@ export default {
|
|||
results: state => state.results
|
||||
})
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.$store.commit('TimelineSpace/Contents/Search/Tag/updateResults', [])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,10 +22,8 @@ export default {
|
|||
results: state => state.TimelineSpace.Contents.Search.Toots.results
|
||||
})
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.$store.commit('TimelineSpace/Contents/Search/Toots/updateResults', [])
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
<template>
|
||||
<div class="side-bar" v-if="openSideBar" v-shortkey="shortcutEnabled ? { close: ['esc'] } : {}" @shortkey="handleKey">
|
||||
<div class="side-bar" v-if="openSideBar">
|
||||
<div class="header">
|
||||
<i class="el-icon-loading" v-show="loading"></i>
|
||||
<i class="el-icon-refresh" @click="reload"></i>
|
||||
<i class="el-icon-close" @click="close"></i>
|
||||
<el-button type="text" @click="reload" class="action">
|
||||
<font-awesome-icon icon="rotate" />
|
||||
</el-button>
|
||||
<el-button type="text" @click="close" class="action">
|
||||
<font-awesome-icon icon="xmark" />
|
||||
</el-button>
|
||||
</div>
|
||||
<div id="sidebar_scrollable">
|
||||
<account-profile v-if="component === 1" v-on:change-loading="changeLoading"></account-profile>
|
||||
|
@ -26,11 +29,11 @@ import TootDetail from './SideBar/TootDetail'
|
|||
import AccountProfile from './SideBar/AccountProfile'
|
||||
|
||||
export default {
|
||||
name: 'side-bar',
|
||||
components: {
|
||||
TootDetail,
|
||||
AccountProfile
|
||||
},
|
||||
name: 'side-bar',
|
||||
props: {
|
||||
overlaid: {
|
||||
type: Boolean,
|
||||
|
@ -48,11 +51,11 @@ export default {
|
|||
component: state => state.TimelineSpace.Contents.SideBar.component,
|
||||
backgroundColor: state => state.App.theme.background_color
|
||||
}),
|
||||
shortcutEnabled: function() {
|
||||
shortcutEnabled: function () {
|
||||
return !this.overlaid
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
this.close()
|
||||
},
|
||||
methods: {
|
||||
|
@ -88,12 +91,14 @@ export default {
|
|||
box-sizing: border-box;
|
||||
font-size: 18px;
|
||||
|
||||
.el-icon-close {
|
||||
cursor: pointer;
|
||||
}
|
||||
.action {
|
||||
color: var(--theme-secondary-color);
|
||||
padding: 0;
|
||||
margin-left: 8px;
|
||||
|
||||
.el-icon-refresh {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<div class="relationship" v-if="relationship !== null && relationship !== '' && !isOwnProfile">
|
||||
<div class="follower-status">
|
||||
<el-tag class="status" size="small" v-if="relationship.followed_by">{{ $t('side_bar.account_profile.follows_you') }}</el-tag>
|
||||
<el-tag class="status" size="medium" v-else>{{ $t('side_bar.account_profile.doesnt_follow_you') }}</el-tag>
|
||||
<el-tag class="status" size="default" v-else>{{ $t('side_bar.account_profile.doesnt_follow_you') }}</el-tag>
|
||||
</div>
|
||||
<div class="notify" v-if="relationship !== null && relationship !== '' && !isOwnProfile">
|
||||
<div
|
||||
|
@ -22,44 +22,44 @@
|
|||
@click="unsubscribe(account)"
|
||||
:title="$t('side_bar.account_profile.unsubscribe')"
|
||||
>
|
||||
<font-awesome-icon icon="bell" size="xl" />
|
||||
<font-awesome-icon icon="bell" size="lg" />
|
||||
</div>
|
||||
<div v-else class="subscribe" @click="subscribe(account)" :title="$t('side_bar.account_profile.subscribe')">
|
||||
<font-awesome-icon :icon="['far', 'bell']" size="xl" />
|
||||
<font-awesome-icon :icon="['far', 'bell']" size="lg" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="user-info">
|
||||
<div class="more" v-if="relationship !== null && relationship !== '' && !isOwnProfile">
|
||||
<popper trigger="click" :options="{ placement: 'bottom' }" ref="popper">
|
||||
<div class="popper">
|
||||
<ul class="menu-list">
|
||||
<li role="button" @click="openBrowser(account)">
|
||||
{{ $t('side_bar.account_profile.open_in_browser') }}
|
||||
</li>
|
||||
<li role="button" @click="addToList(account)">
|
||||
{{ $t('side_bar.account_profile.manage_list_memberships') }}
|
||||
</li>
|
||||
<li role="button" @click="unmute(account)" v-if="muting">
|
||||
{{ $t('side_bar.account_profile.unmute') }}
|
||||
</li>
|
||||
<li role="button" @click="confirmMute(account)" v-else>
|
||||
{{ $t('side_bar.account_profile.mute') }}
|
||||
</li>
|
||||
<li role="button" @click="unblock(account)" v-if="blocking">
|
||||
{{ $t('side_bar.account_profile.unblock') }}
|
||||
</li>
|
||||
<li role="button" @click="block(account)" v-else>
|
||||
{{ $t('side_bar.account_profile.block') }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<el-popover placement="bottom" width="200" trigger="click" popper-class="account-menu-popper">
|
||||
<ul class="menu-list">
|
||||
<li role="button" @click="openBrowser(account)">
|
||||
{{ $t('side_bar.account_profile.open_in_browser') }}
|
||||
</li>
|
||||
<li role="button" @click="addToList(account)">
|
||||
{{ $t('side_bar.account_profile.manage_list_memberships') }}
|
||||
</li>
|
||||
<li role="button" @click="unmute(account)" v-if="muting">
|
||||
{{ $t('side_bar.account_profile.unmute') }}
|
||||
</li>
|
||||
<li role="button" @click="confirmMute(account)" v-else>
|
||||
{{ $t('side_bar.account_profile.mute') }}
|
||||
</li>
|
||||
<li role="button" @click="unblock(account)" v-if="blocking">
|
||||
{{ $t('side_bar.account_profile.unblock') }}
|
||||
</li>
|
||||
<li role="button" @click="block(account)" v-else>
|
||||
{{ $t('side_bar.account_profile.block') }}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<el-button slot="reference" type="text" :title="$t('side_bar.account_profile.detail')">
|
||||
<font-awesome-icon icon="gear" size="xl" />
|
||||
</el-button>
|
||||
</popper>
|
||||
<template #reference>
|
||||
<el-button type="text" :title="$t('side_bar.account_profile.detail')">
|
||||
<font-awesome-icon icon="gear" size="xl" />
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popover>
|
||||
</div>
|
||||
<div class="icon" role="presentation">
|
||||
<FailoverImg :src="account.avatar" :alt="`Avatar of ${account.username}`" />
|
||||
|
@ -88,7 +88,9 @@
|
|||
<dt>
|
||||
{{ identity.provider }}
|
||||
</dt>
|
||||
<dd @click.capture.prevent="identityOpen(identity.profile_url)">{{ identity.provider_username }}</dd>
|
||||
<dd @click.capture.prevent="identityOpen(identity.profile_url)">
|
||||
{{ identity.provider_username }}
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="metadata">
|
||||
|
@ -114,7 +116,9 @@
|
|||
</el-col>
|
||||
<el-col :span="8" :class="activeTab === 3 ? 'info info-active' : 'info'">
|
||||
<el-button type="text" class="tab" @click="changeTab(3)">
|
||||
<div class="title">{{ $t('side_bar.account_profile.followers') }}</div>
|
||||
<div class="title">
|
||||
{{ $t('side_bar.account_profile.followers') }}
|
||||
</div>
|
||||
<div class="count">{{ account.followers_count }}</div>
|
||||
</el-button>
|
||||
</el-col>
|
||||
|
@ -225,29 +229,23 @@ export default {
|
|||
},
|
||||
openBrowser(account) {
|
||||
window.shell.openExternal(account.url)
|
||||
this.$refs.popper.doClose()
|
||||
},
|
||||
addToList(account) {
|
||||
this.$store.dispatch('TimelineSpace/Modals/ListMembership/setAccount', account)
|
||||
this.$store.dispatch('TimelineSpace/Modals/ListMembership/changeModal', true)
|
||||
this.$refs.popper.doClose()
|
||||
},
|
||||
confirmMute(account) {
|
||||
this.$store.dispatch('TimelineSpace/Modals/MuteConfirm/changeAccount', account)
|
||||
this.$store.dispatch('TimelineSpace/Modals/MuteConfirm/changeModal', true)
|
||||
this.$refs.popper.doClose()
|
||||
},
|
||||
unmute(account) {
|
||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/unmute', account)
|
||||
this.$refs.popper.doClose()
|
||||
},
|
||||
block(account) {
|
||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/block', account)
|
||||
this.$refs.popper.doClose()
|
||||
},
|
||||
unblock(account) {
|
||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/unblock', account)
|
||||
this.$refs.popper.doClose()
|
||||
},
|
||||
metadataClick(e) {
|
||||
const link = findLink(e.target, 'metadata')
|
||||
|
@ -340,34 +338,6 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.more {
|
||||
.popper {
|
||||
padding: 2px 0;
|
||||
border-color: #909399;
|
||||
}
|
||||
|
||||
.menu-list {
|
||||
padding: 0;
|
||||
font-size: calc(var(--base-font-size) * 0.9);
|
||||
list-style-type: none;
|
||||
line-height: 32px;
|
||||
text-align: left;
|
||||
color: #303133;
|
||||
margin: 4px 0;
|
||||
|
||||
li {
|
||||
box-sizing: border-box;
|
||||
padding: 0 32px 0 16px;
|
||||
|
||||
&:hover {
|
||||
background-color: #409eff;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
padding: 12px;
|
||||
|
||||
|
@ -378,27 +348,25 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.username /deep/ {
|
||||
.username {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: calc(var(--base-font-size) * 1.71);
|
||||
margin: 0 auto 12px auto;
|
||||
}
|
||||
|
||||
.emojione {
|
||||
max-width: 1em;
|
||||
max-height: 1em;
|
||||
}
|
||||
.username :deep(.emojione) {
|
||||
max-width: 1em;
|
||||
max-height: 1em;
|
||||
}
|
||||
|
||||
.account {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.note {
|
||||
& /deep/ .emojione {
|
||||
max-width: 1.2em;
|
||||
height: 1.2em;
|
||||
}
|
||||
.note :deep(.emojione) {
|
||||
max-width: 1.2em;
|
||||
height: 1.2em;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -477,6 +445,12 @@ export default {
|
|||
width: 100%;
|
||||
text-align: left;
|
||||
line-height: 20px;
|
||||
height: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tab :deep(span) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.title {
|
||||
|
@ -509,3 +483,31 @@ export default {
|
|||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.account-menu-popper {
|
||||
padding: 2px 0 !important;
|
||||
border-color: #909399;
|
||||
|
||||
.menu-list {
|
||||
padding: 0;
|
||||
font-size: calc(var(--base-font-size) * 0.9);
|
||||
list-style-type: none;
|
||||
line-height: 32px;
|
||||
text-align: left;
|
||||
color: #303133;
|
||||
margin: 4px 0;
|
||||
|
||||
li {
|
||||
box-sizing: border-box;
|
||||
padding: 0 32px 0 16px;
|
||||
|
||||
&:hover {
|
||||
background-color: #409eff;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -41,7 +41,7 @@ export default {
|
|||
mounted() {
|
||||
document.getElementById('sidebar_scrollable').addEventListener('scroll', this.onScroll)
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
if (document.getElementById('sidebar_scrollable') !== undefined && document.getElementById('sidebar_scrollable') !== null) {
|
||||
document.getElementById('sidebar_scrollable').removeEventListener('scroll', this.onScroll)
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ export default {
|
|||
mounted() {
|
||||
document.getElementById('sidebar_scrollable').addEventListener('scroll', this.onScroll)
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
if (document.getElementById('sidebar_scrollable') !== undefined && document.getElementById('sidebar_scrollable') !== null) {
|
||||
document.getElementById('sidebar_scrollable').removeEventListener('scroll', this.onScroll)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="tabs" id="sidebar_tabs">
|
||||
<el-tabs v-model="activeName" @tab-click="handleClick" stretch>
|
||||
<div id="sidebar_tabs">
|
||||
<el-tabs :model-value="activeName" @tab-click="handleClick" class="tabs">
|
||||
<el-tab-pane label="Posts" name="posts"><Posts :account="account" :buffer="buffer" :filters="filters" /></el-tab-pane>
|
||||
<el-tab-pane label="Posts and replies" name="posts_and_replies"
|
||||
><PostsAndReplies :account="account" :buffer="buffer" :filters="filters"
|
||||
|
@ -49,7 +49,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tabs /deep/ {
|
||||
.tabs :deep() {
|
||||
.el-tabs__header {
|
||||
background-color: var(--theme-selected-background-color);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<script>
|
||||
import { mapState, mapGetters } from 'vuex'
|
||||
import Toot from '~/src/renderer/components/organisms/Toot'
|
||||
import { Event } from '~/src/renderer/components/event'
|
||||
import { EventEmitter } from '~/src/renderer/components/event'
|
||||
|
||||
export default {
|
||||
name: 'media',
|
||||
|
@ -54,18 +54,18 @@ export default {
|
|||
mounted() {
|
||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/Timeline/Media/clearTimeline')
|
||||
document.getElementById('sidebar_scrollable').addEventListener('scroll', this.onScroll)
|
||||
Event.$on('focus-sidebar', () => {
|
||||
EventEmitter.on('focus-sidebar', () => {
|
||||
this.focusedId = 0
|
||||
this.$nextTick(function () {
|
||||
this.focusedId = this.timeline[0].uri + this.timeline[0].id
|
||||
})
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
Event.$emit('focus-timeline')
|
||||
Event.$off('focus-sidebar')
|
||||
beforeUnmount() {
|
||||
EventEmitter.emit('focus-timeline')
|
||||
EventEmitter.off('focus-sidebar')
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
if (document.getElementById('sidebar_scrollable') !== undefined && document.getElementById('sidebar_scrollable') !== null) {
|
||||
document.getElementById('sidebar_scrollable').removeEventListener('scroll', this.onScroll)
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ export default {
|
|||
},
|
||||
focusTimeline() {
|
||||
this.focusedId = 0
|
||||
Event.$emit('focus-timeline')
|
||||
EventEmitter.emit('focus-timeline')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
<template>
|
||||
<div id="timeline">
|
||||
<template v-for="message in pinnedToots">
|
||||
<template v-for="message in pinnedToots" :key="message.id">
|
||||
<toot
|
||||
:message="message"
|
||||
:key="message.id"
|
||||
:focused="message.uri + message.id === focusedId"
|
||||
:pinned="true"
|
||||
:overlaid="modalOpened"
|
||||
|
@ -44,7 +43,7 @@
|
|||
<script>
|
||||
import { mapState, mapGetters } from 'vuex'
|
||||
import Toot from '~/src/renderer/components/organisms/Toot'
|
||||
import { Event } from '~/src/renderer/components/event'
|
||||
import { EventEmitter } from '~/src/renderer/components/event'
|
||||
|
||||
export default {
|
||||
name: 'posts',
|
||||
|
@ -72,18 +71,18 @@ export default {
|
|||
mounted() {
|
||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/Timeline/Posts/clearTimeline')
|
||||
document.getElementById('sidebar_scrollable').addEventListener('scroll', this.onScroll)
|
||||
Event.$on('focus-sidebar', () => {
|
||||
EventEmitter.on('focus-sidebar', () => {
|
||||
this.focusedId = 0
|
||||
this.$nextTick(function () {
|
||||
this.focusedId = this.timeline[0].uri + this.timeline[0].id
|
||||
})
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
Event.$emit('focus-timeline')
|
||||
Event.$off('focus-sidebar')
|
||||
beforeUnmount() {
|
||||
EventEmitter.emit('focus-timeline')
|
||||
EventEmitter.off('focus-sidebar')
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
if (document.getElementById('sidebar_scrollable') !== undefined && document.getElementById('sidebar_scrollable') !== null) {
|
||||
document.getElementById('sidebar_scrollable').removeEventListener('scroll', this.onScroll)
|
||||
}
|
||||
|
@ -151,7 +150,7 @@ export default {
|
|||
},
|
||||
focusTimeline() {
|
||||
this.focusedId = 0
|
||||
Event.$emit('focus-timeline')
|
||||
EventEmitter.emit('focus-timeline')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<script>
|
||||
import { mapState, mapGetters } from 'vuex'
|
||||
import Toot from '~/src/renderer/components/organisms/Toot'
|
||||
import { Event } from '~/src/renderer/components/event'
|
||||
import { EventEmitter } from '~/src/renderer/components/event'
|
||||
|
||||
export default {
|
||||
name: 'posts-and-replies',
|
||||
|
@ -54,18 +54,18 @@ export default {
|
|||
mounted() {
|
||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/Timeline/PostsAndReplies/clearTimeline')
|
||||
document.getElementById('sidebar_scrollable').addEventListener('scroll', this.onScroll)
|
||||
Event.$on('focus-sidebar', () => {
|
||||
EventEmitter.on('focus-sidebar', () => {
|
||||
this.focusedId = 0
|
||||
this.$nextTick(function () {
|
||||
this.focusedId = this.timeline[0].uri + this.timeline[0].id
|
||||
})
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
Event.$emit('focus-timeline')
|
||||
Event.$off('focus-sidebar')
|
||||
beforeUnmount() {
|
||||
EventEmitter.emit('focus-timeline')
|
||||
EventEmitter.off('focus-sidebar')
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
if (document.getElementById('sidebar_scrollable') !== undefined && document.getElementById('sidebar_scrollable') !== null) {
|
||||
document.getElementById('sidebar_scrollable').removeEventListener('scroll', this.onScroll)
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ export default {
|
|||
},
|
||||
focusTimeline() {
|
||||
this.focusedId = 0
|
||||
Event.$emit('focus-timeline')
|
||||
EventEmitter.emit('focus-timeline')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
<script>
|
||||
import { mapState, mapGetters } from 'vuex'
|
||||
import Toot from '~/src/renderer/components/organisms/Toot'
|
||||
import { Event } from '~/src/renderer/components/event'
|
||||
import { EventEmitter } from '~/src/renderer/components/event'
|
||||
|
||||
export default {
|
||||
name: 'toot-detail',
|
||||
|
@ -76,7 +76,7 @@ export default {
|
|||
this.load()
|
||||
},
|
||||
mounted() {
|
||||
Event.$on('focus-sidebar', () => {
|
||||
EventEmitter.on('focus-sidebar', () => {
|
||||
this.focusedId = 0
|
||||
this.$nextTick(function () {
|
||||
this.focusedId = this.timeline[0].uri + this.timeline[0].id
|
||||
|
@ -88,9 +88,9 @@ export default {
|
|||
this.load()
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
Event.$emit('focus-timeline')
|
||||
Event.$off('focus-sidebar')
|
||||
beforeUnmount() {
|
||||
EventEmitter.emit('focus-timeline')
|
||||
EventEmitter.off('focus-sidebar')
|
||||
},
|
||||
methods: {
|
||||
originalMessage(message) {
|
||||
|
@ -151,7 +151,7 @@ export default {
|
|||
},
|
||||
focusTimeline() {
|
||||
this.focusedId = 0
|
||||
Event.$emit('focus-timeline')
|
||||
EventEmitter.emit('focus-timeline')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,21 +11,23 @@
|
|||
<el-button v-show="reloadable()" type="text" class="action" @click="reload" :title="$t('header_menu.reload')">
|
||||
<font-awesome-icon icon="rotate" />
|
||||
</el-button>
|
||||
<el-popover placement="left-start" width="180" popper-class="theme-popover" trigger="click" v-model="TLOptionVisible">
|
||||
<el-popover v-if="TLOption()" placement="left-start" width="180" popper-class="theme-popover" trigger="click">
|
||||
<div>
|
||||
<el-form role="form" label-position="left" label-width="125px" size="medium">
|
||||
<el-form role="form" label-position="left" label-width="125px" size="default">
|
||||
<el-form-item for="show-reblogs" :label="$t('header_menu.option.show_reblogs')">
|
||||
<el-checkbox id="show-reblogs" v-model="showReblogs"></el-checkbox>
|
||||
<el-checkbox id="show-reblogs" :model-value="showReblogs"></el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item for="show-replies" :label="$t('header_menu.option.show_replies')">
|
||||
<el-checkbox id="show-replies" v-model="showReplies"></el-checkbox>
|
||||
<el-checkbox id="show-replies" :model-value="showReplies"></el-checkbox>
|
||||
</el-form-item>
|
||||
<el-button type="primary" @click="applyTLOption">{{ $t('header_menu.option.apply') }}</el-button>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-button v-show="TLOption()" slot="reference" type="text" class="action" :title="$t('header_menu.option.title')">
|
||||
<font-awesome-icon icon="sliders" />
|
||||
</el-button>
|
||||
<template #reference>
|
||||
<el-button type="text" class="action" :title="$t('header_menu.option.title')">
|
||||
<font-awesome-icon icon="sliders" />
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popover>
|
||||
<el-button type="text" class="action" @click="settings" :title="$t('header_menu.settings')">
|
||||
<font-awesome-icon icon="gear" />
|
||||
|
@ -41,7 +43,6 @@ export default {
|
|||
name: 'header-menu',
|
||||
data() {
|
||||
return {
|
||||
TLOptionVisible: false,
|
||||
showReblogs: true,
|
||||
showReplies: true
|
||||
}
|
||||
|
@ -177,7 +178,6 @@ export default {
|
|||
default:
|
||||
console.log('Not implemented')
|
||||
}
|
||||
this.TLOptionVisible = false
|
||||
},
|
||||
TLOption() {
|
||||
switch (this.$route.name) {
|
||||
|
@ -211,6 +211,7 @@ export default {
|
|||
|
||||
h1 {
|
||||
margin: 0;
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ export default {
|
|||
AddListMember,
|
||||
MuteConfirm,
|
||||
Shortcut,
|
||||
Report
|
||||
}
|
||||
Report,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,34 +1,36 @@
|
|||
<template>
|
||||
<el-dialog :title="$t('modals.add_list_member.title')" :visible.sync="addListMemberModal" width="400px" class="add-member">
|
||||
<div class="search-account" :element-loading-background="loadingBackground">
|
||||
<el-form :inline="true">
|
||||
<input v-model="name" placeholder="Account name" class="account-name" v-shortkey="['enter']" @shortkey="search" autofocus />
|
||||
<el-button type="text" class="search" @click="search">
|
||||
<font-awesome-icon icon="magnifying-glass" />
|
||||
</el-button>
|
||||
</el-form>
|
||||
<div class="search-results">
|
||||
<template v-for="user in accounts">
|
||||
<div class="user">
|
||||
<div class="icon">
|
||||
<img :src="user.avatar" />
|
||||
</div>
|
||||
<div class="name">
|
||||
<div class="username">
|
||||
{{ username(user) }}
|
||||
<div class="add-member">
|
||||
<el-dialog :title="$t('modals.add_list_member.title')" :model-value="addListMemberModal" width="400px" custom-class="add-member-modal">
|
||||
<div class="search-account" :element-loading-background="loadingBackground">
|
||||
<el-form :inline="true">
|
||||
<input v-model="name" placeholder="Account name" class="account-name" autofocus />
|
||||
<el-button type="text" class="search" @click="search">
|
||||
<font-awesome-icon icon="magnifying-glass" />
|
||||
</el-button>
|
||||
</el-form>
|
||||
<div class="search-results">
|
||||
<template v-for="user in accounts">
|
||||
<div class="user">
|
||||
<div class="icon">
|
||||
<img :src="user.avatar" />
|
||||
</div>
|
||||
<div class="name">
|
||||
<div class="username">
|
||||
{{ username(user) }}
|
||||
</div>
|
||||
<div class="acct">@{{ user.acct }}</div>
|
||||
</div>
|
||||
<div class="add">
|
||||
<el-button type="text" @click="add(user)">
|
||||
<font-awesome-icon icon="plus" />
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="acct">@{{ user.acct }}</div>
|
||||
</div>
|
||||
<div class="add">
|
||||
<el-button type="text" @click="add(user)">
|
||||
<font-awesome-icon icon="plus" />
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -86,9 +88,10 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.add-member /deep/ {
|
||||
.add-member :deep() {
|
||||
.el-dialog__header {
|
||||
background-color: var(--theme-header-menu-color);
|
||||
margin-right: 0;
|
||||
|
||||
.el-dialog__title {
|
||||
color: var(--theme-secondary-color);
|
||||
|
@ -100,7 +103,9 @@ export default {
|
|||
color: var(--theme-secondary-color);
|
||||
padding: 8px 12px 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.add-member-modal {
|
||||
.search-account {
|
||||
background-color: var(--theme-selected-background-color);
|
||||
|
||||
|
|
|
@ -1,18 +1,24 @@
|
|||
<template>
|
||||
<transition name="image-viewer">
|
||||
<div id="image" v-show="modalOpen" @click="close" :aria-hidden="!modalOpen" aria-modal="true" role="dialog">
|
||||
<div class="image-wrapper" v-shortkey="modalOpen ? {close: ['esc']} : {}" @shortkey="closeHandle">
|
||||
<div class="image-header">
|
||||
<el-button type="text" icon="el-icon-close" @click="close" class="close-button"></el-button>
|
||||
</div>
|
||||
<div class="image-content" role="presentation">
|
||||
<span class="button-area"><el-button type="text" v-show="showLeft" v-shortkey="['arrowleft']" @shortkey.native="decrementIndex()"><i class="el-icon-arrow-left" @click.stop="decrementIndex"></i></el-button></span>
|
||||
<Media :src="imageURL" :type="imageType"></Media>
|
||||
<span class="button-area"><el-button type="text" v-show="showRight" v-shortkey="['arrowright']" @shortkey.native="incrementIndex()"><i class="el-icon-arrow-right" @click.stop="incrementIndex"></i></el-button></span>
|
||||
<transition name="image-viewer">
|
||||
<div id="image" v-show="modalOpen" :aria-hidden="!modalOpen" aria-modal="true" role="dialog">
|
||||
<div class="image-wrapper">
|
||||
<div class="image-header">
|
||||
<el-button type="text" @click="close" class="close-button">
|
||||
<font-awesome-icon icon="xmark" />
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="image-content" role="presentation">
|
||||
<span class="button-area"
|
||||
><el-button type="text" v-show="showLeft" @click="decrementIndex()"> <font-awesome-icon icon="angle-left" /> </el-button
|
||||
></span>
|
||||
<Media :src="imageURL" :type="imageType"></Media>
|
||||
<span class="button-area"
|
||||
><el-button type="text" v-show="showRight" @click="incrementIndex()"> <font-awesome-icon icon="angle-right" /> </el-button
|
||||
></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -20,38 +26,38 @@ import Media from './Media'
|
|||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'image-viewer',
|
||||
components: {
|
||||
Media
|
||||
},
|
||||
name: 'image-viewer',
|
||||
computed: {
|
||||
...mapState({
|
||||
modalOpen: state => state.TimelineSpace.Modals.ImageViewer.modalOpen
|
||||
}),
|
||||
imageURL () {
|
||||
imageURL() {
|
||||
return this.$store.getters['TimelineSpace/Modals/ImageViewer/imageURL']
|
||||
},
|
||||
imageType () {
|
||||
imageType() {
|
||||
return this.$store.getters['TimelineSpace/Modals/ImageViewer/imageType']
|
||||
},
|
||||
showLeft () {
|
||||
showLeft() {
|
||||
return this.$store.getters['TimelineSpace/Modals/ImageViewer/showLeft']
|
||||
},
|
||||
showRight () {
|
||||
showRight() {
|
||||
return this.$store.getters['TimelineSpace/Modals/ImageViewer/showRight']
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
close () {
|
||||
close() {
|
||||
this.$store.dispatch('TimelineSpace/Modals/ImageViewer/closeModal')
|
||||
},
|
||||
decrementIndex () {
|
||||
decrementIndex() {
|
||||
if (this.showLeft) this.$store.dispatch('TimelineSpace/Modals/ImageViewer/decrementIndex')
|
||||
},
|
||||
incrementIndex () {
|
||||
incrementIndex() {
|
||||
if (this.showRight) this.$store.dispatch('TimelineSpace/Modals/ImageViewer/incrementIndex')
|
||||
},
|
||||
closeHandle (event) {
|
||||
closeHandle(event) {
|
||||
switch (event.srcKey) {
|
||||
case 'close':
|
||||
this.close()
|
||||
|
@ -75,7 +81,7 @@ export default {
|
|||
.image-header {
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
padding: 8px 8px 0 0 ;
|
||||
padding: 8px 8px 0 0;
|
||||
color: #409eff;
|
||||
box-sizing: border-box;
|
||||
position: fixed;
|
||||
|
@ -93,17 +99,21 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.image-viewer-enter-active, .image-viewer-leave-active {
|
||||
.image-viewer-enter-active,
|
||||
.image-viewer-leave-active {
|
||||
transition: opacity 0.5s;
|
||||
}
|
||||
.image-viewer-enter, .image-viewer-leave-to {
|
||||
.image-viewer-enter,
|
||||
.image-viewer-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.button-area {
|
||||
display: inline-block;
|
||||
width: 52px;
|
||||
height: 77px;
|
||||
i {
|
||||
width: 27px;
|
||||
margin: 0 12px;
|
||||
|
||||
svg {
|
||||
font-size: 50px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,17 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
:visible.sync="jumpModal"
|
||||
width="440px"
|
||||
class="jump-modal">
|
||||
<el-dialog :model-value="jumpModal" width="440px" class="jump-modal">
|
||||
<el-form class="jump-form" v-on:submit.prevent="jump">
|
||||
<div class="channel">
|
||||
<input
|
||||
type="text"
|
||||
v-model="channel"
|
||||
:placeholder="$t('modals.jump.jump_to')"
|
||||
ref="channel"
|
||||
v-shortkey="shortcutEnabled ? {next: ['arrowdown'], prev: ['arrowup'], select: ['enter']} : {}"
|
||||
@shortkey="handleKey"
|
||||
/>
|
||||
<input type="text" v-model="channel" :placeholder="$t('modals.jump.jump_to')" ref="channel" />
|
||||
<ul class="channel-list">
|
||||
<li v-for="c in filterdChannel" :class="c.name === selectedChannel.name ? 'channel-list-item selected' : 'channel-list-item'" @click="jump(c)" @mouseover="changeSelected(c)">{{ c.name }}</li>
|
||||
<li
|
||||
v-for="c in filterdChannel"
|
||||
:class="c.name === selectedChannel.name ? 'channel-list-item selected' : 'channel-list-item'"
|
||||
@click="jump(c)"
|
||||
@mouseover="changeSelected(c)"
|
||||
>
|
||||
{{ c.name }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Dummy form to guard submitting with enter -->
|
||||
|
@ -36,21 +33,21 @@ export default {
|
|||
selectedChannel: state => state.selectedChannel
|
||||
}),
|
||||
channel: {
|
||||
get () {
|
||||
get() {
|
||||
return this.$store.state.TimelineSpace.Modals.Jump.channel
|
||||
},
|
||||
set (value) {
|
||||
set(value) {
|
||||
this.$store.commit('TimelineSpace/Modals/Jump/updateChannel', value)
|
||||
}
|
||||
},
|
||||
filterdChannel () {
|
||||
filterdChannel() {
|
||||
return this.filterChannelForm()
|
||||
},
|
||||
jumpModal: {
|
||||
get () {
|
||||
get() {
|
||||
return this.$store.state.TimelineSpace.Modals.Jump.modalOpen
|
||||
},
|
||||
set (value) {
|
||||
set(value) {
|
||||
this.$store.commit('TimelineSpace/Modals/Jump/changeModal', value)
|
||||
}
|
||||
},
|
||||
|
@ -75,41 +72,41 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
filterChannelForm () {
|
||||
return this.channelList.filter((c) => {
|
||||
filterChannelForm() {
|
||||
return this.channelList.filter(c => {
|
||||
return c.name.toLowerCase().indexOf(this.channel.toLowerCase()) !== -1
|
||||
})
|
||||
},
|
||||
nextChannel () {
|
||||
nextChannel() {
|
||||
const filterd = this.filterChannelForm()
|
||||
const i = filterd.findIndex((e) => {
|
||||
const i = filterd.findIndex(e => {
|
||||
return e.name === this.selectedChannel.name
|
||||
})
|
||||
if (i !== undefined && i < (filterd.length - 1)) {
|
||||
if (i !== undefined && i < filterd.length - 1) {
|
||||
this.$store.commit('TimelineSpace/Modals/Jump/changeSelected', filterd[i + 1])
|
||||
}
|
||||
},
|
||||
prevChannel () {
|
||||
prevChannel() {
|
||||
const filterd = this.filterChannelForm()
|
||||
const i = filterd.findIndex((e) => {
|
||||
const i = filterd.findIndex(e => {
|
||||
return e.name === this.selectedChannel.name
|
||||
})
|
||||
if (i !== undefined && i > 0) {
|
||||
this.$store.commit('TimelineSpace/Modals/Jump/changeSelected', filterd[i - 1])
|
||||
}
|
||||
},
|
||||
changeSelected (channel) {
|
||||
changeSelected(channel) {
|
||||
this.$store.commit('TimelineSpace/Modals/Jump/changeSelected', channel)
|
||||
},
|
||||
jumpCurrentSelected () {
|
||||
jumpCurrentSelected() {
|
||||
if (this.jumpModal) {
|
||||
this.$store.dispatch('TimelineSpace/Modals/Jump/jumpCurrentSelected')
|
||||
}
|
||||
},
|
||||
jump (channel) {
|
||||
jump(channel) {
|
||||
this.$store.dispatch('TimelineSpace/Modals/Jump/jump', channel)
|
||||
},
|
||||
handleKey (event) {
|
||||
handleKey(event) {
|
||||
switch (event.srcKey) {
|
||||
case 'next':
|
||||
this.nextChannel()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<el-dialog :title="$t('modals.list_membership.title')" :visible.sync="listMembershipModal" width="400px" class="list-membership-modal">
|
||||
<el-dialog :title="$t('modals.list_membership.title')" :model-value="listMembershipModal" width="400px" class="list-membership-modal">
|
||||
<el-checkbox-group v-model="belongToLists" v-loading="loading">
|
||||
<table class="lists">
|
||||
<tbody>
|
||||
|
|
|
@ -1,8 +1,32 @@
|
|||
<template>
|
||||
<div id="current-media" v-loading="loading" element-loading-background="rgba(0, 0, 0, 0.8)">
|
||||
<video :src="src" v-if="isMovieFile()" autoplay loop controls v-on:loadstart="loaded()"></video>
|
||||
<video :src="src" v-else-if="isGIF()" autoplay loop v-on:loadstart="loaded()"></video>
|
||||
<video :src="src" v-else-if="isAudio()" autoplay loop controls v-on:loadstart="loaded()"></video>
|
||||
<div
|
||||
id="current-media"
|
||||
v-loading="loading"
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)"
|
||||
>
|
||||
<video
|
||||
:src="src"
|
||||
v-if="isMovieFile()"
|
||||
autoplay
|
||||
loop
|
||||
controls
|
||||
v-on:loadstart="loaded()"
|
||||
></video>
|
||||
<video
|
||||
:src="src"
|
||||
v-else-if="isGIF()"
|
||||
autoplay
|
||||
loop
|
||||
v-on:loadstart="loaded()"
|
||||
></video>
|
||||
<video
|
||||
:src="src"
|
||||
v-else-if="isAudio()"
|
||||
autoplay
|
||||
loop
|
||||
controls
|
||||
v-on:loadstart="loaded()"
|
||||
></video>
|
||||
<img :src="imageSrc" v-else v-on:load="loaded()" />
|
||||
</div>
|
||||
</template>
|
||||
|
@ -15,16 +39,16 @@ export default {
|
|||
props: {
|
||||
src: {
|
||||
type: String,
|
||||
default: ''
|
||||
default: '',
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
imageSrc: this.src
|
||||
imageSrc: this.src,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -38,12 +62,12 @@ export default {
|
|||
console.error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
loading: state => state.TimelineSpace.Modals.ImageViewer.loading
|
||||
})
|
||||
loading: (state) => state.TimelineSpace.Modals.ImageViewer.loading,
|
||||
}),
|
||||
},
|
||||
methods: {
|
||||
isMovieFile() {
|
||||
|
@ -57,8 +81,8 @@ export default {
|
|||
},
|
||||
async loaded() {
|
||||
this.$store.dispatch('TimelineSpace/Modals/ImageViewer/loaded')
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
:title="$t('modals.mute_confirm.title')"
|
||||
:visible.sync="muteConfirmModal"
|
||||
width="400px"
|
||||
custom-class="mute-confirm"
|
||||
>
|
||||
<el-form class="description">
|
||||
<el-form-item for="notify" :label="$t('modals.mute_confirm.body')">
|
||||
<el-switch id="notify" v-model="notify"></el-switch>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="closeModal">{{ $t('modals.mute_confirm.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="submit">{{ $t('modals.mute_confirm.ok') }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
<el-dialog :title="$t('modals.mute_confirm.title')" :model-value="muteConfirmModal" width="400px" custom-class="mute-confirm">
|
||||
<el-form class="description">
|
||||
<el-form-item for="notify" :label="$t('modals.mute_confirm.body')">
|
||||
<el-switch id="notify" v-model="notify"></el-switch>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="closeModal">{{ $t('modals.mute_confirm.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="submit">{{ $t('modals.mute_confirm.ok') }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -22,7 +17,7 @@ import { mapState } from 'vuex'
|
|||
|
||||
export default {
|
||||
name: 'MuteConfirm',
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
notify: true
|
||||
}
|
||||
|
@ -32,19 +27,19 @@ export default {
|
|||
account: state => state.account
|
||||
}),
|
||||
muteConfirmModal: {
|
||||
get () {
|
||||
get() {
|
||||
return this.$store.state.TimelineSpace.Modals.MuteConfirm.modalOpen
|
||||
},
|
||||
set (value) {
|
||||
set(value) {
|
||||
this.$store.dispatch('TimelineSpace/Modals/MuteConfirm/changeModal', value)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
closeModal () {
|
||||
closeModal() {
|
||||
this.muteConfirmModal = false
|
||||
},
|
||||
async submit () {
|
||||
async submit() {
|
||||
this.closeModal()
|
||||
await this.$store.dispatch('TimelineSpace/Modals/MuteConfirm/submit', this.notify)
|
||||
}
|
||||
|
|
|
@ -1,144 +1,147 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
:title="$t('modals.new_toot.title')"
|
||||
:visible.sync="newTootModal"
|
||||
v-if="newTootModal"
|
||||
:before-close="closeConfirm"
|
||||
width="600px"
|
||||
class="new-toot-modal"
|
||||
ref="dialog"
|
||||
>
|
||||
<el-form v-on:submit.prevent="toot" role="form">
|
||||
<Quote :message="quoteToMessage" :displayNameStyle="displayNameStyle" v-if="quoteToMessage !== null" ref="quote"></Quote>
|
||||
<div class="spoiler" v-if="showContentWarning" ref="spoiler">
|
||||
<div class="el-input">
|
||||
<input type="text" class="el-input__inner" :placeholder="$t('modals.new_toot.cw')" v-model="spoiler" v-shortkey.avoid />
|
||||
<div class="new-toot">
|
||||
<el-dialog
|
||||
:title="$t('modals.new_toot.title')"
|
||||
:model-value="newTootModal"
|
||||
@update:model-value="newTootModal = $event"
|
||||
:before-close="closeConfirm"
|
||||
width="600px"
|
||||
custom-class="new-toot-modal"
|
||||
ref="dialog"
|
||||
>
|
||||
<el-form v-on:submit.prevent="toot" role="form">
|
||||
<Quote :message="quoteToMessage" :displayNameStyle="displayNameStyle" v-if="quoteToMessage !== null" ref="quote"></Quote>
|
||||
<div class="spoiler" v-if="showContentWarning" ref="spoiler">
|
||||
<div class="el-input">
|
||||
<input type="text" class="el-input__inner" :placeholder="$t('modals.new_toot.cw')" v-model="spoiler" />
|
||||
</div>
|
||||
</div>
|
||||
<Status
|
||||
v-model="status"
|
||||
:opened="newTootModal"
|
||||
:fixCursorPos="hashtagInserting"
|
||||
:height="statusHeight"
|
||||
@paste="onPaste"
|
||||
@toot="toot"
|
||||
@pickerOpened="innerElementOpened"
|
||||
@suggestOpened="innerElementOpened"
|
||||
/>
|
||||
</el-form>
|
||||
<Poll
|
||||
v-if="openPoll"
|
||||
v-model="polls"
|
||||
@addPoll="addPoll"
|
||||
@removePoll="removePoll"
|
||||
:defaultExpire="pollExpire"
|
||||
@changeExpire="changeExpire"
|
||||
ref="poll"
|
||||
></Poll>
|
||||
<div class="preview" ref="preview">
|
||||
<div class="image-wrapper" v-for="media in attachedMedias" v-bind:key="media.id">
|
||||
<img :src="media.preview_url" class="preview-image" />
|
||||
<el-button type="text" @click="removeAttachment(media)" class="remove-image"><font-awesome-icon icon="circle-xmark" /></el-button>
|
||||
<textarea
|
||||
maxlength="420"
|
||||
class="image-description"
|
||||
:placeholder="$t('modals.new_toot.description')"
|
||||
:value="mediaDescriptions[media.id]"
|
||||
@input="updateDescription(media.id, $event.target.value)"
|
||||
role="textbox"
|
||||
contenteditable="true"
|
||||
aria-multiline="true"
|
||||
>
|
||||
</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<Status
|
||||
v-model="status"
|
||||
:opened="newTootModal"
|
||||
:fixCursorPos="hashtagInserting"
|
||||
:height="statusHeight"
|
||||
@paste="onPaste"
|
||||
@toot="toot"
|
||||
@pickerOpened="innerElementOpened"
|
||||
@suggestOpened="innerElementOpened"
|
||||
/>
|
||||
</el-form>
|
||||
<Poll
|
||||
v-if="openPoll"
|
||||
v-model="polls"
|
||||
@addPoll="addPoll"
|
||||
@removePoll="removePoll"
|
||||
:defaultExpire="pollExpire"
|
||||
@changeExpire="changeExpire"
|
||||
ref="poll"
|
||||
></Poll>
|
||||
<div class="preview" ref="preview">
|
||||
<div class="image-wrapper" v-for="media in attachedMedias" v-bind:key="media.id">
|
||||
<img :src="media.preview_url" class="preview-image" />
|
||||
<el-button type="text" @click="removeAttachment(media)" class="remove-image"><font-awesome-icon icon="circle-xmark" /></el-button>
|
||||
<textarea
|
||||
maxlength="420"
|
||||
class="image-description"
|
||||
:placeholder="$t('modals.new_toot.description')"
|
||||
:value="mediaDescriptions[media.id]"
|
||||
@input="updateDescription(media.id, $event.target.value)"
|
||||
v-shortkey.avoid
|
||||
role="textbox"
|
||||
contenteditable="true"
|
||||
aria-multiline="true"
|
||||
>
|
||||
</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<div class="upload-image">
|
||||
<el-button size="default" type="text" @click="selectImage" :title="$t('modals.new_toot.footer.add_image')">
|
||||
<font-awesome-icon icon="camera" />
|
||||
</el-button>
|
||||
<input name="image" type="file" class="image-input" ref="image" @change="onChangeImage" :key="attachedMediaId" />
|
||||
</div>
|
||||
<div class="poll">
|
||||
<el-button size="default" type="text" @click="togglePollForm" :title="$t('modals.new_toot.footer.poll')">
|
||||
<font-awesome-icon icon="square-poll-horizontal" />
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="privacy">
|
||||
<el-dropdown trigger="click" @command="changeVisibility">
|
||||
<el-button size="default" type="text" :title="$t('modals.new_toot.footer.change_visibility')">
|
||||
<font-awesome-icon :icon="visibilityIcon" />
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item :command="visibilityList.Public.value">
|
||||
<font-awesome-icon icon="globe" class="privacy-icon" />
|
||||
{{ $t(visibilityList.Public.name) }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item :command="visibilityList.Unlisted.value">
|
||||
<font-awesome-icon icon="unlock" class="privacy-icon" />
|
||||
{{ $t(visibilityList.Unlisted.name) }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item :command="visibilityList.Private.value">
|
||||
<font-awesome-icon icon="lock" class="privacy-icon" />
|
||||
{{ $t(visibilityList.Private.name) }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item :command="visibilityList.Direct.value">
|
||||
<font-awesome-icon icon="envelope" class="privacy-icon" size="sm" />
|
||||
{{ $t(visibilityList.Direct.name) }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<div class="sensitive" v-show="attachedMedias.length > 0">
|
||||
<el-button
|
||||
size="default"
|
||||
type="text"
|
||||
@click="changeSensitive"
|
||||
:title="$t('modals.new_toot.footer.change_sensitive')"
|
||||
:aria-pressed="sensitive"
|
||||
>
|
||||
<font-awesome-icon icon="eye-slash" v-show="!sensitive" />
|
||||
<font-awesome-icon icon="eye" v-show="sensitive" />
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="content-warning">
|
||||
<el-button
|
||||
size="default"
|
||||
type="text"
|
||||
@click="toggleContentWarning()"
|
||||
:title="$t('modals.new_toot.footer.add_cw')"
|
||||
:class="showContentWarning ? '' : 'clickable'"
|
||||
:aria-pressed="showContentWarning"
|
||||
>
|
||||
<font-awesome-icon icon="eye-slash" />
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="pined-hashtag">
|
||||
<el-button
|
||||
size="default"
|
||||
type="text"
|
||||
@click="pinedHashtag = !pinedHashtag"
|
||||
:title="$t('modals.new_toot.footer.pined_hashtag')"
|
||||
:class="pinedHashtag ? '' : 'clickable'"
|
||||
:aria-pressed="pinedHashtag"
|
||||
>
|
||||
<font-awesome-icon icon="hashtag" />
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="info">
|
||||
<img src="../../../assets/images/loading-spinner-wide.svg" v-show="loading" class="loading" />
|
||||
<span class="text-count">{{ tootMax - status.length }}</span>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<div class="upload-image">
|
||||
<el-button size="default" type="text" @click="selectImage" :title="$t('modals.new_toot.footer.add_image')">
|
||||
<font-awesome-icon icon="camera" />
|
||||
</el-button>
|
||||
<input name="image" type="file" class="image-input" ref="image" @change="onChangeImage" :key="attachedMediaId" />
|
||||
</div>
|
||||
<div class="poll">
|
||||
<el-button size="default" type="text" @click="togglePollForm" :title="$t('modals.new_toot.footer.poll')">
|
||||
<font-awesome-icon icon="square-poll-horizontal" />
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="privacy">
|
||||
<el-dropdown trigger="click" @command="changeVisibility">
|
||||
<el-button size="default" type="text" :title="$t('modals.new_toot.footer.change_visibility')">
|
||||
<font-awesome-icon :icon="visibilityIcon" />
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item :command="visibilityList.Public.value">
|
||||
<font-awesome-icon icon="globe" class="privacy-icon" />
|
||||
{{ $t(visibilityList.Public.name) }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item :command="visibilityList.Unlisted.value">
|
||||
<font-awesome-icon icon="unlock" class="privacy-icon" />
|
||||
{{ $t(visibilityList.Unlisted.name) }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item :command="visibilityList.Private.value">
|
||||
<font-awesome-icon icon="lock" class="privacy-icon" />
|
||||
{{ $t(visibilityList.Private.name) }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item :command="visibilityList.Direct.value">
|
||||
<font-awesome-icon icon="envelope" class="privacy-icon" size="sm" />
|
||||
{{ $t(visibilityList.Direct.name) }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<div class="sensitive" v-show="attachedMedias.length > 0">
|
||||
<el-button
|
||||
size="default"
|
||||
type="text"
|
||||
@click="changeSensitive"
|
||||
:title="$t('modals.new_toot.footer.change_sensitive')"
|
||||
:aria-pressed="sensitive"
|
||||
>
|
||||
<font-awesome-icon icon="eye-slash" v-show="!sensitive" />
|
||||
<font-awesome-icon icon="eye" v-show="sensitive" />
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="content-warning">
|
||||
<el-button
|
||||
size="default"
|
||||
type="text"
|
||||
@click="toggleContentWarning()"
|
||||
:title="$t('modals.new_toot.footer.add_cw')"
|
||||
:class="showContentWarning ? '' : 'clickable'"
|
||||
:aria-pressed="showContentWarning"
|
||||
>
|
||||
<font-awesome-icon icon="eye-slash" />
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="pined-hashtag">
|
||||
<el-button
|
||||
size="default"
|
||||
type="text"
|
||||
@click="pinedHashtag = !pinedHashtag"
|
||||
:title="$t('modals.new_toot.footer.pined_hashtag')"
|
||||
:class="pinedHashtag ? '' : 'clickable'"
|
||||
:aria-pressed="pinedHashtag"
|
||||
>
|
||||
<font-awesome-icon icon="hashtag" />
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="info">
|
||||
<img src="../../../assets/images/loading-spinner-wide.svg" v-show="loading" class="loading" />
|
||||
<span class="text-count">{{ tootMax - status.length }}</span>
|
||||
|
||||
<el-button class="toot-action" size="small" @click="closeConfirm(close)">{{ $t('modals.new_toot.cancel') }}</el-button>
|
||||
<el-button class="toot-action" size="small" type="primary" @click="toot" :loading="blockSubmit">{{
|
||||
$t('modals.new_toot.toot')
|
||||
}}</el-button>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<resize-observer @notify="handleResize" />
|
||||
</el-dialog>
|
||||
<el-button class="toot-action" @click="closeConfirm(close)">{{ $t('modals.new_toot.cancel') }}</el-button>
|
||||
<el-button class="toot-action" type="primary" @click="toot" :loading="blockSubmit">{{ $t('modals.new_toot.toot') }}</el-button>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</template>
|
||||
<resize-observer @notify="handleResize" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -148,7 +151,7 @@ import Status from './NewToot/Status'
|
|||
import Poll from './NewToot/Poll'
|
||||
import Quote from './NewToot/Quote'
|
||||
import { NewTootTootLength, NewTootAttachLength, NewTootModalOpen, NewTootBlockSubmit, NewTootPollInvalid } from '@/errors/validations'
|
||||
import { Event } from '~/src/renderer/components/event'
|
||||
import { EventEmitter } from '~/src/renderer/components/event'
|
||||
|
||||
export default {
|
||||
name: 'new-toot',
|
||||
|
@ -238,7 +241,7 @@ export default {
|
|||
this.$store.dispatch('TimelineSpace/Modals/NewToot/setupLoading')
|
||||
},
|
||||
mounted() {
|
||||
Event.$on('image-uploaded', () => {
|
||||
EventEmitter.on('image-uploaded', () => {
|
||||
if (this.$refs.preview) {
|
||||
this.statusHeight = this.statusHeight - this.$refs.preview.offsetHeight
|
||||
}
|
||||
|
@ -291,7 +294,10 @@ export default {
|
|||
console.error(err)
|
||||
if (err instanceof NewTootTootLength) {
|
||||
this.$message({
|
||||
message: this.$t('validation.new_toot.toot_length', { min: 1, max: this.tootMax }),
|
||||
message: this.$t('validation.new_toot.toot_length', {
|
||||
min: 1,
|
||||
max: this.tootMax
|
||||
}),
|
||||
type: 'error'
|
||||
})
|
||||
} else if (err instanceof NewTootAttachLength) {
|
||||
|
@ -458,189 +464,190 @@ export default {
|
|||
event.height - footerHeight - headerHeight - this.$refs.preview.offsetHeight - pollHeight - spoilerHeight - quoteHeight
|
||||
}
|
||||
},
|
||||
innerElementOpened(open) {
|
||||
if (open) {
|
||||
this.$refs.dialog.$el.firstChild.style.overflow = 'visible'
|
||||
} else {
|
||||
this.$refs.dialog.$el.firstChild.style.overflow = 'hidden'
|
||||
}
|
||||
innerElementOpened() {
|
||||
// if (open) {
|
||||
// this.$refs.dialog.$el.firstChild.style.overflow = 'visible'
|
||||
// } else {
|
||||
// this.$refs.dialog.$el.firstChild.style.overflow = 'hidden'
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.new-toot-modal /deep/ {
|
||||
.el-dialog {
|
||||
.new-toot :deep() {
|
||||
.new-toot-modal {
|
||||
background-color: var(--theme-selected-background-color);
|
||||
overflow: hidden;
|
||||
resize: both;
|
||||
padding-bottom: 20px;
|
||||
max-height: calc(100% - 15vh - 80px);
|
||||
max-width: 95%;
|
||||
}
|
||||
|
||||
.el-dialog__header {
|
||||
background-color: #4a5664;
|
||||
|
||||
.el-dialog__title {
|
||||
color: #ebeef5;
|
||||
}
|
||||
}
|
||||
|
||||
.el-dialog__body {
|
||||
padding: 0;
|
||||
|
||||
.el-input__inner {
|
||||
background-color: var(--theme-background-color);
|
||||
color: var(--theme-primary-color);
|
||||
border: 1px solid var(--theme-border-color);
|
||||
}
|
||||
|
||||
.spoiler {
|
||||
box-sizing: border-box;
|
||||
padding: 4px 0;
|
||||
.el-dialog__header {
|
||||
background-color: #4a5664;
|
||||
margin-right: 0;
|
||||
|
||||
input {
|
||||
border-radius: 0;
|
||||
|
||||
&::placeholder {
|
||||
color: #c0c4cc;
|
||||
}
|
||||
.el-dialog__title {
|
||||
color: #ebeef5;
|
||||
}
|
||||
}
|
||||
|
||||
.preview {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
.el-dialog__body {
|
||||
padding: 0;
|
||||
|
||||
.image-wrapper {
|
||||
position: relative;
|
||||
flex: 1 1 0;
|
||||
min-width: 10%;
|
||||
height: 150px;
|
||||
margin: 4px;
|
||||
.el-input__inner {
|
||||
background-color: var(--theme-background-color);
|
||||
color: var(--theme-primary-color);
|
||||
border: 1px solid var(--theme-border-color);
|
||||
}
|
||||
|
||||
.preview-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border: 0;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.spoiler {
|
||||
box-sizing: border-box;
|
||||
padding: 4px 0;
|
||||
background-color: #4a5664;
|
||||
|
||||
.image-description {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
border: 0;
|
||||
border-bottom-left-radius: 8px;
|
||||
border-bottom-right-radius: 8px;
|
||||
background: linear-gradient(0deg, rgba(0, 0, 0, 0.8) 0, rgba(0, 0, 0, 0.35) 80%, transparent);
|
||||
font-size: var(--font-base-size);
|
||||
color: #fff;
|
||||
opacity: 1;
|
||||
resize: none;
|
||||
overflow: scroll;
|
||||
input {
|
||||
border-radius: 0;
|
||||
|
||||
&::placeholder {
|
||||
color: #c0c4cc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.remove-image {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
font-size: 1.5rem;
|
||||
.preview {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.fa-icon {
|
||||
font-size: 0.9rem;
|
||||
width: auto;
|
||||
height: 1em;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
.image-wrapper {
|
||||
position: relative;
|
||||
flex: 1 1 0;
|
||||
min-width: 10%;
|
||||
height: 150px;
|
||||
margin: 4px;
|
||||
|
||||
.preview-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border: 0;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.image-description {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
border: 0;
|
||||
border-bottom-left-radius: 8px;
|
||||
border-bottom-right-radius: 8px;
|
||||
background: linear-gradient(0deg, rgba(0, 0, 0, 0.8) 0, rgba(0, 0, 0, 0.35) 80%, transparent);
|
||||
font-size: var(--font-base-size);
|
||||
color: #fff;
|
||||
opacity: 1;
|
||||
resize: none;
|
||||
overflow: scroll;
|
||||
|
||||
&::placeholder {
|
||||
color: #c0c4cc;
|
||||
}
|
||||
}
|
||||
|
||||
.remove-image {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
font-size: 1.5rem;
|
||||
|
||||
.fa-icon {
|
||||
font-size: 0.9rem;
|
||||
width: auto;
|
||||
height: 1em;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-dialog__footer {
|
||||
background-color: var(--theme-selected-background-color);
|
||||
font-size: var(--base-font-size);
|
||||
padding-bottom: 0;
|
||||
.el-dialog__footer {
|
||||
background-color: var(--theme-selected-background-color);
|
||||
font-size: var(--base-font-size);
|
||||
padding-bottom: 0;
|
||||
|
||||
.upload-image {
|
||||
text-align: left;
|
||||
float: left;
|
||||
.upload-image {
|
||||
text-align: left;
|
||||
float: left;
|
||||
|
||||
.image-input {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.poll {
|
||||
float: left;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.privacy {
|
||||
float: left;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.sensitive {
|
||||
float: left;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.content-warning {
|
||||
float: left;
|
||||
margin-left: 8px;
|
||||
|
||||
.cw-text {
|
||||
font-weight: 800;
|
||||
line-height: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.pined-hashtag {
|
||||
float: left;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.clickable {
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
|
||||
.loading {
|
||||
width: 18px;
|
||||
margin-right: 4px;
|
||||
.image-input {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.text-count {
|
||||
padding-right: 10px;
|
||||
.poll {
|
||||
float: left;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.privacy {
|
||||
float: left;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.sensitive {
|
||||
float: left;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.content-warning {
|
||||
float: left;
|
||||
margin-left: 8px;
|
||||
|
||||
.cw-text {
|
||||
font-weight: 800;
|
||||
line-height: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.pined-hashtag {
|
||||
float: left;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.clickable {
|
||||
color: #909399;
|
||||
}
|
||||
}
|
||||
|
||||
.toot-action {
|
||||
font-size: var(--base-font-size);
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
.info {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
|
||||
.loading {
|
||||
width: 18px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.text-count {
|
||||
padding-right: 10px;
|
||||
color: #909399;
|
||||
}
|
||||
}
|
||||
|
||||
.toot-action {
|
||||
font-size: var(--base-font-size);
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,14 +3,43 @@
|
|||
<ul class="poll-list">
|
||||
<li class="poll-option" v-for="(option, id) in value" v-bind:key="id">
|
||||
<el-radio :disabled="true" :label="id">
|
||||
<el-input :placeholder="`choice ${id}`" :value="value[id]" @input="value => updateOption(value, id)" size="small"></el-input>
|
||||
<el-button class="remove-poll" type="text" @click="removePoll(id)" size="small"><font-awesome-icon icon="xmark" /></el-button>
|
||||
<el-input
|
||||
:placeholder="`choice ${id}`"
|
||||
:model-value="value[id]"
|
||||
@input="(value) => updateOption(value, id)"
|
||||
size="small"
|
||||
></el-input>
|
||||
<el-button
|
||||
class="remove-poll"
|
||||
type="text"
|
||||
@click="removePoll(id)"
|
||||
size="small"
|
||||
><font-awesome-icon icon="xmark"
|
||||
/></el-button>
|
||||
</el-radio>
|
||||
</li>
|
||||
</ul>
|
||||
<el-button class="add-poll" type="info" size="small" @click="addPoll" plain>{{ $t('modals.new_toot.poll.add_choice') }}</el-button>
|
||||
<el-select v-model="expiresIn" size="small" value-key="value" @change="changeExpire">
|
||||
<el-option v-for="exp in expires" :key="exp.value" :label="exp.label" :value="exp"> </el-option>
|
||||
<el-button
|
||||
class="add-poll"
|
||||
type="info"
|
||||
size="small"
|
||||
@click="addPoll"
|
||||
plain
|
||||
>{{ $t('modals.new_toot.poll.add_choice') }}</el-button
|
||||
>
|
||||
<el-select
|
||||
v-model="expiresIn"
|
||||
size="small"
|
||||
value-key="value"
|
||||
@change="changeExpire"
|
||||
>
|
||||
<el-option
|
||||
v-for="exp in expires"
|
||||
:key="exp.value"
|
||||
:label="exp.label"
|
||||
:value="exp"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -24,34 +53,34 @@ export default {
|
|||
expires: [
|
||||
{
|
||||
label: this.$t('modals.new_toot.poll.expires.5_minutes'),
|
||||
value: 60 * 5
|
||||
value: 60 * 5,
|
||||
},
|
||||
{
|
||||
label: this.$t('modals.new_toot.poll.expires.30_minutes'),
|
||||
value: 60 * 30
|
||||
value: 60 * 30,
|
||||
},
|
||||
{
|
||||
label: this.$t('modals.new_toot.poll.expires.1_hour'),
|
||||
value: 3600
|
||||
value: 3600,
|
||||
},
|
||||
{
|
||||
label: this.$t('modals.new_toot.poll.expires.6_hours'),
|
||||
value: 3600 * 6
|
||||
value: 3600 * 6,
|
||||
},
|
||||
{
|
||||
label: this.$t('modals.new_toot.poll.expires.1_day'),
|
||||
value: 3600 * 24
|
||||
value: 3600 * 24,
|
||||
},
|
||||
{
|
||||
label: this.$t('modals.new_toot.poll.expires.3_days'),
|
||||
value: 3600 * 24 * 3
|
||||
value: 3600 * 24 * 3,
|
||||
},
|
||||
{
|
||||
label: this.$t('modals.new_toot.poll.expires.7_days'),
|
||||
value: 3600 * 24 * 7
|
||||
}
|
||||
value: 3600 * 24 * 7,
|
||||
},
|
||||
],
|
||||
expiresIn: null
|
||||
expiresIn: null,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
@ -65,13 +94,17 @@ export default {
|
|||
this.$emit('removePoll', id)
|
||||
},
|
||||
updateOption(item, index) {
|
||||
const newValue = [...this.value.slice(0, index), item, ...this.value.slice(index + 1)]
|
||||
const newValue = [
|
||||
...this.value.slice(0, index),
|
||||
item,
|
||||
...this.value.slice(index + 1),
|
||||
]
|
||||
this.$emit('input', newValue)
|
||||
},
|
||||
changeExpire(exp) {
|
||||
this.$emit('changeExpire', exp)
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ export default {
|
|||
float: left;
|
||||
width: calc(100% - 52px);
|
||||
|
||||
.content-wrapper /deep/ {
|
||||
.content-wrapper {
|
||||
font-size: var(--base-font-size);
|
||||
color: var(--theme-primary-color);
|
||||
|
||||
|
@ -119,11 +119,11 @@ export default {
|
|||
.content p {
|
||||
unicode-bidi: plaintext;
|
||||
}
|
||||
}
|
||||
|
||||
.emojione {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
.content-wrapper :deep(.emojione) {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.toot-header {
|
||||
|
@ -135,14 +135,14 @@ export default {
|
|||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
.display-name /deep/ {
|
||||
.display-name {
|
||||
font-weight: 800;
|
||||
color: var(--theme-primary-color);
|
||||
}
|
||||
|
||||
.emojione {
|
||||
max-width: 14px;
|
||||
max-height: 14px;
|
||||
}
|
||||
.display-name :deep(.emojione) {
|
||||
max-width: 14px;
|
||||
max-height: 14px;
|
||||
}
|
||||
|
||||
.acct {
|
||||
|
|
|
@ -3,12 +3,6 @@
|
|||
<textarea
|
||||
v-model="status"
|
||||
ref="status"
|
||||
v-shortkey="
|
||||
openSuggest
|
||||
? { up: ['arrowup'], down: ['arrowdown'], enter: ['enter'], esc: ['esc'] }
|
||||
: { linux: ['ctrl', 'enter'], mac: ['meta', 'enter'], left: ['arrowleft'], right: ['arrowright'] }
|
||||
"
|
||||
@shortkey="handleKey"
|
||||
@paste="onPaste"
|
||||
v-on:input="startSuggest"
|
||||
:placeholder="$t('modals.new_toot.status')"
|
||||
|
@ -19,13 +13,12 @@
|
|||
autofocus
|
||||
>
|
||||
</textarea>
|
||||
<el-popover placement="bottom-start" width="300" trigger="manual" :value="openSuggest" popper-class="suggest-popper">
|
||||
<el-popover placement="bottom-start" width="300" trigger="manual" v-model:visible="openSuggest" popper-class="suggest-popper">
|
||||
<ul class="suggest-list">
|
||||
<li
|
||||
v-for="(item, index) in filteredSuggestion"
|
||||
:key="index"
|
||||
@click="insertItem(item)"
|
||||
@shortkey="insertItem(item)"
|
||||
@mouseover="highlightedIndex = index"
|
||||
:class="{ highlighted: highlightedIndex === index }"
|
||||
>
|
||||
|
@ -38,29 +31,45 @@
|
|||
{{ item.name }}
|
||||
</li>
|
||||
</ul>
|
||||
<!-- dummy object to open suggest popper -->
|
||||
<template #reference>
|
||||
<span></span>
|
||||
</template>
|
||||
</el-popover>
|
||||
<div v-click-outside="hideEmojiPicker">
|
||||
<el-button type="text" class="emoji-selector" @click="toggleEmojiPicker">
|
||||
<font-awesome-icon :icon="['far', 'face-smile']" size="lg" />
|
||||
</el-button>
|
||||
<div v-if="openEmojiPicker" class="emoji-picker">
|
||||
<picker set="emojione" :autoFocus="true" :custom="pickerEmojis" @select="selectEmoji" />
|
||||
</div>
|
||||
<div>
|
||||
<el-popover placement="bottom" width="281" trigger="click" popper-class="new-toot-emoji-picker" ref="new_toot_emoji_picker">
|
||||
<picker
|
||||
:data="emojiIndex"
|
||||
set="twitter"
|
||||
:autoFocus="true"
|
||||
@select="selectEmoji"
|
||||
:custom="pickerEmojis"
|
||||
:perLine="7"
|
||||
:emojiSize="24"
|
||||
:showPreview="false"
|
||||
:emojiTooltip="true"
|
||||
/>
|
||||
<template #reference>
|
||||
<el-button class="emoji-selector" type="text">
|
||||
<font-awesome-icon :icon="['far', 'face-smile']" size="lg" />
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import 'emoji-mart-vue-fast/css/emoji-mart.css'
|
||||
import data from 'emoji-mart-vue-fast/data/all.json'
|
||||
import { mapState, mapGetters } from 'vuex'
|
||||
import { Picker } from 'emoji-mart-vue'
|
||||
import ClickOutside from 'vue-click-outside'
|
||||
import { Picker, EmojiIndex } from 'emoji-mart-vue-fast/src'
|
||||
import suggestText from '@/utils/suggestText'
|
||||
|
||||
const emojiIndex = new EmojiIndex(data)
|
||||
|
||||
export default {
|
||||
name: 'status',
|
||||
directives: {
|
||||
ClickOutside
|
||||
},
|
||||
components: {
|
||||
Picker
|
||||
},
|
||||
|
@ -84,7 +93,8 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
highlightedIndex: 0,
|
||||
openEmojiPicker: false
|
||||
openEmojiPicker: false,
|
||||
emojiIndex: emojiIndex
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -125,7 +135,6 @@ export default {
|
|||
})
|
||||
} else if (oldState && !newState) {
|
||||
this.closeSuggest()
|
||||
this.hideEmojiPicker()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -257,12 +266,6 @@ export default {
|
|||
this.openEmojiPicker = !this.openEmojiPicker
|
||||
this.$emit('pickerOpened', this.openEmojiPicker)
|
||||
},
|
||||
hideEmojiPicker() {
|
||||
if (this.openEmojiPicker) {
|
||||
this.$emit('pickerOpened', false)
|
||||
}
|
||||
this.openEmojiPicker = false
|
||||
},
|
||||
selectEmoji(emoji) {
|
||||
const current = this.$refs.status.selectionStart
|
||||
if (emoji.native) {
|
||||
|
@ -281,6 +284,37 @@ export default {
|
|||
.suggest-popper {
|
||||
background-color: var(--theme-background-color);
|
||||
border: 1px solid var(--theme-header-menu-color);
|
||||
|
||||
.suggest-list {
|
||||
list-style: none;
|
||||
padding: 6px 0;
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
|
||||
li {
|
||||
font-size: var(--base-font-size);
|
||||
padding: 0 20px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
color: var(--theme-regular-color);
|
||||
|
||||
.icon {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.highlighted {
|
||||
background-color: var(--theme-selected-background-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
@ -318,37 +352,6 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.suggest-list {
|
||||
list-style: none;
|
||||
padding: 6px 0;
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
|
||||
li {
|
||||
font-size: var(--base-font-size);
|
||||
padding: 0 20px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
color: var(--theme-regular-color);
|
||||
|
||||
.icon {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.highlighted {
|
||||
background-color: var(--theme-selected-background-color);
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-selector {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
:title="$t('modals.report.title')"
|
||||
:visible.sync="reportModal"
|
||||
width="400px"
|
||||
custom-class="report"
|
||||
>
|
||||
<el-input type="textarea" v-model="comment" :placeholder="$t('modals.report.comment')"></el-input>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="closeModal">{{ $t('modals.report.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="submit">{{ $t('modals.report.ok') }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
<el-dialog :title="$t('modals.report.title')" :model-value="reportModal" width="400px" custom-class="report">
|
||||
<el-input type="textarea" v-model="comment" :placeholder="$t('modals.report.comment')"></el-input>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="closeModal">{{ $t('modals.report.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="submit">{{ $t('modals.report.ok') }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -18,7 +15,7 @@ import { mapState } from 'vuex'
|
|||
|
||||
export default {
|
||||
name: 'Report',
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
comment: ''
|
||||
}
|
||||
|
@ -28,19 +25,19 @@ export default {
|
|||
toot: state => state.message
|
||||
}),
|
||||
reportModal: {
|
||||
get () {
|
||||
get() {
|
||||
return this.$store.state.TimelineSpace.Modals.Report.modalOpen
|
||||
},
|
||||
set (value) {
|
||||
set(value) {
|
||||
this.$store.commit('TimelineSpace/Modals/Report/changeModalOpen', value)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
closeModal () {
|
||||
closeModal() {
|
||||
this.reportModal = false
|
||||
},
|
||||
async submit () {
|
||||
async submit() {
|
||||
this.closeModal()
|
||||
await this.$store.dispatch('TimelineSpace/Modals/Report/submit', {
|
||||
account_id: this.toot.account.id,
|
||||
|
@ -52,5 +49,4 @@ export default {
|
|||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue