Skip to content

Commit 317d84b

Browse files
committed
feat(pomodoro): 深潜设置页下潜档案重构与番茄钟体验增强
- 设置页重构为下潜档案布局:潜航档案数据摘要 + 氧气配比/潜航任务/预警声呐/水下声景/智能领航 2x2 卡片,即改即存无保存按钮,恢复出厂深度重置链接 - 新增 useDiveProfile hook:聚合近 30 天会话生成数据洞察文案(完成率/最佳时段/中断率) - 新增预设右键菜单(编辑/复制/删除),内置预设禁用删除 - 主页白噪音条新增音轨选择下拉(focus+both 音轨) - 科学音量推荐:Electron IPC 获取系统音量 + 设备类型 dB 偏移(耳机/入耳/音箱/笔记本),动态显示估算分贝与推荐区间 - 循环标记 0/0 显示(无长休预设保留计数) - 渐变背景移至 FunctionalOverlay 面板,移除 DiveBackground 组件 - 死代码清理:删除 10 个废弃文件(旧设置组件/useAIRecommendation/EnergySuggestionBar/energyMatcher/DiveBackground),清理 pomodoro-dive.css 未用动画
1 parent 7d76b6e commit 317d84b

31 files changed

Lines changed: 1231 additions & 1143 deletions

‎client/electron/ipc/channels.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ export const IPC_CHANNELS = {
120120
EINK_SHOW_CARD: 'eink:show-card',
121121
EINK_HIDE: 'eink:hide',
122122
EINK_CARD: 'eink:card',
123+
124+
// 系统音量
125+
SYSTEM_GET_VOLUME: 'system:get-volume',
123126
} as const;
124127

125128
export type IpcChannel = (typeof IPC_CHANNELS)[keyof typeof IPC_CHANNELS];

‎client/electron/main.ts‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import { app, BrowserWindow, Menu, session, clipboard, safeStorage } from 'electron';
2121
import { safeHandle, setMainWindowId, requireText } from './ipcUtils.js';
22+
import { getMachineId } from './machineId.js';
2223
import { logger } from './logger.js';
2324
import { registerAIHandlers, initAIModule } from './ai/index.js';
2425
import { loadPersistedGatewayUrl, setRuntimeGatewayUrl, gatewayUrl, isDevMode } from './ai/utils.js';
@@ -278,6 +279,11 @@ if (!gotTheLock) {
278279
return app.getVersion();
279280
});
280281

