mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-04-14 06:30:49 +08:00
✨ feat: 优化语言设置和国际化处理
This commit is contained in:
@@ -12,7 +12,8 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { darkTheme, lightTheme } from 'naive-ui';
|
||||
import { computed, onMounted, watch } from 'vue';
|
||||
import { computed, onMounted, onUnmounted, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import homeRouter from '@/router/home';
|
||||
import globalStore from '@/store';
|
||||
@@ -20,6 +21,15 @@ import { isElectron } from '@/utils';
|
||||
|
||||
import { isMobile } from './utils';
|
||||
|
||||
const { locale } = useI18n();
|
||||
|
||||
const savedLanguage = isElectron
|
||||
? window.electron.ipcRenderer.sendSync('get-store-value', 'set.language')
|
||||
: JSON.parse(localStorage.getItem('appSettings') || '{}').language || 'zh-CN';
|
||||
if (savedLanguage) {
|
||||
locale.value = savedLanguage;
|
||||
}
|
||||
|
||||
const theme = computed(() => {
|
||||
return globalStore.state.theme;
|
||||
});
|
||||
@@ -59,9 +69,16 @@ watch(
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// 监听来自主进程的语言切换事件
|
||||
const handleSetLanguage = (_: any, value: string) => {
|
||||
// 更新 i18n locale
|
||||
locale.value = value;
|
||||
// 通过 mutation 更新 store
|
||||
globalStore.commit('setLanguage', value);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
globalStore.dispatch('initializeSettings');
|
||||
globalStore.dispatch('initializeLanguage');
|
||||
globalStore.dispatch('initializeTheme');
|
||||
globalStore.dispatch('initializeSystemFonts');
|
||||
globalStore.dispatch('initializePlayState');
|
||||
@@ -71,6 +88,11 @@ onMounted(() => {
|
||||
homeRouter.filter((item) => item.meta.isMobile)
|
||||
);
|
||||
}
|
||||
window.electron.ipcRenderer.on('set-language', handleSetLanguage);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
window.electron.ipcRenderer.removeListener('set-language', handleSetLanguage);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -13,3 +13,7 @@ body {
|
||||
background-color: transparent !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.settings-slider .n-slider-mark {
|
||||
font-size: 10px !important;
|
||||
}
|
||||
|
||||
@@ -1,83 +1,83 @@
|
||||
<template>
|
||||
<div class="settings-panel transparent-popover">
|
||||
<div class="settings-title">{{ t('lyricSettings.title') }}</div>
|
||||
<div class="settings-title">{{ t('settings.lyricSettings.title') }}</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-item">
|
||||
<span>{{ t('lyricSettings.pureMode') }}</span>
|
||||
<span>{{ t('settings.lyricSettings.pureMode') }}</span>
|
||||
<n-switch v-model:value="config.pureModeEnabled" />
|
||||
</div>
|
||||
|
||||
<div class="settings-item">
|
||||
<span>{{ t('lyricSettings.hideCover') }}</span>
|
||||
<span>{{ t('settings.lyricSettings.hideCover') }}</span>
|
||||
<n-switch v-model:value="config.hideCover" />
|
||||
</div>
|
||||
|
||||
<div class="settings-item">
|
||||
<span>{{ t('lyricSettings.centerDisplay') }}</span>
|
||||
<span>{{ t('settings.lyricSettings.centerDisplay') }}</span>
|
||||
<n-switch v-model:value="config.centerLyrics" />
|
||||
</div>
|
||||
|
||||
<div class="settings-item">
|
||||
<span>{{ t('lyricSettings.showTranslation') }}</span>
|
||||
<span>{{ t('settings.lyricSettings.showTranslation') }}</span>
|
||||
<n-switch v-model:value="config.showTranslation" />
|
||||
</div>
|
||||
|
||||
<div class="settings-item">
|
||||
<span>{{ t('lyricSettings.hidePlayBar') }}</span>
|
||||
<span>{{ t('settings.lyricSettings.hidePlayBar') }}</span>
|
||||
<n-switch v-model:value="config.hidePlayBar" />
|
||||
</div>
|
||||
|
||||
<div class="settings-slider">
|
||||
<span>{{ t('lyricSettings.fontSize') }}</span>
|
||||
<span>{{ t('settings.lyricSettings.fontSize') }}</span>
|
||||
<n-slider
|
||||
v-model:value="config.fontSize"
|
||||
:step="1"
|
||||
:min="12"
|
||||
:max="32"
|
||||
:marks="{
|
||||
12: t('lyricSettings.fontSizeMarks.small'),
|
||||
22: t('lyricSettings.fontSizeMarks.medium'),
|
||||
32: t('lyricSettings.fontSizeMarks.large')
|
||||
12: t('settings.lyricSettings.fontSizeMarks.small'),
|
||||
22: t('settings.lyricSettings.fontSizeMarks.medium'),
|
||||
32: t('settings.lyricSettings.fontSizeMarks.large')
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="settings-slider">
|
||||
<span>{{ t('lyricSettings.letterSpacing') }}</span>
|
||||
<span>{{ t('settings.lyricSettings.letterSpacing') }}</span>
|
||||
<n-slider
|
||||
v-model:value="config.letterSpacing"
|
||||
:step="0.2"
|
||||
:min="-2"
|
||||
:max="10"
|
||||
:marks="{
|
||||
'-2': t('lyricSettings.letterSpacingMarks.compact'),
|
||||
0: t('lyricSettings.letterSpacingMarks.default'),
|
||||
10: t('lyricSettings.letterSpacingMarks.loose')
|
||||
'-2': t('settings.lyricSettings.letterSpacingMarks.compact'),
|
||||
0: t('settings.lyricSettings.letterSpacingMarks.default'),
|
||||
10: t('settings.lyricSettings.letterSpacingMarks.loose')
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="settings-slider">
|
||||
<span>{{ t('lyricSettings.lineHeight') }}</span>
|
||||
<span>{{ t('settings.lyricSettings.lineHeight') }}</span>
|
||||
<n-slider
|
||||
v-model:value="config.lineHeight"
|
||||
:step="0.1"
|
||||
:min="1"
|
||||
:max="3"
|
||||
:marks="{
|
||||
1: t('lyricSettings.lineHeightMarks.compact'),
|
||||
1.5: t('lyricSettings.lineHeightMarks.default'),
|
||||
3: t('lyricSettings.lineHeightMarks.loose')
|
||||
1: t('settings.lyricSettings.lineHeightMarks.compact'),
|
||||
1.5: t('settings.lyricSettings.lineHeightMarks.default'),
|
||||
3: t('settings.lyricSettings.lineHeightMarks.loose')
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="settings-item">
|
||||
<span>{{ t('lyricSettings.backgroundTheme') }}</span>
|
||||
<span>{{ t('settings.lyricSettings.backgroundTheme') }}</span>
|
||||
<n-radio-group v-model:value="config.theme" name="theme">
|
||||
<n-radio value="default">{{ t('lyricSettings.themeOptions.default') }}</n-radio>
|
||||
<n-radio value="light">{{ t('lyricSettings.themeOptions.light') }}</n-radio>
|
||||
<n-radio value="dark">{{ t('lyricSettings.themeOptions.dark') }}</n-radio>
|
||||
<n-radio value="default">{{ t('settings.lyricSettings.themeOptions.default') }}</n-radio>
|
||||
<n-radio value="light">{{ t('settings.lyricSettings.themeOptions.light') }}</n-radio>
|
||||
<n-radio value="dark">{{ t('settings.lyricSettings.themeOptions.dark') }}</n-radio>
|
||||
</n-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -41,10 +41,13 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useStore } from 'vuex';
|
||||
|
||||
import { isElectron } from '@/utils';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const store = useStore();
|
||||
const showCloseModal = ref(false);
|
||||
const rememberChoice = ref(false);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { createStore } from 'vuex';
|
||||
|
||||
import i18n from '@/../i18n/renderer';
|
||||
import setData from '@/../main/set.json';
|
||||
import { logout } from '@/api/login';
|
||||
import { getLikedList, likeSong } from '@/api/music';
|
||||
@@ -376,13 +375,10 @@ const actions = {
|
||||
initializeLanguage({ state }: { state: State }) {
|
||||
state.setData.language = getLocalStorageItem('appSettings', { language: 'zh-CN' }).language;
|
||||
if (isElectron) {
|
||||
window.electron.ipcRenderer.on('set-language', (_, language: string) => {
|
||||
state.setData.language = language;
|
||||
});
|
||||
window.electron.ipcRenderer.send('set-store-value', 'set.language', state.setData.language);
|
||||
} else {
|
||||
localStorage.setItem('appSettings', JSON.stringify(state.setData));
|
||||
}
|
||||
i18n.global.locale.value = state.setData.language as 'zh-CN' | 'en-US';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user