mirror of
https://github.com/HiMeditator/auto-caption.git
synced 2026-02-04 12:24:42 +08:00
refactor(renderer): 重构项目前端
- 拆分了 CaptionData 和 ControlPage 组件 - 对部分页面和变量进行了重命名 - 重构优化了状态管理,新增状态管理
This commit is contained in:
@@ -23,5 +23,7 @@
|
||||
|
||||
## v1.0.0
|
||||
|
||||
2025-07-
|
||||
|
||||
> 预计为稳定版,之后除非大改,否则版本号第一位不再改变。
|
||||
|
||||
|
||||
11
assets/technical-docs/api-doc.md
Normal file
11
assets/technical-docs/api-doc.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# api-doc
|
||||
|
||||
本文档主要记录主进程和渲染进程的通信约定。
|
||||
|
||||
## 背景知识
|
||||
|
||||
本项目渲染进程包含两个:字幕窗口和控制窗口。主进程需要分别和两者进行通信,通信命令一般有三个关键词组成,由点号隔开。
|
||||
|
||||
第一个词表示发送/接收处理对象,`config` 表示配置对象,`engine` 表示字幕引擎对象,`both` 表示两者同时。
|
||||
|
||||
比如 ``
|
||||
@@ -1,34 +1,4 @@
|
||||
<template>
|
||||
<div class="caption-stat">
|
||||
<a-row>
|
||||
<a-col :span="6">
|
||||
<a-statistic title="字幕引擎" :value="(customized && customizedApp)?'自定义':engine" />
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-statistic title="字幕引擎状态" :value="engineEnabled?'已启动':'未启动'" />
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-statistic title="已记录字幕" :value="captionData.length" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
|
||||
<div class="caption-control">
|
||||
<a-button
|
||||
type="primary"
|
||||
class="control-button"
|
||||
@click="openCaptionWindow"
|
||||
>打开字幕窗口</a-button>
|
||||
<a-button
|
||||
class="control-button"
|
||||
@click="captionControl.startEngine"
|
||||
>启动字幕引擎</a-button>
|
||||
<a-button
|
||||
danger class="control-button"
|
||||
@click="captionControl.stopEngine"
|
||||
>关闭字幕引擎</a-button>
|
||||
</div>
|
||||
|
||||
<div class="caption-list">
|
||||
<div class="caption-title">
|
||||
<span style="margin-right: 30px;">字幕记录</span>
|
||||
@@ -77,11 +47,8 @@
|
||||
import { ref } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useCaptionLogStore } from '@renderer/stores/captionLog'
|
||||
import { useCaptionControlStore } from '@renderer/stores/captionControl'
|
||||
const captionLog = useCaptionLogStore()
|
||||
const { captionData } = storeToRefs(captionLog)
|
||||
const captionControl = useCaptionControlStore()
|
||||
const { engineEnabled, engine, customized, customizedApp } = storeToRefs(captionControl)
|
||||
const pagination = ref({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
@@ -118,10 +85,6 @@ const columns = [
|
||||
},
|
||||
]
|
||||
|
||||
function openCaptionWindow() {
|
||||
window.electron.ipcRenderer.send('control.captionWindow.activate')
|
||||
}
|
||||
|
||||
function exportCaptions() {
|
||||
const jsonData = JSON.stringify(captionData.value, null, 2)
|
||||
const blob = new Blob([jsonData], { type: 'application/json' })
|
||||
@@ -142,19 +105,6 @@ function clearCaptions() {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.caption-control {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
margin: 30px;
|
||||
}
|
||||
|
||||
.control-button {
|
||||
height: 40px;
|
||||
margin: 20px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.caption-list {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
@@ -199,4 +149,4 @@ function clearCaptions() {
|
||||
padding-left: 16px;
|
||||
border-left: 3px solid #1890ff;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -69,15 +69,15 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useCaptionControlStore } from '@renderer/stores/captionControl'
|
||||
import { useEngineControlStore } from '@renderer/stores/engineControl'
|
||||
import { notification } from 'ant-design-vue'
|
||||
|
||||
const captionControl = useCaptionControlStore()
|
||||
const { captionEngine, audioType, changeSignal } = storeToRefs(captionControl)
|
||||
const engineControl = useEngineControlStore()
|
||||
const { captionEngine, audioType, changeSignal } = storeToRefs(engineControl)
|
||||
|
||||
const currentSourceLang = ref('auto')
|
||||
const currentTargetLang = ref('zh')
|
||||
const currentEngine = ref('gummy')
|
||||
const currentEngine = ref<'gummy'>('gummy')
|
||||
const currentAudio = ref<0 | 1>(0)
|
||||
const currentTranslation = ref<boolean>(false)
|
||||
|
||||
@@ -95,17 +95,17 @@ const langList = computed(() => {
|
||||
})
|
||||
|
||||
function applyChange(){
|
||||
captionControl.sourceLang = currentSourceLang.value
|
||||
captionControl.targetLang = currentTargetLang.value
|
||||
captionControl.engine = currentEngine.value
|
||||
captionControl.audio = currentAudio.value
|
||||
captionControl.translation = currentTranslation.value
|
||||
engineControl.sourceLang = currentSourceLang.value
|
||||
engineControl.targetLang = currentTargetLang.value
|
||||
engineControl.engine = currentEngine.value
|
||||
engineControl.audio = currentAudio.value
|
||||
engineControl.translation = currentTranslation.value
|
||||
|
||||
captionControl.customized = currentCustomized.value
|
||||
captionControl.customizedApp = currentCustomizedApp.value
|
||||
captionControl.customizedCommand = currentCustomizedCommand.value
|
||||
engineControl.customized = currentCustomized.value
|
||||
engineControl.customizedApp = currentCustomizedApp.value
|
||||
engineControl.customizedCommand = currentCustomizedCommand.value
|
||||
|
||||
captionControl.sendControlChange()
|
||||
engineControl.sendControlChange()
|
||||
|
||||
notification.open({
|
||||
message: '字幕控制已更改',
|
||||
@@ -114,21 +114,21 @@ function applyChange(){
|
||||
}
|
||||
|
||||
function cancelChange(){
|
||||
currentSourceLang.value = captionControl.sourceLang
|
||||
currentTargetLang.value = captionControl.targetLang
|
||||
currentEngine.value = captionControl.engine
|
||||
currentAudio.value = captionControl.audio
|
||||
currentTranslation.value = captionControl.translation
|
||||
currentSourceLang.value = engineControl.sourceLang
|
||||
currentTargetLang.value = engineControl.targetLang
|
||||
currentEngine.value = engineControl.engine
|
||||
currentAudio.value = engineControl.audio
|
||||
currentTranslation.value = engineControl.translation
|
||||
|
||||
currentCustomized.value = captionControl.customized
|
||||
currentCustomizedApp.value = captionControl.customizedApp
|
||||
currentCustomizedCommand.value = captionControl.customizedCommand
|
||||
currentCustomized.value = engineControl.customized
|
||||
currentCustomizedApp.value = engineControl.customizedApp
|
||||
currentCustomizedCommand.value = engineControl.customizedCommand
|
||||
}
|
||||
|
||||
watch(changeSignal, (val) => {
|
||||
if(val == true) {
|
||||
cancelChange();
|
||||
captionControl.changeSignal = false;
|
||||
engineControl.changeSignal = false;
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -162,4 +162,4 @@ watch(changeSignal, (val) => {
|
||||
font-size: 12px;
|
||||
color: #666
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
68
src/renderer/src/components/EngineStatus.vue
Normal file
68
src/renderer/src/components/EngineStatus.vue
Normal file
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<div class="caption-stat">
|
||||
<a-row>
|
||||
<a-col :span="6">
|
||||
<a-statistic title="字幕引擎" :value="(customized && customizedApp)?'自定义':engine" />
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-statistic title="字幕引擎状态" :value="engineEnabled?'已启动':'未启动'" />
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-statistic title="已记录字幕" :value="captionData.length" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
|
||||
<div class="caption-control">
|
||||
<a-button
|
||||
type="primary"
|
||||
class="control-button"
|
||||
@click="openCaptionWindow"
|
||||
>打开字幕窗口</a-button>
|
||||
<a-button
|
||||
class="control-button"
|
||||
@click="startEngine"
|
||||
>启动字幕引擎</a-button>
|
||||
<a-button
|
||||
danger class="control-button"
|
||||
@click="stopEngine"
|
||||
>关闭字幕引擎</a-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useCaptionLogStore } from '@renderer/stores/captionLog'
|
||||
import { useEngineControlStore } from '@renderer/stores/engineControl'
|
||||
const captionLog = useCaptionLogStore()
|
||||
const { captionData } = storeToRefs(captionLog)
|
||||
const engineControl = useEngineControlStore()
|
||||
const { engineEnabled, engine, customized, customizedApp } = storeToRefs(engineControl)
|
||||
|
||||
function openCaptionWindow() {
|
||||
window.electron.ipcRenderer.send('control.captionWindow.activate')
|
||||
}
|
||||
|
||||
function startEngine() {
|
||||
window.electron.ipcRenderer.send('control.engine.start')
|
||||
}
|
||||
|
||||
function stopEngine() {
|
||||
window.electron.ipcRenderer.send('control.engine.stop')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.caption-control {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
margin: 30px;
|
||||
}
|
||||
|
||||
.control-button {
|
||||
height: 40px;
|
||||
margin: 20px;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
54
src/renderer/src/components/GeneralSetting.vue
Normal file
54
src/renderer/src/components/GeneralSetting.vue
Normal file
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<a-card size="small" title="页面宽度">
|
||||
<template #extra>
|
||||
<a-button type="link" @click="showAbout = true">关于本项目</a-button>
|
||||
</template>
|
||||
<div>
|
||||
<a-input type="range" class="span-input" min="6" max="18" v-model:value="leftBarWidth" />
|
||||
</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>
|
||||
.span-input {
|
||||
width: 100px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,6 @@
|
||||
import './assets/reset.css'
|
||||
import { createPinia } from 'pinia'
|
||||
import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
@@ -11,4 +11,5 @@ const app = createApp(App)
|
||||
app.use(createPinia())
|
||||
app.use(router)
|
||||
app.use(Antd)
|
||||
app.mount('#app')
|
||||
|
||||
app.mount('#app')
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
import { ref } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
interface CaptionItem {
|
||||
index: number,
|
||||
time_s: string,
|
||||
time_t: string,
|
||||
text: string,
|
||||
translation: string
|
||||
}
|
||||
import { CaptionItem } from '../types'
|
||||
|
||||
export const useCaptionLogStore = defineStore('captionLog', () => {
|
||||
const captionData = ref<CaptionItem[]>([])
|
||||
@@ -34,4 +27,4 @@ export const useCaptionLogStore = defineStore('captionLog', () => {
|
||||
captionData,
|
||||
clear
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ref, computed } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
import { Styles } from '@renderer/types'
|
||||
|
||||
export const useCaptionStyleStore = defineStore('captionStyle', () => {
|
||||
const fontFamily = ref<string>('sans-serif')
|
||||
@@ -7,7 +8,7 @@ export const useCaptionStyleStore = defineStore('captionStyle', () => {
|
||||
const fontColor = ref<string>('#000000')
|
||||
const background = ref<string>('#dbe2ef')
|
||||
const opacity = ref<number>(80)
|
||||
|
||||
|
||||
const transDisplay = ref<boolean>(true)
|
||||
const transFontFamily = ref<string>('sans-serif')
|
||||
const transFontSize = ref<number>(24)
|
||||
@@ -26,7 +27,7 @@ export const useCaptionStyleStore = defineStore('captionStyle', () => {
|
||||
})
|
||||
|
||||
function sendStyleChange() {
|
||||
const styles = {
|
||||
const styles: Styles = {
|
||||
fontFamily: fontFamily.value,
|
||||
fontSize: fontSize.value,
|
||||
fontColor: fontColor.value,
|
||||
@@ -69,7 +70,7 @@ export const useCaptionStyleStore = defineStore('captionStyle', () => {
|
||||
transFontColor, // 翻译字体颜色
|
||||
backgroundRGBA, // 带透明度的背景颜色
|
||||
sendStyleChange, // 发送样式改变
|
||||
sendStyleReset, // 恢复默认样式
|
||||
sendStyleReset, // 恢复默认样式
|
||||
changeSignal // 样式改变信号
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -5,7 +5,9 @@ import { notification } from 'ant-design-vue'
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
|
||||
import { h } from 'vue'
|
||||
|
||||
export const useCaptionControlStore = defineStore('captionControl', () => {
|
||||
import { Controls } from '@renderer/types'
|
||||
|
||||
export const useEngineControlStore = defineStore('engineControl', () => {
|
||||
const captionEngine = ref([
|
||||
{
|
||||
value: 'gummy',
|
||||
@@ -39,7 +41,7 @@ export const useCaptionControlStore = defineStore('captionControl', () => {
|
||||
|
||||
const sourceLang = ref<string>('en')
|
||||
const targetLang = ref<string>('zh')
|
||||
const engine = ref<string>('gummy')
|
||||
const engine = ref<'gummy'>('gummy')
|
||||
const audio = ref<0 | 1>(0)
|
||||
const translation = ref<boolean>(true)
|
||||
const customized = ref<boolean>(false)
|
||||
@@ -49,7 +51,7 @@ export const useCaptionControlStore = defineStore('captionControl', () => {
|
||||
const changeSignal = ref<boolean>(false)
|
||||
|
||||
function sendControlChange() {
|
||||
const controls = {
|
||||
const controls: Controls = {
|
||||
engineEnabled: engineEnabled.value,
|
||||
sourceLang: sourceLang.value,
|
||||
targetLang: targetLang.value,
|
||||
@@ -63,14 +65,6 @@ export const useCaptionControlStore = defineStore('captionControl', () => {
|
||||
window.electron.ipcRenderer.send('control.control.change', controls)
|
||||
}
|
||||
|
||||
function startEngine() {
|
||||
window.electron.ipcRenderer.send('control.engine.start')
|
||||
}
|
||||
|
||||
function stopEngine() {
|
||||
window.electron.ipcRenderer.send('control.engine.stop')
|
||||
}
|
||||
|
||||
window.electron.ipcRenderer.on('control.control.set', (_, controls) => {
|
||||
sourceLang.value = controls.sourceLang
|
||||
targetLang.value = controls.targetLang
|
||||
@@ -84,16 +78,16 @@ export const useCaptionControlStore = defineStore('captionControl', () => {
|
||||
changeSignal.value = true
|
||||
})
|
||||
|
||||
window.electron.ipcRenderer.on('control.engine.already', () => {
|
||||
window.electron.ipcRenderer.on('control.engine.already', () => {
|
||||
notification.open({
|
||||
message: '字幕引擎已经启动',
|
||||
description: '字幕引擎已经启动,请勿重复启动'
|
||||
});
|
||||
})
|
||||
|
||||
window.electron.ipcRenderer.on('control.engine.started', () => {
|
||||
const str0 =
|
||||
`原语言:${sourceLang.value},是否翻译:${translation.value?'是':'否'},` +
|
||||
|
||||
window.electron.ipcRenderer.on('control.engine.started', () => {
|
||||
const str0 =
|
||||
`原语言:${sourceLang.value},是否翻译:${translation.value?'是':'否'},` +
|
||||
`字幕引擎:${engine.value},音频类型:${audio.value ? '输入音频' : '输出音频'}` +
|
||||
(translation.value ? `,翻译语言:${targetLang.value}` : '');
|
||||
const str1 = `类型:自定义引擎,引擎路径:${customizedApp.value},命令参数:${customizedCommand.value}`;
|
||||
@@ -103,14 +97,14 @@ export const useCaptionControlStore = defineStore('captionControl', () => {
|
||||
});
|
||||
})
|
||||
|
||||
window.electron.ipcRenderer.on('control.engine.stopped', () => {
|
||||
window.electron.ipcRenderer.on('control.engine.stopped', () => {
|
||||
notification.open({
|
||||
message: '字幕引擎停止',
|
||||
description: '可点击“启动字幕引擎”按钮重新启动'
|
||||
});
|
||||
})
|
||||
|
||||
window.electron.ipcRenderer.on('control.error.send', (_, message) => {
|
||||
window.electron.ipcRenderer.on('control.error.send', (_, message) => {
|
||||
notification.open({
|
||||
message: '发生错误',
|
||||
description: message,
|
||||
@@ -133,8 +127,6 @@ export const useCaptionControlStore = defineStore('captionControl', () => {
|
||||
customizedApp, // 自定义字幕引擎的应用程序
|
||||
customizedCommand, // 自定义字幕引擎的命令
|
||||
sendControlChange, // 发送最新控制消息到后端
|
||||
startEngine, // 启动字幕引擎
|
||||
stopEngine, // 停止字幕引擎
|
||||
changeSignal, // 配置改变信号
|
||||
}
|
||||
})
|
||||
})
|
||||
9
src/renderer/src/stores/generalSetting.ts
Normal file
9
src/renderer/src/stores/generalSetting.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { ref } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useGeneralSettingStore = defineStore('generalSetting', () => {
|
||||
const leftBarWidth = ref<number>(8)
|
||||
return {
|
||||
leftBarWidth
|
||||
}
|
||||
})
|
||||
33
src/renderer/src/types/index.ts
Normal file
33
src/renderer/src/types/index.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
export type UILanguage = "zh" | "en" | "ja"
|
||||
|
||||
export interface Styles {
|
||||
fontFamily: string,
|
||||
fontSize: number,
|
||||
fontColor: string,
|
||||
background: string,
|
||||
opacity: number,
|
||||
transDisplay: boolean,
|
||||
transFontFamily: string,
|
||||
transFontSize: number,
|
||||
transFontColor: string
|
||||
}
|
||||
|
||||
export interface CaptionItem {
|
||||
index: number,
|
||||
time_s: string,
|
||||
time_t: string,
|
||||
text: string,
|
||||
translation: string
|
||||
}
|
||||
|
||||
export interface Controls {
|
||||
engineEnabled: boolean,
|
||||
sourceLang: string,
|
||||
targetLang: string,
|
||||
engine: 'gummy',
|
||||
audio: 0 | 1,
|
||||
translation: boolean,
|
||||
customized: boolean,
|
||||
customizedApp: string,
|
||||
customizedCommand: string
|
||||
}
|
||||
@@ -111,7 +111,7 @@ function closeCaptionWindow() {
|
||||
background-color: #2221;
|
||||
}
|
||||
|
||||
.caption-container {
|
||||
.caption-container {
|
||||
-webkit-app-region: drag;
|
||||
}
|
||||
|
||||
@@ -121,4 +121,4 @@ function closeCaptionWindow() {
|
||||
line-height: 1.5em;
|
||||
padding: 0 10px 10px 10px;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -1,63 +1,32 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-row>
|
||||
<a-col :span="controlSpan">
|
||||
<div class="caption-control">
|
||||
<a-card size="small" title="页面宽度">
|
||||
<template #extra>
|
||||
<a-button type="link" @click="showAbout = true">关于本项目</a-button>
|
||||
</template>
|
||||
<div>
|
||||
<a-input type="range" class="span-input" min="6" max="18" v-model:value="controlSpan" />
|
||||
</div>
|
||||
</a-card>
|
||||
<CaptionControl />
|
||||
<CaptionStyle />
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="24 - controlSpan">
|
||||
<div class="caption-data">
|
||||
<CaptionData />
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<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>
|
||||
<a-row>
|
||||
<a-col :span="leftBarWidth">
|
||||
<div class="caption-control">
|
||||
<GeneralSetting />
|
||||
<EngineControl />
|
||||
<CaptionStyle />
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="24 - leftBarWidth">
|
||||
<div class="caption-data">
|
||||
<EngineStatus />
|
||||
<CaptionLog />
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import GeneralSetting from '../components/GeneralSetting.vue'
|
||||
import CaptionStyle from '../components/CaptionStyle.vue'
|
||||
import CaptionControl from '../components/CaptionControl.vue';
|
||||
import CaptionData from '../components/CaptionData.vue'
|
||||
import { ref } from 'vue'
|
||||
const controlSpan = ref(8)
|
||||
const showAbout = ref(false)
|
||||
import EngineControl from '../components/EngineControl.vue'
|
||||
import EngineStatus from '@renderer/components/EngineStatus.vue'
|
||||
import CaptionLog from '../components/CaptionLog.vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useGeneralSettingStore } from '@renderer/stores/generalSetting'
|
||||
|
||||
const generalSettingStore = useGeneralSettingStore()
|
||||
const { leftBarWidth } = storeToRefs(generalSettingStore)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -76,10 +45,6 @@ const showAbout = ref(false)
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
.span-input {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.about-modal-content {
|
||||
text-align: center;
|
||||
padding: 8px 0 0 0;
|
||||
@@ -109,4 +74,4 @@ const showAbout = ref(false)
|
||||
font-size: 0.95em;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user