Merge pull request #488 from h3poteto/iss-151

refs #151 Switch language in preferences
This commit is contained in:
AkiraFukushima 2018-08-14 22:35:54 +09:00 committed by GitHub
commit 4b7e0df7dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 267 additions and 33 deletions

View File

@ -102,6 +102,17 @@
"confirm": "Confirm",
"cancel": "Cancel",
"confirm_message": "Are you sure to remove all associations?"
},
"language": {
"title": "Language",
"display_language": "language",
"notice": "Require relaunch",
"confirm": {
"title": "Warning",
"message": "You have to restart this application. Continue?",
"ok": "Restart Now",
"cancel": "Cancel"
}
}
},
"modals": {

View File

@ -102,6 +102,17 @@
"confirm": "確認",
"cancel": "キャンセル",
"confirm_message": "本当に全ての連携を削除しますか?"
},
"language": {
"title": "言語",
"display_language": "表示言語",
"notice": "再起動が必要です",
"confirm": {
"title": "再起動します",
"message": "設定を有効化するために再起動する必要があります",
"ok": "再起動する",
"cancel": "キャンセル"
}
}
},
"modals": {

View File

@ -1,16 +1,14 @@
import i18n from '../config/i18n'
export default {
DisplayNameAndUsername: {
name: i18n.t('preferences.general.display_style.display_name_and_username'),
name: 'preferences.general.display_style.display_name_and_username',
value: 0
},
DisplayName: {
name: i18n.t('preferences.general.display_style.display_name'),
name: 'preferences.general.display_style.display_name',
value: 1
},
Username: {
name: i18n.t('preferences.general.display_style.username'),
name: 'preferences.general.display_style.username',
value: 2
}
}

10
src/constants/language.js Normal file
View File

@ -0,0 +1,10 @@
export default {
en: {
name: 'English',
key: 'en'
},
ja: {
name: '日本語',
key: 'ja'
}
}

View File

@ -1,12 +1,10 @@
import i18n from '../config/i18n'
export default {
Light: {
name: i18n.t('preferences.general.theme.light'),
name: 'preferences.general.theme.light',
key: 'light'
},
Dark: {
name: i18n.t('preferences.general.theme.dark'),
name: 'preferences.general.theme.dark',
key: 'dark'
}
}

View File

@ -1,23 +1,21 @@
import i18n from '../config/i18n'
export default {
Public: {
name: i18n.t('preferences.general.visibility.public'),
name: 'preferences.general.visibility.public',
value: 0,
key: 'public'
},
Unlisted: {
name: i18n.t('preferences.general.visibility.unlisted'),
name: 'preferences.general.visibility.unlisted',
value: 1,
key: 'unlisted'
},
Private: {
name: i18n.t('preferences.general.visibility.private'),
name: 'preferences.general.visibility.private',
value: 2,
key: 'private'
},
Direct: {
name: i18n.t('preferences.general.visibility.direct'),
name: 'preferences.general.visibility.direct',
value: 3,
key: 'direct'
}

View File

@ -17,6 +17,7 @@ import Streaming from './streaming'
import Preferences from './preferences'
import Hashtags from './hashtags'
import i18n from '../config/i18n'
import Language from '../constants/language'
/**
* Context menu
@ -96,6 +97,16 @@ async function changeAccount (account, index) {
}
}
async function getLanguage () {
try {
const preferences = new Preferences(preferencesDBPath)
const conf = await preferences.load()
return conf.language.language
} catch (err) {
return Language.en.key
}
}
async function createWindow () {
/**
* List accounts
@ -109,6 +120,12 @@ async function createWindow () {
}
})
/**
* Get language
*/
const language = await getLanguage()
i18n.changeLanguage(language)
/**
* Set application menu
*/
@ -593,6 +610,20 @@ ipcMain.on('get-collapse', (event, _) => {
})
})
ipcMain.on('change-language', (event, value) => {
const preferences = new Preferences(preferencesDBPath)
preferences.update(
{
language: {
language: value
}
})
.then((conf) => {
i18n.changeLanguage(conf.language.language)
event.sender.send('response-change-language', conf.language.language)
})
})
// hashtag
ipcMain.on('save-hashtag', (event, tag) => {
const hashtags = new Hashtags(hashtagsDB)
@ -624,6 +655,12 @@ ipcMain.on('remove-hashtag', (event, tag) => {
})
})
// Application control
ipcMain.on('relaunch', (event, _) => {
app.relaunch()
app.exit()
})
/**
* Auto Updater
*

View File

@ -3,6 +3,7 @@ import objectAssignDeep from 'object-assign-deep'
import Visibility from '../constants/visibility'
import DisplayStyle from '../constants/displayStyle'
import Theme from '../constants/theme'
import Language from '../constants/language'
const Base = {
general: {
@ -17,6 +18,9 @@ const Base = {
},
state: {
collapse: false
},
language: {
language: Language.en.key
}
}

View File

@ -31,6 +31,9 @@ export default {
created () {
this.$store.dispatch('App/watchShortcutsEvents')
this.$store.dispatch('App/loadPreferences')
.then((conf) => {
this.$i18n.i18next.changeLanguage(conf.language.language)
})
},
destroyed () {
this.$store.dispatch('App/removeShortcutsEvents')

View File

@ -26,6 +26,10 @@
<icon name="user" class="icon" scale="1.3"></icon>
<span>{{ $t('preferences.account.title') }}</span>
</el-menu-item>
<el-menu-item index="3" :route="{path: '/preferences/language'}" @click="language">
<icon name="language" class="icon" scale="1.3"></icon>
<span>{{ $t('preferences.language.title') }}</span>
</el-menu-item>
</el-menu>
</el-aside>
<el-main>
@ -56,6 +60,9 @@ export default {
},
account () {
this.$router.push('/preferences/account')
},
language () {
this.$router.push('/preferences/language')
}
}
}

View File

@ -8,7 +8,7 @@
<tr>
<td class="title">{{ $t('preferences.general.theme_color') }}</td>
<td class="status">
<el-radio v-for="t in themes" :key="t.key" v-model="theme" :label="t.key">{{ t.name }}</el-radio>
<el-radio v-for="t in themes" :key="t.key" v-model="theme" :label="t.key">{{ $t(t.name) }}</el-radio>
</td>
</tr>
<tr>
@ -24,7 +24,7 @@
<el-option
v-for="style in nameStyles"
:key="style.value"
:label="style.name"
:label="$t(style.name)"
:value="style.value">
</el-option>
</el-select>
@ -44,7 +44,7 @@
<el-option
v-for="v in visibilities"
:key="v.value"
:label="v.name"
:label="$t(v.name)"
:value="v.value">
</el-option>
</el-select>

View File

@ -0,0 +1,102 @@
<template>
<div id="language">
<h2>{{ $t('preferences.language.title') }}</h2>
<div class="display-language">
<table class="language">
<tbody>
<tr>
<td class="title">{{ $t('preferences.language.display_language') }}</td>
<td class="status">
<el-select v-model="displayLanguage" placeholder="style">
<el-option
v-for="lang in languages"
:key="lang.key"
:label="lang.name"
:value="lang.key">
</el-option>
</el-select>
<p class="notice">{{ $t('preferences.language.notice') }}</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script>
import Language from '~/src/constants/language'
export default {
name: 'language',
data () {
return {
languages: [
Language.en,
Language.ja
]
}
},
computed: {
displayLanguage: {
get () {
return this.$store.state.Preferences.Language.language.language
},
set (value) {
this.$store.dispatch('Preferences/Language/changeLanguage', value)
.then(() => {
this.confirm()
})
}
}
},
created () {
this.$store.dispatch('Preferences/Language/loadLanguage')
},
methods: {
confirm () {
this.$confirm(
this.$t('preferences.language.confirm.message'),
this.$t('preferences.language.confirm.title'),
{
confirmButtonText: this.$t('preferences.language.confirm.ok'),
cancelButtonText: this.$t('preferences.language.confirm.cancel'),
type: 'warning'
}
)
.then(() => {
this.$store.dispatch('Preferences/Language/relaunch')
})
.cancel(() => {
})
}
}
}
</script>
<style lang="scss" scoped>
#language {
table {
width: 100%;
}
td {
padding: 16px 0;
}
.title {
text-align: right;
width: 50%;
}
.status {
width: 50%;
text-align: center;
.notice {
color: #c0c4cc;
font-size: 12px;
}
}
}
</style>

View File

@ -31,19 +31,19 @@
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="visibilityList.Public.value">
<icon name="globe" class="privacy-icon"></icon>
{{ visibilityList.Public.name }}
{{ $t(visibilityList.Public.name) }}
</el-dropdown-item>
<el-dropdown-item :command="visibilityList.Unlisted.value">
<icon name="unlock" class="privacy-icon"></icon>
{{ visibilityList.Unlisted.name }}
{{ $t(visibilityList.Unlisted.name) }}
</el-dropdown-item>
<el-dropdown-item :command="visibilityList.Private.value">
<icon name="lock" class="privacy-icon"></icon>
{{ visibilityList.Private.name }}
{{ $t(visibilityList.Private.name) }}
</el-dropdown-item>
<el-dropdown-item :command="visibilityList.Direct.value">
<icon name="envelope" class="privacy-icon" scale="0.8"></icon>
{{ visibilityList.Direct.name }}
{{ $t(visibilityList.Direct.name) }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>

View File

@ -30,6 +30,11 @@ export default new Router({
path: 'account',
name: 'account',
component: require('@/components/Preferences/Account').default
},
{
path: 'language',
name: 'language',
component: require('@/components/Preferences/Language').default
}
]
},

View File

@ -44,15 +44,19 @@ const App = {
ipcRenderer.removeAllListeners('open-preferences')
},
loadPreferences ({ commit }) {
ipcRenderer.send('get-preferences')
ipcRenderer.once('error-get-preferences', (event, err) => {
ipcRenderer.removeAllListeners('response-get-preferences')
})
ipcRenderer.once('response-get-preferences', (event, conf) => {
ipcRenderer.removeAllListeners('error-get-preferences')
commit('updateTheme', conf.general.theme)
commit('updateDisplayNameStyle', conf.general.displayNameStyle)
commit('updateFontSize', conf.general.fontSize)
return new Promise((resolve, reject) => {
ipcRenderer.send('get-preferences')
ipcRenderer.once('error-get-preferences', (event, err) => {
ipcRenderer.removeAllListeners('response-get-preferences')
reject(err)
})
ipcRenderer.once('response-get-preferences', (event, conf) => {
ipcRenderer.removeAllListeners('error-get-preferences')
commit('updateTheme', conf.general.theme)
commit('updateDisplayNameStyle', conf.general.displayNameStyle)
commit('updateFontSize', conf.general.fontSize)
resolve(conf)
})
})
}
}

View File

@ -1,11 +1,13 @@
import General from './Preferences/General'
import Account from './Preferences/Account'
import Language from './Preferences/Language'
const Preferences = {
namespaced: true,
modules: {
General,
Account
Account,
Language
},
state: {
defaultActive: '1'

View File

@ -0,0 +1,44 @@
import { ipcRenderer } from 'electron'
import Language from '~/src/constants/language'
export default {
namespaced: true,
state: {
language: {
language: Language.en.key
}
},
mutations: {
updateLanguage (state, conf) {
state.language = conf
},
changeLanguage (state, key) {
state.language.language = key
}
},
actions: {
loadLanguage ({ commit }) {
return new Promise((resolve, reject) => {
ipcRenderer.send('get-preferences')
ipcRenderer.once('error-get-preferences', (event, err) => {
ipcRenderer.removeAllListeners('response-get-preferences')
reject(err)
})
ipcRenderer.once('response-get-preferences', (event, conf) => {
ipcRenderer.removeAllListeners('error-get-preferences')
commit('updateLanguage', conf.language)
resolve(conf)
})
})
},
changeLanguage ({ commit }, key) {
ipcRenderer.send('change-language', key)
ipcRenderer.once('response-change-language', (event, value) => {
commit('changeLanguage', value)
})
},
relaunch () {
ipcRenderer.send('relaunch')
}
}
}

View File

@ -99,7 +99,7 @@ const NewToot = {
},
openModal ({ dispatch, commit, rootState }) {
commit('changeModal', true)
commit('changeVisibilityValue', rootState.tootVisibility)
commit('changeVisibilityValue', rootState.App.tootVisibility)
},
closeModal ({ commit }) {
commit('changeModal', false)