282+
// 设备指纹(激活码一码多设备绑定;仅主进程持有,渲染进程只读获取)
283+
safeHandle('machine-id:get', async () => {
284+
return getMachineId();
285+
});
286+
281287
// 剪贴板写入:渲染进程 navigator.clipboard 在 Electron 非聚焦/受限上下文下
282288
// 会抛 "Document is not focused" 而失败,改由主进程 clipboard 模块写入更可靠。
283289
safeHandle('clipboard:write-text', async (_event, text: unknown) => {
@@ -352,6 +358,24 @@ safeHandle('eink:hide', async () => {
352358
return { success: true };
353359
});
354360

361+
// 系统音量(Windows 下通过 PowerShell 获取)
362+
safeHandle('system:get-volume', async () => {
363+
try {
364+
const { execFile } = await import('child_process');
365+
const { promisify } = await import('util');
366+
const execFileAsync = promisify(execFile);
367+
const { stdout } = await execFileAsync('powershell', [
368+
'-Command',
369+
'(New-Object -ComObject WMPlayer.OCX).settings.volume',
370+
], { timeout: 3000 });
371+
const vol = parseInt(stdout.trim(), 10);
372+
return { success: true, volume: Number.isNaN(vol) ? 50 : Math.max(0, Math.min(100, vol)) };
373+
} catch {
374+
// 非 Windows 或 PowerShell 不可用时返回默认值 50
375+
return { success: true, volume: 50 };
376+
}
377+
});
378+
355379
// 更新相关 IPC handler
356380
safeHandle('update:check', async () => {
357381
checkForUpdate();

‎client/electron/preload.ts‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ const ALLOWED_CHANNELS = [
6161
// A2 语音对话:启动前查询是否已有活跃采集(互斥保护,避免误伤课堂采集)
6262
'audio_capture_status',
6363
'get-app-version',
64+
// 设备指纹(激活码一码多设备绑定;仅主进程生成,渲染进程只读)
65+
'machine-id:get',
6466
// 剪贴板写入(渲染进程 navigator.clipboard 在 Electron 受限上下文下不可靠)
6567
'clipboard:write-text',
6668
'dialog:selectDirectory',
@@ -95,6 +97,8 @@ const ALLOWED_CHANNELS = [
9597
'sync:quit-complete',
9698
// 文件读取(课堂助手视频分析)
9799
'fs:read-file',
100+
// 系统音量
101+
'system:get-volume',
98102
// Path C 视频录制 IPC channel
99103
'video_record_start',
100104
'video_record_stop',
@@ -294,6 +298,9 @@ contextBridge.exposeInMainWorld('electronAPI', {
294298
// ---- 阶段 A:知识入籍拖拽 API(Electron 35 移除 File.path,必须经 webUtils 转换) ----
295299
/** 拖拽文件 → 绝对路径(供 import:parse-pdf 使用) */
296300
getPathForFile: (file: File) => webUtils.getPathForFile(file),
301+
// ---- 设备指纹 API(激活码绑定用) ----
302+
/** 获取设备指纹(主进程生成,首次调用后恒定) */
303+
getMachineId: () => ipcRenderer.invoke('machine-id:get'),
297304
// ---- v0.9.0: 备份 API ----
298305
/** 保存备份文件(显示系统保存对话框) */
299306
backupSave: (data: string, defaultName?: string) => ipcRenderer.invoke('backup:save', data, defaultName),

‎client/src/components/overlay/FunctionalOverlay.tsx‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export function FunctionalOverlay({ children, visible, className, panelClassName
7171
"max-h-[calc(100vh-5rem)] sm:max-h-[85vh]", // 移动端适配底部导航
7272
"overflow-y-auto",
7373
"rounded-2xl sm:rounded-[24px_12px_20px_16px]", // 移动端统一圆角
74-
"bg-white/10 dark:bg-black/30",
74+
"bg-transparent",
7575
visible && "backdrop-blur-2xl",
7676
"border border-white/20 dark:border-white/10",
7777
"shadow-[0_8px_40px_rgba(0,0,0,0.3)]",
@@ -80,7 +80,10 @@ export function FunctionalOverlay({ children, visible, className, panelClassName
8080
"p-3 sm:p-5 md:p-8"
8181
)}
8282
/* 修复:提示浏览器提前创建合成层,避免动画时触发重绘/重排,提升动画流畅度 */
83-
style={{ willChange: 'transform, opacity' }}
83+
style={{
84+
willChange: 'transform, opacity',
85+
background: 'linear-gradient(180deg, var(--kb-dive-top) 0%, var(--kb-dive-mid) 42%, var(--kb-dive-bot) 100%)',
86+
}}
8487
initial={{ scale: 0.9, y: 30 }}
8588
animate={visible ? { scale: 1, y: 0 } : { scale: 0.9, y: 30 }}
8689
transition={{ type: 'spring', stiffness: 300, damping: 30 }}

‎client/src/features/pomodoro/components/CycleMarkers.tsx‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,16 @@ interface CycleMarkersProps {
2424
}
2525

2626
export default memo(function CycleMarkers({ total, filled, className }: CycleMarkersProps) {
27-
if (total <= 0) return null;
27+
// 无长休预设:不渲染标记条,但保留计数文字 0/0
28+
if (total <= 0) {
29+
return (
30+
<div className={cn('flex items-center gap-1.5', className)}>
31+
<span className="text-[11px] text-text-tertiary/60 font-mono tabular-nums">
32+
{filled}/{total}
33+
</span>
34+
</div>
35+
);
36+
}
2837

2938
return (
3039
<div className={cn('flex items-center gap-1.5', className)}>

‎client/src/features/pomodoro/components/DiveBackground.tsx‎

Lines changed: 0 additions & 118 deletions
This file was deleted.

‎client/src/features/pomodoro/components/EnergySuggestionBar.tsx‎

Lines changed: 0 additions & 63 deletions
This file was deleted.

0 commit comments

Comments
 (0)