首页
/ Folo Desktop v0.3.0 版本解析:自定义 RSSHub 实例、可配置 OPML 导出与账号管理

Folo Desktop v0.3.0 版本解析:自定义 RSSHub 实例、可配置 OPML 导出与账号管理

2026-09-05 12:52:32作者:郁楠烈Hubert

Folo(AI RSS Reader)桌面端 v0.3.0 是一次围绕"数据获取与数据带走"能力展开的版本更新:新增可接入的自定义 RSSHub 实例、带选项的 OPML 订阅导出,以及更完整的账号信息管理。读完本文,你可以掌握 v0.3.0 中每项新功能的实际形态——RSSHub 实例页面的组织与排序规则、自建实例的接入字段与环境变量约定、OPML 导出表单的校验逻辑与请求参数,并能在 Folo 源码中快速定位这些功能的实现位置。

版本概览:v0.3.0 改了什么

v0.3.0 的变更说明记录在 apps/desktop/changelog/0.3.0.md,整体分为三部分:

  • New Features(新增功能)
    1. Custom RSSHub Instances(自定义 RSSHub 实例):接入自建 RSSHub 实例以提升数据获取效率;贡献自己部署的 RSSHub 实例还可获得额外 $POWER 激励。
    2. OPML Export Options(OPML 导出选项):导出 OPML 文件时,可可选地指定 RSSHub URL 与文件夹分类模式。
    3. Account Management(账号管理):支持更新邮箱,并方便地管理已关联的第三方社交账号。
  • Improvements(改进)
    • 支持更新邮箱并管理关联的社交账号;
    • 当用户已停留在 Discover(发现)页面时再次导航进入,会自动滚动回顶部。
  • Bug Fixes:修复了若干缺陷(原文未逐一列举)。

下面按功能逐项展开,并结合当前仓库中的源码实现说明其行为边界。

功能一:自定义 RSSHub 实例

这是 v0.3.0 的核心功能。Folo 内置了官方 RSSHub("Folo Built-in RSSHub"),但用户现在可以添加、编辑、删除自己部署的 RSSHub 实例,并自由切换当前账号使用的实例。

实例页面:官方实例置顶,用户实例按可用性排序

RSSHub 实例管理页面的入口在 rsshub 子视图页面/(layer)/(subview)/rsshub/index.tsx)。页面结构从源码结构看是:顶部标题与简介、"Add new instance" 按钮,然后是实例卡片网格(响应式 1/2/3 列)。

实例列表的排序逻辑在 List 组件中(同文件 L245-L283):

  1. 官方实例永远排在第一位,以 { id: "official", isOfficial: true } 的形式虚拟插入列表;
  2. 用户实例中,当前正在使用的实例排前(依据 status.usage.rsshubId);
  3. 其次按健康状态排序,带 errorMessage 的实例排后;
  4. 最后按负载率userCount / userLimit)从低到高排序,满载实例沉底。

每张实例卡片展示 owner 头像、描述、当前用户数(Users)与容量上限(Limit),并带有若干状态标签(L124-L143):

  • official:Folo 官方内置实例;
  • in use:当前账号正在使用的实例;
  • yours:当前登录用户自己部署的实例;
  • Error:实例健康检查报错。

对于自己拥有的实例,页面还提供 Edit 与 Del 操作;其中 Delete 按钮会在"实例上还有其他用户"时禁用(L205-L216,disabled={!!instanceUserCountExceptOwner}),避免误删影响他人。

添加实例:baseUrl + accessKey,以及自建实例的环境变量约定

添加实例的表单在 add-modal-content.tsx,其 Zod schema(L41-L48)定义了两个字段:

  • baseUrl:必填,且必须是合法 URL(z.string().url());
  • accessKey:可选,用于访问受限实例时的密钥。

提交后调用 useAddRSSHubMutation,即以 { baseUrl, accessKey, id } 参数请求后端创建实例记录(id 存在时为编辑已有实例)。

更值得注意的是,添加弹窗内直接用 Shiki 高亮展示了一段 dotenv 格式的部署指引(L69-L73),告诉实例部署方需要在服务端配置哪些环境变量:

FOLLOW_OWNER_USER_ID=${用户 id 或 handle}   # 你的 Folo 账号 id 或 handle
FOLLOW_DESCRIPTION=${实例描述}              # 你的实例描述
FOLLOW_USER_LIMIT=${容量上限}               # 用户数上限;设为 0 或 1 可将实例私有化,留空表示不限制

从默认值处理看,userLimit 缺省时按 1000 展示(L72)。也就是说,自建实例的容量策略是:0/1 = 私有、留空 = 不限制、其他正整数 = 明确上限。实例卡片上 userLimit > 1 时显示具体数字,≤ 1 时显示 "Private" 标签(rsshub/index.tsx/(layer)/(subview)/rsshub/index.tsx) L116-L122)。

切换实例:使用状态、二次验证与容量校验

切换("Use")实例的确认弹窗在 set-modal-content.tsx,会展示该实例的 owner、描述、当前用户数与容量上限(L34-L59),用户确认后才执行切换。从源码结构看,切换动作被包在 useTOTPModalWrapper 中(L21),即切换实例属于敏感操作,会触发 TOTP 二次验证

