首页
/ Folo 桌面端 v0.4.0 技术解析:全局 AI 设置落地、标题音频时长标注与发布工程质量改进

Folo 桌面端 v0.4.0 技术解析:全局 AI 设置落地、标题音频时长标注与发布工程质量改进

2026-09-08 20:00:16作者:温玫谨Lighthearted

本篇基于 apps/desktop/changelog/0.4.0.md 的发布说明,结合 Folo 桌面端渲染层源码,逐项还原 v0.4.0 在"全局 AI 摘要/翻译设置、标题音频时长展示、设置面板精简、发布工程化(Windows 签名)与若干体验修复"上的具体实现。读完本文,你将了解这些版本变更背后的状态设计(三级设置层级、Jotai atom 组织)、设置面板构建方式(SettingBuilder + defineSettingItem)以及对应源码文件位置,便于在 Folo 仓库中按图索骥继续追踪演进。

一、v0.4.0 版本概览

v0.4.0 是 Folo 桌面端(Electron)的一个以"AI 能力设置收敛 + 阅读信息密度优化 + 发布工程化"为主题的版本。原发布说明共包含三类变更,现完整罗列如下:

New Features(新特性)

特性 来源
为 AI 摘要与翻译新增全局设置 PR #3294
在条目标题处展示音频时长估计 PR #3292
通过增强设置开关简化设置项 commit 217e1a8

Improvements(改进)

改进 来源
提升条目内容翻译质量 PR #3294
细化工具栏自定义 PR #3284
使用 SignPath 对 Windows 可执行文件签名 PR #3286
移除邮箱验证 toast 通知 commit 9bb723a
限制 Zen 模式的显示宽度 commit d107127
升级 MGC Icon 至 v1.36 PR #3310
增强提现弹窗的用户体验 PR #3311
提升操作(Action)设置按钮的可见性与布局 commit 0d5cb13

Bug Fixes(缺陷修复)

修复 来源
修复 reCAPTCHA 无法点击的问题 commit 305c4bc
修复在列表中标记已读后 store 不更新的问题 commit e8305f8

下面按"设置架构 → 信息展示 → 发布工程 → 缺陷修复"四个维度展开。

二、新特性详解

1. 为 AI 摘要与翻译新增全局设置(#3294)

v0.4.0 之前,AI 摘要(Summary)与翻译(Translation)主要通过动作(Action)或工具栏按钮按需触发;本版本将"全局是否自动开启 AI 摘要/翻译"收敛为普通设置项,同时结合同 PR 的翻译质量增强,使开启后所有条目内容能够自动获得翻译与摘要。

从渲染层源码看,这套能力的开关设计存在三个设置层级ai-translation.ts 的注释完整描述了这一架构:

// NOTE: We have three levels of settings can enable AI translation or Summary:
// 1. General setting, which is the global settings for all entries.
// 2. Action setting, which is defined in an action and applied to specific entries.
// 3. Toolbar control, which is a temporary setting for the current entry.
//
// When general setting or action setting is enabled, we should hide the toolbar control, which can save some space.
//
// Different from AI summary, AI translation also can show up in the entry list, which should only be controlled by the General setting or Action setting.
  • General setting(全局设置):即 v0.4.0 新增的"Settings → General → AI"区域里的 summarytranslation 两个开关,作用于所有条目;
  • Action setting(动作级设置):定义在某个 Action 中,只作用于被该动作匹配的具体条目;
  • Toolbar control(工具栏临时开关):仅对当前条目生效的临时开关,如工具栏上的"翻译一次"按钮;当全局或动作级设置开启时,为避免占空间,工具条控件会被隐藏。

对应地,ai-translation.ts 用 Jotai 原子维护"一次性显示"状态与自动开关判定:

export const [, , useShowAITranslationOnce, , getShowAITranslationOnce, setShowAITranslationOnce] =
  createAtomHooks(atom<boolean>(false))

export const toggleShowAITranslationOnce = () => setShowAITranslationOnce((prev) => !prev)

export const useShowAITranslationAuto = (settings?: boolean | null) => {
  return useGeneralSettingKey("translation") || !!settings
}

export const useShowAITranslation = (settings?: boolean | null) => {
  const showAITranslationAuto = useShowAITranslationAuto(settings)
  const showAITranslationOnce = useShowAITranslationOnce()
  return showAITranslationAuto || showAITranslationOnce
}

可以看到,"是否显示翻译"最终由 useShowAITranslationAuto(全局设置或动作设置)与 useShowAITranslationOnce(工具栏临时开关)共同决定;而 useShowAITranslationAuto 的实现即 useGeneralSettingKey("translation"),它直接读取的就是 v0.4.0 新增的全局设置键 translation

设置面板侧,general.tsxaction 分组下通过 SettingBuilderdefineSettingItem 声明了两个开关:

defineSettingItem("summary", {
  label: t("general.action.summary.label"),
  description: t("general.action.summary.description"),
}),
defineSettingItem("translation", {
  label: t("general.action.translation.label"),
  description: t("general.action.translation.description"),
}),
TranslationModeSelector,
ActionLanguageSelector,

紧随其后的是 TranslationModeSelectorActionLanguageSelector(目标语言选择器),说明全局开关与"翻译模式、翻译目标语言"是成组配置的。结合同 PR 的"提升条目内容翻译质量",本版本实际上把翻译从"偶发动作"升级为"可常开的内容呈现能力"——开启全局翻译后,条目标题与正文在条目流与阅读视图中会按需替换为目标语言。

2. 在标题处展示音频时长估计(#3292)

对于播客、音视频类 RSS 条目,v0.4.0 会根据附件的时长元数据,在条目标题下方的元信息区显示预估时长(如 XX 分钟),让读者在点开前即可判断内容投入成本。

核心实现在 EntryTitle.tsx:从条目的 attachments 中找到带有 duration_in_seconds 的附件,将其解析为分钟并格式化:

const attachments = state.attachments || []
const { duration_in_seconds } =
  attachments?.find((attachment) => attachment.duration_in_seconds) ?? {}
const seconds = duration_in_seconds ? formatTimeToSeconds(duration_in_seconds) : undefined
const estimatedMins = seconds ? formatEstimatedMins(Math.floor(seconds / 60)) : undefined

在渲染层,EntryTitle.tsxentry.estimatedMins 存在时,用 i-mgc-time-cute-re 时钟图标 + tabular-nums 数字字体展示:

{entry.estimatedMins && (
  <div className="flex items-center gap-1.5">
    <i className="i-mgc-time-cute-re text-base" />
    <span className="text-xs tabular-nums">{entry.estimatedMins}</span>
  </div>
)}

这一显示逻辑并非只在阅读视图中存在,条目列表模板同样接入。列表侧 list-item-template.tsx 通过 const estimatedMins = seconds && Math.floor(seconds / 60) 计算并渲染相同信息,且按 isChinese 环境分别输出 XX 分钟formatEstimatedMins(...) 的结果。

两个格式化工具函数的实现在 utils.ts

  • formatTimeToSecondsL412-L426):依次按 h:mm:ssmm:ssm:ss 三种格式解析时长为秒数;
  • formatEstimatedMinsL449 起):将分钟拆分为 月/天/小时/分钟 层级做人性化输出(month 阈值约 30 天、day 为 24 小时等)。

由于 duration_in_seconds 来自 attachments 元数据,该项能力对播客类订阅(audio attachment)尤其有效——RSS 源的 enclosure 时长字段会被解析进附件结构,进而驱动标题区展示。

3. 通过增强设置开关简化设置面板(commit 217e1a8)

v0.4.0 引入 enhancedSettings(增强设置)开关:默认关闭时设置面板只展示高频常用项,避免选项过载;开启后解锁进阶选项。这个"开关决定面板内容密度"的交互通过两个机制实现:

第一,general.tsx 中用 useGeneralSettingKey("enhancedSettings") 生成 reRenderKey,并作为 SettingBuilderkey,使开关变化时整个设置构建器重新渲染:

const reRenderKey = useGeneralSettingKey("enhancedSettings")

return (
  <div className="mt-4">
    <SettingBuilder
      key={reRenderKey.toString()}
      settings={[ ... ]}
    />
  </div>
)

因此,凡是被增强设置隐藏/显示的设置项,都会在切换后按最新状态重建。

第二,开关本身带确认守卫。面板底部以 defineSettingItem("enhancedSettings", { ... }) 声明,并实现 onChangeGuardgeneral.tsx):开启时会弹出一个 variant: "danger" 的对话框(标题/描述/确认/取消文案全部走 i18n),用户确认后才真正写入 enhancedSettings;返回 "handled" 表示变更已由守卫代为处理。这能防止用户误触后面对大量高级选项不知所措。

在原子层,general.ts 提供了对应的 hook 化访问:

useEnhancedEnabled: () => useGeneralSettingKeyInternal("enhancedSettings"),
getEnhancedEnabled: () => jotaiStore.get(__generalSettingAtom).enhancedSettings,

也就是说,任意设置面板组件都可以通过 useEnhancedEnabled() 判断当前是否处于"增强模式",进而条件渲染 settings 数组中的高级项——这正是"简化设置项"这一特性在 UI 骨架上的落点。

三、体验与发布工程化改进

工具栏自定义细化与操作设置按钮布局(#3284 / commit 0d5cb13)

v0.4.0 继续打磨阅读视图顶部工具区:PR #3284 细化了工具栏的自定义能力(让用户能更精细地编排条目操作按钮的展示与顺序),commit 0d5cb13 则提升"操作(Action)设置按钮"本身的可见性与布局,避免入口被折叠后难以发现。从整体结构看,该区域属于阅读视图的操作集合模块,具体按钮组件的展示/隐藏逻辑与"AI 摘要/翻译、音频播放、星标、分享"等命令项的组织相关,读者可在渲染层的 entry-content/entry-header 相关模块中继续追踪按钮组的编排方式。

Zen 模式显示宽度限制(commit d107127)

Zen 模式(沉浸式阅读)下,v0.4.0 限制了内容容器的最大显示宽度,避免超宽显示器上文本行过长导致阅读疲劳。这是一个纯排版/布局层的改动:在阅读视图外层容器上施加宽度上限约束,属于对既有 Zen 模式 UI 的可用性收敛。

Windows 可执行文件使用 SignPath 签名(#3286)

作为发布工程化改进,v0.4.0 起桌面端 Windows 构建产物(如安装包与可执行文件)通过 SignPath 进行代码签名。代码签名可降低 Windows SmartScreen 对未知发布者的警告概率,属于 Folo 桌面端发布流水线(electron-builder/forge 相关配置)的供应链加固,与功能层代码解耦。

移除邮箱验证 toast(commit 9bb723a)

此前账号操作过程中会弹出"邮箱已验证"之类的 toast 提示;本版本删除该噪音通知,让通知系统只保留用户真正需要关注的提醒。

升级 MGC Icon 至 v1.36(#3310)

Folo 的图标体系大量使用 MGC(Material/图标集合)线性/填充图标,仓库内 icons/mgc 目录存放了对应的 SVG 源(如 i-mgc-time-cute-rei-mgc-user-3-cute-rei-mgc-calendar-time-add-cute-re 等)。v0.4.0 将图标集升级到 v1.36,主要带来新增图标与图形细节修正,属于视觉层的低风险依赖升级。

提现弹窗用户体验增强(#3311)

桌面端的钱包/提现入口位于 "Power" 模块,相关实现见 my-wallet-section/index.tsxmy-wallet-section/withdraw.tsx。本版本的改动聚焦提现表单的交互细节(如输入态、校验反馈、提交状态展示),让用户在资金操作流程中更清楚当前所处环节。

四、缺陷修复

reCAPTCHA 无法点击(commit 305c4bc)

修复了登录/注册流程中嵌入的 reCAPTCHA 校验组件无法响应点击的问题。此类问题通常源于组件在 Electron 渲染环境下的 iframe 层级、样式覆盖或 pointer-events 处理不当,修复后验证码可以正常完成人机校验。

列表中标记已读后 store 不同步(commit e8305f8)

修复了在列表视图中对条目执行"标记已读"后,客户端 store(基于 zustand + jotai 的订阅/条目状态层,如 packages/internal/store 下的 entry hooks)未及时更新的问题。此前可能出现"已标记已读但仍显示未读角标/未从未读计数中扣除"的状态漂移;修复后列表内的已读变更会正确同步到 store,进而驱动条目流、未读数徽标等 UI 保持一致。

五、小结与后续追踪建议

v0.4.0 的实质贡献可以概括为三条主线:

  1. AI 能力常开化:借助"全局(General)/动作(Action)/工具栏(Toolbar)"三级设置架构,让 AI 摘要与翻译成为可全局自动开启的阅读能力,开关状态落在 ai-translation.ts 与设置面板 general.tsx,读者可据此理解其与 useEntryTranslation 等消费方的联动;
  2. 信息密度优化:通过 EntryTitle.tsxutils.ts 的时长解析与人性化格式化,把音频时长变成标题区的一等元信息;
  3. 工程与体验收尾:SignPath 签名、图标升级、Zen 宽度限制、提现弹窗交互打磨以及两处状态/交互缺陷修复,共同构成一个偏"稳"的发布。

如果你正在阅读这条演进线,建议以 v0.4.0 为基线对比它前后的版本:0.3.x 系列 与后续 0.4.x 补丁说明,可以更完整地还原该阶段的迭代节奏。上述所有设置键、atoms 与设置面板代码都位于桌面渲染层源码中,可直接在仓库内继续深挖。

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

项目优选

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