-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprogress.html
More file actions
379 lines (357 loc) · 19 KB
/
Copy pathprogress.html
File metadata and controls
379 lines (357 loc) · 19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NotchBlock — 开发进度看板</title>
<style>
:root {
--bg: #0d1117; --card: #161b22; --border: #30363d;
--text: #e6edf3; --muted: #8b949e;
--green: #3fb950; --blue: #58a6ff; --purple: #a371f7;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', sans-serif;
background: var(--bg); color: var(--text); line-height: 1.6;
max-width: 960px; margin: 0 auto; padding: 40px 24px;
}
h1 { font-size: 2rem; font-weight: 700; margin-bottom: 4px; }
h1 span { color: var(--blue); }
.subtitle { color: var(--muted); margin-bottom: 32px; font-size: 0.95rem; }
h2 { font-size: 1.25rem; margin: 32px 0 16px; padding-bottom: 8px; border-bottom: 1px solid var(--border); }
h3 { font-size: 1rem; margin: 20px 0 10px; }
.stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 12px; margin-bottom: 32px;
}
.stat-card {
background: var(--card); border: 1px solid var(--border);
border-radius: 10px; padding: 16px; text-align: center;
}
.stat-value { font-size: 1.8rem; font-weight: 700; }
.stat-label { font-size: 0.8rem; color: var(--muted); margin-top: 4px; }
.stat-value.green { color: var(--green); }
.stat-value.blue { color: var(--blue); }
.stat-value.purple { color: var(--purple); }
.phase {
background: var(--card); border: 1px solid var(--border);
border-radius: 12px; margin-bottom: 20px; overflow: hidden;
}
.phase-header {
display: flex; align-items: center; gap: 12px;
padding: 16px 20px; border-bottom: 1px solid var(--border);
}
.phase-badge {
width: 32px; height: 32px; border-radius: 8px;
display: flex; align-items: center; justify-content: center;
font-weight: 700; font-size: 0.9rem; background: var(--green); color: #000;
}
.phase-title { font-weight: 600; font-size: 1.05rem; }
.phase-status { margin-left: auto; font-size: 0.8rem; padding: 3px 10px; border-radius: 12px; background: var(--green); color: #000; }
.phase-body { padding: 16px 20px; }
.ac-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 8px;
}
.ac-item {
display: flex; align-items: flex-start; gap: 8px;
font-size: 0.88rem; padding: 6px 0;
}
.ac-icon { font-size: 1rem; flex-shrink: 0; margin-top: 1px; color: var(--green); }
.file-list {
font-size: 0.80rem; color: var(--muted); margin-top: 12px;
padding: 10px 14px; background: #0d1117; border-radius: 6px;
font-family: 'SF Mono', 'Menlo', monospace; line-height: 1.9;
}
.commits { margin-top: 8px; }
.commit {
display: flex; gap: 12px; padding: 10px 0;
border-bottom: 1px solid var(--border); font-size: 0.88rem;
}
.commit-hash { font-family: 'SF Mono', monospace; color: var(--blue); font-size: 0.8rem; flex-shrink: 0; }
.commit-msg { font-weight: 500; }
.commit-meta { color: var(--muted); font-size: 0.78rem; }
.arch-diagram {
background: var(--card); border: 1px solid var(--border);
border-radius: 10px; padding: 20px; margin: 16px 0;
font-family: 'SF Mono', monospace; font-size: 0.80rem;
line-height: 1.9; white-space: pre; overflow-x: auto;
}
.footer {
text-align: center; margin-top: 40px; padding-top: 20px;
border-top: 1px solid var(--border); color: var(--muted); font-size: 0.82rem;
}
</style>
</head>
<body>
<h1><span>NotchBlock</span> 刘海时间块</h1>
<p class="subtitle">macOS 时间块强制执行工具 · 开发进度看板 · 2026-06-04 · <strong>v0.6.0</strong></p>
<div class="stats">
<div class="stat-card"><div class="stat-value green">6/6</div><div class="stat-label">开发阶段</div></div>
<div class="stat-card"><div class="stat-value blue">20</div><div class="stat-label">Swift 源文件</div></div>
<div class="stat-card"><div class="stat-value purple">2,588</div><div class="stat-label">总代码行数</div></div>
<div class="stat-card"><div class="stat-value green">✅</div><div class="stat-label">构建状态</div></div>
<div class="stat-card"><div class="stat-value blue">52</div><div class="stat-label">Git 提交</div></div>
</div>
<h2>🏗️ 架构总览</h2>
<div class="arch-diagram">
NotchBlock/
├── NotchBlock.xcodeproj/ # Xcode 项目 (脚本生成)
├── generate_xcode_project.py # PBX 生成器
├── progress.html # 本看板
│
└── NotchBlock/
├── NotchBlockApp.swift # @main 入口点
├── Info.plist # LSUIElement + 权限声明
│
├── Models/
│ ├── TimeBlock.swift # 核心数据模型 (Identifiable, Codable)
│ └── BlockStatus.swift # 状态枚举 (.pending, .completed, .missed)
│
├── Managers/
│ ├── TimeBlockStore.swift # UserDefaults 持久化 + CRUD + 冲突检测
│ ├── NotchTracker.swift # 刘海鼠标追踪 (0.5s 防抖 + 全屏检测)
│ ├── NotchPanelController.swift # 下拉面板 NSPanel 管理
│ ├── OverlayWindowController.swift # 全屏强提醒遮罩 (CGShieldingWindowLevel)
│ └── BlockScheduler.swift # 定时检测任务到期 → 触发遮罩
│
├── Views/
│ ├── MainSchedulerView.swift # 今日排程主界面
│ ├── TimeBlockRowView.swift # 单条任务行
│ ├── AddEditBlockView.swift # 添加/编辑任务 (含冲突校验)
│ ├── NotchPanelView.swift # 刘海下拉面板内容
│ └── OverlayView.swift # 全屏强制提醒 UI
│
├── Utilities/
│ ├── DateExtensions.swift # 日期格式化扩展
│ └── LaunchManager.swift # 开机启动 (SMAppService)
│
└── Resources/
└── Assets.xcassets/ # 资源目录
</div>
<h2>📋 迭代阶段</h2>
<!-- Phase 1 -->
<div class="phase">
<div class="phase-header">
<div class="phase-badge">1</div>
<div class="phase-title">第一阶段:基础骨架 & 数据持久化</div>
<div class="phase-status">✅ 已完成</div>
</div>
<div class="phase-body">
<h3>验收标准</h3>
<div class="ac-grid">
<div class="ac-item"><span class="ac-icon">✅</span> AC 1.1 时间冲突校验 — AddEditBlockView 实时检测 + Alert 阻止保存</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 1.2 状态栏常驻 — MenuBarExtra + LSUIElement + 开机启动</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 1.3 本地持久化 — UserDefaults JSON 编码,重启数据不丢失</div>
</div>
<div class="file-list">
Models/TimeBlock.swift · Models/BlockStatus.swift · Managers/TimeBlockStore.swift · NotchBlockApp.swift · Views/MainSchedulerView.swift · Views/TimeBlockRowView.swift · Views/AddEditBlockView.swift · Utilities/DateExtensions.swift
</div>
</div>
</div>
<!-- Phase 2 -->
<div class="phase">
<div class="phase-header">
<div class="phase-badge">2</div>
<div class="phase-title">第二阶段:刘海悬停 & 下拉面板</div>
<div class="phase-status">✅ 已完成</div>
</div>
<div class="phase-body">
<h3>验收标准</h3>
<div class="ac-grid">
<div class="ac-item"><span class="ac-icon">✅</span> AC 2.1 防误触 — 0.5s 悬停防抖,NSTrackingArea + Timer</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 2.2 动态面板 — 当前任务倒计时 + 后续 2 个任务</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 2.3 自动隐藏 — 0.3s 离开防抖,鼠标移出后收回</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 2.4 全屏避让 — CGWindowList 检测全屏状态 → 禁用追踪</div>
</div>
<div class="file-list">
Managers/NotchTracker.swift · Managers/NotchPanelController.swift · Views/NotchPanelView.swift
</div>
</div>
</div>
<!-- Phase 3 -->
<div class="phase">
<div class="phase-header">
<div class="phase-badge">3</div>
<div class="phase-title">第三阶段:全屏强提醒遮罩</div>
<div class="phase-status">✅ 已完成</div>
</div>
<div class="phase-body">
<h3>验收标准</h3>
<div class="ac-grid">
<div class="ac-item"><span class="ac-icon">✅</span> AC 3.1 全屏变暗 — 70% 不透明度 NSPanel,拦截所有底层点击</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 3.2 核心交互 — 任务名称 + [已完成] / [去调整计划]</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 3.3 超时惩罚 — 5 分钟无操作 → .missed + 本地通知</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 3.4 全屏穿透 — .fullScreenAuxiliary + CGShieldingWindowLevel</div>
</div>
<div class="file-list">
Managers/OverlayWindowController.swift · Managers/BlockScheduler.swift · Views/OverlayView.swift
</div>
</div>
</div>
<!-- Phase 4 -->
<div class="phase">
<div class="phase-header">
<div class="phase-badge">4</div>
<div class="phase-title">第四阶段:打磨 & 边界处理</div>
<div class="phase-status">✅ 已完成</div>
</div>
<div class="phase-body">
<h3>验收标准</h3>
<div class="ac-grid">
<div class="ac-item"><span class="ac-icon">✅</span> 登录项注册 — SMAppService.mainApp 开机自动启动</div>
<div class="ac-item"><span class="ac-icon">✅</span> 屏幕变更处理 — 外接显示器插拔自动重建追踪窗口</div>
<div class="ac-item"><span class="ac-icon">✅</span> 全局动画 — 面板淡入淡出、遮罩弹性动画</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 4.1 历史补录 — 右键菜单修改状态、点击编辑时间</div>
</div>
<div class="file-list">
Utilities/LaunchManager.swift · NotchTracker 屏幕变更监听 · NotchBlockApp 菜单栏登录开关
</div>
</div>
</div>
<!-- Phase 5 -->
<div class="phase">
<div class="phase-header">
<div class="phase-badge">5</div>
<div class="phase-title">第五阶段:NotchPanel V2 重设计</div>
<div class="phase-status">✅ 已完成</div>
</div>
<div class="phase-body">
<h3>验收标准</h3>
<div class="ac-grid">
<div class="ac-item"><span class="ac-icon">✅</span> AC 5.1 简约大气 UI — 毛玻璃 18px 圆角 + 渐变边框 + 大倒计时</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 5.2 交互持久 — 鼠标移入面板保持显示,离开后 0.5s 缓慢消失</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 5.3 倒计时 — 1 秒刷新,.common runloop 模式下不冻结</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 5.4 互斥显示 — 排程面板打开时刘海 hover 不触发</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 5.5 空状态 — 无任务时显示友好空态提示</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 5.6 动态高度 — fittingSize 自适应内容,最多 5 个 upcoming 可滚动</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 5.7 点击跳转 — 点击任意任务/添加按钮 → 打开主排程窗口</div>
</div>
<div class="file-list">
Views/NotchPanelView.swift · Managers/NotchPanelController.swift · Managers/NotchTracker.swift · NotchBlockApp.swift
</div>
</div>
</div>
<!-- Phase 6 -->
<div class="phase">
<div class="phase-header">
<div class="phase-badge">6</div>
<div class="phase-title">第六阶段:NotchTracker 架构重写 — NSTrackingArea → 鼠标位置轮询</div>
<div class="phase-status">✅ 已验证</div>
</div>
<div class="phase-body">
<h3>根本问题</h3>
<p style="color:var(--muted);font-size:0.88rem;margin-bottom:12px;">
NSTrackingArea 在菜单栏/刘海区域(顶部 ~37px)<strong>根本上无法工作</strong>。macOS Window Server 无论窗口层级高低(.statusBar=25, .popUpMenu=101, overlay+1=103)都会拦截该区域的鼠标事件,将其路由给系统菜单栏而非应用窗口。
</p>
<h3>新方案</h3>
<p style="color:var(--muted);font-size:0.88rem;margin-bottom:12px;">
使用 <code>NSEvent.mouseLocation</code> 以 10 Hz 轮询全局鼠标位置。该 API 直接从 Window Server 共享内存读取光标坐标,<strong>完全绕过事件分发管线</strong>。触发区域:屏幕顶部 5px × 中心 180px 宽。
</p>
<h3>验收标准</h3>
<div class="ac-grid">
<div class="ac-item"><span class="ac-icon">✅</span> AC 6.1 触发区域 — 顶部 5px、中心 180px 宽,需故意将光标推到屏幕顶端</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 6.2 悬停防抖 — 在触发区停留 ≥0.5s → 面板显示</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 6.3 离开隐藏 — 离开触发区 + 离开面板 >0.5s → 面板消失</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 6.4 全屏避让 — 全屏检测 + 主窗口互斥保持不变</div>
<div class="ac-item"><span class="ac-icon">✅</span> AC 6.5 无刘海 Mac — 自动检测 safeAreaInsets.top > 0,非刘海屏不轮询</div>
</div>
<div class="file-list">
Managers/NotchTracker.swift (76 行增, 110 行删 · 完全重写)
</div>
</div>
</div>
<!-- Commits -->
<h2>📝 Git 提交历史</h2>
<div class="commits">
<div class="commit">
<div class="commit-hash">0d70642</div>
<div><div class="commit-msg">fix: three bugs preventing polling — @StateObject + timer + auto-show</div><div class="commit-meta">v0.6.0 · NotchTracking working ✅ · 320x149 panel confirmed via CGWarp test</div></div>
</div>
<div class="commit">
<div class="commit-hash">65428c7</div>
<div><div class="commit-msg">docs: add Phase 6 — NotchTracker polling rewrite to progress.html</div><div class="commit-meta">v0.6.0 · HTML documentation update</div></div>
</div>
<div class="commit">
<div class="commit-hash">fd47e4c</div>
<div><div class="commit-msg">feat: replace NSTrackingArea with NSEvent.mouseLocation polling</div><div class="commit-meta">v0.6.0 · NotchTracker rewritten · 10 Hz cursor polling · zero NSTrackingArea</div></div>
</div>
<div class="commit">
<div class="commit-hash">63f5a2c</div>
<div><div class="commit-msg">fix: notch tracking — three stacked bugs from v0.1.0</div><div class="commit-meta">v0.6.0 · startup timing + zero tracking rect + menu bar event zone</div></div>
</div>
<div class="commit">
<div class="commit-hash">c579478</div>
<div><div class="commit-msg">docs: update CHANGELOG and progress.html for v0.5.9</div><div class="commit-meta">v0.5.9 · documentation update</div></div>
</div>
<div class="commit">
<div class="commit-hash">66906f2</div>
<div><div class="commit-msg">fix: notch tracking never starts on cold launch — start() in init()</div><div class="commit-meta">v0.5.9 · NotchTracker now starts at app init, not Window.onAppear</div></div>
</div>
<div class="commit">
<div class="commit-hash">a91eda4</div>
<div><div class="commit-msg">chore: optimize harness — remove irrelevant agents, settings.local.json</div><div class="commit-meta">v0.5.9 · 40 agents removed · effortLevel: high</div></div>
</div>
<div class="commit">
<div class="commit-hash">9fae695</div>
<div><div class="commit-msg">docs: update all documentation for v0.5.8</div><div class="commit-meta">v0.5.8 · CHANGELOG + README + CLAUDE.md</div></div>
</div>
<div class="commit">
<div class="commit-hash">48fa418</div>
<div><div class="commit-msg">feat: NotchPanel V2 redesign — elegant notch dropdown</div><div class="commit-meta">v0.5.8 · 4 files · dynamic height · read-only glance · mutual exclusion · timer lifecycle fix · NSScreen.main thread safety</div></div>
</div>
<div class="commit">
<div class="commit-hash">80a3add</div>
<div><div class="commit-msg">fix: menu bar open-panel unresponsive + notch hover dead</div><div class="commit-meta">v0.5.8 · WindowGroup→Window(id:) · ignoresMouseEvents fix</div></div>
</div>
<div class="commit">
<div class="commit-hash">c6c4c2f</div>
<div><div class="commit-msg">feat: new app icon — notch silhouette + focus block design</div><div class="commit-meta">v0.5.6 · 10 files · programmatic generation 16→1024px · icon embedded in app bundle</div></div>
</div>
<div class="commit">
<div class="commit-hash">d7bd95b</div>
<div><div class="commit-msg">fix: DMG filename auto-detects version from git tag</div><div class="commit-meta">v0.5.5 · build-dmg.sh improvement</div></div>
</div>
<div class="commit">
<div class="commit-hash">ea91f28</div>
<div><div class="commit-msg">fix: v0.5.3 — All MEDIUM issues resolved</div><div class="commit-meta">v0.5.3 · code quality improvements</div></div>
</div>
<div class="commit">
<div class="commit-hash">1d29e0c</div>
<div><div class="commit-msg">fix: v0.5.2 — Multi-agent code review fixes</div><div class="commit-meta">v0.5.2 · review-based improvements</div></div>
</div>
<div class="commit">
<div class="commit-hash">77fec63</div>
<div><div class="commit-msg">fix: v0.5.1 — Code review fixes</div><div class="commit-meta">v0.5.1 · initial code review pass</div></div>
</div>
<div class="commit">
<div class="commit-hash">f24e236</div>
<div><div class="commit-msg">feat: v0.5.0 — Auto-break scheduling between time blocks</div><div class="commit-meta">v0.5.0 · smart break insertion</div></div>
</div>
<div class="commit">
<div class="commit-hash">57660d8</div>
<div><div class="commit-msg">feat: v0.4.0 — Productivity heatmap + weekly trend charts</div><div class="commit-meta">v0.4.0 · data visualization</div></div>
</div>
</div>
<!-- Tech Stack -->
<h2>🛠️ 技术栈</h2>
<div class="stats">
<div class="stat-card"><div class="stat-label">语言</div><div style="font-weight:600;margin-top:4px;">Swift 6.1</div></div>
<div class="stat-card"><div class="stat-label">UI 框架</div><div style="font-weight:600;margin-top:4px;">SwiftUI + AppKit</div></div>
<div class="stat-card"><div class="stat-label">最低系统</div><div style="font-weight:600;margin-top:4px;">macOS 14.0</div></div>
<div class="stat-card"><div class="stat-label">持久化</div><div style="font-weight:600;margin-top:4px;">UserDefaults / JSON</div></div>
<div class="stat-card"><div class="stat-label">关键 API</div><div style="font-weight:600;margin-top:4px;">CGShieldingWindowLevel</div></div>
</div>
<h3>系统权限需求</h3>
<div class="ac-grid">
<div class="ac-item"><span class="ac-icon">📋</span> 辅助功能权限 (Accessibility) — 全屏检测</div>
<div class="ac-item"><span class="ac-icon">📋</span> 本地通知权限 (Notifications) — 超时提醒</div>
</div>
<div class="footer">
NotchBlock v0.6.0 · 构建于 2026-06-05 · Xcode 16.4 · Swift 6.1 · Apple Silicon (arm64)
</div>
</body>
</html>