新增关闭历史记录开关:可在设置中停止保存历史记录(默认开启)
This commit is contained in:
1 parent
670f43c309
commit
67b23f687f
3 files changed
+53
-31
No files matched your search
@@ -29,6 +29,7 @@ export default function GeneralSettingsPage() {
|
||||
const [protectClipboard, setProtectClipboard] = useState(true)
|
||||
const [pttKey, setPttKey] = useState('AltLeft')
|
||||
const [handsFreeKey, setHandsFreeKey] = useState('Alt+L')
|
||||
const [historyEnabled, setHistoryEnabled] = useState(true)
|
||||
const [audioRetentionEnabled, setAudioRetentionEnabled] = useState(true)
|
||||
const [audioRetentionDays, setAudioRetentionDays] = useState(30)
|
||||
const [logRetentionDays, setLogRetentionDays] = useState(30)
|
||||
@@ -45,6 +46,7 @@ export default function GeneralSettingsPage() {
|
||||
getSetting('protectClipboard', true).then((value) => setProtectClipboard(Boolean(value)))
|
||||
getSetting('shortcutPTT', 'AltRight').then((value) => setPttKey(value as string))
|
||||
getSetting('shortcutHandsFree', 'Alt+L').then((value) => setHandsFreeKey(value as string))
|
||||
getSetting('historyEnabled', true).then((value) => setHistoryEnabled(Boolean(value)))
|
||||
getSetting('audioRetentionEnabled', true).then((value) => setAudioRetentionEnabled(Boolean(value)))
|
||||
getSetting('readySoundEnabled', true).then((value) => setReadySoundEnabled(Boolean(value)))
|
||||
getSetting('audioRetentionDays', -1).then((value) => {
|
||||
@@ -55,7 +57,7 @@ export default function GeneralSettingsPage() {
|
||||
const v = Number(value)
|
||||
if (v === 7 || v === 15 || v === 30 || v === 90) setLogRetentionDays(v)
|
||||
})
|
||||
listMicrophones().then(setMics).catch(() => {})
|
||||
listMicrophones().then(setMics).catch(() => { })
|
||||
}, [])
|
||||
|
||||
const toggleAutoLaunch = async () => { const next = !autoLaunch; setAutoLaunch(next); await bridge.setAutoLaunch(next) }
|
||||
@@ -63,6 +65,7 @@ export default function GeneralSettingsPage() {
|
||||
const handleMicChange = async (deviceId: string) => { setSelectedMic(deviceId); await setSetting('selectedMic', deviceId); await refreshRecorderSettings() }
|
||||
const toggleMuteSystemAudio = async () => { const next = !muteSystemAudio; setMuteSystemAudio(next); await setSetting('muteSystemAudioWhileRecording', next); await refreshRecorderSettings() }
|
||||
const toggleProtectClipboard = async () => { const next = !protectClipboard; setProtectClipboard(next); await setSetting('protectClipboard', next); await refreshRecorderSettings() }
|
||||
const toggleHistoryEnabled = async () => { const next = !historyEnabled; setHistoryEnabled(next); await setSetting('historyEnabled', next) }
|
||||
const toggleAudioRetention = async () => { const next = !audioRetentionEnabled; setAudioRetentionEnabled(next); await setSetting('audioRetentionEnabled', next) }
|
||||
const toggleReadySound = async () => { const next = !readySoundEnabled; setReadySoundEnabled(next); await setSetting('readySoundEnabled', next); await refreshRecorderSettings() }
|
||||
const handleAudioRetentionDaysChange = async (value: number) => { setAudioRetentionDays(value); await setSetting('audioRetentionDays', value) }
|
||||
@@ -173,6 +176,18 @@ export default function GeneralSettingsPage() {
|
||||
|
||||
<AppSection autoLaunch={autoLaunch} onToggleAutoLaunch={toggleAutoLaunch} autoCheckUpdate={autoCheckUpdate} onToggleAutoCheckUpdate={toggleAutoCheckUpdate} />
|
||||
|
||||
<Card>
|
||||
<CardContent className="p-6">
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div>
|
||||
<h2 className="text-lg font-semibold">历史记录</h2>
|
||||
<p className="mt-1 text-sm text-muted-foreground">保存每次转写的文本与录音到本地历史,可随时回看、复制和重新识别。关闭后不再保存新的记录(适合与他人共用的电脑);已有记录不会被删除,可在历史页手动清除。</p>
|
||||
</div>
|
||||
<Switch checked={historyEnabled} onChange={() => void toggleHistoryEnabled()} />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardContent className="p-6">
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
|
||||
@@ -69,6 +69,7 @@ export const DEFAULTS: Record<string, unknown> = {
|
||||
|
||||
// ── 应用设置 ──
|
||||
autoCheckUpdate: true, // 自动检查更新。可选: true | false
|
||||
historyEnabled: true, // 保存历史记录(文本+录音)。关闭后不再保存新记录,适合共享电脑。可选: true | false
|
||||
audioRetentionEnabled: true, // 保留录音文件。可选: true | false
|
||||
audioRetentionDays: -1, // 录音保留天数。可选: 7 | 30 | 90 | -1(永久)
|
||||
logRetentionDays: 30, // 日志保留天数。可选: 7 | 15 | 30 | 90
|
||||
|
||||
@@ -603,6 +603,7 @@ export class RecorderOrchestrator {
|
||||
const wallSec = this.wallTimeAtStopSec > 0 ? this.wallTimeAtStopSec : audioDur
|
||||
// Save audio even for empty results
|
||||
const saveAndRecord = async () => {
|
||||
if (!(await getSetting('historyEnabled', true))) return
|
||||
let audioFilePath: string | undefined
|
||||
const recordId = Date.now().toString(36) + Math.random().toString(36).slice(2, 6)
|
||||
const saveAudioEnabled = await getSetting('audioRetentionEnabled', true)
|
||||
@@ -703,6 +704,7 @@ export class RecorderOrchestrator {
|
||||
const wallSec = this.wallTimeAtStopSec > 0 ? this.wallTimeAtStopSec : audioDur
|
||||
if (audioDur >= 0.5 && this.recordedChunks.length > 0) {
|
||||
const saveErrorHistory = async () => {
|
||||
if (!(await getSetting('historyEnabled', true))) return
|
||||
let audioFilePath: string | undefined
|
||||
const recordId = Date.now().toString(36) + Math.random().toString(36).slice(2, 6)
|
||||
const saveAudioEnabled = await getSetting('audioRetentionEnabled', true)
|
||||
@@ -1353,6 +1355,7 @@ export class RecorderOrchestrator {
|
||||
this.timedOutProcessingContext = null
|
||||
void (async () => {
|
||||
try {
|
||||
if (!(await getSetting('historyEnabled', true))) return
|
||||
let audioFilePath: string | undefined
|
||||
const recordId = Date.now().toString(36) + Math.random().toString(36).slice(2, 6)
|
||||
const saveAudioEnabled = await getSetting('audioRetentionEnabled', true)
|
||||
@@ -1614,38 +1617,41 @@ export class RecorderOrchestrator {
|
||||
})
|
||||
|
||||
try {
|
||||
// Save audio file if we have recorded chunks
|
||||
let audioFilePath: string | undefined
|
||||
const recordId = Date.now().toString(36) + Math.random().toString(36).slice(2, 6)
|
||||
const saveAudioEnabled = await getSetting('audioRetentionEnabled', true)
|
||||
if (saveAudioEnabled && this.recordedChunks.length > 0) {
|
||||
try {
|
||||
const savedPath = await saveRecordingAudio(recordId, this.recordedChunks)
|
||||
if (savedPath) audioFilePath = savedPath
|
||||
} catch (err) {
|
||||
addRuntimeEvent('warn', 'recorder', '保存音频文件失败', { error: String(err) })
|
||||
// 关闭历史记录时不保存任何记录与音频(共享电脑隐私),但仍完成文本插入
|
||||
if (await getSetting('historyEnabled', true)) {
|
||||
// Save audio file if we have recorded chunks
|
||||
let audioFilePath: string | undefined
|
||||
const recordId = Date.now().toString(36) + Math.random().toString(36).slice(2, 6)
|
||||
const saveAudioEnabled = await getSetting('audioRetentionEnabled', true)
|
||||
if (saveAudioEnabled && this.recordedChunks.length > 0) {
|
||||
try {
|
||||
const savedPath = await saveRecordingAudio(recordId, this.recordedChunks)
|
||||
if (savedPath) audioFilePath = savedPath
|
||||
} catch (err) {
|
||||
addRuntimeEvent('warn', 'recorder', '保存音频文件失败', { error: String(err) })
|
||||
}
|
||||
}
|
||||
|
||||
const providerMeta = await this.buildProviderMetadata(result)
|
||||
|
||||
await addHistory({
|
||||
id: recordId,
|
||||
timestamp: Date.now(),
|
||||
asrText: result.asrText,
|
||||
llmText: textToPaste,
|
||||
asrMs: result.asrMs,
|
||||
llmMs: result.llmMs,
|
||||
durationSec: wallSec,
|
||||
audioDurationSec: audioDur > 0 ? audioDur : undefined,
|
||||
asrDurationSec: result.durationSec > 0 ? result.durationSec : undefined,
|
||||
charCount: hasText ? textToPaste.length : 0,
|
||||
isEmpty: !hasText,
|
||||
audioFilePath,
|
||||
...this.buildHistoryMetadata(promptResolution),
|
||||
...providerMeta,
|
||||
})
|
||||
void bridge.emit('history-updated')
|
||||
}
|
||||
|
||||
const providerMeta = await this.buildProviderMetadata(result)
|
||||
|
||||
await addHistory({
|
||||
id: recordId,
|
||||
timestamp: Date.now(),
|
||||
asrText: result.asrText,
|
||||
llmText: textToPaste,
|
||||
asrMs: result.asrMs,
|
||||
llmMs: result.llmMs,
|
||||
durationSec: wallSec,
|
||||
audioDurationSec: audioDur > 0 ? audioDur : undefined,
|
||||
asrDurationSec: result.durationSec > 0 ? result.durationSec : undefined,
|
||||
charCount: hasText ? textToPaste.length : 0,
|
||||
isEmpty: !hasText,
|
||||
audioFilePath,
|
||||
...this.buildHistoryMetadata(promptResolution),
|
||||
...providerMeta,
|
||||
})
|
||||
void bridge.emit('history-updated')
|
||||
} catch (error) {
|
||||
addRuntimeEvent('warn', 'recorder', '写入历史记录失败', { error: String(error) })
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user