首页
/ Folo 移动端 v0.1.5 版本特性技术解读:通知与未读体系、批量已读与体验打磨

Folo 移动端 v0.1.5 版本特性技术解读:通知与未读体系、批量已读与体验打磨

2026-09-08 12:44:16作者:仰钰奇

导读

本文围绕 Folo(AI RSS Reader)移动端 v0.1.5 变更记录 展开,逐条解读该版本引入的可配置新条目通知、未读角标与详细未读计数、批量将订阅源或分类标记为已读、AI 摘要默认开启等核心改动,并结合 apps/mobile 源码说明其底层实现链路(Firebase Cloud Messaging 推送、expo-notifications 角标、上下文菜单批量操作等)。读完本文,你将能对照当前仓库源码理解这些发布说明背后的功能入口、默认值配置与数据流走向。

一、版本概览:一次围绕“未读治理”的集中交付

v0.1.5 的变更按 changelog 模板 的三段式组织:Shiny new things(新特性)Improvements(改进)No longer broken(修复)。三部分围绕同一条主线展开:帮助用户更高效地掌握“有新内容 → 有多少未读 → 一键清空 → 点击直达正文”这一完整阅读链路。

新特性清单如下:

  • 为新条目提供可配置的通知(#3424)
  • 引入未读角标(#3424)
  • 文档链接整合进动作页(7e553db)
  • 支持将订阅源或分类一键标记为已读(53b2136)
  • 提供显示详细未读计数的选项(#3453)

其中 #3424 从变更记录看同时牵动通知、角标、分享入口隐藏与分享修复等多个改动,可以推断这是一个围绕“推送与分享体系”的横切工作流。

二、可配置的新条目通知:从 FCM 令牌到点击直达正文

2.1 功能描述

v0.1.5 为移动端引入了可配置的新条目通知:当用户订阅的源产生新条目时,App 可推送提醒,且用户能够按需开关该能力。这说明“是否接收推送”已成为一个可配置项,而不再是无条件行为。

2.2 源码侧的推送链路

useMessaging.ts 中可以看到完整链路:

  1. 令牌注册useUpdateMessagingToken 在用户登录(whoami?.id 存在)且具备通知操作权限(hasNotificationActions)时触发,通过 followClient.api.messaging.createToken({ token, channel: Platform.OS }) 将设备 FCM 令牌上报服务端,同时缓存在本地 kv(键名为 firebase_messaging_token,见 useMessaging.ts)。
  2. 令牌刷新:通过 Firebase Messaging 的 onTokenRefresh 监听令牌轮换并自动重新注册。
  3. 消息路由useMessaging 接收 Remote Message,识别 message.data.type === "new-entry" 类型的推送,读取其中的 entryIdview 字段,然后调用 navigation.pushControllerView(EntryDetailScreen, ...) 直接将用户带入对应条目详情页(见 useMessaging.ts)。

这一设计意味着服务端推送的 data 载荷至少包含 typeviewentryId 三个字段,移动端据此完成“点开推送即读文章”的深度链接体验。

从依赖清单看,推送能力由 @react-native-firebase/messaging(FCM)与 expo-notifications(通知呈现、权限与角标)共同承担,二者均声明于 apps/mobile/package.json

2.3 权限请求与系统通道

[v0.1.5 之后仍沿用的] 通知权限申请逻辑位于 permission.ts

  • Android 端首先创建名为 default 的通知渠道,配置 importance: AndroidImportance.MAX、振动模式 [0, 250, 250, 250] 与提示色;
  • 随后按“先查询、再请求”的顺序获取权限,未授权时弹出系统请求;
  • 权限被拒绝时返回 false 并弹出错误提示,不会静默失败。

2.4 可配置性入口

仓库中 Notifications 设置路由 已为通知设置页预留了占位实现,同时 SettingsList.tsxtitles.notifications 作为菜单项文案并配 NotificationCuteReIcon 图标,从源码结构看通知配置入口已接入设置体系。

三、未读角标与详细未读计数:一个开关,两种粒度

3.1 未读角标(App Icon Badge)

角标能力由 useUnreadCountBadge.ts 实现:它通过 useUnreadAll() 读取全局未读总数,在每次变化后调用 setBadgeCountAsyncWithPermission(unread) 把数字同步到系统桌面角标(expo-notificationssetBadgeCountAsync)。

关键约束在其开关语义上:角标默认关闭。在共享设置默认值 defaults.tsshowUnreadCountBadgeMobile: false,对应 UI 设置接口 interface.ts。开关判定实现在 permission.ts

  • 读取 getUISettings().showUnreadCountBadgeMobile
  • 开关关闭(默认状态)且未显式跳过检查时直接返回 false,不写角标;
  • 开启后还需完成通知授权,否则同样放弃;
  • 为避免无效调用,若目标计数与当前角标相同则直接返回(幂等保护)。

3.2 详细未读计数(#3453)

除“角标显示/隐藏”这一粗粒度选项外,#3453 提供了显示详细未读计数的选项。从订阅列表组件(如 SubscriptionItem.tsxInboxItem.tsx)与 CategoryGrouped.tsx 对未读计数的使用可以推断:该选项控制列表内未读数字的展示粒度(例如分组/分类维度上的统计明细),使得大列表场景下用户无需进入具体分组即可感知各维度积压量。

四、批量已读:订阅源与分类的“一键清零”

4.1 功能描述

v0.1.5 让用户可以对单个订阅源整个分类执行“标记为已读”操作,解决订阅量大时逐条划掉的痛点。

4.2 上下文菜单的实现

feeds.tsx 的订阅源上下文菜单中可以看到 markFeedAsRead 的调用:菜单项触发后执行 unreadSyncService.markFeedAsRead(feedIds)(见 feeds.tsx),其中 feedIds 可来自单选订阅源或整组订阅源集合。分类场景则通过对选中分类展开为 feedIds 数组后复用同一 markFeedAsRead 服务完成批量清零,达到“分类维度一键已读”的效果。

4.3 与既有已读能力的配合

该能力与移动端既有“条目级已读”逻辑(apps/mobile/src/modules/entry-list/hooks.ts 等)互补:条目级用于逐条消费,源/分类级用于整体清空,二者共同构成完整的未读治理闭环。

五、动作页文档链接与分享链路收口(#3424 / 7e553db)

5.1 文档链接进入动作页

7e553db 将“文档链接”接入动作页(Actions),对应设置路由 Actions.tsx。从变更语义推断,用户可在条目/订阅的动作面板中直接跳转查看对应的原文文档,减少“复制链接 → 浏览器打开”的手动步骤。

5.2 分享按钮的可用性判断(#3424)

Improvements 中“在不适用于某订阅源时隐藏分享按钮”与 No longer broken 中“修复无法分享订阅源 URL”同属 #3424 的分享链路整改:

  • 旧行为:分享按钮无条件出现,但对某些订阅源(例如无站点的纯列表源或特殊订阅类型)分享操作会失败;
  • 新行为:先判断该订阅源是否存在可分享的 URL/资源,再决定按钮显隐;同时修复了此前导致分享动作失败的根因,保证对具备分享条件的源能稳定完成分享。

这两条改动在 feeds.tsx 的上下文菜单中也有对应:仅当 subscription.feedId 对应源存在(getFeedById 可命中)时才执行 setStringAsync(feed.url) 之类分享逻辑。

六、AI 摘要与阅读视觉层的打磨

6.1 AI 摘要默认开启(8da8a71)

v0.1.5 将 AI 摘要设置为默认启用。这一语义在共享 UI 设置的默认值中得到印证:defaults.tssummary: true,对应接口 interface.ts 的布尔字段。默认开启意味着新用户开箱即可看到条目摘要,无需手动进入设置开启;该默认值位于 @follow/shared 共享包,可推断为保证桌面端与移动端行为一致。

6.2 AI 摘要样式增强(87aa062)

同版本对 AI 摘要的视觉样式做了增强,使其在正文中与普通内容区分更清晰。移动端 AI 摘要相关 UI 集中在 modules/ai/summary.tsx,可结合该文件继续查看样式实现。

6.3 其余视觉与反馈改进

  • 订阅源请求失败的错误提示(#3455):当订阅源抓取失败时不再静默,而是向用户展示明确错误信息。上下文菜单中 feed.errorAt / feed.errorMessage 字段的存在(见 feeds.tsx)说明数据层已具备错误状态字段,前端据此渲染提示。
  • 时间线列表分隔线样式(b1c356f)Toast 样式升级(83e7764):属于信息密度与反馈层的一致性打磨。
  • 显著性能改进(23eaf86):变更记录仅给出哈希而未量化具体指标,从措辞看属于渲染/滚动链路的优化,具体收益以实际使用为准。

七、No longer broken:六个关键修复的技术要点

修复点 影响
订阅源 URL 分享失效(#3424) 恢复对可分享订阅源的分享能力
同名分类在不同视图下的区分错误(d70f082) 订阅列表按视图准确区分同名分类,避免“标记已读/展开”作用于错误目标
重复菜单项(f24f21a) 清理上下文菜单与动作面板中的重复操作项
条目文字偶发错位(17dd1e7) 修正条目文本定位,保证正文排版稳定
视图选择器按压缩放闪烁(d66d49c) 消除 Timeline 视图切换时的闪烁,提升交互顺滑度
特定图片加载导致崩溃(7b20633) 修复特定图片来源下的稳定性问题

其中“同名分类跨视图混淆”的修复对多视图(如时间线/收件箱/订阅列表等视图体系,见 TimelineViewSelector.tsx)用户尤为重要:分类名称相同但归属视图不同时,此前操作可能命中错误上下文,修复后按视图隔离语义得到保证。

八、如何在本仓库验证这些能力

若希望对照源码逐条验证 v0.1.5 的能力,推荐按以下路径阅读:

  1. 推送与角标useMessaging.tspermission.tsuseUnreadCountBadge.ts,配合共享默认值 defaults.ts
  2. 批量已读context-menu/feeds.tsx
  3. 设置入口modules/settings/SettingsList.tsxmodules/settings/routes/ 下的 Actions、Notifications、General 路由;
  4. 依赖版本:通知与角标相关的 expo-notifications@react-native-firebase/messaging 等声明见 apps/mobile/package.json
  5. 相邻版本对比:可对比 v0.1.4v0.1.6 的变更记录,观察该特性线的演进脉络。

需要说明的是:changelog 中的版本号(0.1.x)是移动端早期里程碑的记录;以当前仓库为准,apps/mobile/package.json 中包的当前版本已迭代至更高版本,本文所述功能的能力入口与默认值均以仓库内源码现状为准。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
858
1.35 K
docsdocs
暂无描述
Markdown
899
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
923
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.83 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
532
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.03 K
524
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
393