数据层封装在 queries/rsshub.ts

  • useAddRSSHubMutation:调用 followClient.api.rsshub.create({ baseUrl, accessKey, id }),成功后使 rsshub.list()rsshub.status() 两个查询失效并刷新;
  • useSetRSSHubMutation:调用 followClient.api.rsshub.use 切换当前使用实例,成功后同样刷新列表、状态与对应实例详情;
  • useDeleteRSSHubMutation:按 id 删除实例;
  • 查询侧提供 rsshub.get / rsshub.list / rsshub.status 三个 defineQuery 封装,其中 list 成功时会顺带把实例 owner 信息写入用户 store(L75-L81),供页面渲染头像使用。

另外,实例卡片上的选择按钮(SelectInstanceButton,rsshub/index.tsx/(layer)/(subview)/rsshub/index.tsx) L295-L329)有两道可用性拦截:

  • 实例带 errorMessage(健康检查失败)时按钮禁用,显示 "unavailable";
  • userCount >= userLimit(容量已满)时按钮禁用,显示 "limit reached"。

这与 changelog 中"使用自定义 RSSHub 实例提升数据获取效率"的定位一致:官方实例不可用时,用户可以切换到自建的、负载更低的实例。

功能二:OPML 导出选项

v0.3.0 让 OPML 导出不再是"一键全量",而是允许用户在导出前指定两个可选项。实现位于桌面端设置页的数据管理标签页 data-control.tsx 中的 ExportFeedsForm(L116-L196)。

表单字段与校验规则

导出的表单 schema(L116-L119):

const exportFeedFormSchema = z.object({
  rsshubUrl: z.string().url().optional(),   // 可选,但填写后必须是合法 URL
  folderMode: z.enum(["view", "category"]), // 二选一,默认 "view"
})
  • RSSHub URL(rsshubUrl:可选项。输入框 placeholder 为 https://rsshub.app,提示用户可以填入自己使用的 RSSHub 地址;
  • 文件夹分类模式(folderMode:枚举值只有两个——view(按视图/收藏组织)与 category(按分类组织),默认选中 viewdefaultValues: { folderMode: "view" },L124-L129)。

导出流程:拼接导出请求并触发下载

提交逻辑(L131-L141)并不在客户端本地生成 OPML,而是动态构造一个带查询参数的导出接口 URL 并触发浏览器下载:

function onSubmit(values) {
  const exportUrl = new URL(`${env.VITE_API_URL}/subscriptions/export`)
  exportUrl.searchParams.append("folderMode", values.folderMode)
  if (values.rsshubUrl) {
    exportUrl.searchParams.append("RSSHubURL", values.rsshubUrl)
  }
  // 通过创建 <a download> 触发下载
  link.href = exportUrl.toString()
  link.download = "follow.opml"
  link.click()
}

也就是说,最终请求形如:

GET {API_URL}/subscriptions/export?folderMode=view[&RSSHubURL=https://your-rsshub.example.com]

文件名固定为 follow.opml。从参数设计可以推断两个选项的作用:folderMode 决定 OPML 内的层级如何映射(跟随 App 内的视图结构或分类结构),而 RSSHubURL 决定导出文件中那些经由 RSSHub 生成的订阅地址以哪个实例前缀写出——配合"自定义 RSSHub 实例"功能,用户换环境或换实例时导入的 OPML 依然指向自己能访问的实例。

同一个数据管理标签页还包含其他数据操作(可作为对照):导出本地数据库(exportDB())、清理缓存(Electron 与 Web 两套实现)、数据库重建等,见 data-control.tsx L38-L114。

功能三:账号管理

changelog 将"Account Management"列为 v0.3.0 的新功能,并在 Improvements 中再次强调"Update email and manage linked social accounts"。该能力允许用户在 Folo 中:

  • 更新绑定邮箱
  • 管理已关联的第三方社交账号(查看/解除关联)。

从源码结构看,桌面端个人资料相关界面集中在 profile 模块(如 UserProfileModalContent.tsx),账号状态数据则由共享的 user store 维护(packages/internal/store/src/modules/user/store.ts)。changelog 本身未展开该功能的细节,此处以版本说明为准,具体交互以上述模块当前实现为参考入口。

改进项与其他修复

  • Discover 页面重复导航回顶:当用户已处于 Discover(发现)页时再次导航进入,会自动滚动到顶部,避免停留在上次浏览的滚动位置。这类滚动控制逻辑位于 discover 相关页面与路由钩子(如 useDiscoverRSSHubRoute 所在的功能区)中。
  • Bug 修复:changelog 以"Some bugs are fixed."一笔带过,未逐项列举具体缺陷。

延伸阅读:与 v0.3.0 相关的源码路径

如需继续深入 v0.3.0 的功能实现,可以从以下文件入手:

功能 文件
版本变更说明 apps/desktop/changelog/0.3.0.md
RSSHub 实例管理页(列表/排序/卡片/操作) rsshub/index.tsx/(layer)/(subview)/rsshub/index.tsx)
添加/编辑实例表单与部署环境变量 add-modal-content.tsx
实例详情与切换(Use)确认 set-modal-content.tsx
RSSHub 增删切换的 React Query 封装 queries/rsshub.ts
OPML 导出选项表单与导出请求构造 data-control.tsx

需要说明的是:v0.3.0 是较早的版本,当前仓库中的上述源码是演进后的实现(例如 OPML 导出表单已并入设置页的数据管理标签),细节字段与交互可能比 0.3.0 发布时更完整,但整体功能脉络与该版本 changelog 的三项新功能保持一致。

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

项目优选

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