refs #901 Replace shell and clipboard using window object
This commit is contained in:
parent
fd1c31bf31
commit
e8bfffc58b
|
@ -1,6 +1,6 @@
|
|||
import { createLocalVue } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import { ipcMain } from '~/spec/mock/electron'
|
||||
import { ipcMain, ipcRenderer } from '~/spec/mock/electron'
|
||||
import App from '@/store/App'
|
||||
import DisplayStyle from '~/src/constants/displayStyle'
|
||||
import { LightTheme, DarkTheme } from '~/src/constants/themeColor'
|
||||
|
@ -8,6 +8,7 @@ import Theme from '~/src/constants/theme'
|
|||
import TimeFormat from '~/src/constants/timeFormat'
|
||||
import Language from '~/src/constants/language'
|
||||
import DefaultFonts from '@/utils/fonts'
|
||||
import { MyWindow } from '~/src/types/global'
|
||||
|
||||
const state = () => {
|
||||
return {
|
||||
|
@ -43,6 +44,7 @@ describe('App', () => {
|
|||
let localVue
|
||||
|
||||
beforeEach(() => {
|
||||
;(<MyWindow>window).ipcRenderer = ipcRenderer
|
||||
localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
store = new Vuex.Store({
|
||||
|
@ -58,11 +60,10 @@ describe('App', () => {
|
|||
ipcMain.once('get-preferences', (event: any, _) => {
|
||||
event.sender.send('error-get-preferences', new Error())
|
||||
})
|
||||
await store.dispatch('App/loadPreferences')
|
||||
.catch((err) => {
|
||||
expect(err instanceof Error).toEqual(true)
|
||||
expect(store.state.App.theme).toEqual(LightTheme)
|
||||
})
|
||||
await store.dispatch('App/loadPreferences').catch(err => {
|
||||
expect(err instanceof Error).toEqual(true)
|
||||
expect(store.state.App.theme).toEqual(LightTheme)
|
||||
})
|
||||
})
|
||||
})
|
||||
describe('success', () => {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
const electron = require('electron')
|
||||
global.ipcRenderer = electron.ipcRenderer
|
||||
global.shell = electron.shell
|
||||
global.clipboard = electron.clipboard
|
||||
global.process = process
|
||||
|
|
|
@ -1,114 +1,125 @@
|
|||
<template>
|
||||
<div id="account_profile"
|
||||
v-loading="loading"
|
||||
:element-loading-text="$t('message.loading')"
|
||||
element-loading-spinner="el-icon-loading"
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)"
|
||||
role="article"
|
||||
aria-label="account profile">
|
||||
<div class="header-background" v-bind:style="{ backgroundImage: 'url(' + account.header + ')' }">
|
||||
<div class="header">
|
||||
<div class="follow-follower" 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>
|
||||
<div
|
||||
id="account_profile"
|
||||
v-loading="loading"
|
||||
:element-loading-text="$t('message.loading')"
|
||||
element-loading-spinner="el-icon-loading"
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)"
|
||||
role="article"
|
||||
aria-label="account profile"
|
||||
>
|
||||
<div class="header-background" v-bind:style="{ backgroundImage: 'url(' + account.header + ')' }">
|
||||
<div class="header">
|
||||
<div class="follow-follower" 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>
|
||||
</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>
|
||||
<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-button slot="reference" type="text" :title="$t('side_bar.account_profile.detail')">
|
||||
<icon name="cog" scale="1.4"></icon>
|
||||
</el-button>
|
||||
</popper>
|
||||
</div>
|
||||
<div class="icon" role="presentation">
|
||||
<FailoverImg :src="account.avatar" :alt="`Avatar of ${account.username}`" />
|
||||
</div>
|
||||
<div class="follow-status" v-if="relationship !== null && relationship !== '' && !isOwnProfile">
|
||||
<div v-if="relationship.following" class="unfollow" @click="unfollow(account)" :title="$t('side_bar.account_profile.unfollow')">
|
||||
<icon name="user-times" scale="1.5"></icon>
|
||||
<el-button slot="reference" type="text" :title="$t('side_bar.account_profile.detail')">
|
||||
<icon name="cog" scale="1.4"></icon>
|
||||
</el-button>
|
||||
</popper>
|
||||
</div>
|
||||
<div v-else-if="relationship.requested" :title="$t('side_bar.account_profile.follow_requested')">
|
||||
<icon name="hourglass" scale="1.5"></icon>
|
||||
<div class="icon" role="presentation">
|
||||
<FailoverImg :src="account.avatar" :alt="`Avatar of ${account.username}`" />
|
||||
</div>
|
||||
<div v-else class="follow" @click="follow(account)" :title="$t('side_bar.account_profile.follow')">
|
||||
<icon name="user-plus" scale="1.5"></icon>
|
||||
<div class="follow-status" v-if="relationship !== null && relationship !== '' && !isOwnProfile">
|
||||
<div v-if="relationship.following" class="unfollow" @click="unfollow(account)" :title="$t('side_bar.account_profile.unfollow')">
|
||||
<icon name="user-times" scale="1.5"></icon>
|
||||
</div>
|
||||
<div class="icon" role="presentation">
|
||||
<FailoverImg :src="account.avatar" :alt="`Avatar of ${account.username}`" />
|
||||
</div>
|
||||
<div class="follow-status" v-if="relationship !== null && relationship !== '' && account.username !== user.username">
|
||||
<div
|
||||
v-if="relationship.following"
|
||||
class="unfollow"
|
||||
@click="unfollow(account)"
|
||||
:title="$t('side_bar.account_profile.unfollow')"
|
||||
>
|
||||
<icon name="user-times" scale="1.5"></icon>
|
||||
</div>
|
||||
<div v-else-if="relationship.requested" :title="$t('side_bar.account_profile.follow_requested')">
|
||||
<icon name="hourglass" scale="1.5"></icon>
|
||||
</div>
|
||||
<div v-else class="follow" @click="follow(account)" :title="$t('side_bar.account_profile.follow')">
|
||||
<icon name="user-plus" scale="1.5"></icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="username">
|
||||
<bdi v-html="username(account)"></bdi>
|
||||
</div>
|
||||
<div class="account">@{{ account.acct }}</div>
|
||||
<div class="note" v-html="note(account)" @click.capture.prevent="noteClick"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="username">
|
||||
<bdi v-html="username(account)"></bdi>
|
||||
<div class="metadata">
|
||||
<dl v-for="(data, index) in account.fields" :key="index">
|
||||
<dt>
|
||||
{{ data.name }}
|
||||
</dt>
|
||||
<dd v-html="data.value" @click.capture.prevent="metadataClick"></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="account">
|
||||
@{{ account.acct }}
|
||||
<el-row class="basic-info">
|
||||
<el-col :span="8" :class="activeTab === 1 ? 'info info-active' : 'info'" @click="changeTab">
|
||||
<el-button type="text" class="tab" @click="changeTab(1)">
|
||||
<div class="title">{{ $t('side_bar.account_profile.toots') }}</div>
|
||||
<div class="count">{{ account.statuses_count }}</div>
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="8" :class="activeTab === 2 ? 'info info-active' : 'info'">
|
||||
<el-button type="text" class="tab" @click="changeTab(2)">
|
||||
<div class="title">{{ $t('side_bar.account_profile.follows') }}</div>
|
||||
<div class="count">{{ account.following_count }}</div>
|
||||
</el-button>
|
||||
</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="count">{{ account.followers_count }}</div>
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="timeline">
|
||||
<timeline :account="account" v-if="activeTab === 1"></timeline>
|
||||
<follows :account="account" v-if="activeTab === 2"></follows>
|
||||
<followers :account="account" v-if="activeTab === 3"></followers>
|
||||
</div>
|
||||
<div class="note" v-html="note(account)" @click.capture.prevent="noteClick"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="metadata">
|
||||
<dl v-for="(data, index) in account.fields" :key="index">
|
||||
<dt>
|
||||
{{ data.name }}
|
||||
</dt>
|
||||
<dd v-html="data.value" @click.capture.prevent="metadataClick">
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<el-row class="basic-info">
|
||||
<el-col :span="8" :class="activeTab === 1 ? 'info info-active' : 'info'" @click="changeTab">
|
||||
<el-button type="text" class="tab" @click="changeTab(1)">
|
||||
<div class="title">{{ $t('side_bar.account_profile.toots') }}</div>
|
||||
<div class="count">{{ account.statuses_count }}</div>
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="8" :class="activeTab === 2 ? 'info info-active' : 'info'">
|
||||
<el-button type="text" class="tab" @click="changeTab(2)">
|
||||
<div class="title">{{ $t('side_bar.account_profile.follows') }}</div>
|
||||
<div class="count">{{ account.following_count }}</div>
|
||||
</el-button>
|
||||
</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="count">{{ account.followers_count }}</div>
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="timeline">
|
||||
<timeline :account="account" v-if="activeTab === 1"></timeline>
|
||||
<follows :account="account" v-if="activeTab === 2"></follows>
|
||||
<followers :account="account" v-if="activeTab === 3"></followers>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from 'vuex'
|
||||
import { shell } from 'electron'
|
||||
import { findLink } from '~/src/renderer/utils/tootParser'
|
||||
import emojify from '~/src/renderer/utils/emojify'
|
||||
import Timeline from './AccountProfile/Timeline'
|
||||
|
@ -124,14 +135,14 @@ export default {
|
|||
Followers,
|
||||
FailoverImg
|
||||
},
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
activeTab: 1
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
theme: (state) => {
|
||||
theme: state => {
|
||||
return {
|
||||
'--theme-mask-color': state.App.theme.wrapper_mask_color,
|
||||
'--theme-border-color': state.App.theme.border_color,
|
||||
|
@ -149,31 +160,31 @@ export default {
|
|||
...mapGetters('TimelineSpace/Contents/SideBar/AccountProfile', ['isOwnProfile'])
|
||||
},
|
||||
watch: {
|
||||
account: function () {
|
||||
account: function() {
|
||||
this.activeTab = 1
|
||||
},
|
||||
loading: function (newState, _oldState) {
|
||||
loading: function(newState, _oldState) {
|
||||
this.$emit('change-loading', newState)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
username (account) {
|
||||
username(account) {
|
||||
if (account.display_name !== '') {
|
||||
return emojify(account.display_name, account.emojis)
|
||||
} else {
|
||||
return account.username
|
||||
}
|
||||
},
|
||||
note (account) {
|
||||
note(account) {
|
||||
return emojify(account.note, account.emojis)
|
||||
},
|
||||
noteClick (e) {
|
||||
noteClick(e) {
|
||||
const link = findLink(e.target, 'note')
|
||||
if (link !== null) {
|
||||
shell.openExternal(link)
|
||||
window.shell.openExternal(link)
|
||||
}
|
||||
},
|
||||
follow (account) {
|
||||
follow(account) {
|
||||
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', true)
|
||||
try {
|
||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/follow', account)
|
||||
|
@ -186,7 +197,7 @@ export default {
|
|||
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', false)
|
||||
}
|
||||
},
|
||||
unfollow (account) {
|
||||
unfollow(account) {
|
||||
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', true)
|
||||
try {
|
||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/unfollow', account)
|
||||
|
@ -199,39 +210,39 @@ export default {
|
|||
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', false)
|
||||
}
|
||||
},
|
||||
changeTab (index) {
|
||||
changeTab(index) {
|
||||
this.activeTab = index
|
||||
},
|
||||
openBrowser (account) {
|
||||
shell.openExternal(account.url)
|
||||
openBrowser(account) {
|
||||
window.shell.openExternal(account.url)
|
||||
this.$refs.popper.doClose()
|
||||
},
|
||||
addToList (account) {
|
||||
addToList(account) {
|
||||
this.$store.dispatch('TimelineSpace/Modals/ListMembership/setAccount', account)
|
||||
this.$store.dispatch('TimelineSpace/Modals/ListMembership/changeModal', true)
|
||||
this.$refs.popper.doClose()
|
||||
},
|
||||
confirmMute (account) {
|
||||
confirmMute(account) {
|
||||
this.$store.dispatch('TimelineSpace/Modals/MuteConfirm/changeAccount', account)
|
||||
this.$store.dispatch('TimelineSpace/Modals/MuteConfirm/changeModal', true)
|
||||
this.$refs.popper.doClose()
|
||||
},
|
||||
unmute (account) {
|
||||
unmute(account) {
|
||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/unmute', account)
|
||||
this.$refs.popper.doClose()
|
||||
},
|
||||
block (account) {
|
||||
block(account) {
|
||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/block', account)
|
||||
this.$refs.popper.doClose()
|
||||
},
|
||||
unblock (account) {
|
||||
unblock(account) {
|
||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/unblock', account)
|
||||
this.$refs.popper.doClose()
|
||||
},
|
||||
metadataClick (e) {
|
||||
metadataClick(e) {
|
||||
const link = findLink(e.target, 'metadata')
|
||||
if (link !== null) {
|
||||
return shell.openExternal(link)
|
||||
return window.shell.openExternal(link)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,7 +130,6 @@
|
|||
|
||||
<script>
|
||||
import { mapState, mapGetters } from 'vuex'
|
||||
import { clipboard } from 'electron'
|
||||
import Visibility from '~/src/constants/visibility'
|
||||
import Status from './NewToot/Status'
|
||||
import Poll from './NewToot/Poll'
|
||||
|
@ -295,7 +294,7 @@ export default {
|
|||
this.updateImage(file)
|
||||
},
|
||||
onPaste(e) {
|
||||
const mimeTypes = clipboard.availableFormats().filter(type => type.startsWith('image'))
|
||||
const mimeTypes = window.clipboard.availableFormats().filter(type => type.startsWith('image'))
|
||||
if (mimeTypes.length === 0) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -133,7 +133,6 @@
|
|||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import { shell } from 'electron'
|
||||
|
||||
export default {
|
||||
name: 'side-menu',
|
||||
|
@ -178,7 +177,7 @@ export default {
|
|||
this.$store.dispatch('TimelineSpace/Contents/SideBar/openAccountComponent')
|
||||
break
|
||||
case 'edit':
|
||||
shell.openExternal(this.account.baseURL + '/settings/profile')
|
||||
window.shell.openExternal(this.account.baseURL + '/settings/profile')
|
||||
break
|
||||
case 'settings':
|
||||
const url = `/${this.id()}/settings`
|
||||
|
|
|
@ -101,7 +101,6 @@
|
|||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import moment from 'moment'
|
||||
import { shell } from 'electron'
|
||||
import { findAccount, findLink, findTag } from '~/src/renderer/utils/tootParser'
|
||||
import emojify from '~/src/renderer/utils/emojify'
|
||||
import TimeFormat from '~/src/constants/timeFormat'
|
||||
|
@ -209,7 +208,7 @@ export default {
|
|||
openLink(e) {
|
||||
const link = findLink(e.target, 'favourite')
|
||||
if (link !== null) {
|
||||
return shell.openExternal(link)
|
||||
return window.shell.openExternal(link)
|
||||
}
|
||||
},
|
||||
openUser(account) {
|
||||
|
|
|
@ -103,7 +103,6 @@
|
|||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import moment from 'moment'
|
||||
import { shell } from 'electron'
|
||||
import { findAccount, findLink, findTag } from '~/src/renderer/utils/tootParser'
|
||||
import emojify from '~/src/renderer/utils/emojify'
|
||||
import TimeFormat from '~/src/constants/timeFormat'
|
||||
|
@ -209,7 +208,7 @@ export default {
|
|||
openLink(e) {
|
||||
const link = findLink(e.target, 'reblog')
|
||||
if (link !== null) {
|
||||
return shell.openExternal(link)
|
||||
return window.shell.openExternal(link)
|
||||
}
|
||||
},
|
||||
openUser(account) {
|
||||
|
|
|
@ -178,7 +178,6 @@
|
|||
|
||||
<script>
|
||||
import moment from 'moment'
|
||||
import { shell, clipboard } from 'electron'
|
||||
import { mapState } from 'vuex'
|
||||
import { findAccount, findLink, findTag } from '~/src/renderer/utils/tootParser'
|
||||
import DisplayStyle from '~/src/constants/displayStyle'
|
||||
|
@ -391,7 +390,7 @@ export default {
|
|||
openLink(e) {
|
||||
const link = findLink(e.target, 'toot')
|
||||
if (link !== null) {
|
||||
return shell.openExternal(link)
|
||||
return window.shell.openExternal(link)
|
||||
}
|
||||
},
|
||||
openReply() {
|
||||
|
@ -404,11 +403,11 @@ export default {
|
|||
this.$refs.popper.doClose()
|
||||
},
|
||||
openBrowser(message) {
|
||||
shell.openExternal(message.url)
|
||||
window.shell.openExternal(message.url)
|
||||
this.$refs.popper.doClose()
|
||||
},
|
||||
copyLink(message) {
|
||||
clipboard.writeText(message.url, 'toot-link')
|
||||
window.clipboard.writeText(message.url, 'toot-link')
|
||||
this.$refs.popper.doClose()
|
||||
},
|
||||
reportUser() {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { Shell, IpcRenderer } from 'electron'
|
||||
import { Shell, IpcRenderer, Clipboard } from 'electron'
|
||||
|
||||
export interface MyWindow extends Window {
|
||||
shell: Shell
|
||||
ipcRenderer: IpcRenderer
|
||||
clipboard: Clipboard
|
||||
process: NodeJS.Process
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue