Folo 移动端 v0.1.9 更新全解读:隐藏已读订阅、Discover Trending 源与 AI 摘要默认开启
2026/9/17 6:00:16 网站建设 项目流程

Folo 移动端 v0.1.9 更新全解读:隐藏已读订阅、Discover Trending 源与 AI 摘要默认开启

本文以 apps/mobile/changelog/0.1.9.md 为骨架,结合 Folo 移动端仓库源码(apps/mobile 与 packages/internal/shared)逐项剖析本次发布的新功能、体验改进与缺陷修复,帮助读者理解每个变更背后的实现机制、对应设置入口与实际影响。读完你不仅能掌握 v0.1.9 的全部更新点,还能顺着源码定位到每个功能的实现文件与参数默认值,便于二次开发或参与贡献。

一、v0.1.9 更新总览

v0.1.9 是 Folo(AI RSS Reader)移动端的增量版本,变更集中在订阅列表的信息噪音治理、发现(Discover)页面的内容发现能力、AI 能力的默认体验三个方向,并修复了一批列表与视图层面的缺陷。按 changelog 原文分类可归纳为:

分类内容
Shiny new things(新特性)新增“隐藏无未读条目订阅”选项;Trending Feeds 出现在 Discover 页与新手引导流程中
Improvements(体验改进)RSSHub 源异常时错误提示更清晰;AI 摘要默认开启;图标加载失败时展示占位图标;精简登录/注册流程
No longer broken(缺陷修复)点头像导航不正确;视频视图下无图条目显示异常;部分订阅不出现在搜索结果;图片/视频视图未读指示器显示错误

下文将逐项对照源码展开说明。仓库同时维护了完整的历史变更记录目录(apps/mobile/changelog),如需回溯此前行为可对照阅读相邻版本记录。

二、新特性:隐藏“无未读条目”的订阅

2.1 设置入口与开关语义

v0.1.9 在Settings → General → Subscriptions(订阅)分组下新增了一个“Hide Read”(隐藏无未读订阅)开关,对应的设置键为hideAllReadSubscriptions。设置界面实现在 apps/mobile/src/modules/settings/routes/General.tsx,它与其他订阅行为开关(如autoGroup自动分组、hidePrivateSubscriptionsInTimeline在时间线隐藏私密订阅)并列放置在 Subscriptions 分组卡片内:

  • 开关键:hideAllReadSubscriptions,由 General.tsx 中setGeneralSetting("hideAllReadSubscriptions", value)写入;
  • 对应文案 i18n 键:general.hide_all_read_subscriptions.label/.description(见 locales 等语言资源)。

2.2 源码视角:开关如何真正生效

值得注意的一点是:在 Folo 的实现中,该开关并不是“独立生效”的,而是与unreadOnly(启动/默认只显示未读)配合使用。核心逻辑位于 apps/mobile/src/atoms/settings/general.ts:

export function useHideAllReadSubscriptions() { const hideAllReadSubscriptions = useGeneralSettingKey("hideAllReadSubscriptions") const unreadOnly = useGeneralSettingKey("unreadOnly") return hideAllReadSubscriptions && unreadOnly } export function getHideAllReadSubscriptions() { const { hideAllReadSubscriptions, unreadOnly } = getGeneralSettings() return hideAllReadSubscriptions && unreadOnly }

也就是说,只有同时开启“隐藏无未读订阅”与“仅显示未读”(unreadOnly)时,该功能才会真正启用(hook 返回hideAllReadSubscriptions && unreadOnly)。这可以理解为一种安全护栏:如果你并不处于“未读优先”模式,列表不会被误过滤。

该判定结果被多处以“是否同时排除私密/已读订阅”的入参形式使用,例如:

  • 订阅管理列表过滤:apps/mobile/src/modules/subscription/SubscriptionLists.tsx 与 apps/mobile/src/modules/subscription/UnGroupedList.tsx 均通过useHideAllReadSubscriptions()过滤“全部已读”的订阅分组/订阅项;
  • “全部标记为已读”对话框在完成后是否需要刷新/剔除:apps/mobile/src/modules/dialogs/MarkAllAsReadDialog.tsx 读取getHideAllReadSubscriptions()作为excludePrivate参数;
  • 时间线底部“全部已读”操作及上下文菜单同样会携带该判定:apps/mobile/src/modules/entry-list/EntryListFooter.tsx、apps/mobile/src/modules/context-menu/entry.tsx、apps/mobile/src/modules/screen/TimelineViewSelectorContextMenu.tsx。

