From 6418c2f36f02bce158f94e5538649fd090efc6fd Mon Sep 17 00:00:00 2001 From: dongliang Date: Wed, 29 Apr 2026 16:42:09 +0930 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E4=BB=BB=E5=8A=A1=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=E6=9D=A1=20+=20=E6=8C=89taskIds=E7=9B=B4=E6=8E=A5?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 首页新增"有N条新任务 点击查看"提示条 - pendingCount>0 时显示,点击/查看后消失 - 和红点共存:提示条=统一入口,红点=分类提示 2. TaskListFragment 通知模式 - 有 filterTaskIds 时跳过 queryTaskIds - 直接按 taskId 构建列表,调 lookTaskDetail 加载详情 - 不受 status 筛选限制,跨状态任务都能显示 3. 横幅/提示条共用 navigateToNewTasks() - 1个任务→跳详情,多个→跳列表 - 跳转后清除红点+提示条+pendingTaskIds Co-Authored-By: Claude Opus 4.6 (1M context) --- .../com/xiaoqu/watch/ui/home/HomeFragment.kt | 89 +++++++++++++------ .../xiaoqu/watch/ui/task/TaskListFragment.kt | 27 +++--- .../main/res/drawable/bg_new_task_hint.xml | 7 ++ app/src/main/res/layout/page_main.xml | 16 ++++ 4 files changed, 100 insertions(+), 39 deletions(-) create mode 100644 app/src/main/res/drawable/bg_new_task_hint.xml diff --git a/app/src/main/java/com/xiaoqu/watch/ui/home/HomeFragment.kt b/app/src/main/java/com/xiaoqu/watch/ui/home/HomeFragment.kt index 34839ac..71b74ca 100644 --- a/app/src/main/java/com/xiaoqu/watch/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/xiaoqu/watch/ui/home/HomeFragment.kt @@ -69,6 +69,8 @@ class HomeFragment : BaseFragment() { private lateinit var dotPool: View private lateinit var dotPunch: View private lateinit var dotComplete: View + // 新任务提示条 + private lateinit var tvNewTaskHint: TextView // ===== 设置页 View 引用 ===== private lateinit var tvAvatarLetter: TextView @@ -128,12 +130,14 @@ class HomeFragment : BaseFragment() { override fun onResume() { super.onResume() - // 从其他页面返回时,有未读通知 → 直接显示红点(不靠 diffStats) - // 原因:onViewCreated 的 fetchStatistics 已更新 lastStats,diffStats 对比不出差异 + // 从其他页面返回时,恢复新任务提示 if (notificationManager.pendingCount > 0) { + // 红点(不靠 diffStats,直接显示) dotPool.visibility = View.VISIBLE dotPunch.visibility = View.VISIBLE dotComplete.visibility = View.VISIBLE + // 提示条 + updateNewTaskHint() } } @@ -280,6 +284,12 @@ class HomeFragment : BaseFragment() { dotPunch = page.findViewById(R.id.dotPunch) dotComplete = page.findViewById(R.id.dotComplete) + // 新任务提示条 + tvNewTaskHint = page.findViewById(R.id.tvNewTaskHint) + tvNewTaskHint.setOnClickListener { + navigateToNewTasks() + } + // 快捷区卡片点击 → 跳转任务列表 + 清除红点 page.findViewById(R.id.cardPool)?.setOnClickListener { dotPool.visibility = View.GONE @@ -429,10 +439,11 @@ class HomeFragment : BaseFragment() { is AppEvent.BluetoothStateChanged -> { statusBar.updateBluetooth(event.isOn) } - // 新任务到达 → 刷新统计 + 红点 + // 新任务到达 → 刷新统计 + 红点 + 提示条 is AppEvent.NewTaskArrived -> { Timber.d("首页: 新任务到达 (${event.count} 条)") fetchStatistics(checkDots = true) + updateNewTaskHint() setupBannerClick(event.taskIds) } // MQTT 消息 @@ -524,37 +535,57 @@ class HomeFragment : BaseFragment() { findNavController().navigate(R.id.action_home_to_taskList, bundle) } + /** 更新新任务提示条 */ + private fun updateNewTaskHint() { + val count = notificationManager.pendingCount + if (count > 0) { + tvNewTaskHint.text = "有${count}条新任务 点击查看" + tvNewTaskHint.visibility = View.VISIBLE + } else { + tvNewTaskHint.visibility = View.GONE + } + } + /** - * 设置通知横幅点击回调 - * 点击时从 notificationManager.pendingTaskIds 取所有累积的任务 ID - * 1 个任务 → 跳任务详情;多个 → 跳任务列表(传 taskIds 只显示新任务) + * 跳转查看所有新任务(横幅/提示条共用) + * 1 个任务 → 跳详情;多个 → 跳列表按 taskIds 加载 */ + private fun navigateToNewTasks() { + val currentDest = findNavController().currentDestination?.id + if (currentDest != R.id.homeFragment) return + + val allIds = notificationManager.pendingTaskIds + if (allIds.isEmpty()) return + + if (allIds.size == 1) { + val taskId = allIds.first().toLongOrNull() ?: 0L + val bundle = bundleOf("taskId" to taskId) + findNavController().navigate(R.id.action_home_to_taskDetail, bundle) + } else { + val bundle = bundleOf( + "taskIds" to allIds.mapNotNull { it.toLongOrNull() }.toLongArray() + ) + findNavController().navigate(R.id.action_home_to_taskList, bundle) + } + + // 清除所有提示 + clearNewTaskIndicators() + } + + /** 清除所有新任务提示(红点+提示条+未读) */ + private fun clearNewTaskIndicators() { + dotPool.visibility = View.GONE + dotPunch.visibility = View.GONE + dotComplete.visibility = View.GONE + tvNewTaskHint.visibility = View.GONE + notificationManager.consumeAll() + } + + /** 设置通知横幅点击回调 */ private fun setupBannerClick(taskIds: List) { val mainActivity = activity as? com.xiaoqu.watch.app.MainActivity ?: return mainActivity.notificationBanner.onClick = { - val currentDest = findNavController().currentDestination?.id - if (currentDest == R.id.homeFragment) { - // 取所有累积的任务 ID(不是事件参数的,防覆盖丢失) - val allIds = notificationManager.pendingTaskIds - if (allIds.size == 1) { - // 1 个任务 → 直接跳详情 - val taskId = allIds.first().toLongOrNull() ?: 0L - val bundle = bundleOf("taskId" to taskId) - findNavController().navigate(R.id.action_home_to_taskDetail, bundle) - } else if (allIds.isNotEmpty()) { - // 多个任务 → 跳任务列表(传 taskIds 只显示新任务) - val bundle = bundleOf( - "tableStatus" to 2, - "taskIds" to allIds.mapNotNull { it.toLongOrNull() }.toLongArray() - ) - findNavController().navigate(R.id.action_home_to_taskList, bundle) - } - // 清除所有红点和未读 - dotPool.visibility = View.GONE - dotPunch.visibility = View.GONE - dotComplete.visibility = View.GONE - notificationManager.consumeAll() - } + navigateToNewTasks() } } } diff --git a/app/src/main/java/com/xiaoqu/watch/ui/task/TaskListFragment.kt b/app/src/main/java/com/xiaoqu/watch/ui/task/TaskListFragment.kt index 8c3b77e..6dcfea7 100644 --- a/app/src/main/java/com/xiaoqu/watch/ui/task/TaskListFragment.kt +++ b/app/src/main/java/com/xiaoqu/watch/ui/task/TaskListFragment.kt @@ -120,22 +120,29 @@ class TaskListFragment : BaseFragment() { /** 第一步:获取任务 ID 列表 */ private fun fetchTaskIds() { showLoading() + + // 通知跳转:有 taskIds 时不走 queryTaskIds,直接按 ID 构建列表 + val ids = filterTaskIds + if (ids != null && ids.isNotEmpty()) { + taskList = ids.map { TaskItem(id = it) } + Timber.d("任务列表: 通知模式, ${ids.size} 个任务") + if (taskList.isNotEmpty()) { + fetchCurrentDetail() + } else { + showEmpty() + } + return + } + + // 正常流程:按 status 筛选 viewLifecycleOwner.lifecycleScope.launch { val params = hashMapOf("status" to currentStatus) val result = safeApiCall { taskApi.getTaskIds(params) } when (result) { is ApiResult.Success -> { - var list = result.data ?: emptyList() - // 如果有 taskIds 过滤(通知跳转),只保留指定任务 - val ids = filterTaskIds - if (ids != null && ids.isNotEmpty()) { - list = list.filter { item -> - ids.any { it.toString() == item.id.toString() } - } - } - taskList = list - Timber.d("任务列表: status=$currentStatus, count=${taskList.size}, filter=${ids?.size ?: 0}") + taskList = result.data ?: emptyList() + Timber.d("任务列表: status=$currentStatus, count=${taskList.size}") if (taskList.isNotEmpty()) { // 确保 taskIndex 在范围内 if (taskIndex >= taskList.size) taskIndex = taskList.size - 1 diff --git a/app/src/main/res/drawable/bg_new_task_hint.xml b/app/src/main/res/drawable/bg_new_task_hint.xml new file mode 100644 index 0000000..a4b6052 --- /dev/null +++ b/app/src/main/res/drawable/bg_new_task_hint.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/layout/page_main.xml b/app/src/main/res/layout/page_main.xml index a457d02..361043a 100644 --- a/app/src/main/res/layout/page_main.xml +++ b/app/src/main/res/layout/page_main.xml @@ -42,6 +42,22 @@ + + +