feat(overview): 「近 7 天」脱离历史 200 条上限,并支持近 7/30 天 × 条数/字数/时长切换 - #909
Open
bigsongeth wants to merge 3 commits into
Open
feat(overview): 「近 7 天」脱离历史 200 条上限,并支持近 7/30 天 × 条数/字数/时长切换#909bigsongeth wants to merge 3 commits into
bigsongeth wants to merge 3 commits into
Conversation
activity.json 此前每天只存一个条数。概览页想给出「近 30 天说了多少字」
这类周期指标时,只能回头从 list_history() 现算 —— 而历史有 200 条硬上限,
日均上百次的用户两三天就把上周挤没了,算出来的字数与时长必然偏低。
把单日值从裸数字扩成 {count, chars, durationMs}:
- chars 口径 = 最终插入文本的 Unicode 字符数,与历史详情页的「N 字」一致;
- durationMs 口径 = 录音时长,不含识别/润色耗时,与详情页「录音 x.x 秒」同源。
两个口径都刻意跟已有 UI 对齐,避免同一个数在两处对不上。
磁盘格式用 untagged enum 兼容旧文件:老用户的 activity.json 全是裸数字,
读不回来的话年度热力图会一次性清空(会被当成数据丢失)。旧日期没有字数/
时长,读回 0 —— 诚实缺省,好过整天丢掉条数。四个单测钉住这个契约:纯旧
格式、纯新格式、新旧混排(升级当天必然出现)、以及缺字段的对象。
存储代价可忽略:只存聚合数字、不存文本,一天一行,两年上限 731 行。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
两件事,同一张卡: 1. 修数据源。「近 7 天」此前从 list_history() 现算,而历史有 200 条硬上限。 实测(日均约 88 次听写的真实数据):history.json 正好卡在 200 条,只装得下 两天多,于是近 7 天里前 4 天全画成 0 —— 而同一页的年度热力图上那 4 天分别是 40 / 118 / 108 / 37,亮着的。同一个页面两块数据自相矛盾。改读 activity 后 两者同源,柱子和格子对得上。 2. 加周期与指标切换。卡片标题位变成「近 7 天 / 近 30 天」,右侧原来的「条数 / 天」变成「条数 / 字数 / 时长」。月度字数是用户实际想看的数(跟按月计费的 竞品比较时要用),此前完全看不到。 卡片顶部显示周期总计(大字)+ 日均:想知道「这个月总共说了多少字」是要一个数, 不是在 30 根柱子里目测求和。30 天模式下柱子只有几像素宽,逐柱数字会糊成一片, 改为 title 悬浮显示、横轴只标首/中/末三个日期。 聚合逻辑抽成 lib/activityMetrics.ts 并带单测:窗口长度恒定、缺失日期补 0、 跨月边界、老数据无 chars/durationMs 时不产生 NaN(NaN 会把柱状图的 max 算坏)。 日期键一律用本地年月日拼,不能用 toISOString() —— 后者按 UTC 切日,东八区凌晨 的会话会算到前一天,与后端 chrono::Local 写的键对不上。 顺带:活动数据的 IPC 不再按 mobile 跳过。热力图在移动端仍不渲染(issue Open-Less#861), 但周期指标卡是要渲染的,跳过 IPC 会让它在移动端永远空。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
历史页早就有这个键(History.tsx),概览页没有 —— 想看到新数据只能切到别的 页再切回来触发重挂载。⌘R 是「重新加载」的通用直觉,两个数据页应该一致。 一次刷新本页全部三份数据:历史、活动、凭据。preventDefault 拦掉 webview 默认的整页 reload,只重发 IPC,不让整个前端重挂载。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
User description
问题:概览页的「近 7 天」会说谎
「近 7 天」柱状图从
list_history()现算,而历史有 200 条硬上限。日均上百次听写的用户,两三天就把上周挤没了。实测本机真实数据(
history.json正好卡在 200 条):前四天全画成 0,而同一个页面上方的年度热力图那四天是亮的。同一页两块数据自相矛盾,用户没法判断该信哪个。
改动
1. 换数据源
「近 7 天」改读 activity 存储 —— 它保留两年、只存聚合数字、与历史保留策略解耦,本来就是年度热力图的数据源。改完之后柱子和格子同源,对得上。
2. activity 记录字数与时长
activity 此前每天只存一个条数。要支持「近 30 天说了多少字」,得先扩成
{count, chars, durationMs}。写入点手边就有polished和raw.duration_ms,口径刻意与已有 UI 对齐:chars= 最终插入文本的 Unicode 字符数,与历史详情页的「N 字」一致durationMs= 录音时长,不含识别/润色耗时,与详情页「录音 x.x 秒」同源磁盘格式向后兼容:老用户的
activity.json全是裸数字({"2026-08-01": 5}),读不回来的话年度热力图会一次性清空,会被当成数据丢失。用 untagged enum 兼容,四个单测钉住契约:纯旧格式、纯新格式、新旧混排(升级当天必然出现)、缺字段的对象。旧日期没有字数/时长,读回 0 —— 诚实缺省,好过整天丢掉条数。
存储代价可忽略:只存聚合数字、不存文本,一天一行,两年上限 731 行。
3. 周期 × 指标切换
卡片标题位变成「近 7 天 / 近 30 天」,右侧原来的「条数 / 天」变成「条数 / 字数 / 时长」。
卡片顶部显示周期总计(大字)+ 日均:想知道「这个月总共说了多少字」是要一个数,不是在 30 根柱子里目测求和。30 天模式下柱子只有几像素宽,逐柱数字会糊成一片,改为悬浮显示、横轴只标首/中/末三个日期。
4. ⌘R 刷新
历史页早就有这个键,概览页没有 —— 想看到新数据只能切到别的页再切回来触发重挂载。一次刷新本页三份数据(历史、活动、凭据),
preventDefault拦掉 webview 默认的整页 reload。实现注记
lib/activityMetrics.ts带单测:窗口长度恒定、缺失日期补 0、跨月边界、老数据无chars时不产生 NaN(NaN 会把柱状图的 max 算坏)toISOString()—— 后者按 UTC 切日,东八区凌晨的会话会算到前一天,与后端chrono::Local写的键对不上验证
cargo check/cargo test --lib/npm test/tsc --noEmit全绿;浏览器里逐个切过两个周期 × 三个指标,核对总计与逐日数值;本地装机实测。🤖 Generated with Claude Code
PR Type
Bug fix, Enhancement, Tests
Description
activity 存储新增每日字数与时长聚合
近 7/30 天指标改用 activity 数据源
支持条数/字数/时长切换与总计、日均
兼容旧格式数据,新增测试与多语文案
Diagram Walkthrough
File Walkthrough
7 files
Extend activity stats response with chars and durationRecord char count and duration on session endExpand activity store to aggregate chars and durationAdd chars and duration fields to ActivityDayAdd period series builder for activity metricsAdd optional chars and duration fields to ActivityDayReplace week chart with switchable period metrics card5 files
Add period and metric localization stringsAdd Japanese period and metric localization stringsAdd Korean period and metric localization stringsAdd Simplified Chinese period and metric localization stringsAdd Traditional Chinese period and metric localization strings2 files
Add tests for period series and legacy entriesUpdate mock activity days with chars and duration