refs #901 Replace shell and clipboard using window object

This commit is contained in:
AkiraFukushima 2019-05-10 00:05:40 +09:00
parent fd1c31bf31
commit e8bfffc58b
9 changed files with 144 additions and 134 deletions

View File

@ -1,6 +1,6 @@
import { createLocalVue } from '@vue/test-utils' import { createLocalVue } from '@vue/test-utils'
import Vuex from 'vuex' import Vuex from 'vuex'
import { ipcMain } from '~/spec/mock/electron' import { ipcMain, ipcRenderer } from '~/spec/mock/electron'
import App from '@/store/App' import App from '@/store/App'
import DisplayStyle from '~/src/constants/displayStyle' import DisplayStyle from '~/src/constants/displayStyle'
import { LightTheme, DarkTheme } from '~/src/constants/themeColor' import { LightTheme, DarkTheme } from '~/src/constants/themeColor'
@ -8,6 +8,7 @@ import Theme from '~/src/constants/theme'
import TimeFormat from '~/src/constants/timeFormat' import TimeFormat from '~/src/constants/timeFormat'
import Language from '~/src/constants/language' import Language from '~/src/constants/language'
import DefaultFonts from '@/utils/fonts' import DefaultFonts from '@/utils/fonts'
import { MyWindow } from '~/src/types/global'
const state = () => { const state = () => {
return { return {
@ -43,6 +44,7 @@ describe('App', () => {
let localVue let localVue
beforeEach(() => { beforeEach(() => {
;(<MyWindow>window).ipcRenderer = ipcRenderer
localVue = createLocalVue() localVue = createLocalVue()
localVue.use(Vuex) localVue.use(Vuex)
store = new Vuex.Store({ store = new Vuex.Store({
@ -58,8 +60,7 @@ describe('App', () => {
ipcMain.once('get-preferences', (event: any, _) => { ipcMain.once('get-preferences', (event: any, _) => {
event.sender.send('error-get-preferences', new Error()) event.sender.send('error-get-preferences', new Error())
}) })
await store.dispatch('App/loadPreferences') await store.dispatch('App/loadPreferences').catch(err => {
.catch((err) => {
expect(err instanceof Error).toEqual(true) expect(err instanceof Error).toEqual(true)
expect(store.state.App.theme).toEqual(LightTheme) expect(store.state.App.theme).toEqual(LightTheme)
}) })

View File

@ -1,3 +1,5 @@
const electron = require('electron') const electron = require('electron')
global.ipcRenderer = electron.ipcRenderer global.ipcRenderer = electron.ipcRenderer
global.shell = electron.shell
global.clipboard = electron.clipboard
global.process = process global.process = process

View File

@ -1,11 +1,13 @@
<template> <template>
<div id="account_profile" <div
id="account_profile"
v-loading="loading" v-loading="loading"
:element-loading-text="$t('message.loading')" :element-loading-text="$t('message.loading')"
element-loading-spinner="el-icon-loading" element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.8)" element-loading-background="rgba(0, 0, 0, 0.8)"
role="article" role="article"
aria-label="account profile"> aria-label="account profile"
>
<div class="header-background" v-bind:style="{ backgroundImage: 'url(' + account.header + ')' }"> <div class="header-background" v-bind:style="{ backgroundImage: 'url(' + account.header + ')' }">
<div class="header"> <div class="header">
<div class="follow-follower" v-if="relationship !== null && relationship !== '' && !isOwnProfile"> <div class="follow-follower" v-if="relationship !== null && relationship !== '' && !isOwnProfile">
@ -16,7 +18,7 @@
</div> </div>
<div class="user-info"> <div class="user-info">
<div class="more" v-if="relationship !== null && relationship !== '' && !isOwnProfile"> <div class="more" v-if="relationship !== null && relationship !== '' && !isOwnProfile">
<popper trigger="click" :options="{placement: 'bottom'}" ref="popper"> <popper trigger="click" :options="{ placement: 'bottom' }" ref="popper">
<div class="popper"> <div class="popper">
<ul class="menu-list"> <ul class="menu-list">
<li role="button" @click="openBrowser(account)"> <li role="button" @click="openBrowser(account)">
@ -52,6 +54,18 @@
<div v-if="relationship.following" class="unfollow" @click="unfollow(account)" :title="$t('side_bar.account_profile.unfollow')"> <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> <icon name="user-times" scale="1.5"></icon>
</div> </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')"> <div v-else-if="relationship.requested" :title="$t('side_bar.account_profile.follow_requested')">
<icon name="hourglass" scale="1.5"></icon> <icon name="hourglass" scale="1.5"></icon>
</div> </div>
@ -63,9 +77,7 @@
<div class="username"> <div class="username">
<bdi v-html="username(account)"></bdi> <bdi v-html="username(account)"></bdi>
</div> </div>
<div class="account"> <div class="account">@{{ account.acct }}</div>
@{{ account.acct }}
</div>
<div class="note" v-html="note(account)" @click.capture.prevent="noteClick"></div> <div class="note" v-html="note(account)" @click.capture.prevent="noteClick"></div>
</div> </div>
</div> </div>
@ -74,8 +86,7 @@
<dt> <dt>
{{ data.name }} {{ data.name }}
</dt> </dt>
<dd v-html="data.value" @click.capture.prevent="metadataClick"> <dd v-html="data.value" @click.capture.prevent="metadataClick"></dd>
</dd>
</dl> </dl>
</div> </div>
<el-row class="basic-info"> <el-row class="basic-info">
@ -103,12 +114,12 @@
<follows :account="account" v-if="activeTab === 2"></follows> <follows :account="account" v-if="activeTab === 2"></follows>
<followers :account="account" v-if="activeTab === 3"></followers> <followers :account="account" v-if="activeTab === 3"></followers>
</div> </div>
</div> </div>
</div>
</template> </template>
<script> <script>
import { mapState, mapGetters } from 'vuex' import { mapState, mapGetters } from 'vuex'
import { shell } from 'electron'
import { findLink } from '~/src/renderer/utils/tootParser' import { findLink } from '~/src/renderer/utils/tootParser'
import emojify from '~/src/renderer/utils/emojify' import emojify from '~/src/renderer/utils/emojify'
import Timeline from './AccountProfile/Timeline' import Timeline from './AccountProfile/Timeline'
@ -124,14 +135,14 @@ export default {
Followers, Followers,
FailoverImg FailoverImg
}, },
data () { data() {
return { return {
activeTab: 1 activeTab: 1
} }
}, },
computed: { computed: {
...mapState({ ...mapState({
theme: (state) => { theme: state => {
return { return {
'--theme-mask-color': state.App.theme.wrapper_mask_color, '--theme-mask-color': state.App.theme.wrapper_mask_color,
'--theme-border-color': state.App.theme.border_color, '--theme-border-color': state.App.theme.border_color,
@ -149,31 +160,31 @@ export default {
...mapGetters('TimelineSpace/Contents/SideBar/AccountProfile', ['isOwnProfile']) ...mapGetters('TimelineSpace/Contents/SideBar/AccountProfile', ['isOwnProfile'])
}, },
watch: { watch: {
account: function () { account: function() {
this.activeTab = 1 this.activeTab = 1
}, },
loading: function (newState, _oldState) { loading: function(newState, _oldState) {
this.$emit('change-loading', newState) this.$emit('change-loading', newState)
} }
}, },
methods: { methods: {
username (account) { username(account) {
if (account.display_name !== '') { if (account.display_name !== '') {
return emojify(account.display_name, account.emojis) return emojify(account.display_name, account.emojis)
} else { } else {
return account.username return account.username
} }
}, },
note (account) { note(account) {
return emojify(account.note, account.emojis) return emojify(account.note, account.emojis)
}, },
noteClick (e) { noteClick(e) {
const link = findLink(e.target, 'note') const link = findLink(e.target, 'note')
if (link !== null) { if (link !== null) {
shell.openExternal(link) window.shell.openExternal(link)
} }
}, },
follow (account) { follow(account) {
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', true) this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', true)
try { try {
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/follow', account) this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/follow', account)
@ -186,7 +197,7 @@ export default {
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', false) this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', false)
} }
}, },
unfollow (account) { unfollow(account) {
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', true) this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', true)
try { try {
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/unfollow', account) this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/unfollow', account)
@ -199,39 +210,39 @@ export default {
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', false) this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', false)
} }
}, },
changeTab (index) { changeTab(index) {
this.activeTab = index this.activeTab = index
}, },
openBrowser (account) { openBrowser(account) {
shell.openExternal(account.url) window.shell.openExternal(account.url)
this.$refs.popper.doClose() this.$refs.popper.doClose()
}, },
addToList (account) { addToList(account) {
this.$store.dispatch('TimelineSpace/Modals/ListMembership/setAccount', account) this.$store.dispatch('TimelineSpace/Modals/ListMembership/setAccount', account)
this.$store.dispatch('TimelineSpace/Modals/ListMembership/changeModal', true) this.$store.dispatch('TimelineSpace/Modals/ListMembership/changeModal', true)
this.$refs.popper.doClose() this.$refs.popper.doClose()
}, },
confirmMute (account) { confirmMute(account) {
this.$store.dispatch('TimelineSpace/Modals/MuteConfirm/changeAccount', account) this.$store.dispatch('TimelineSpace/Modals/MuteConfirm/changeAccount', account)
this.$store.dispatch('TimelineSpace/Modals/MuteConfirm/changeModal', true) this.$store.dispatch('TimelineSpace/Modals/MuteConfirm/changeModal', true)
this.$refs.popper.doClose() this.$refs.popper.doClose()
}, },
unmute (account) { unmute(account) {
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/unmute', account) this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/unmute', account)
this.$refs.popper.doClose() this.$refs.popper.doClose()
}, },
block (account) { block(account) {
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/block', account) this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/block', account)
this.$refs.popper.doClose() this.$refs.popper.doClose()
}, },
unblock (account) { unblock(account) {
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/unblock', account) this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/unblock', account)
this.$refs.popper.doClose() this.$refs.popper.doClose()
}, },
metadataClick (e) { metadataClick(e) {
const link = findLink(e.target, 'metadata') const link = findLink(e.target, 'metadata')
if (link !== null) { if (link !== null) {
return shell.openExternal(link) return window.shell.openExternal(link)
} }
} }
} }

View File

@ -130,7 +130,6 @@
<script> <script>
import { mapState, mapGetters } from 'vuex' import { mapState, mapGetters } from 'vuex'
import { clipboard } from 'electron'
import Visibility from '~/src/constants/visibility' import Visibility from '~/src/constants/visibility'
import Status from './NewToot/Status' import Status from './NewToot/Status'
import Poll from './NewToot/Poll' import Poll from './NewToot/Poll'
@ -295,7 +294,7 @@ export default {
this.updateImage(file) this.updateImage(file)
}, },
onPaste(e) { 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) { if (mimeTypes.length === 0) {
return return
} }

View File

@ -133,7 +133,6 @@
<script> <script>
import { mapState } from 'vuex' import { mapState } from 'vuex'
import { shell } from 'electron'
export default { export default {
name: 'side-menu', name: 'side-menu',
@ -178,7 +177,7 @@ export default {
this.$store.dispatch('TimelineSpace/Contents/SideBar/openAccountComponent') this.$store.dispatch('TimelineSpace/Contents/SideBar/openAccountComponent')
break break
case 'edit': case 'edit':
shell.openExternal(this.account.baseURL + '/settings/profile') window.shell.openExternal(this.account.baseURL + '/settings/profile')
break break
case 'settings': case 'settings':
const url = `/${this.id()}/settings` const url = `/${this.id()}/settings`

View File

@ -101,7 +101,6 @@
<script> <script>
import { mapState } from 'vuex' import { mapState } from 'vuex'
import moment from 'moment' import moment from 'moment'
import { shell } from 'electron'
import { findAccount, findLink, findTag } from '~/src/renderer/utils/tootParser' import { findAccount, findLink, findTag } from '~/src/renderer/utils/tootParser'
import emojify from '~/src/renderer/utils/emojify' import emojify from '~/src/renderer/utils/emojify'
import TimeFormat from '~/src/constants/timeFormat' import TimeFormat from '~/src/constants/timeFormat'
@ -209,7 +208,7 @@ export default {
openLink(e) { openLink(e) {
const link = findLink(e.target, 'favourite') const link = findLink(e.target, 'favourite')
if (link !== null) { if (link !== null) {
return shell.openExternal(link) return window.shell.openExternal(link)
} }
}, },
openUser(account) { openUser(account) {

View File

@ -103,7 +103,6 @@
<script> <script>
import { mapState } from 'vuex' import { mapState } from 'vuex'
import moment from 'moment' import moment from 'moment'
import { shell } from 'electron'
import { findAccount, findLink, findTag } from '~/src/renderer/utils/tootParser' import { findAccount, findLink, findTag } from '~/src/renderer/utils/tootParser'
import emojify from '~/src/renderer/utils/emojify' import emojify from '~/src/renderer/utils/emojify'
import TimeFormat from '~/src/constants/timeFormat' import TimeFormat from '~/src/constants/timeFormat'
@ -209,7 +208,7 @@ export default {
openLink(e) { openLink(e) {
const link = findLink(e.target, 'reblog') const link = findLink(e.target, 'reblog')
if (link !== null) { if (link !== null) {
return shell.openExternal(link) return window.shell.openExternal(link)
} }
}, },
openUser(account) { openUser(account) {

View File

@ -178,7 +178,6 @@
<script> <script>
import moment from 'moment' import moment from 'moment'
import { shell, clipboard } from 'electron'
import { mapState } from 'vuex' import { mapState } from 'vuex'
import { findAccount, findLink, findTag } from '~/src/renderer/utils/tootParser' import { findAccount, findLink, findTag } from '~/src/renderer/utils/tootParser'
import DisplayStyle from '~/src/constants/displayStyle' import DisplayStyle from '~/src/constants/displayStyle'
@ -391,7 +390,7 @@ export default {
openLink(e) { openLink(e) {
const link = findLink(e.target, 'toot') const link = findLink(e.target, 'toot')
if (link !== null) { if (link !== null) {
return shell.openExternal(link) return window.shell.openExternal(link)
} }
}, },
openReply() { openReply() {
@ -404,11 +403,11 @@ export default {
this.$refs.popper.doClose() this.$refs.popper.doClose()
}, },
openBrowser(message) { openBrowser(message) {
shell.openExternal(message.url) window.shell.openExternal(message.url)
this.$refs.popper.doClose() this.$refs.popper.doClose()
}, },
copyLink(message) { copyLink(message) {
clipboard.writeText(message.url, 'toot-link') window.clipboard.writeText(message.url, 'toot-link')
this.$refs.popper.doClose() this.$refs.popper.doClose()
}, },
reportUser() { reportUser() {

View File

@ -1,7 +1,8 @@
import { Shell, IpcRenderer } from 'electron' import { Shell, IpcRenderer, Clipboard } from 'electron'
export interface MyWindow extends Window { export interface MyWindow extends Window {
shell: Shell shell: Shell
ipcRenderer: IpcRenderer ipcRenderer: IpcRenderer
clipboard: Clipboard
process: NodeJS.Process process: NodeJS.Process
} }