fix: 红点改为直接显示,不依赖diffStats

diffStats方案因lastStats竞态反复失败。
改为:有pending通知→所有未ack的卡片直接显示红点。
点了哪个消哪个,简单可靠无竞态。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
dongliang
2026-04-29 19:31:51 +09:30
parent 93a31e76a3
commit 5e5c44cacd

View File

@@ -139,42 +139,17 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
if (notificationManager.pendingCount <= 0) { if (notificationManager.pendingCount <= 0) {
// 全部已查看/无通知 → 清除
activeDotCards.clear() activeDotCards.clear()
renderDots() renderDots()
return return
} }
// 有未读通知 → 所有未 ack 的卡片显示红点
// 有未读通知 → 用 preNotificationStats 精确补充红点到 activeDotCards val ack = notificationManager.acknowledgedCards
val baseline = notificationManager.preNotificationStats activeDotCards.clear()
if (baseline != null && activeDotCards.isEmpty()) { if (2 !in ack) activeDotCards.add(2)
// 非首页返回activeDotCards 为空view 重建),需要重新计算 if (3 !in ack) activeDotCards.add(3)
viewLifecycleOwner.lifecycleScope.launch { if (4 !in ack) activeDotCards.add(4)
val result = safeApiCall { taskApi.getStatistics() } renderDots()
if (result is ApiResult.Success && result.data != null) {
val data = result.data
val changed = notificationManager.diffStats(baseline, data)
val ack = notificationManager.acknowledgedCards
// 只加未查看的
for (status in changed) {
if (status !in ack) activeDotCards.add(status)
}
// 记录增量
if (2 in changed) notificationManager.recordCardIncrement(2, data.waitForTask - baseline.waitForTask)
if (3 in changed) notificationManager.recordCardIncrement(3, data.treatTask - baseline.treatTask)
if (4 in changed) notificationManager.recordCardIncrement(4, data.incompleteTask - baseline.incompleteTask)
// 更新数字
tvPoolNum.text = data.waitForTask.toString()
tvPunchNum.text = data.treatTask.toString()
tvCompleteNum.text = data.incompleteTask.toString()
notificationManager.lastStats = data
renderDots()
}
}
} else {
// 首页返回从卡片列表回来等activeDotCards 已有值,直接渲染
renderDots()
}
} }
override fun onDestroyView() { override fun onDestroyView() {
@@ -387,30 +362,12 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
if (result is ApiResult.Success && result.data != null) { if (result is ApiResult.Success && result.data != null) {
val data = result.data val data = result.data
// 对比红点:累积到 activeDotCards不覆盖已有的 // 有 pending 通知 → 所有未 ack 的卡片显示红点(不用 diffStats避免竞态
if (checkDots) { if (checkDots && notificationManager.pendingCount > 0) {
val oldStats = notificationManager.lastStats val ack = notificationManager.acknowledgedCards
if (oldStats != null) { if (2 !in ack) activeDotCards.add(2)
// 有旧数据 → 精确对比 if (3 !in ack) activeDotCards.add(3)
val changedCards = notificationManager.diffStats(oldStats, data) if (4 !in ack) activeDotCards.add(4)
for (status in changedCards) {
activeDotCards.add(status)
val increment = when (status) {
2 -> data.waitForTask - oldStats.waitForTask
3 -> data.treatTask - oldStats.treatTask
4 -> data.incompleteTask - oldStats.incompleteTask
else -> 0
}
notificationManager.recordCardIncrement(status, increment)
}
} else {
// 无旧数据(首次加载 lastStats 还为 null→ 有 pending 通知就显示所有有值的
if (notificationManager.pendingCount > 0) {
if (data.waitForTask > 0) activeDotCards.add(2)
if (data.treatTask > 0) activeDotCards.add(3)
if (data.incompleteTask > 0) activeDotCards.add(4)
}
}
renderDots() renderDots()
} }