mirror of
https://github.com/HiMeditator/auto-caption.git
synced 2026-03-07 03:47:29 +08:00
feat(log): 添加软件日志功能
- 新增 SoftwareLog 相关接口和数据结构 - 实现日志数据的收集和展示 - 添加日志相关的国际化支持 - 优化控制页面布局,支持日志切换显示
This commit is contained in:
@@ -284,6 +284,16 @@
|
|||||||
|
|
||||||
**数据类型:** `Controls`
|
**数据类型:** `Controls`
|
||||||
|
|
||||||
|
### `control.softwareLog.add`
|
||||||
|
|
||||||
|
**介绍:** 添加一条新的日志数据
|
||||||
|
|
||||||
|
**发起方:** 后端
|
||||||
|
|
||||||
|
**接收方:** 前端控制窗口
|
||||||
|
|
||||||
|
**数据类型:** `SoftwareLog`
|
||||||
|
|
||||||
### `both.styles.set`
|
### `both.styles.set`
|
||||||
|
|
||||||
**介绍:** 后端将最新字幕样式发送给前端,前端进行设置
|
**介绍:** 后端将最新字幕样式发送给前端,前端进行设置
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ if __name__ == "__main__":
|
|||||||
# vosk only
|
# vosk only
|
||||||
parser.add_argument('-m', '--model_path', default='', help='The path to the vosk model.')
|
parser.add_argument('-m', '--model_path', default='', help='The path to the vosk model.')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
if int(args.port) == 0:
|
if int(args.port) == 0:
|
||||||
thread_data.status = "running"
|
thread_data.status = "running"
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -7,8 +7,10 @@ import icon from '../../build/icon.png?asset'
|
|||||||
import { captionWindow } from './CaptionWindow'
|
import { captionWindow } from './CaptionWindow'
|
||||||
import { allConfig } from './utils/AllConfig'
|
import { allConfig } from './utils/AllConfig'
|
||||||
import { captionEngine } from './utils/CaptionEngine'
|
import { captionEngine } from './utils/CaptionEngine'
|
||||||
|
import { Log } from './utils/Log'
|
||||||
|
|
||||||
class ControlWindow {
|
class ControlWindow {
|
||||||
|
mounted: boolean = false;
|
||||||
window: BrowserWindow | undefined;
|
window: BrowserWindow | undefined;
|
||||||
|
|
||||||
public createWindow(): void {
|
public createWindow(): void {
|
||||||
@@ -34,6 +36,7 @@ class ControlWindow {
|
|||||||
})
|
})
|
||||||
|
|
||||||
this.window.on('closed', () => {
|
this.window.on('closed', () => {
|
||||||
|
this.mounted = false
|
||||||
this.window = undefined
|
this.window = undefined
|
||||||
allConfig.writeConfig()
|
allConfig.writeConfig()
|
||||||
})
|
})
|
||||||
@@ -63,7 +66,8 @@ class ControlWindow {
|
|||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.handle('both.window.mounted', () => {
|
ipcMain.handle('both.window.mounted', () => {
|
||||||
return allConfig.getFullConfig()
|
this.mounted = true
|
||||||
|
return allConfig.getFullConfig(Log.getAndClearLogQueue())
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.handle('control.nativeTheme.get', () => {
|
ipcMain.handle('control.nativeTheme.get', () => {
|
||||||
|
|||||||
@@ -45,6 +45,13 @@ export interface CaptionItem {
|
|||||||
translation: string
|
translation: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SoftwareLogItem {
|
||||||
|
type: "INFO" | "WARN" | "ERROR",
|
||||||
|
index: number,
|
||||||
|
time: string,
|
||||||
|
text: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface FullConfig {
|
export interface FullConfig {
|
||||||
platform: string,
|
platform: string,
|
||||||
uiLanguage: UILanguage,
|
uiLanguage: UILanguage,
|
||||||
@@ -53,7 +60,8 @@ export interface FullConfig {
|
|||||||
leftBarWidth: number,
|
leftBarWidth: number,
|
||||||
styles: Styles,
|
styles: Styles,
|
||||||
controls: Controls,
|
controls: Controls,
|
||||||
captionLog: CaptionItem[]
|
captionLog: CaptionItem[],
|
||||||
|
softwareLog: SoftwareLogItem[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EngineInfo {
|
export interface EngineInfo {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
UILanguage, UITheme, Styles, Controls,
|
UILanguage, UITheme, Styles, Controls,
|
||||||
CaptionItem, FullConfig
|
CaptionItem, FullConfig, SoftwareLogItem
|
||||||
} from '../types'
|
} from '../types'
|
||||||
import { Log } from './Log'
|
import { Log } from './Log'
|
||||||
import { app, BrowserWindow } from 'electron'
|
import { app, BrowserWindow } from 'electron'
|
||||||
@@ -88,7 +88,7 @@ class AllConfig {
|
|||||||
Log.info('Write Config to:', configPath)
|
Log.info('Write Config to:', configPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
public getFullConfig(): FullConfig {
|
public getFullConfig(softwareLog: SoftwareLogItem[]): FullConfig {
|
||||||
return {
|
return {
|
||||||
platform: process.platform,
|
platform: process.platform,
|
||||||
uiLanguage: this.uiLanguage,
|
uiLanguage: this.uiLanguage,
|
||||||
@@ -97,7 +97,8 @@ class AllConfig {
|
|||||||
leftBarWidth: this.leftBarWidth,
|
leftBarWidth: this.leftBarWidth,
|
||||||
styles: this.styles,
|
styles: this.styles,
|
||||||
controls: this.controls,
|
controls: this.controls,
|
||||||
captionLog: this.captionLog
|
captionLog: this.captionLog,
|
||||||
|
softwareLog: softwareLog
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,12 +85,16 @@ export class CaptionEngine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log.info('Engine Path:', this.appPath)
|
Log.info('Engine Path:', this.appPath)
|
||||||
Log.info('Engine Command:', this.command)
|
if(this.command.length > 2 && this.command.at(-2) === '-k') {
|
||||||
|
const _command = [...this.command]
|
||||||
|
_command[_command.length -1] = _command[_command.length -1].replace(/./g, '*')
|
||||||
|
Log.info('Engine Command:', _command)
|
||||||
|
}
|
||||||
|
else Log.info('Engine Command:', this.command)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
public connect() {
|
public connect() {
|
||||||
Log.info('Connecting to caption engine server...')
|
|
||||||
if(this.client) { Log.warn('Client already exists, ignoring...') }
|
if(this.client) { Log.warn('Client already exists, ignoring...') }
|
||||||
this.client = net.createConnection({ port: this.port }, () => {
|
this.client = net.createConnection({ port: this.port }, () => {
|
||||||
Log.info('Connected to caption engine server');
|
Log.info('Connected to caption engine server');
|
||||||
@@ -177,7 +181,6 @@ export class CaptionEngine {
|
|||||||
this.client = undefined
|
this.client = undefined
|
||||||
}
|
}
|
||||||
this.status = 'stopping'
|
this.status = 'stopping'
|
||||||
Log.info('Caption engine process stopping...')
|
|
||||||
this.timerID = setTimeout(() => {
|
this.timerID = setTimeout(() => {
|
||||||
if(this.status !== 'stopping') return
|
if(this.status !== 'stopping') return
|
||||||
Log.warn('Engine process still not stopped, trying to kill...')
|
Log.warn('Engine process still not stopped, trying to kill...')
|
||||||
@@ -226,7 +229,7 @@ function handleEngineData(data: any) {
|
|||||||
Log.info('Engine Info:', data.content)
|
Log.info('Engine Info:', data.content)
|
||||||
}
|
}
|
||||||
else if(data.command === 'usage') {
|
else if(data.command === 'usage') {
|
||||||
Log.info('Engine Usage: ', data.content)
|
Log.info('Engine Token Usage: ', data.content)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Log.warn('Unknown command:', data)
|
Log.warn('Unknown command:', data)
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
import { controlWindow } from "../ControlWindow"
|
||||||
|
import { type SoftwareLogItem } from "../types"
|
||||||
|
|
||||||
|
let logIndex = 0
|
||||||
|
const logQueue: SoftwareLogItem[] = []
|
||||||
|
|
||||||
function getTimeString() {
|
function getTimeString() {
|
||||||
const now = new Date()
|
const now = new Date()
|
||||||
const HH = String(now.getHours()).padStart(2, '0')
|
const HH = String(now.getHours()).padStart(2, '0')
|
||||||
@@ -8,15 +14,45 @@ function getTimeString() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Log {
|
export class Log {
|
||||||
|
static getAndClearLogQueue() {
|
||||||
|
const copiedQueue = structuredClone(logQueue)
|
||||||
|
logQueue.length = 0
|
||||||
|
return copiedQueue
|
||||||
|
}
|
||||||
|
|
||||||
|
static handleLog(logType: "INFO" | "WARN" | "ERROR", ...msg: any[]) {
|
||||||
|
const timeStr = getTimeString()
|
||||||
|
const logPre = `[${logType} ${timeStr}]`
|
||||||
|
let logStr = ""
|
||||||
|
for(let i = 0; i < msg.length; i++) {
|
||||||
|
logStr += i ? " " : ""
|
||||||
|
if(typeof msg[i] === "string") logStr += msg[i]
|
||||||
|
else logStr += JSON.stringify(msg[i], undefined, 2)
|
||||||
|
}
|
||||||
|
console.log(logPre, logStr)
|
||||||
|
const logItem: SoftwareLogItem = {
|
||||||
|
type: logType,
|
||||||
|
index: ++logIndex,
|
||||||
|
time: timeStr,
|
||||||
|
text: logStr
|
||||||
|
}
|
||||||
|
if(controlWindow.mounted && controlWindow.window) {
|
||||||
|
controlWindow.window.webContents.send('control.softwareLog.add', logItem)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logQueue.push(logItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static info(...msg: any[]){
|
static info(...msg: any[]){
|
||||||
console.log(`[INFO ${getTimeString()}]`, ...msg)
|
this.handleLog("INFO", ...msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static warn(...msg: any[]){
|
static warn(...msg: any[]){
|
||||||
console.warn(`[WARN ${getTimeString()}]`, ...msg)
|
this.handleLog("WARN", ...msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static error(...msg: any[]){
|
static error(...msg: any[]){
|
||||||
console.error(`[ERROR ${getTimeString()}]`, ...msg)
|
this.handleLog("ERROR", ...msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<title>Auto Caption</title>
|
<title>Auto Caption v0.7.0</title>
|
||||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||||
<meta
|
<meta
|
||||||
http-equiv="Content-Security-Policy"
|
http-equiv="Content-Security-Policy"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
import { onMounted } from 'vue'
|
import { onMounted } from 'vue'
|
||||||
import { FullConfig } from './types'
|
import { FullConfig } from './types'
|
||||||
import { useCaptionLogStore } from './stores/captionLog'
|
import { useCaptionLogStore } from './stores/captionLog'
|
||||||
|
import { useSoftwareLogStore } from './stores/softwareLog'
|
||||||
import { useCaptionStyleStore } from './stores/captionStyle'
|
import { useCaptionStyleStore } from './stores/captionStyle'
|
||||||
import { useEngineControlStore } from './stores/engineControl'
|
import { useEngineControlStore } from './stores/engineControl'
|
||||||
import { useGeneralSettingStore } from './stores/generalSetting'
|
import { useGeneralSettingStore } from './stores/generalSetting'
|
||||||
@@ -20,6 +21,7 @@ onMounted(() => {
|
|||||||
useEngineControlStore().platform = data.platform
|
useEngineControlStore().platform = data.platform
|
||||||
useEngineControlStore().setControls(data.controls)
|
useEngineControlStore().setControls(data.controls)
|
||||||
useCaptionLogStore().captionData = data.captionLog
|
useCaptionLogStore().captionData = data.captionLog
|
||||||
|
useSoftwareLogStore().softwareLogs = data.softwareLog
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,141 +1,139 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="caption-list">
|
<div>
|
||||||
<div>
|
<div class="caption-title">
|
||||||
<a-app class="caption-title">
|
<span style="margin-right: 30px;">{{ $t('log.title') }}</span>
|
||||||
<span style="margin-right: 30px;">{{ $t('log.title') }}</span>
|
|
||||||
</a-app>
|
|
||||||
<a-popover :title="$t('log.baseTime')">
|
|
||||||
<template #content>
|
|
||||||
<div class="base-time">
|
|
||||||
<div class="base-time-container">
|
|
||||||
<a-input
|
|
||||||
type="number" min="0"
|
|
||||||
v-model:value="baseHH"
|
|
||||||
></a-input>
|
|
||||||
<span class="base-time-label">{{ $t('log.hour') }}</span>
|
|
||||||
</div>
|
|
||||||
</div><span style="margin: 0 4px;">:</span>
|
|
||||||
<div class="base-time">
|
|
||||||
<div class="base-time-container">
|
|
||||||
<a-input
|
|
||||||
type="number" min="0" max="59"
|
|
||||||
v-model:value="baseMM"
|
|
||||||
></a-input>
|
|
||||||
<span class="base-time-label">{{ $t('log.min') }}</span>
|
|
||||||
</div>
|
|
||||||
</div><span style="margin: 0 4px;">:</span>
|
|
||||||
<div class="base-time">
|
|
||||||
<div class="base-time-container">
|
|
||||||
<a-input
|
|
||||||
type="number" min="0" max="59"
|
|
||||||
v-model:value="baseSS"
|
|
||||||
></a-input>
|
|
||||||
<span class="base-time-label">{{ $t('log.sec') }}</span>
|
|
||||||
</div>
|
|
||||||
</div><span style="margin: 0 4px;">.</span>
|
|
||||||
<div class="base-time">
|
|
||||||
<div class="base-time-container">
|
|
||||||
<a-input
|
|
||||||
type="number" min="0" max="999"
|
|
||||||
v-model:value="baseMS"
|
|
||||||
></a-input>
|
|
||||||
<span class="base-time-label">{{ $t('log.ms') }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<a-button
|
|
||||||
type="primary"
|
|
||||||
style="margin-right: 20px;"
|
|
||||||
@click="changeBaseTime"
|
|
||||||
:disabled="captionData.length === 0"
|
|
||||||
>{{ $t('log.changeTime') }}</a-button>
|
|
||||||
</a-popover>
|
|
||||||
<a-popover :title="$t('log.exportOptions')">
|
|
||||||
<template #content>
|
|
||||||
<div class="input-item">
|
|
||||||
<span class="input-label">{{ $t('log.exportFormat') }}</span>
|
|
||||||
<a-radio-group v-model:value="exportFormat">
|
|
||||||
<a-radio-button value="srt"><code>.srt</code></a-radio-button>
|
|
||||||
<a-radio-button value="json"><code>.json</code></a-radio-button>
|
|
||||||
</a-radio-group>
|
|
||||||
</div>
|
|
||||||
<div class="input-item">
|
|
||||||
<span class="input-label">{{ $t('log.exportContent') }}</span>
|
|
||||||
<a-radio-group v-model:value="contentOption">
|
|
||||||
<a-radio-button value="both">{{ $t('log.both') }}</a-radio-button>
|
|
||||||
<a-radio-button value="source">{{ $t('log.source') }}</a-radio-button>
|
|
||||||
<a-radio-button value="target">{{ $t('log.translation') }}</a-radio-button>
|
|
||||||
</a-radio-group>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<a-button
|
|
||||||
style="margin-right: 20px;"
|
|
||||||
@click="exportCaptions"
|
|
||||||
:disabled="captionData.length === 0"
|
|
||||||
>{{ $t('log.export') }}</a-button>
|
|
||||||
</a-popover>
|
|
||||||
<a-popover :title="$t('log.copyOptions')">
|
|
||||||
<template #content>
|
|
||||||
<div class="input-item">
|
|
||||||
<span class="input-label">{{ $t('log.addIndex') }}</span>
|
|
||||||
<a-switch v-model:checked="showIndex" />
|
|
||||||
<span class="input-label">{{ $t('log.copyTime') }}</span>
|
|
||||||
<a-switch v-model:checked="copyTime" />
|
|
||||||
</div>
|
|
||||||
<div class="input-item">
|
|
||||||
<span class="input-label">{{ $t('log.copyContent') }}</span>
|
|
||||||
<a-radio-group v-model:value="contentOption">
|
|
||||||
<a-radio-button value="both">{{ $t('log.both') }}</a-radio-button>
|
|
||||||
<a-radio-button value="source">{{ $t('log.source') }}</a-radio-button>
|
|
||||||
<a-radio-button value="target">{{ $t('log.translation') }}</a-radio-button>
|
|
||||||
</a-radio-group>
|
|
||||||
</div>
|
|
||||||
<div class="input-item">
|
|
||||||
<span class="input-label">{{ $t('log.copyNum') }}</span>
|
|
||||||
<a-radio-group v-model:value="copyNum">
|
|
||||||
<a-radio-button :value="0"><code>[:]</code></a-radio-button>
|
|
||||||
<a-radio-button :value="1"><code>[-1:]</code></a-radio-button>
|
|
||||||
<a-radio-button :value="2"><code>[-2:]</code></a-radio-button>
|
|
||||||
<a-radio-button :value="3"><code>[-3:]</code></a-radio-button>
|
|
||||||
</a-radio-group>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<a-button
|
|
||||||
style="margin-right: 20px;"
|
|
||||||
@click="copyCaptions"
|
|
||||||
>{{ $t('log.copy') }}</a-button>
|
|
||||||
</a-popover>
|
|
||||||
<a-button
|
|
||||||
danger
|
|
||||||
@click="clearCaptions"
|
|
||||||
>{{ $t('log.clear') }}</a-button>
|
|
||||||
</div>
|
</div>
|
||||||
|
<a-popover :title="$t('log.baseTime')">
|
||||||
<a-table
|
<template #content>
|
||||||
:columns="columns"
|
<div class="base-time">
|
||||||
:data-source="captionData"
|
<div class="base-time-container">
|
||||||
v-model:pagination="pagination"
|
<a-input
|
||||||
style="margin-top: 10px;"
|
type="number" min="0"
|
||||||
>
|
v-model:value="baseHH"
|
||||||
<template #bodyCell="{ column, record }">
|
></a-input>
|
||||||
<template v-if="column.key === 'index'">
|
<span class="base-time-label">{{ $t('log.hour') }}</span>
|
||||||
{{ record.index }}
|
|
||||||
</template>
|
|
||||||
<template v-if="column.key === 'time'">
|
|
||||||
<div class="time-cell">
|
|
||||||
<div class="time-start">{{ record.time_s }}</div>
|
|
||||||
<div class="time-end">{{ record.time_t }}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</div><span style="margin: 0 4px;">:</span>
|
||||||
<template v-if="column.key === 'content'">
|
<div class="base-time">
|
||||||
<div class="caption-content">
|
<div class="base-time-container">
|
||||||
<div class="caption-text">{{ record.text }}</div>
|
<a-input
|
||||||
<div class="caption-translation">{{ record.translation }}</div>
|
type="number" min="0" max="59"
|
||||||
|
v-model:value="baseMM"
|
||||||
|
></a-input>
|
||||||
|
<span class="base-time-label">{{ $t('log.min') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</div><span style="margin: 0 4px;">:</span>
|
||||||
|
<div class="base-time">
|
||||||
|
<div class="base-time-container">
|
||||||
|
<a-input
|
||||||
|
type="number" min="0" max="59"
|
||||||
|
v-model:value="baseSS"
|
||||||
|
></a-input>
|
||||||
|
<span class="base-time-label">{{ $t('log.sec') }}</span>
|
||||||
|
</div>
|
||||||
|
</div><span style="margin: 0 4px;">.</span>
|
||||||
|
<div class="base-time">
|
||||||
|
<div class="base-time-container">
|
||||||
|
<a-input
|
||||||
|
type="number" min="0" max="999"
|
||||||
|
v-model:value="baseMS"
|
||||||
|
></a-input>
|
||||||
|
<span class="base-time-label">{{ $t('log.ms') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</a-table>
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
style="margin-right: 20px;"
|
||||||
|
@click="changeBaseTime"
|
||||||
|
:disabled="captionData.length === 0"
|
||||||
|
>{{ $t('log.changeTime') }}</a-button>
|
||||||
|
</a-popover>
|
||||||
|
<a-popover :title="$t('log.exportOptions')">
|
||||||
|
<template #content>
|
||||||
|
<div class="input-item">
|
||||||
|
<span class="input-label">{{ $t('log.exportFormat') }}</span>
|
||||||
|
<a-radio-group v-model:value="exportFormat">
|
||||||
|
<a-radio-button value="srt"><code>.srt</code></a-radio-button>
|
||||||
|
<a-radio-button value="json"><code>.json</code></a-radio-button>
|
||||||
|
</a-radio-group>
|
||||||
|
</div>
|
||||||
|
<div class="input-item">
|
||||||
|
<span class="input-label">{{ $t('log.exportContent') }}</span>
|
||||||
|
<a-radio-group v-model:value="contentOption">
|
||||||
|
<a-radio-button value="both">{{ $t('log.both') }}</a-radio-button>
|
||||||
|
<a-radio-button value="source">{{ $t('log.source') }}</a-radio-button>
|
||||||
|
<a-radio-button value="target">{{ $t('log.translation') }}</a-radio-button>
|
||||||
|
</a-radio-group>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<a-button
|
||||||
|
style="margin-right: 20px;"
|
||||||
|
@click="exportCaptions"
|
||||||
|
:disabled="captionData.length === 0"
|
||||||
|
>{{ $t('log.export') }}</a-button>
|
||||||
|
</a-popover>
|
||||||
|
<a-popover :title="$t('log.copyOptions')">
|
||||||
|
<template #content>
|
||||||
|
<div class="input-item">
|
||||||
|
<span class="input-label">{{ $t('log.addIndex') }}</span>
|
||||||
|
<a-switch v-model:checked="showIndex" />
|
||||||
|
<span class="input-label">{{ $t('log.copyTime') }}</span>
|
||||||
|
<a-switch v-model:checked="copyTime" />
|
||||||
|
</div>
|
||||||
|
<div class="input-item">
|
||||||
|
<span class="input-label">{{ $t('log.copyContent') }}</span>
|
||||||
|
<a-radio-group v-model:value="contentOption">
|
||||||
|
<a-radio-button value="both">{{ $t('log.both') }}</a-radio-button>
|
||||||
|
<a-radio-button value="source">{{ $t('log.source') }}</a-radio-button>
|
||||||
|
<a-radio-button value="target">{{ $t('log.translation') }}</a-radio-button>
|
||||||
|
</a-radio-group>
|
||||||
|
</div>
|
||||||
|
<div class="input-item">
|
||||||
|
<span class="input-label">{{ $t('log.copyNum') }}</span>
|
||||||
|
<a-radio-group v-model:value="copyNum">
|
||||||
|
<a-radio-button :value="0"><code>[:]</code></a-radio-button>
|
||||||
|
<a-radio-button :value="1"><code>[-1:]</code></a-radio-button>
|
||||||
|
<a-radio-button :value="2"><code>[-2:]</code></a-radio-button>
|
||||||
|
<a-radio-button :value="3"><code>[-3:]</code></a-radio-button>
|
||||||
|
</a-radio-group>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<a-button
|
||||||
|
style="margin-right: 20px;"
|
||||||
|
@click="copyCaptions"
|
||||||
|
>{{ $t('log.copy') }}</a-button>
|
||||||
|
</a-popover>
|
||||||
|
<a-button
|
||||||
|
danger
|
||||||
|
@click="clearCaptions"
|
||||||
|
>{{ $t('log.clear') }}</a-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<a-table
|
||||||
|
:columns="columns"
|
||||||
|
:data-source="captionData"
|
||||||
|
v-model:pagination="pagination"
|
||||||
|
style="margin-top: 10px;"
|
||||||
|
>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'index'">
|
||||||
|
{{ record.index }}
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'time'">
|
||||||
|
<div class="time-cell">
|
||||||
|
<div class="time-start">{{ record.time_s }}</div>
|
||||||
|
<div class="time-end">{{ record.time_t }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'content'">
|
||||||
|
<div class="caption-content">
|
||||||
|
<div class="caption-text">{{ record.text }}</div>
|
||||||
|
<div class="caption-translation">{{ record.translation }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -195,7 +193,7 @@ const columns = [
|
|||||||
title: 'time',
|
title: 'time',
|
||||||
dataIndex: 'time',
|
dataIndex: 'time',
|
||||||
key: 'time',
|
key: 'time',
|
||||||
width: 160,
|
width: 150,
|
||||||
sorter: (a: CaptionItem, b: CaptionItem) => {
|
sorter: (a: CaptionItem, b: CaptionItem) => {
|
||||||
if(a.time_s <= b.time_s) return -1
|
if(a.time_s <= b.time_s) return -1
|
||||||
return 1
|
return 1
|
||||||
@@ -300,7 +298,7 @@ function clearCaptions() {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin-bottom: 10px;
|
margin: 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.base-time {
|
.base-time {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="caption-stat">
|
<div class="caption-stat">
|
||||||
<a-row>
|
<a-row>
|
||||||
<a-col :span="6">
|
<a-col :span="5">
|
||||||
<a-statistic
|
<a-statistic
|
||||||
:title="$t('status.engine')"
|
:title="$t('status.engine')"
|
||||||
:value="customized?$t('status.customized'):engine"
|
:value="customized?$t('status.customized'):engine"
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
</template>
|
</template>
|
||||||
<a-col :span="6" @mouseenter="getEngineInfo" style="cursor: pointer;">
|
<a-col :span="5" @mouseenter="getEngineInfo" style="cursor: pointer;">
|
||||||
<a-statistic
|
<a-statistic
|
||||||
:title="$t('status.status')"
|
:title="$t('status.status')"
|
||||||
:value="engineEnabled?$t('status.started'):$t('status.stopped')"
|
:value="engineEnabled?$t('status.started'):$t('status.stopped')"
|
||||||
@@ -47,10 +47,13 @@
|
|||||||
</a-statistic>
|
</a-statistic>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-popover>
|
</a-popover>
|
||||||
<a-col :span="6">
|
<a-col :span="5">
|
||||||
<a-statistic :title="$t('status.logNumber')" :value="captionData.length" />
|
<a-statistic :title="$t('status.logNumber')" :value="captionData.length" />
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="6">
|
<a-col :span="5">
|
||||||
|
<a-statistic :title="$t('status.logNumber2')" :value="softwareLogs.length" />
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="4">
|
||||||
<div class="about-tag">{{ $t('status.aboutProj') }}</div>
|
<div class="about-tag">{{ $t('status.aboutProj') }}</div>
|
||||||
<GithubOutlined class="proj-info" @click="showAbout = true"/>
|
<GithubOutlined class="proj-info" @click="showAbout = true"/>
|
||||||
</a-col>
|
</a-col>
|
||||||
@@ -128,14 +131,17 @@ import { EngineInfo } from '@renderer/types'
|
|||||||
import { ref, watch } from 'vue'
|
import { ref, watch } from 'vue'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { useCaptionLogStore } from '@renderer/stores/captionLog'
|
import { useCaptionLogStore } from '@renderer/stores/captionLog'
|
||||||
|
import { useSoftwareLogStore } from '@renderer/stores/softwareLog'
|
||||||
import { useEngineControlStore } from '@renderer/stores/engineControl'
|
import { useEngineControlStore } from '@renderer/stores/engineControl'
|
||||||
import { GithubOutlined, InfoCircleOutlined } from '@ant-design/icons-vue';
|
import { GithubOutlined, InfoCircleOutlined } from '@ant-design/icons-vue'
|
||||||
|
|
||||||
const showAbout = ref(false)
|
const showAbout = ref(false)
|
||||||
const pending = ref(false)
|
const pending = ref(false)
|
||||||
|
|
||||||
const captionLog = useCaptionLogStore()
|
const captionLog = useCaptionLogStore()
|
||||||
const { captionData } = storeToRefs(captionLog)
|
const { captionData } = storeToRefs(captionLog)
|
||||||
|
const softwareLog = useSoftwareLogStore()
|
||||||
|
const { softwareLogs } = storeToRefs(softwareLog)
|
||||||
const engineControl = useEngineControlStore()
|
const engineControl = useEngineControlStore()
|
||||||
const { engineEnabled, engine, customized, errorSignal } = storeToRefs(engineControl)
|
const { engineEnabled, engine, customized, errorSignal } = storeToRefs(engineControl)
|
||||||
|
|
||||||
|
|||||||
@@ -33,10 +33,11 @@
|
|||||||
<a-radio-group v-model:value="uiColor">
|
<a-radio-group v-model:value="uiColor">
|
||||||
<template v-for="color in colorList" :key="color">
|
<template v-for="color in colorList" :key="color">
|
||||||
<a-radio-button :value="color"
|
<a-radio-button :value="color"
|
||||||
:style="{
|
:style="{backgroundColor: color}"
|
||||||
backgroundColor: color
|
>
|
||||||
}"
|
<CheckOutlined style="color: white;" v-if="color === uiColor" />
|
||||||
> </a-radio-button>
|
<span v-else> </span>
|
||||||
|
</a-radio-button>
|
||||||
</template>
|
</template>
|
||||||
</a-radio-group>
|
</a-radio-group>
|
||||||
</div>
|
</div>
|
||||||
@@ -55,7 +56,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { useGeneralSettingStore } from '@renderer/stores/generalSetting'
|
import { useGeneralSettingStore } from '@renderer/stores/generalSetting'
|
||||||
import { InfoCircleOutlined } from '@ant-design/icons-vue';
|
import { InfoCircleOutlined, CheckOutlined } from '@ant-design/icons-vue'
|
||||||
|
|
||||||
const colorList = [
|
const colorList = [
|
||||||
'#1677ff',
|
'#1677ff',
|
||||||
|
|||||||
111
src/renderer/src/components/SoftwareLog.vue
Normal file
111
src/renderer/src/components/SoftwareLog.vue
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="log-title">
|
||||||
|
<span style="margin-right: 30px;">{{ $t('log.title2') }}</span>
|
||||||
|
</div>
|
||||||
|
<a-button
|
||||||
|
danger
|
||||||
|
@click="softwareLog.clear()"
|
||||||
|
>{{ $t('log.clear') }}</a-button>
|
||||||
|
</div>
|
||||||
|
<a-table
|
||||||
|
:columns="columns"
|
||||||
|
:data-source="softwareLogs"
|
||||||
|
v-model:pagination="pagination"
|
||||||
|
style="margin-top: 10px;"
|
||||||
|
>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'type'">
|
||||||
|
<span :class="record.type">{{ record.type }}</span>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'index'">
|
||||||
|
{{ record.index }}
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'content'">
|
||||||
|
<code>{{ record.text }}</code>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
|
import { useSoftwareLogStore } from '@renderer/stores/softwareLog'
|
||||||
|
import { type SoftwareLogItem } from '../types'
|
||||||
|
|
||||||
|
const softwareLog = useSoftwareLogStore()
|
||||||
|
const { softwareLogs } = storeToRefs(softwareLog)
|
||||||
|
|
||||||
|
const pagination = ref({
|
||||||
|
current: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
showSizeChanger: true,
|
||||||
|
pageSizeOptions: ['10', '20', '50', '100'],
|
||||||
|
onChange: (page: number, pageSize: number) => {
|
||||||
|
pagination.value.current = page
|
||||||
|
pagination.value.pageSize = pageSize
|
||||||
|
},
|
||||||
|
onShowSizeChange: (current: number, size: number) => {
|
||||||
|
pagination.value.current = current
|
||||||
|
pagination.value.pageSize = size
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: 'index',
|
||||||
|
dataIndex: 'index',
|
||||||
|
key: 'index',
|
||||||
|
width: 80,
|
||||||
|
sorter: (a: SoftwareLogItem, b: SoftwareLogItem) => {
|
||||||
|
if(a.index <= b.index) return -1
|
||||||
|
return 1
|
||||||
|
},
|
||||||
|
sortDirections: ['descend'],
|
||||||
|
defaultSortOrder: 'descend',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'type',
|
||||||
|
dataIndex: 'type',
|
||||||
|
key: 'type',
|
||||||
|
width: 80,
|
||||||
|
sorter: (a: SoftwareLogItem, b: SoftwareLogItem) => {
|
||||||
|
if(a.type <= b.type) return -1
|
||||||
|
return 1
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'time',
|
||||||
|
dataIndex: 'time',
|
||||||
|
key: 'time',
|
||||||
|
width: 120,
|
||||||
|
sortDirections: ['descend'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'content',
|
||||||
|
dataIndex: 'content',
|
||||||
|
key: 'content',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.log-title {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.WARN {
|
||||||
|
color: #ff7c05;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ERROR {
|
||||||
|
color: #ff0000;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
41
src/renderer/src/i18n/config/logMenu.ts
Normal file
41
src/renderer/src/i18n/config/logMenu.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { h } from 'vue';
|
||||||
|
import { OrderedListOutlined, FileTextOutlined } from '@ant-design/icons-vue'
|
||||||
|
|
||||||
|
export const logMenu = {
|
||||||
|
zh: [
|
||||||
|
{
|
||||||
|
key: 'captionLog',
|
||||||
|
icon: () => h(OrderedListOutlined),
|
||||||
|
label: '字幕记录',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'projLog',
|
||||||
|
icon: () => h(FileTextOutlined),
|
||||||
|
label: '日志记录',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
en: [
|
||||||
|
{
|
||||||
|
key: 'captionLog',
|
||||||
|
icon: () => h(OrderedListOutlined),
|
||||||
|
label: 'Caption Log',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'projLog',
|
||||||
|
icon: () => h(FileTextOutlined),
|
||||||
|
label: 'Software Log',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
ja: [
|
||||||
|
{
|
||||||
|
key: 'captionLog',
|
||||||
|
icon: () => h(OrderedListOutlined),
|
||||||
|
label: '字幕記録',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'projLog',
|
||||||
|
icon: () => h(FileTextOutlined),
|
||||||
|
label: 'ログ記録',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -18,3 +18,4 @@ export * from './config/engine'
|
|||||||
export * from './config/audio'
|
export * from './config/audio'
|
||||||
export * from './config/theme'
|
export * from './config/theme'
|
||||||
export * from './config/linebreak'
|
export * from './config/linebreak'
|
||||||
|
export * from './config/logMenu'
|
||||||
@@ -106,6 +106,7 @@ export default {
|
|||||||
"started": "Started",
|
"started": "Started",
|
||||||
"stopped": "Not Started",
|
"stopped": "Not Started",
|
||||||
"logNumber": "Caption Count",
|
"logNumber": "Caption Count",
|
||||||
|
"logNumber2": "Log Count",
|
||||||
"aboutProj": "About Project",
|
"aboutProj": "About Project",
|
||||||
"openCaption": "Open Caption Window",
|
"openCaption": "Open Caption Window",
|
||||||
"startEngine": "Start Caption Engine",
|
"startEngine": "Start Caption Engine",
|
||||||
@@ -146,6 +147,7 @@ export default {
|
|||||||
"copyNum": "Copy Count",
|
"copyNum": "Copy Count",
|
||||||
"all": "All",
|
"all": "All",
|
||||||
"copySuccess": "Subtitle copied to clipboard",
|
"copySuccess": "Subtitle copied to clipboard",
|
||||||
"clear": "Clear Log"
|
"clear": "Clear Log",
|
||||||
|
"title2": "Software Log"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ export default {
|
|||||||
"started": "開始済み",
|
"started": "開始済み",
|
||||||
"stopped": "未開始",
|
"stopped": "未開始",
|
||||||
"logNumber": "字幕数",
|
"logNumber": "字幕数",
|
||||||
|
"logNumber2": "ログ数",
|
||||||
"aboutProj": "プロジェクト情報",
|
"aboutProj": "プロジェクト情報",
|
||||||
"openCaption": "字幕ウィンドウを開く",
|
"openCaption": "字幕ウィンドウを開く",
|
||||||
"startEngine": "字幕エンジンを開始",
|
"startEngine": "字幕エンジンを開始",
|
||||||
@@ -124,7 +125,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
log: {
|
log: {
|
||||||
"title": "字幕ログ",
|
"title": "字幕記録",
|
||||||
"changeTime": "時間を変更",
|
"changeTime": "時間を変更",
|
||||||
"baseTime": "最初の字幕開始時間",
|
"baseTime": "最初の字幕開始時間",
|
||||||
"hour": "時",
|
"hour": "時",
|
||||||
@@ -132,7 +133,7 @@ export default {
|
|||||||
"sec": "秒",
|
"sec": "秒",
|
||||||
"ms": "ミリ秒",
|
"ms": "ミリ秒",
|
||||||
"export": "エクスポート",
|
"export": "エクスポート",
|
||||||
"copy": "ログをコピー",
|
"copy": "記録をコピー",
|
||||||
"exportOptions": "エクスポートオプション",
|
"exportOptions": "エクスポートオプション",
|
||||||
"exportFormat": "形式",
|
"exportFormat": "形式",
|
||||||
"exportContent": "内容",
|
"exportContent": "内容",
|
||||||
@@ -146,6 +147,7 @@ export default {
|
|||||||
"copyNum": "コピー数",
|
"copyNum": "コピー数",
|
||||||
"all": "すべて",
|
"all": "すべて",
|
||||||
"copySuccess": "字幕がクリップボードにコピーされました",
|
"copySuccess": "字幕がクリップボードにコピーされました",
|
||||||
"clear": "ログをクリア"
|
"clear": "記録をクリア",
|
||||||
|
"title2": "ログ記録"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ export default {
|
|||||||
"started": "已启动",
|
"started": "已启动",
|
||||||
"stopped": "未启动",
|
"stopped": "未启动",
|
||||||
"logNumber": "字幕数量",
|
"logNumber": "字幕数量",
|
||||||
|
"logNumber2": "日志数量",
|
||||||
"aboutProj": "项目关于",
|
"aboutProj": "项目关于",
|
||||||
"openCaption": "打开字幕窗口",
|
"openCaption": "打开字幕窗口",
|
||||||
"startEngine": "启动字幕引擎",
|
"startEngine": "启动字幕引擎",
|
||||||
@@ -146,6 +147,7 @@ export default {
|
|||||||
"copyNum": "复制数量",
|
"copyNum": "复制数量",
|
||||||
"all": "全部",
|
"all": "全部",
|
||||||
"copySuccess": "字幕已复制到剪贴板",
|
"copySuccess": "字幕已复制到剪贴板",
|
||||||
"clear": "清空记录"
|
"clear": "清空记录",
|
||||||
|
"title2": "日志记录"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
src/renderer/src/stores/softwareLog.ts
Normal file
21
src/renderer/src/stores/softwareLog.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { ref } from 'vue'
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import { type SoftwareLogItem } from '../types'
|
||||||
|
|
||||||
|
export const useSoftwareLogStore = defineStore('softwareLog', () => {
|
||||||
|
const softwareLogs = ref<SoftwareLogItem[]>([])
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
softwareLogs.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
window.electron.ipcRenderer.on('control.softwareLog.add', (_, log) => {
|
||||||
|
softwareLogs.value.push(log)
|
||||||
|
console.log(log)
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
softwareLogs,
|
||||||
|
clear
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -45,6 +45,13 @@ export interface CaptionItem {
|
|||||||
translation: string
|
translation: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SoftwareLogItem {
|
||||||
|
type: "INFO" | "WARN" | "ERROR",
|
||||||
|
index: number,
|
||||||
|
time: string,
|
||||||
|
text: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface FullConfig {
|
export interface FullConfig {
|
||||||
platform: string,
|
platform: string,
|
||||||
uiLanguage: UILanguage,
|
uiLanguage: UILanguage,
|
||||||
@@ -53,7 +60,8 @@ export interface FullConfig {
|
|||||||
leftBarWidth: number,
|
leftBarWidth: number,
|
||||||
styles: Styles,
|
styles: Styles,
|
||||||
controls: Controls,
|
controls: Controls,
|
||||||
captionLog: CaptionItem[]
|
captionLog: CaptionItem[],
|
||||||
|
softwareLog: SoftwareLogItem[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EngineInfo {
|
export interface EngineInfo {
|
||||||
|
|||||||
@@ -11,7 +11,13 @@
|
|||||||
<a-col :span="24 - leftBarWidth">
|
<a-col :span="24 - leftBarWidth">
|
||||||
<div class="caption-data">
|
<div class="caption-data">
|
||||||
<EngineStatus />
|
<EngineStatus />
|
||||||
<CaptionLog />
|
<div class="log-container">
|
||||||
|
<a-menu v-model:selectedKeys="current" mode="horizontal" :items="items" />
|
||||||
|
<div style="padding: 16px;">
|
||||||
|
<CaptionLog v-if="current[0] === 'captionLog'" />
|
||||||
|
<SoftwareLog v-else />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
@@ -24,11 +30,22 @@ import CaptionStyle from '../components/CaptionStyle.vue'
|
|||||||
import EngineControl from '../components/EngineControl.vue'
|
import EngineControl from '../components/EngineControl.vue'
|
||||||
import EngineStatus from '@renderer/components/EngineStatus.vue'
|
import EngineStatus from '@renderer/components/EngineStatus.vue'
|
||||||
import CaptionLog from '../components/CaptionLog.vue'
|
import CaptionLog from '../components/CaptionLog.vue'
|
||||||
|
import SoftwareLog from '@renderer/components/SoftwareLog.vue'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { useGeneralSettingStore } from '@renderer/stores/generalSetting'
|
import { useGeneralSettingStore } from '@renderer/stores/generalSetting'
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
import { MenuProps } from 'ant-design-vue'
|
||||||
|
import { logMenu } from '@renderer/i18n'
|
||||||
|
|
||||||
const generalSettingStore = useGeneralSettingStore()
|
const generalSettingStore = useGeneralSettingStore()
|
||||||
const { leftBarWidth, antdTheme } = storeToRefs(generalSettingStore)
|
const { leftBarWidth, antdTheme, uiLanguage } = storeToRefs(generalSettingStore)
|
||||||
|
|
||||||
|
const current = ref<string[]>(['captionLog'])
|
||||||
|
const items = ref<MenuProps['items']>(logMenu[uiLanguage.value])
|
||||||
|
|
||||||
|
watch(uiLanguage, (val) => {
|
||||||
|
items.value = logMenu[val]
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@@ -53,4 +70,10 @@ const { leftBarWidth, antdTheme } = storeToRefs(generalSettingStore)
|
|||||||
.caption-data::-webkit-scrollbar {
|
.caption-data::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.log-container {
|
||||||
|
padding: 20px 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user