fix: 用通知前快照精确显示红点(区分首页/非首页场景)
问题:非首页返回时,onViewCreated已覆盖lastStats, 导致diffStats对比不出差异,红点要么全显要么不显。 修复: 1. NotificationManager新增preNotificationStats - 首条通知到达时保存当前lastStats快照 - consumeAll时清除 - 不会被onViewCreated的fetchStatistics覆盖 2. HomeFragment.onResume用preNotificationStats做精确diffStats - 有快照→fetchStatisticsForDots(baseline, acknowledged) - 只给变化且未查看的分类显示红点 - 无快照→降级为全显(未查看的) 场景验证: - 首页收到通知→当场diffStats→红点精确 ✅ - 首页点红点→对应消除,其他保留 ✅ - 首页点通知→consumeAll→返回后全部消除 ✅ - 非首页返回→preNotificationStats对比→红点精确 ✅ Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -66,6 +66,10 @@ class NotificationManager @Inject constructor(
|
||||
/** 上次统计数据(对比红点用) */
|
||||
var lastStats: TaskStatistics? = null
|
||||
|
||||
/** 通知到达前的统计快照(用于非首页返回后精确 diffStats) */
|
||||
var preNotificationStats: TaskStatistics? = null
|
||||
private set
|
||||
|
||||
/** 协程作用域 */
|
||||
private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())
|
||||
|
||||
@@ -111,6 +115,11 @@ class NotificationManager @Inject constructor(
|
||||
val taskIds = parseTaskIds(rawJson)
|
||||
if (taskIds.isEmpty()) return
|
||||
|
||||
// 保存通知到达前的统计快照(只在首次通知时保存,后续累积不覆盖)
|
||||
if (preNotificationStats == null) {
|
||||
preNotificationStats = lastStats?.copy()
|
||||
}
|
||||
|
||||
addTaskIds(taskIds)
|
||||
|
||||
// 震动 + 亮屏(只在首条时触发,暂存的合并后不重复震动)
|
||||
@@ -152,6 +161,7 @@ class NotificationManager @Inject constructor(
|
||||
_pendingTaskIds.clear()
|
||||
acknowledgedCards.clear()
|
||||
_cardIncrements.clear()
|
||||
preNotificationStats = null
|
||||
Timber.d("通知: 已清空全部未读")
|
||||
}
|
||||
|
||||
|
||||
@@ -130,19 +130,59 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
// 从其他页面返回时,只恢复未查看分类的红点
|
||||
if (notificationManager.pendingCount > 0) {
|
||||
val ack = notificationManager.acknowledgedCards
|
||||
if (2 !in ack) dotPool.visibility = View.VISIBLE
|
||||
if (3 !in ack) dotPunch.visibility = View.VISIBLE
|
||||
if (4 !in ack) dotComplete.visibility = View.VISIBLE
|
||||
updateNewTaskHint()
|
||||
} else {
|
||||
if (notificationManager.pendingCount <= 0) {
|
||||
// 全部已查看 → 清除所有提示
|
||||
dotPool.visibility = View.GONE
|
||||
dotPunch.visibility = View.GONE
|
||||
dotComplete.visibility = View.GONE
|
||||
tvNewTaskHint.visibility = View.GONE
|
||||
return
|
||||
}
|
||||
|
||||
// 有未读通知 → 用 preNotificationStats 精确对比红点
|
||||
// (preNotificationStats 是通知到达前的快照,不会被 onViewCreated 的 fetchStatistics 覆盖)
|
||||
val ack = notificationManager.acknowledgedCards
|
||||
val baseline = notificationManager.preNotificationStats
|
||||
if (baseline != null) {
|
||||
// 精确模式:对比快照和当前统计,只给变化的分类显示红点
|
||||
fetchStatisticsForDots(baseline, ack)
|
||||
} else {
|
||||
// 无快照(首次加载等):已查看的不显示,未查看的显示
|
||||
if (2 !in ack) dotPool.visibility = View.VISIBLE
|
||||
if (3 !in ack) dotPunch.visibility = View.VISIBLE
|
||||
if (4 !in ack) dotComplete.visibility = View.VISIBLE
|
||||
}
|
||||
updateNewTaskHint()
|
||||
}
|
||||
|
||||
/**
|
||||
* 用通知前快照精确对比红点(非首页返回时调用)
|
||||
* @param baseline 通知到达前的统计快照
|
||||
* @param acknowledged 已查看的分类集合
|
||||
*/
|
||||
private fun fetchStatisticsForDots(baseline: com.xiaoqu.watch.data.task.TaskStatistics, acknowledged: Set<Int>) {
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
val result = safeApiCall { taskApi.getStatistics() }
|
||||
if (result is ApiResult.Success && result.data != null) {
|
||||
val data = result.data
|
||||
val changed = notificationManager.diffStats(baseline, data)
|
||||
|
||||
// 只给变化且未查看的分类显示红点
|
||||
dotPool.visibility = if (2 in changed && 2 !in acknowledged) View.VISIBLE else View.GONE
|
||||
dotPunch.visibility = if (3 in changed && 3 !in acknowledged) View.VISIBLE else View.GONE
|
||||
dotComplete.visibility = if (4 in changed && 4 !in acknowledged) View.VISIBLE else View.GONE
|
||||
|
||||
// 记录增量(供 acknowledgeCard 扣减用)
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user