mirror of
https://github.com/HiMeditator/auto-caption.git
synced 2026-02-15 04:14:46 +08:00
feat(i18n): 后端添加国际化支持、优化前端界面
- 后端添加并实现国际化支持 - 前端引入 vue-i18n 模块(尚未添加国际化逻辑) - 优化用户界面样式,统一输入框和标签样式
This commit is contained in:
22
src/renderer/src/assets/input.css
Normal file
22
src/renderer/src/assets/input.css
Normal file
@@ -0,0 +1,22 @@
|
||||
.input-item {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.input-label {
|
||||
display: inline-block;
|
||||
width: 80px;
|
||||
text-align: right;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.input-area {
|
||||
width: calc(100% - 100px);
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.input-item-value {
|
||||
width: 80px;
|
||||
text-align: right;
|
||||
font-size: 12px;
|
||||
color: #666
|
||||
}
|
||||
@@ -5,57 +5,57 @@
|
||||
<a @click="backStyle">取消更改</a> |
|
||||
<a @click="resetStyle">恢复默认</a>
|
||||
</template>
|
||||
<div class="style-item">
|
||||
<span class="style-label">字体族</span>
|
||||
<div class="input-item">
|
||||
<span class="input-label">字体族</span>
|
||||
<a-input
|
||||
class="style-input"
|
||||
class="input-area"
|
||||
v-model:value="currentFontFamily"
|
||||
/>
|
||||
/>
|
||||
</div>
|
||||
<div class="style-item">
|
||||
<span class="style-label">字体颜色</span>
|
||||
<div class="input-item">
|
||||
<span class="input-label">字体颜色</span>
|
||||
<a-input
|
||||
class="style-input"
|
||||
class="input-area"
|
||||
type="color"
|
||||
v-model:value="currentFontColor"
|
||||
/>
|
||||
<div class="style-item-value">{{ currentFontColor }}</div>
|
||||
<div class="input-item-value">{{ currentFontColor }}</div>
|
||||
</div>
|
||||
<div class="style-item">
|
||||
<span class="style-label">字体大小</span>
|
||||
<div class="input-item">
|
||||
<span class="input-label">字体大小</span>
|
||||
<a-input
|
||||
class="style-input"
|
||||
class="input-area"
|
||||
type="range"
|
||||
min="0" max="64"
|
||||
v-model:value="currentFontSize"
|
||||
/>
|
||||
<div class="style-item-value">{{ currentFontSize }}px</div>
|
||||
/>
|
||||
<div class="input-item-value">{{ currentFontSize }}px</div>
|
||||
</div>
|
||||
<div class="style-item">
|
||||
<span class="style-label">背景颜色</span>
|
||||
<div class="input-item">
|
||||
<span class="input-label">背景颜色</span>
|
||||
<a-input
|
||||
class="style-input"
|
||||
class="input-area"
|
||||
type="color"
|
||||
v-model:value="currentBackground"
|
||||
/>
|
||||
<div class="style-item-value">{{ currentBackground }}</div>
|
||||
<div class="input-item-value">{{ currentBackground }}</div>
|
||||
</div>
|
||||
<div class="style-item">
|
||||
<span class="style-label">背景透明度</span>
|
||||
<div class="input-item">
|
||||
<span class="input-label">背景透明度</span>
|
||||
<a-input
|
||||
class="style-input"
|
||||
class="input-area"
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
v-model:value="currentOpacity"
|
||||
/>
|
||||
<div class="style-item-value">{{ currentOpacity }}</div>
|
||||
<div class="input-item-value">{{ currentOpacity }}</div>
|
||||
</div>
|
||||
|
||||
<div class="style-item">
|
||||
<span class="style-label">显示预览</span>
|
||||
|
||||
<div class="input-item">
|
||||
<span class="input-label">显示预览</span>
|
||||
<a-switch v-model:checked="displayPreview" />
|
||||
<span class="style-label">显示翻译</span>
|
||||
<span class="input-label">显示翻译</span>
|
||||
<a-switch v-model:checked="currentTransDisplay" />
|
||||
</div>
|
||||
|
||||
@@ -64,31 +64,31 @@
|
||||
<template #extra>
|
||||
<a @click="useSameStyle">使用相同样式</a>
|
||||
</template>
|
||||
<div class="style-item">
|
||||
<span class="style-label">翻译字体</span>
|
||||
<div class="input-item">
|
||||
<span class="input-label">翻译字体</span>
|
||||
<a-input
|
||||
class="style-input"
|
||||
class="input-area"
|
||||
v-model:value="currentTransFontFamily"
|
||||
/>
|
||||
/>
|
||||
</div>
|
||||
<div class="style-item">
|
||||
<span class="style-label">翻译颜色</span>
|
||||
<div class="input-item">
|
||||
<span class="input-label">翻译颜色</span>
|
||||
<a-input
|
||||
class="style-input"
|
||||
class="input-area"
|
||||
type="color"
|
||||
v-model:value="currentTransFontColor"
|
||||
/>
|
||||
<div class="style-item-value">{{ currentTransFontColor }}</div>
|
||||
<div class="input-item-value">{{ currentTransFontColor }}</div>
|
||||
</div>
|
||||
<div class="style-item">
|
||||
<span class="style-label">翻译大小</span>
|
||||
<div class="input-item">
|
||||
<span class="input-label">翻译大小</span>
|
||||
<a-input
|
||||
class="style-input"
|
||||
class="input-area"
|
||||
type="range"
|
||||
min="0" max="64"
|
||||
v-model:value="currentTransFontSize"
|
||||
/>
|
||||
<div class="style-item-value">{{ currentTransFontSize }}px</div>
|
||||
/>
|
||||
<div class="input-item-value">{{ currentTransFontSize }}px</div>
|
||||
</div>
|
||||
</a-card>
|
||||
</div>
|
||||
@@ -115,10 +115,10 @@
|
||||
:style="{
|
||||
fontFamily: currentTransFontFamily,
|
||||
fontSize: currentTransFontSize + 'px',
|
||||
color: currentTransFontColor
|
||||
color: currentTransFontColor
|
||||
}"
|
||||
>这是字幕样式预览(翻译)</p>
|
||||
</div>
|
||||
</div>
|
||||
</Teleport>
|
||||
|
||||
</template>
|
||||
@@ -154,7 +154,7 @@ function useSameStyle(){
|
||||
currentTransFontColor.value = currentFontColor.value;
|
||||
}
|
||||
|
||||
function applyStyle(){
|
||||
function applyStyle(){
|
||||
captionStyle.fontFamily = currentFontFamily.value;
|
||||
captionStyle.fontSize = currentFontSize.value;
|
||||
captionStyle.fontColor = currentFontColor.value;
|
||||
@@ -182,7 +182,7 @@ function backStyle(){
|
||||
currentTransFontColor.value = captionStyle.transFontColor;
|
||||
}
|
||||
|
||||
function resetStyle() {
|
||||
function resetStyle() {
|
||||
captionStyle.sendStyleReset();
|
||||
}
|
||||
|
||||
@@ -195,33 +195,7 @@ watch(changeSignal, (val) => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.caption-button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.style-item {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.style-label {
|
||||
display: inline-block;
|
||||
width: 80px;
|
||||
text-align: right;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.style-input {
|
||||
width: calc(100% - 100px);
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.style-item-value {
|
||||
width: 80px;
|
||||
text-align: right;
|
||||
font-size: 12px;
|
||||
color: #666
|
||||
}
|
||||
@import url(../assets/input.css);
|
||||
|
||||
.preview-container {
|
||||
line-height: 2em;
|
||||
@@ -239,4 +213,4 @@ watch(changeSignal, (val) => {
|
||||
margin: 0;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -5,58 +5,58 @@
|
||||
<a @click="applyChange">更改设置</a> |
|
||||
<a @click="cancelChange">取消更改</a>
|
||||
</template>
|
||||
<div class="control-item">
|
||||
<span class="control-label">源语言</span>
|
||||
<div class="input-item">
|
||||
<span class="input-label">源语言</span>
|
||||
<a-select
|
||||
class="control-input"
|
||||
class="input-area"
|
||||
v-model:value="currentSourceLang"
|
||||
:options="langList"
|
||||
></a-select>
|
||||
</div>
|
||||
<div class="control-item">
|
||||
<span class="control-label">翻译语言</span>
|
||||
<div class="input-item">
|
||||
<span class="input-label">翻译语言</span>
|
||||
<a-select
|
||||
class="control-input"
|
||||
class="input-area"
|
||||
v-model:value="currentTargetLang"
|
||||
:options="langList.filter((item) => item.value !== 'auto')"
|
||||
></a-select>
|
||||
</div>
|
||||
<div class="control-item">
|
||||
<span class="control-label">字幕引擎</span>
|
||||
<div class="input-item">
|
||||
<span class="input-label">字幕引擎</span>
|
||||
<a-select
|
||||
class="control-input"
|
||||
class="input-area"
|
||||
v-model:value="currentEngine"
|
||||
:options="captionEngine"
|
||||
></a-select>
|
||||
</div>
|
||||
<div class="control-item">
|
||||
<span class="control-label">音频选择</span>
|
||||
<div class="input-item">
|
||||
<span class="input-label">音频选择</span>
|
||||
<a-select
|
||||
class="control-input"
|
||||
class="input-area"
|
||||
v-model:value="currentAudio"
|
||||
:options="audioType"
|
||||
></a-select>
|
||||
</div>
|
||||
<div class="control-item">
|
||||
<span class="control-label">启用翻译</span>
|
||||
<div class="input-item">
|
||||
<span class="input-label">启用翻译</span>
|
||||
<a-switch v-model:checked="currentTranslation" />
|
||||
<span class="control-label">自定义引擎</span>
|
||||
<span class="input-label">自定义引擎</span>
|
||||
<a-switch v-model:checked="currentCustomized" />
|
||||
</div>
|
||||
<div v-show="currentCustomized">
|
||||
<a-card size="small" title="自定义字幕引擎">
|
||||
<p class="customize-note">说明:允许用户使用自定义字幕引擎提供字幕。提供的引擎要能通过 <code>child_process.spawn()</code> 进行启动,且需要通过 IPC 与项目 node.js 后端进行通信。具体通信接口见后端实现。</p>
|
||||
<div class="control-item">
|
||||
<span class="control-label">引擎路径</span>
|
||||
<div class="input-item">
|
||||
<span class="input-label">引擎路径</span>
|
||||
<a-input
|
||||
class="control-input"
|
||||
class="input-area"
|
||||
v-model:value="currentCustomizedApp"
|
||||
></a-input>
|
||||
</div>
|
||||
<div class="control-item">
|
||||
<span class="control-label">引擎指令</span>
|
||||
<div class="input-item">
|
||||
<span class="input-label">引擎指令</span>
|
||||
<a-input
|
||||
class="control-input"
|
||||
class="input-area"
|
||||
v-model:value="currentCustomizedCommand"
|
||||
></a-input>
|
||||
</div>
|
||||
@@ -134,32 +134,11 @@ watch(changeSignal, (val) => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.control-item {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.control-label {
|
||||
display: inline-block;
|
||||
width: 80px;
|
||||
text-align: right;
|
||||
margin-right: 10px;
|
||||
}
|
||||
@import url(../assets/input.css);
|
||||
|
||||
.customize-note {
|
||||
padding: 0 20px;
|
||||
color: red;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.control-input {
|
||||
width: calc(100% - 100px);
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.control-item-value {
|
||||
width: 80px;
|
||||
text-align: right;
|
||||
font-size: 12px;
|
||||
color: #666
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
<a-col :span="6">
|
||||
<a-statistic title="已记录字幕" :value="captionData.length" />
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<div class="about-tag">关于本项目</div>
|
||||
<GithubOutlined class="proj-info" @click="showAbout = true"/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
|
||||
@@ -28,12 +32,45 @@
|
||||
@click="stopEngine"
|
||||
>关闭字幕引擎</a-button>
|
||||
</div>
|
||||
|
||||
<a-modal v-model:open="showAbout" title="关于本项目" :footer="null">
|
||||
<div class="about-modal-content">
|
||||
<h2 class="about-title">Auto Caption 项目</h2>
|
||||
<p class="about-desc">一个跨平台的实时字幕显示软件。</p>
|
||||
<a-divider />
|
||||
<div class="about-info">
|
||||
<p><b>作者:</b>HiMeditator</p>
|
||||
<p><b>版本:</b>v0.1.0</p>
|
||||
<p>
|
||||
<b>项目地址:</b>
|
||||
<a href="https://github.com/HiMeditator/auto-caption" target="_blank">
|
||||
GitHub | auto-caption
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<b>用户手册:</b>
|
||||
<a
|
||||
href="https://github.com/HiMeditator/auto-caption/blob/main/assets/user-manual_zh.md"
|
||||
target="_blank"
|
||||
>
|
||||
GitHub | user-manual_zh.md
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-date">2026 年 6 月 26 日</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useCaptionLogStore } from '@renderer/stores/captionLog'
|
||||
import { useEngineControlStore } from '@renderer/stores/engineControl'
|
||||
import { GithubOutlined } from '@ant-design/icons-vue';
|
||||
|
||||
const showAbout = ref(false)
|
||||
|
||||
const captionLog = useCaptionLogStore()
|
||||
const { captionData } = storeToRefs(captionLog)
|
||||
const engineControl = useEngineControlStore()
|
||||
@@ -53,6 +90,48 @@ function stopEngine() {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.about-tag {
|
||||
color: rgba(0,0,0,0.45);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.proj-info {
|
||||
display: inline-block;
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
color: #1f2328;
|
||||
}
|
||||
|
||||
.about-modal-content {
|
||||
text-align: center;
|
||||
padding: 8px 0 0 0;
|
||||
}
|
||||
|
||||
.about-title {
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.2em;
|
||||
}
|
||||
|
||||
.about-desc {
|
||||
color: #666;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.about-info {
|
||||
text-align: left;
|
||||
display: inline-block;
|
||||
margin: 0 auto;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.about-date {
|
||||
margin-top: 1.5em;
|
||||
color: #aaa;
|
||||
font-size: 0.95em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.caption-control {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
@@ -1,53 +1,29 @@
|
||||
<template>
|
||||
<a-card size="small" title="页面宽度">
|
||||
<template #extra>
|
||||
<a-button type="link" @click="showAbout = true">关于本项目</a-button>
|
||||
</template>
|
||||
<a-card size="small" title="通用设置">
|
||||
<div>
|
||||
<a-input type="range" class="span-input" min="6" max="18" v-model:value="leftBarWidth" />
|
||||
<div class="input-item">
|
||||
<span class="input-label">边栏宽度</span>
|
||||
<a-input
|
||||
type="range" class="span-input"
|
||||
min="6" max="12" v-model:value="leftBarWidth"
|
||||
/>
|
||||
<div class="input-item-value">{{ (leftBarWidth * 100 / 24).toFixed(0) }}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
|
||||
<a-modal v-model:open="showAbout" title="关于本项目" :footer="null">
|
||||
<div class="about-modal-content">
|
||||
<h2 class="about-title">Auto Caption 项目</h2>
|
||||
<p class="about-desc">一个跨平台的实时字幕显示软件。</p>
|
||||
<a-divider />
|
||||
<div class="about-info">
|
||||
<p><b>作者:</b>HiMeditator</p>
|
||||
<p><b>版本:</b>v0.1.0</p>
|
||||
<p>
|
||||
<b>项目地址:</b>
|
||||
<a href="https://github.com/HiMeditator/auto-caption" target="_blank">
|
||||
GitHub | auto-caption
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<b>用户手册:</b>
|
||||
<a
|
||||
href="https://github.com/HiMeditator/auto-caption/blob/main/assets/user-manual_zh.md"
|
||||
target="_blank"
|
||||
>
|
||||
GitHub | user-manual_zh.md
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-date">2026 年 6 月 26 日</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useGeneralSettingStore } from '@renderer/stores/generalSetting'
|
||||
|
||||
const generalSettingStore = useGeneralSettingStore()
|
||||
const { leftBarWidth } = storeToRefs(generalSettingStore)
|
||||
const showAbout = ref(false)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@import url(../assets/input.css);
|
||||
|
||||
.span-input {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
17
src/renderer/src/i18n/index.ts
Normal file
17
src/renderer/src/i18n/index.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { createI18n } from 'vue-i18n';
|
||||
|
||||
import zh from './lang/zh';
|
||||
import en from './lang/en';
|
||||
import ja from './lang/ja';
|
||||
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'zh',
|
||||
messages: {
|
||||
zh,
|
||||
en,
|
||||
ja
|
||||
}
|
||||
});
|
||||
|
||||
export default i18n;
|
||||
3
src/renderer/src/i18n/lang/en.ts
Normal file
3
src/renderer/src/i18n/lang/en.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
|
||||
}
|
||||
3
src/renderer/src/i18n/lang/ja.ts
Normal file
3
src/renderer/src/i18n/lang/ja.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
|
||||
}
|
||||
8
src/renderer/src/i18n/lang/zh.ts
Normal file
8
src/renderer/src/i18n/lang/zh.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export default {
|
||||
example: {
|
||||
"original": "This is a preview of subtitle styles.",
|
||||
"translation": "这是字幕样式预览(翻译)"
|
||||
},
|
||||
general: {
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,14 @@ import { createPinia } from 'pinia'
|
||||
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import i18n from './i18n'
|
||||
import Antd from 'ant-design-vue';
|
||||
import 'ant-design-vue/dist/reset.css';
|
||||
|
||||
const app = createApp(App)
|
||||
app.use(createPinia())
|
||||
app.use(router)
|
||||
app.use(i18n)
|
||||
app.use(Antd)
|
||||
|
||||
app.mount('#app')
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
color: captionStyle.fontColor
|
||||
}">
|
||||
<span v-if="captionData.length">{{ captionData[captionData.length-1].text }}</span>
|
||||
<span v-else>{{ "This is a preview of subtitle styles." }}</span>
|
||||
<span v-else>{{ $t('example.original') }}</span>
|
||||
</p>
|
||||
<p class="preview-translation" v-if="captionStyle.transDisplay" :style="{
|
||||
fontFamily: captionStyle.transFontFamily,
|
||||
@@ -34,7 +34,7 @@
|
||||
color: captionStyle.transFontColor
|
||||
}">
|
||||
<span v-if="captionData.length">{{ captionData[captionData.length-1].translation }}</span>
|
||||
<span v-else>{{ "这是字幕样式预览(翻译)" }}</span>
|
||||
<span v-else>{{ $t('example.translation') }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -44,34 +44,4 @@ const { leftBarWidth } = storeToRefs(generalSettingStore)
|
||||
overflow-y: auto;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
.about-modal-content {
|
||||
text-align: center;
|
||||
padding: 8px 0 0 0;
|
||||
}
|
||||
|
||||
.about-title {
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.2em;
|
||||
}
|
||||
|
||||
.about-desc {
|
||||
color: #666;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.about-info {
|
||||
text-align: left;
|
||||
display: inline-block;
|
||||
margin: 0 auto;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.about-date {
|
||||
margin-top: 1.5em;
|
||||
color: #aaa;
|
||||
font-size: 0.95em;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user