2.3 默认值与数据流

GeneralSettings的类型与默认值统一收敛在共享包 packages/internal/shared/src/settings/defaults.ts 中:

// subscription autoGroup: true, hideAllReadSubscriptions: false, hidePrivateSubscriptionsInTimeline: false,

可以看到v0.1.9 新增的hideAllReadSubscriptions默认值为false,即默认不隐藏,需要用户在设置中主动开启(为避免默认行为突变)。设置写入路径遵循移动端统一的createSettingAtom("general", …)模式:由 general.ts 创建 general 设置原子,再被设置页与各业务模块订阅,形成“UI 开关 → 设置原子 → 订阅列表/时间线过滤”的完整链路。

三、新特性:Trending Feeds 进入 Discover 与新手引导

3.1 功能位置

v0.1.9 将Trending(热门源)区块同时接入两处:

  1. Discover(发现)页面:作为独立区块渲染,见 apps/mobile/src/modules/discover/DiscoverContent.tsx,其内部直接引入<Trending />
  2. 新手引导(onboarding)的兴趣选择步骤:apps/mobile/src/modules/onboarding/step-interests.tsx 在步骤底部同样渲染<Trending className="mb-4 w-full" />,让新用户在订阅兴趣推荐之外,可以顺手一键关注社区热门源。

3.2 实现剖析:数据来源与渲染

热门源的 UI 实现在 apps/mobile/src/modules/discover/Trending.tsx,关键点如下:

  • 数据请求:组件内通过useQuery发起,queryKey 为["trending", "feeds", discoverLanguage],并使用meta: { persist: true }让结果可被本地持久化缓存;请求函数是fetchFeedTrending({ lang, limit: 20 })
  • 接口封装:apps/mobile/src/modules/discover/api.ts 中fetchFeedTrending调用后端 APIfollowClient.api.trending.getFeeds({ language, view, limit }),即网络请求由服务端聚合;
  • 语言映射:读取 UI 设置discoverLanguage(默认"all",见 defaults.ts),并对法语做了"fra" → "eng"的兜底(当前热门源暂未覆盖法语);语言参数为"all"时不下发lang
  • 排序徽标与订阅数:列表对前 3 名使用 accent 高亮圆形排名徽标(第 1 名实心、第 2/3 名按透明度递减),每行右侧展示item.analytics.subscriptionCount(经formatNumber格式化)作为热度佐证;
  • 筛选项:区块头部右侧有筛选按钮(Filter 图标),点击弹出DiscoverSettingsScreen,用于切换 Discover 语言偏好。

3.3 对新手引导的意义

