mirror of
https://github.com/HiMeditator/auto-caption.git
synced 2026-02-04 04:14:42 +08:00
feat(renderer): 增加长字幕隐藏功能 (#1)
- 修复暗色主题部分内容的显示颜色 - 添加长字幕内容隐藏功能 - 优化字幕样式预览界面,支持动态显示最新字幕内容
This commit is contained in:
@@ -6,4 +6,7 @@ indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.py]
|
||||
indent_size = 4
|
||||
|
||||
@@ -12,7 +12,7 @@ import sys
|
||||
import argparse
|
||||
|
||||
def convert_audio_to_text(s_lang, t_lang, audio_type):
|
||||
sys.stdout.reconfigure(line_buffering=True)
|
||||
sys.stdout.reconfigure(line_buffering=True) # type: ignore
|
||||
stream = AudioStream(audio_type)
|
||||
stream.openStream()
|
||||
|
||||
@@ -45,4 +45,3 @@ if __name__ == "__main__":
|
||||
args.target_language,
|
||||
0 if args.audio_type == '0' else 1
|
||||
)
|
||||
|
||||
@@ -15,6 +15,7 @@ export interface Controls {
|
||||
}
|
||||
|
||||
export interface Styles {
|
||||
lineBreak: number,
|
||||
fontFamily: string,
|
||||
fontSize: number,
|
||||
fontColor: string,
|
||||
|
||||
@@ -7,6 +7,7 @@ import * as path from 'path'
|
||||
import * as fs from 'fs'
|
||||
|
||||
const defaultStyles: Styles = {
|
||||
lineBreak: 1,
|
||||
fontFamily: 'sans-serif',
|
||||
fontSize: 24,
|
||||
fontColor: '#000000',
|
||||
|
||||
@@ -4,17 +4,13 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { FullConfig } from './types'
|
||||
import { useCaptionLogStore } from './stores/captionLog'
|
||||
import { useCaptionStyleStore } from './stores/captionStyle'
|
||||
import { useEngineControlStore } from './stores/engineControl'
|
||||
import { useGeneralSettingStore } from './stores/generalSetting'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
onMounted(() => {
|
||||
console.log('Current route:', router.currentRoute.value.fullPath)
|
||||
window.electron.ipcRenderer.invoke('both.window.mounted').then((data: FullConfig) => {
|
||||
useGeneralSettingStore().uiLanguage = data.uiLanguage
|
||||
useGeneralSettingStore().uiTheme = data.uiTheme
|
||||
|
||||
@@ -23,5 +23,5 @@
|
||||
width: 80px;
|
||||
text-align: right;
|
||||
font-size: 12px;
|
||||
color: #666
|
||||
color: var(--tag-color)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
:root {
|
||||
--control-background: #fff;
|
||||
--tag-color: rgba(0, 0, 0, 0.45);
|
||||
--icon-color: rgba(0, 0, 0, 0.88);
|
||||
}
|
||||
|
||||
body {
|
||||
|
||||
@@ -5,6 +5,16 @@
|
||||
<a @click="backStyle">{{ $t('style.cancelChange') }}</a> |
|
||||
<a @click="resetStyle">{{ $t('style.resetStyle') }}</a>
|
||||
</template>
|
||||
|
||||
<div class="input-item">
|
||||
<span class="input-label">{{ $t('style.longCaption') }}</span>
|
||||
<a-select
|
||||
class="input-area"
|
||||
v-model:value="currentLineBreak"
|
||||
:options="captionStyle.iBreakOptions"
|
||||
></a-select>
|
||||
</div>
|
||||
|
||||
<div class="input-item">
|
||||
<span class="input-label">{{ $t('style.fontFamily') }}</span>
|
||||
<a-input
|
||||
@@ -105,21 +115,26 @@
|
||||
backgroundColor: addOpicityToColor(currentBackground, currentOpacity)
|
||||
}"
|
||||
>
|
||||
<p class="preview-caption"
|
||||
<p :class="[captionStyle.lineBreak?'':'left-ellipsis']"
|
||||
:style="{
|
||||
fontFamily: currentFontFamily,
|
||||
fontSize: currentFontSize + 'px',
|
||||
color: currentFontColor
|
||||
}">
|
||||
{{ $t('example.original') }}
|
||||
}">
|
||||
<span v-if="captionData.length">{{ captionData[captionData.length-1].text }}</span>
|
||||
<span v-else>{{ $t('example.original') }}</span>
|
||||
</p>
|
||||
<p class="preview-translation" v-if="currentTransDisplay"
|
||||
<p :class="[captionStyle.lineBreak?'':'left-ellipsis']"
|
||||
v-if="currentTransDisplay"
|
||||
:style="{
|
||||
fontFamily: currentTransFontFamily,
|
||||
fontSize: currentTransFontSize + 'px',
|
||||
color: currentTransFontColor
|
||||
}"
|
||||
>{{ $t('example.translation') }}</p>
|
||||
>
|
||||
<span v-if="captionData.length">{{ captionData[captionData.length-1].translation }}</span>
|
||||
<span v-else>{{ $t('example.translation') }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</Teleport>
|
||||
|
||||
@@ -131,12 +146,17 @@ import { useCaptionStyleStore } from '@renderer/stores/captionStyle'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { notification } from 'ant-design-vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useCaptionLogStore } from '@renderer/stores/captionLog';
|
||||
|
||||
const captionLog = useCaptionLogStore();
|
||||
const { captionData } = storeToRefs(captionLog);
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const captionStyle = useCaptionStyleStore()
|
||||
const { changeSignal } = storeToRefs(captionStyle)
|
||||
|
||||
const currentLineBreak = ref<number>(0)
|
||||
const currentFontFamily = ref<string>('sans-serif')
|
||||
const currentFontSize = ref<number>(24)
|
||||
const currentFontColor = ref<string>('#000000')
|
||||
@@ -161,6 +181,7 @@ function useSameStyle(){
|
||||
}
|
||||
|
||||
function applyStyle(){
|
||||
captionStyle.lineBreak = currentLineBreak.value;
|
||||
captionStyle.fontFamily = currentFontFamily.value;
|
||||
captionStyle.fontSize = currentFontSize.value;
|
||||
captionStyle.fontColor = currentFontColor.value;
|
||||
@@ -175,12 +196,13 @@ function applyStyle(){
|
||||
captionStyle.sendStylesChange();
|
||||
|
||||
notification.open({
|
||||
message: t('noti.engineChange'),
|
||||
description: t('noti.changeInfo')
|
||||
message: t('noti.styleChange'),
|
||||
description: t('noti.styleInfo')
|
||||
});
|
||||
}
|
||||
|
||||
function backStyle(){
|
||||
currentLineBreak.value = captionStyle.lineBreak;
|
||||
currentFontFamily.value = captionStyle.fontFamily;
|
||||
currentFontSize.value = captionStyle.fontSize;
|
||||
currentFontColor.value = captionStyle.fontColor;
|
||||
@@ -221,7 +243,20 @@ watch(changeSignal, (val) => {
|
||||
}
|
||||
|
||||
.preview-container p {
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.left-ellipsis {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
direction: rtl;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.left-ellipsis > span {
|
||||
direction: ltr;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -107,7 +107,7 @@ function stopEngine() {
|
||||
|
||||
<style scoped>
|
||||
.about-tag {
|
||||
color: rgba(0,0,0,0.45);
|
||||
color: var(--tag-color);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ function stopEngine() {
|
||||
display: inline-block;
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
color: #1f2328;
|
||||
color: var(--icon-color);
|
||||
}
|
||||
|
||||
.about-modal-content {
|
||||
|
||||
32
src/renderer/src/i18n/config/linebreak.ts
Normal file
32
src/renderer/src/i18n/config/linebreak.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
export const breakOptions = {
|
||||
zh: [
|
||||
{
|
||||
value: 1,
|
||||
label: '换行(可能造成字幕窗口高度增加)'
|
||||
},
|
||||
{
|
||||
value: 0,
|
||||
label: '不换行(省略掉超出字幕窗口宽度的内容)'
|
||||
}
|
||||
],
|
||||
en: [
|
||||
{
|
||||
value: 1,
|
||||
label: 'Wrap (may increase caption window height)'
|
||||
},
|
||||
{
|
||||
value: 0,
|
||||
label: 'Do not wrap (truncate content that exceeds caption window width)'
|
||||
}
|
||||
],
|
||||
ja: [
|
||||
{
|
||||
value: 1,
|
||||
label: '改行する(字幕ウィンドウの高さが増える可能性があります)'
|
||||
},
|
||||
{
|
||||
value: 0,
|
||||
label: '改行しない(字幕ウィンドウの幅を超える内容は省略します)'
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -17,3 +17,4 @@ export const i18n = createI18n({
|
||||
export * from './config/engine'
|
||||
export * from './config/audio'
|
||||
export * from './config/theme'
|
||||
export * from './config/linebreak'
|
||||
|
||||
@@ -20,14 +20,16 @@ export default {
|
||||
"stoppedInfo": "The caption engine has stopped. You can click the 'Start Caption Engine' button to restart it.",
|
||||
"error": "An error occurred",
|
||||
"engineChange": "Cpation Engine Configuration Changed",
|
||||
"changeInfo": "If the caption engine is already running, you need to restart it for the changes to take effect."
|
||||
"changeInfo": "If the caption engine is already running, you need to restart it for the changes to take effect.",
|
||||
"styleChange": "Caption Style Changed",
|
||||
"styleInfo": "Caption style changes have been saved and applied."
|
||||
},
|
||||
general: {
|
||||
"title": "General Settings",
|
||||
"uiLanguage": "Language",
|
||||
"barWidth": "Width",
|
||||
"note": "General Settings take effect immediately. Please note that changes to the Caption Engine Settings and Caption Style Settings will only take effect after clicking Apply.",
|
||||
"theme": "theme",
|
||||
"theme": "Theme",
|
||||
"light": "light",
|
||||
"dark": "dark",
|
||||
"system": "system"
|
||||
@@ -57,6 +59,7 @@ export default {
|
||||
"applyStyle": "Apply",
|
||||
"cancelChange": "Cancel",
|
||||
"resetStyle": "Reset",
|
||||
"longCaption": "LongCaption",
|
||||
"fontFamily": "Font Family",
|
||||
"fontColor": "Font Color",
|
||||
"fontSize": "Font Size",
|
||||
|
||||
@@ -20,7 +20,9 @@ export default {
|
||||
"stoppedInfo": "字幕エンジンが停止しました。再起動するには「字幕エンジンを開始」ボタンをクリックしてください。",
|
||||
"error": "エラーが発生しました",
|
||||
"engineChange": "字幕エンジンの設定が変更されました",
|
||||
"changeInfo": "字幕エンジンがすでに起動している場合、変更を有効にするには再起動が必要です。"
|
||||
"changeInfo": "字幕エンジンがすでに起動している場合、変更を有効にするには再起動が必要です。",
|
||||
"styleChange": "字幕のスタイルが変更されました",
|
||||
"styleInfo": "字幕のスタイル変更が保存され、適用されました"
|
||||
},
|
||||
general: {
|
||||
"title": "一般設定",
|
||||
@@ -57,6 +59,7 @@ export default {
|
||||
"applyStyle": "適用",
|
||||
"cancelChange": "キャンセル",
|
||||
"resetStyle": "リセット",
|
||||
"longCaption": "長い字幕",
|
||||
"fontFamily": "フォント",
|
||||
"fontColor": "カラー",
|
||||
"fontSize": "サイズ",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export default {
|
||||
example: {
|
||||
"original": "This is a preview of caption styles.",
|
||||
"original": "This is a preview of caption styles. ",
|
||||
"translation": "(翻译)这是字幕样式预览。"
|
||||
},
|
||||
noti: {
|
||||
@@ -21,8 +21,8 @@ export default {
|
||||
"error": "发生错误",
|
||||
"engineChange": "字幕引擎配置已更改",
|
||||
"changeInfo": "如果字幕引擎已经启动,需要重启字幕引擎修改才会生效",
|
||||
"styleChange": "字幕样式修改已更改",
|
||||
"styleInfo": "字幕样式修改已经生效"
|
||||
"styleChange": "字幕样式已修改",
|
||||
"styleInfo": "字幕样式修改已经保存并生效"
|
||||
},
|
||||
general: {
|
||||
"title": "通用设置",
|
||||
@@ -59,6 +59,7 @@ export default {
|
||||
"applyStyle": "应用样式",
|
||||
"cancelChange": "取消更改",
|
||||
"resetStyle": "恢复默认",
|
||||
"longCaption": "长字幕",
|
||||
"fontFamily": "字体族",
|
||||
"fontColor": "字体颜色",
|
||||
"fontSize": "字体大小",
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { ref, computed } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
import { Styles } from '@renderer/types'
|
||||
import { breakOptions } from '@renderer/i18n'
|
||||
|
||||
export const useCaptionStyleStore = defineStore('captionStyle', () => {
|
||||
const lineBreak = ref<number>(1)
|
||||
const fontFamily = ref<string>('sans-serif')
|
||||
const fontSize = ref<number>(24)
|
||||
const fontColor = ref<string>('#000000')
|
||||
@@ -14,6 +16,7 @@ export const useCaptionStyleStore = defineStore('captionStyle', () => {
|
||||
const transFontSize = ref<number>(24)
|
||||
const transFontColor = ref<string>('#000000')
|
||||
|
||||
const iBreakOptions = ref(breakOptions['zh'])
|
||||
const changeSignal = ref<boolean>(false)
|
||||
|
||||
function addOpicityToColor(color: string, opicity: number) {
|
||||
@@ -28,6 +31,7 @@ export const useCaptionStyleStore = defineStore('captionStyle', () => {
|
||||
|
||||
function sendStylesChange() {
|
||||
const styles: Styles = {
|
||||
lineBreak: lineBreak.value,
|
||||
fontFamily: fontFamily.value,
|
||||
fontSize: fontSize.value,
|
||||
fontColor: fontColor.value,
|
||||
@@ -47,6 +51,7 @@ export const useCaptionStyleStore = defineStore('captionStyle', () => {
|
||||
}
|
||||
|
||||
function setStyles(args: Styles){
|
||||
lineBreak.value = args.lineBreak
|
||||
fontFamily.value = args.fontFamily
|
||||
fontSize.value = args.fontSize
|
||||
fontColor.value = args.fontColor
|
||||
@@ -65,6 +70,7 @@ export const useCaptionStyleStore = defineStore('captionStyle', () => {
|
||||
})
|
||||
|
||||
return {
|
||||
lineBreak, // 换行方式
|
||||
fontFamily, // 字体族
|
||||
fontSize, // 字体大小
|
||||
fontColor, // 字体颜色
|
||||
@@ -79,6 +85,7 @@ export const useCaptionStyleStore = defineStore('captionStyle', () => {
|
||||
setStyles, // 设置样式
|
||||
sendStylesChange, // 发送样式改变
|
||||
sendStylesReset, // 恢复默认样式
|
||||
iBreakOptions, // 换行选项
|
||||
changeSignal // 样式改变信号
|
||||
}
|
||||
})
|
||||
|
||||
@@ -3,8 +3,9 @@ import { defineStore } from 'pinia'
|
||||
import { i18n } from '../i18n'
|
||||
import type { UILanguage, UITheme } from '../types'
|
||||
|
||||
import { engines, audioTypes, antDesignTheme } from '../i18n'
|
||||
import { engines, audioTypes, antDesignTheme, breakOptions } from '../i18n'
|
||||
import { useEngineControlStore } from './engineControl'
|
||||
import { useCaptionStyleStore } from './captionStyle'
|
||||
|
||||
export const useGeneralSettingStore = defineStore('generalSetting', () => {
|
||||
const uiLanguage = ref<UILanguage>('zh')
|
||||
@@ -17,6 +18,7 @@ export const useGeneralSettingStore = defineStore('generalSetting', () => {
|
||||
i18n.global.locale.value = newValue
|
||||
useEngineControlStore().captionEngine = engines[newValue]
|
||||
useEngineControlStore().audioType = audioTypes[newValue]
|
||||
useCaptionStyleStore().iBreakOptions = breakOptions[newValue]
|
||||
window.electron.ipcRenderer.send('control.uiLanguage.change', newValue)
|
||||
})
|
||||
|
||||
@@ -49,12 +51,16 @@ export const useGeneralSettingStore = defineStore('generalSetting', () => {
|
||||
antdTheme.value = antDesignTheme.light
|
||||
const root = document.documentElement
|
||||
root.style.setProperty('--control-background', '#fff')
|
||||
root.style.setProperty('--tag-color', 'rgba(0, 0, 0, 0.45)')
|
||||
root.style.setProperty('--icon-color', 'rgba(0, 0, 0, 0.88)')
|
||||
}
|
||||
|
||||
function setDarkTheme(){
|
||||
antdTheme.value = antDesignTheme.dark
|
||||
const root = document.documentElement
|
||||
root.style.setProperty('--control-background', '#000')
|
||||
root.style.setProperty('--tag-color', 'rgba(255, 255, 255, 0.45)')
|
||||
root.style.setProperty('--icon-color', 'rgba(255, 255, 255, 0.85)')
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -15,6 +15,7 @@ export interface Controls {
|
||||
}
|
||||
|
||||
export interface Styles {
|
||||
lineBreak: number,
|
||||
fontFamily: string,
|
||||
fontSize: number,
|
||||
fontColor: string,
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="caption-container">
|
||||
<p class="preview-caption" :style="{
|
||||
<p :class="[captionStyle.lineBreak?'':'left-ellipsis']" :style="{
|
||||
fontFamily: captionStyle.fontFamily,
|
||||
fontSize: captionStyle.fontSize + 'px',
|
||||
color: captionStyle.fontColor
|
||||
@@ -28,7 +28,9 @@
|
||||
<span v-if="captionData.length">{{ captionData[captionData.length-1].text }}</span>
|
||||
<span v-else>{{ $t('example.original') }}</span>
|
||||
</p>
|
||||
<p class="preview-translation" v-if="captionStyle.transDisplay" :style="{
|
||||
<p :class="[captionStyle.lineBreak?'':'left-ellipsis']"
|
||||
v-if="captionStyle.transDisplay"
|
||||
:style="{
|
||||
fontFamily: captionStyle.transFontFamily,
|
||||
fontSize: captionStyle.transFontSize + 'px',
|
||||
color: captionStyle.transFontColor
|
||||
@@ -121,4 +123,16 @@ function closeCaptionWindow() {
|
||||
line-height: 1.5em;
|
||||
padding: 0 10px 10px 10px;
|
||||
}
|
||||
|
||||
.left-ellipsis {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
direction: rtl;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.left-ellipsis > span {
|
||||
direction: ltr;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -39,7 +39,7 @@ const { leftBarWidth, antdTheme } = storeToRefs(generalSettingStore)
|
||||
|
||||
.caption-control {
|
||||
height: 100vh;
|
||||
border-right: 1px solid #7774;
|
||||
border-right: 1px solid var(--tag-color);
|
||||
padding: 20px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user