引导页本身维护了数套内置推荐订阅 JSON(如 apps/mobile/src/modules/onboarding/feeds.json、feeds-english.json,内含大量rsshub://协议源)。Trending 区块的加入等于在“按分类挑订阅”之外,提供了一条基于实时订阅统计的发现路径,降低了新用户冷启动时“不知道订阅什么”的门槛。

四、体验改进:错误信息、AI 默认值与图标兜底

4.1 RSSHub 订阅失败的提示更清晰

RSSHub 是 Folo 获取长尾内容源的重要协议(引导内置源大量使用rsshub://youtube/...rsshub://hackernews等,Discover 页的“Popular”推荐也基于 RSSHub 分类),因此其源异常时给出可读的错误文案对排障至关重要。v0.1.9 的变更目标是:当某个 RSSHub 源抓取失败时,界面提示不再只有笼统的“订阅失败”,而是带上具体的失败原因/链路阶段,方便用户区分“路由不存在、站点反爬、网络超时”等情形。相关订阅与发现逻辑集中在 apps/mobile/src/modules/discover(如 Recommendations.tsx、Category.tsx)中,其渲染依赖@follow/constants提供的RSSHubCategories@follow/models/rsshub中的路由声明类型。

4.2 AI 摘要改为默认开启

此前移动端的 AI 摘要开关默认是关闭的,用户需要手动在 General → Action 中打开“Summary”;v0.1.9 将其改为默认开启。这一变更的证据在共享默认配置 packages/internal/shared/src/settings/defaults.ts:summary: true

export const defaultGeneralSettings: GeneralSettings = { translation: false, translationMode: "bilingual", summary: true, actionLanguage: "default", ... }

设置页开关见 General.tsx(general-ai-summary-switch)。需要说明两点:

  • 该默认值仅作用于新安装/未初始化过设置的设备;升级用户如曾在旧版本手动关闭过 AI 摘要,其本地设置会保留false,不会被强制改回(设置原子只在首次初始化时写入默认值,参见 general.ts 的initializeDefaultSettings流程);
  • 实际能否生成摘要仍取决于当前账号的 AI 能力/配额,默认开启只代表“请求摘要的行为默认启用”。

4.3 图标加载失败的占位兜底

若某个 feed 的站点图标(favicon)加载失败(网络、源站 404 等),列表将不再出现破图/空白,而是回退显示占位图标。此类“图标解析 → 加载 → 失败回退”的处理在移动端订阅与条目卡片中被广泛复用(相关基础组件位于 apps/mobile/src/components),占位逻辑与空态展示样式可在仓库内结合具体组件验证。

4.4 精简登录/注册流程

登录与注册链路被重新梳理,减少中间跳转与不必要的确认步骤。移动端认证相关逻辑可参见仓库中浏览器/设备登录引导的实现(cli 侧对应 apps/cli/src/browser-login.ts,移动端账号引导逻辑位于 e2e 支持脚本 apps/mobile/e2e 相关 support 及 src 中认证模块)。

五、缺陷修复逐个拆解

v0.1.9 修复了 4 个用户可感知的问题,逐一说明其场景与验证方式:

  1. 点击头像的导航不正确:在部分页面(如帖子/条目头部)点击用户头像无法进入正确的用户主页或列表。修复后头像点击按预期触发对应导航。
  2. 视频视图下无图条目显示异常:条目没有配图时,在“视频/图文视图”渲染会出现占位错位、高度异常等。修复使无图条目在视频视图中按纯文本卡片正确布局。
  3. 部分订阅不出现在搜索结果中:此前搜索订阅源时个别已订阅/合法源匹配不到(结果集会遗漏)。修复涉及搜索结果构建逻辑(可结合 apps/mobile/src/modules/discover/search-tabs 下的search-feed-items.ts及其测试search-feed-items.test.ts理解搜索条目的组装与去重)。
  4. 图片/视频两种视图下未读指示器显示错误:未读红点/计数在 picture 视图与 video 视图的条目上出现错显,修复统一了两种视图消费未读状态的方式。

这些修复点与订阅列表过滤(第二节)、发现页内容(第三节)共同属于“视图状态正确性”范畴。由于 changelog 中每个修复只附了 commit 引用,具体到行级实现可以在各视图组件(apps/mobile/src/modules/entry-list 与view相关组件)中按需继续排查。

六、如何在仓库中验证 v0.1.9 的行为

如果你是开发者或希望复现验证上述行为,可以从以下几处入手:

  • 对照默认配置:所有新增设置键的默认值、注释分组都在 packages/internal/shared/src/settings/defaults.ts,类型定义在 packages/internal/shared/src/settings/interface.ts;
  • 跟踪设置页 UI:apps/mobile/src/modules/settings/routes/General.tsx 是 General 设置页的完整实现(Language、Action、TTS、Subscriptions、Timeline、Mark as Read、Content 全部分组);
  • 运行移动端测试:仓库使用 Vitest 组织测试(vitest.workspace.ts),可在 apps/mobile 目录下按既有测试约定运行与搜索相关的单测(如 search-tabs 下对搜索条目聚合逻辑的测试);
  • 查看移动端 i18n 文案:设置项的中英日法繁体文案分别位于 locales/mobile/default 各语言 JSON,便于核对开关的显示名与描述。

七、小结

v0.1.9 是 Folo 移动端在“订阅管理效率 + 内容发现 + AI 默认体验”上的一次集中迭代:新增的“隐藏无未读订阅”与unreadOnly联动设计体现对“未读优先”工作流的尊重;Trending 区块被同时注入 Discover 与引导流程,打通了新用户冷启动的热门源推荐;而 AI 摘要默认开启、RSSHub 错误信息优化则降低了普通用户理解与使用门槛。若想继续追踪后续版本演进(如热门源的分组/视图支持、摘要触发策略调整等),可对照 apps/mobile/changelog 目录下相邻版本记录,并结合 defaults.ts 观察设置默认值的演进轨迹。

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询