8
26
2025
7

Arch Linux 中文论坛迁移杂记

本篇只是心得体会加上赞美和吐槽。技术性的迁移记录在这里。

一个多月前,肥猫在 Arch Linux 中文群里说:

(希望有好心人研究一下php74,最好加到archlinuxcn里,因为咱中文社区论坛卡在这个老版本了

然后话题自然就又到了论坛迁移的事情上来——毕竟 FluxBB 年久失修也不是一两天的事了。Arch Linux 官方讨论了几年还没结果,但中文社区这边并不是卡在往哪迁上,而是

基于什么的都可以迁移,但得有人干活

然后又过了些天,论坛使用的本就递送困难的 Sendgrid 停止了免费服务,导致中文论坛完全无法注册新用户了。虽然这件事通过更改为使用我们自己的邮件服务器就解决了,但迁移论坛的想法在我脑中开始成长。

至于迁移到哪个软件,我早已有了想法——包括 OpenSUSE 中文社区Debian 中文社区NixOSOpenSUSEFedoraUbuntuManjaroGaruda LinuxCachyOSKDEGNOMEPythonRustAtuinF-DroidOpenWrtLet's EncryptMozillaCloudflareGrafanaDocker 等等(还有一堆我没有那么熟悉的就不列了)大家都在用的 Discourse。这么多开源社区和商业组织都选择了它,试试总不会错的,用户也会比较熟悉。令我惊喜的是,它甚至有个 FluxBB 导入脚本。

于是在虚拟机里安装尝试。安装过程是由他们的脚本驱动构建的 docker 镜像,没什么特别的——除了比较耗资源。Docker 嘛,硬盘要吃好几 GiB,然后它是现场编译前端资源文件,CPU 和内存也消耗不少。默认的构建是包含 PostgreSQL、Redis、Nginx 的,但 PostgreSQL 也可以用外边的,就是得监听 TCP,并且构建出来的镜像里依旧会存在 PostgreSQL 的服务文件。Nginx 可以改成监听 UNIX 域套接字,然后让外边我自己的 Nginx proxy_pass 过来,这样证书也按自己的方式管理。Redis 我本来也是想拆出来的,但是为安全起见要设个密码嘛,然后构建就失败了……不过算了,反正也没别人用 Redis。

本地测的没有问题,于是去服务器上部署。由于发现它比较吃资源,所以给服务器加了几十G内存、100G 硬盘,还有闲置的 CPU 核心也分配上去了。后来发现运行起来其实也还好,就是内存吃得比较多——每个 Rails 进程大几百,32个加起来就快 10G 了。运行起来之后 CPU 不怎么吃,甚至性能比 MediaWiki 要好上不少,以至于我把反 LLM 爬虫的机制给降级到大部分用户都不需要做了。哦它的 nginx 会起 $(nproc) 个,太多了,被我 sed 了一下,只留下了八只(但其实也完全用不上,毕竟是异步的;Rails 那些进程可是同步的啊)。

run:
  - exec: sed -i "/^worker_processes/s/auto/8/" /etc/nginx/nginx.conf

说回部署。跑起来是没什么问题的。问题出在那个 FluxBB 导入脚本——本来导入就不快,它还跑到一半崩了,修了还崩。然后它不支持导入个性签名、用户头像、置顶帖,还遇到著名的 MySQL「utf8 不 mb4」的问题。来来回回修了又改,花了我好些天。等保留数据测试的时候,发现有好多帖子的作者变成「system」了。一查才发现我刻意没有导入被封禁的用户造成的。都已经配得差不多了,实在是不想删库重来,研究了一下,直接在 Rails 控制台写了段脚本更正了。这个 Rails 控制台能在 Rails 的上下文里交互式地执行代码,很方便改数据,我很喜欢,比 PHP 方便太多了!

另外这个导入脚本有一点好的是,它能够反复执行来更新数据——虽然这种支持反复执行的操作在我写的脚本里是常有的事,基本上从头开始成本太高的都会有,但别人写的脚本能考虑到这一点的可太少了。

用户的密码也导入了!帖子的重定向服务也写好了!虽然后来发现用户个人页面是登录用户才能访问的,给它重定向没什么用……反而是 RSS 重定向更有用,后来也补上了!

后来还发现有些用户名包含空格或者特殊符号啥的,被自动改名了。好在可以用邮箱认用户,不管了,等受影响的用户出现了再改。另外正式迁移之后才发现还有些数据没有迁移——版块的对应关系、用户的主题订阅,不是很重要,算了。

然后就迁移结束啦~所有到旧论坛的访问全部重定向到新论坛啦~不过我还是保留了一个不跳转的后门以便有需要时回去看看。为此我折腾了好久神奇的 nginx 的配置文件,最终得到以下片段:

set $up 'redir';
if ($http_cookie ~ "noredir=1") {
    set $up 'noredir';
    proxy_pass https://104.245.9.3;
}
if ($up = redir) {
    proxy_pass http://127.0.0.1:9009;
}

就是根据 cookie 来 proxy_pass 到不同的服务啦。这样就可以访问一下 /noredir 设置上 cookie,就可以访问旧论坛,再访问一下 /yesredir 清一下 cookie 就恢复跳转到新论坛了。

说起 nginx,Discourse 还在这方面坑了我一下。它文档里给的设置是:

proxy_set_header Host $http_host;

这个配置在 HTTP/3 时是坏的,应该用 $host。别问我 HTTP/2 也没有 Host 头啊,为什么它在用 HTTP/2 时就不会出错。我也不知道 ¯\(ツ)/¯。

于是新论坛上线啦~很多中国大陆用户的首次加载时间变成几十秒啦……还好这只是无缓存加载的时间,就当是下载软件了吧。之后每个标签页大约需要一两秒加载整个 SPA,在不同页面之间跳转并不慢。而这代价付出之后的回报是更现代的界面、丰富的功能。相比于旧论坛,现在:

  • 终于有手机版啦,甚至还支持 PWA,体验非常丝滑。
  • 实时预览的 markdown + bbcode 编辑器,还支持上传图片!再也不会有用户问论坛怎么传图片和日志了!
  • 编辑器还支持草稿功能!不用怕写一半弄丢了,甚至可以换个设备接着写。
  • 代码块角落里有个复制按钮,我再也不需要拖半天鼠标来复制日志然后粘贴进 Vim 里分析了!
  • 快速、简单的搜索体验,用户再也不会找不到搜索功能在哪里了!
  • 实时显示在回复的人。有人在回复的时候就可以等一等,发布帖子之后会立刻出现。发帖不需要跳转到不知道干什么的跳转页面了,读帖也不需要反复刷新了。
  • 有收藏功能了,用户不用发一个根本没什么用的「mark 一下」的帖子了。
  • 有「标记为已解决」的功能了。用户再也不需要问怎么把帖子标记为「已解决」了。
  • 不用自己跑脚本解析 HTML 来向群里发新帖通知了。Discourse 的「聊天集成」功能配一下就好了。
  • 甚至还有「RSS Polling」插件,可以把主站新闻转到论坛里,方便大家讨论。

Discourse 的邮件集成功能也挺不错的。配好之后,可以检测到退信,也可以直接回复邮件通知来回帖。甚至还有个邮件列表模式,就是把所有帖子都给用户发一遍,用户也可以直接回帖。通过邮件发布新主题的功能也有,但我没有启用——不同版块需要配不同的收件地址,有点麻烦,我不觉得有人会想用……就是这个邮件传回 Discourse 部分坑了我一把,但不是 Discourse 的错。

是 maddy 的文档太缺欠了。我要把 forum+...@archlinuxcn.org 这种地址给重写到 noreply@archlinuxcn.org,按例子像这样

table.chain local_rewrites {                                                                                                                   
    optional_step regexp "forum\+(.+)@(.+)" "noreply@$2"
    optional_step regexp "(.+)\+(.+)@(.+)" "$1@$3"
    optional_step static {
        entry postmaster postmaster@$(primary_domain)
    }
    optional_step file /etc/maddy/aliases
    step sql_query {
        driver postgres
        dsn "user=maddy host=/run/postgresql dbname=maddy sslmode=disable"
        lookup "SELECT mailname FROM mailusers.mailinfo WHERE $1 = ANY(alias) and new = false"
    }
}

这里第二行是我加的(虽然一开始把 $2 照着下边那个已有的写成了 $3)。结果是报错「用户不存在」、被退信。我开 debug 选项研究了好久,才意识到最后一步写的是 step,所以它总是要执行的——然而 noreply 这个用户并不在数据库里,所以就找不到了。

那把最后一行改成 optional_step 就好啦——我是这么想的,也是这么做的。然后就有人报告说 admin 邮箱拒收邮件了……又是一通研究,才发现因为这里的步骤全是 optional_step,所以 maddy 第一次用整个邮件地址来查的时候,无论如何都是会通过的——不会返回「目标不存在」,所以也就不会触发去掉域名、只用用户名查询的步骤,而数据库里记录的只有用户名,就导致 admin 邮箱的映射查不到了(映射到它本身,然而并没有以它为名的邮箱)。把 SQL 查询那一行改成这样子就好了:

lookup "SELECT mailname || '@archlinuxcn.org' FROM mailusers.mailinfo WHERE regexp_replace($1, '@archlinuxcn.org$', '') = ANY(alias) and new = false"

然后是把收件的邮件交给 Discourse。他们有个 mail-receiver 容器用来干这事,但这个容器的主要部分其实是 Postfix。我读了一下它的代码,实际上只需要把邮件通过 API 发过去就行了。于是我用 Python 写了一个服务——imap2discourse。这部分的坑在于,这个 API 是把邮件全文用指定的参数 base64 或者不 base64 用 form-data 传过去的,我以为是用上传文件的方式来传,搞了半天它都报奇奇怪怪的错,后来一步一步在 irb 里按 mail-receiver 的代码对照检查,才发现原来是按传字符串的方式传的……

Discourse 的中文翻译不怎么样,好多随意的空格,也好多看不懂的翻译。好在它像 MediaWiki,支持修改界面文本。于是就一点一点地修了好多。上游使用的是 Crowdin 翻译平台,并不能直接 pr 翻译,所以等我什么时候研究一下才能把翻译贡献给上游了。

Discourse 的通知功能挺全面的。可以选择回帖之后要不要通知,邮件通知是只在没访问时发、完全不要还是全都要,网站图标上要不要显示通知计数,还可以开启浏览器的推送通知(然后我就发现 Android 火狐的推送通知无法切换到 PWA 窗口)。

至于管理功能,比 FluxBB 丰富好用太多啦~有各种访问统计报表。设置项有搜索功能。有管理员操作日志,也有选项变更日志,还有邮件收发日志(看看谁又把自己的邮箱域名拼错了)。能给用户添加备注,也能切换成指定的用户看看他们看到的论坛是什么样子的。能给用户添加字段,让用户填写他们用的操作系统和桌面环境,省得回帖时经常要询问。还能加载自定义的 JavaScript 和 CSS,甚至是加强版本。还有暂时用不上的 API 和 webhook。哦对了,我发现它还会自己拒绝一些常见的讨厌爬虫。

除了 FluxBB 之外,还有一个叫 planetplanet 的 RSS 聚合软件也是死了好多年,导致 planet.archlinuxcn.org 多年不更新了。Discourse 正好有从 RSS 发帖的功能,于是将星球也复活了一下,将大家的 RSS 作为帖子在专门的版块发出。虽然界面不是很理想,但将就着用啦。RSS 聚合也是有的。Discourse 的 RSS 功能相当完善,几乎在所有合理的网址后边添加 .rss 就能订阅。

也给旧论坛做了个静态存档站。暂时还没上线,因为肥猫又跑掉了

Discourse 的备份功能会报错,因为它的容器里的 pg_dump 版本比较旧,和我在外边 Arch Linux 里运行的版本不一致。不过我觉得这样也挺好的——因为管理员是可以生成和下载备份文件的,也就是说,如果有管理员的权限被人恶意获取,那么他就能通过下载备份文件的方式获取整个 Discourse 数据库的内容。备份不了就少了这么个风险啦。当然备份我肯定是做了的,至于是如何做的,就等下一篇啦。

Category: Linux | Tags: Discourse 社群 web Arch Linux
7
9
2024
20

我正在使用的火狐扩展(2024年版)

距离上次分享好久了,于是又来啦~

桌面版

每一项第一行是扩展标题和链接,第二行是扩展自己的描述信息,第三行(如有)是我为写本文添加的介绍和评论。

篡改猴
使用用户脚本自由地改变网络
复制链接/标签名称和地址
将链接名称和地址复制到剪贴板
复制链接地址
使用快捷键 "a" 来复制链接地址
对着链接点右键,然后按 a 键就可以复制到链接啦。
书签搜索
使用已加为书签的搜索引擎搜索选定文本
我在访问哪个 Cloudflare® 数据中心?
显示正在访问的 Cloudflare® 名称信息
云盘万能钥匙
您的云盘智能助手
大概没什么用了吧……
About Sync
Show information about Firefox Sync.
同步出现问题时用过。它也可以直接发送请求、修改服务端的信息,比如删掉已卸载扩展的同步数据啥的。
Auto Tab Discard
如果您打开了很多标签页,这个扩展能提升浏览器速度并减少内存占用。
就是标签页休眠啦。
Behind The Overlay Revival
Click to close any overlay popup on any website.
一键关弹窗,不用找关闭按钮在哪里。
Bypass Paywalls
Bypass News Sites' Paywalls
cliget
Download login-protected files from the command line.
为下载的文件生成 wget / curl 的命令行。我现在很少用了,主要用途是在服务器上下载不能直接下载的文件。
Control Panel for YouTube
Gives you more control over YouTube by adding missing options and UI improvements
这个扩展功能不少,我主要用的地方有:隐藏短视频(浪费时间)、自动生成的音乐合集(我从来不听这个)、即将开播的视频(又不能看,显示着干嘛)、已观看完毕的视频。隐藏视频结尾总是挡到我看内容的卡片、结束时的推荐视频。将短视频播放器重定向到有进度条的正常播放器。
Cookie Quick Manager
An addon to manage (view, search, create, edit, delete, backup, restore) cookies.
Dark Reader
适用于所有网站的暗色主题。关爱眼睛,就使用 Dark Reader 进行日常浏览。
Decentraleyes
保护您免受集中式的内容交付网络(CDN)的跟踪。
Discard Tab
Adds Discard action to tab right-click
手动休眠标签页,避免浪费系统资源。
Flagfox
显示描述当前服务器位置的国旗。
Foxy Gestures
适用于 Firefox 的鼠标手势
FoxyImage
Collection of Image Related Actions
Google™ Translator
A handy multi-language translator built on top of Google translate.
Header Editor
管理浏览器请求,包括修改请求头和响应头、重定向请求、取消请求
用来做一些 hack 操作的,比如添加 referrer、跨域头;在新标签页中查看 imgur 的图片(不要给我网页);让 Grafana 不走代理、直连数据源以加快加载速度。这扩展在火狐上还能修改响应体。
I don't care about cookies
Get rid of cookie warnings from almost all websites!
Image Max URL
Finds larger or original versions of images
Link Status Redux
Shows an indicator on a popup panel along with the link address when the mouse cursor is over a link to a page you bookmarked or visited before.
显示链接的上次访问时间用的。
matrix.to opener
在你的 Matrix 客户端中直接打开 matrix.to 链接
MergEase • GitHub Code Review
Diff tool for GitHub pull requests
更准确地 diff GitHub 提交和 pull request,有点像 difft,是把 diff 发给服务端来生成的。
Mind the Time
Keep track of how much time you spend on the web, and where you spend it. A ticker shows the time spent at the current site or total time spent on the web today. A summary page shows data for today and recent history.
Octotree - GitHub code tree
GitHub on steroids
给 GitHub 的侧边栏文件树。
Popup window
將 Tab 彈出至獨立視窗,去除頁籤列、網址列和書籤列等介面
这扩展在 Wayfire 上不太好用,弹窗和原本窗口会跟在一起,而且关闭的时候容易关到弹窗后边的窗口。
Push to Kindle
Send web articles to your Kindle
哦,这个应该没用了……
Redirect Link
Redirect a link to somewhere else.
用于打开网页对应的互联网档案馆或者 archive.today 存档用的。
Redirector
Automatically redirect content based on user-defined rules.
和上边那个名字相似、但功能完全不同。自动重定向用的,比如看图要看原图、绕开 link.zhihu.com、统一中文维基百科中间的语种路径、把移动版 URL 重定向到桌面版、去掉 b23.tv 的小尾巴等等。
Reload PAC button
A button to reload the PAC definitions
Rotate and Zoom Image
Allows to rotate and zoom images directly on any website from context menu.
RSS Reader Extension (by Inoreader)
Build your own newsfeed
装了这个才能用快捷键让 InoReader 在后台打开文章。
RSSPreview
Preview RSS feeds in browser
ScrollAnywhere
使用鼠标中键在页面上的任何位置拖动滚动条。还支持“抓取和拖动”样式和动画。
横着滚、竖着滚、滚来滚去~
SingleFile
将一个完整的页面保存到单个 HTML 文件中
Snap Links
Select multiple links, checkboxes and other elements and act on them such as open them in new tabs or check/un-check them.
SponsorBlock for YouTube - 跳过赞助商广告
跳过 YouTube 视频中的赞助广告、订阅提醒等片段。标记视频中的赞助广告来节约大家的时间。
Stylus
Stylus 是一个调整网页外观的用户样式管理器。它可以让您轻松为许多热门网站安装主题和皮肤。
给网页加自定义 CSS 用的,我的用途有:叫网页不要使用奇奇怪怪的 Windows / MacOS 系字体;把暗色网页弄亮堂一点,避免在白天看不清;在各种文档网页里标记访问过的链接,免得老是点过去才发现内容已经读过了,或者不容易找到自己频繁访问的链接;去掉讨厌的圆角。
Textarea Cache
Allows to save automatically the content in a text input field.
不小心关掉了正在编写、尚未提交的内容,可以用它来恢复。
Tile Tabs WE
Take tabs from parent windows and arrange them in layouts of tiled sub-windows.
这扩展在 Wayland 上不能移动窗口,不过还是可以把窗口调整为合适平铺的大小,并可选加上滚动同步啥的。
Tree Style Tab - 树状标签页管理
以树状结构显示标签页。
uBlacklist
在谷歌的搜索结果中屏蔽特定的网站显示。
内容农场走开!
uBlock Origin
一款高效的网络请求过滤工具,占用极低的内存和 CPU。
Unpaywall
Legally get full text of scholarly articles as you browse.
User-Agent Switcher and Manager
Spoof websites trying to gather information about your web navigation to deliver distinct content you may not want
有时候还是不得不假装自己在用 Google Chrome 或者 Windows。
v2ex plus
优雅便捷的 V2EX 扩展
Vimium
The Hacker's Browser. Vimium provides keyboard shortcuts for navigation and control in the spirit of Vim.
wxIF
View the EXIF/IPTC/XMP data for images.
YouTube Anti Translate Updated
A small extension to disable YT video titles autotranslation.
机器翻译太难懂啦。Google 从来都意识不到人是可以会多种语言的。

移动版

由于获取方式的差异,这个列表没有扩展描述。不过大部分都和桌面版是重复的。

篡改猴
我在访问哪个 Cloudflare® 数据中心?
ClearURLs
Control Panel for YouTube
Cookie Quick Manager
Dark Reader
Decentraleyes
Google Search Fixer
Header Editor
Push to Kindle
Stylus
Text Reflow WE
uBlacklist
uBlock Origin
Unpaywall
Video Background Play Fix
在后台继续播放视频和音频,可以用于在后台播放 YouTube Music。
Web Archives
打开当前页面的存档页面。移动版没有右键菜单所以用不了 Redirect Link。

代码

桌面版的列表是在 about:addons 页面,打开 devtools 执行以下代码取得的:

const r = $$('addon-card').map(
  (el) => {
    return {
      title: el.querySelector('h3').textContent,
      desc: el.querySelector('.addon-description').textContent,
      id: el.getAttribute('addon-id'),
    }
  }
)

let parts = []
for(let ext of r) {
  parts.push(`<dt><a href="https://addons.mozilla.org/firefox/addon/${encodeURIComponent(ext.id)}/">${ext.title}</a></dt>\n<dd>${ext.desc}</dd>`)
}

console.log(parts.join('\n'))

而移动版是在 about:debugging 页面,连接上移动版火狐之后,执行以下代码获取的:

const r = $$('[data-qa-target-type="extension"]').map(
  (el) => {
    return {
      title: el.querySelector('[title]').title,
      id: el.querySelector('dd').textContent,
    }
  }
)

let parts = []
for(let ext of r) {
  parts.push(`<dt><a href="https://addons.mozilla.org/android/addon/${encodeURIComponent(ext.id)}/">${ext.title}</a></dt>`)
}

console.log(parts.join('\n'))
Category: 火狐 | Tags: web 火狐 WebExtensions
10
1
2021
3

纯 CSS 实现倒三角箭头

想实现这样的悬停提示框效果:

悬停提示框示例

这个绝对定位的框不是问题,边框的阴影也不是问题。问题是,我怎么弄出来那个倒三角的箭头呢?

在网上搜了一圈,找到的代码是这样的:

.tooltip .tooltiptext::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: black transparent transparent transparent;
}

拿边框给挤出来的。倒三角是有了,但是是纯色的,像这样子:

纯色背景提示框

很多 tooltip 提示框都是这么实现的,反正它们是黑底白字,并没有个边框。而我的是白底灰框,在下边接个纯色的三角块,就太丑啦。可是我又不想在这个被挤的边框上玩出花来,就只能是纯色的一块,所以此路不通了。

于是我就想啊,这个三角箭头怎么能弄出来呢?它不就是个正方形的框被砍了一半,再旋转45°吗?正好 CSS 能单独控制每一边的边框。也不用挤边框那么难以理解的操作了。于是:

#reply-popup::after {
  content: "";
  position: absolute;
  top: calc(100% - 6px);
  left: calc(50% - 6px);
  width: 10px;
  height: 10px;
  background-color: white;
  border-width: 1px;
  border-style: solid;
  border-color: transparent #bfbfbf #bfbfbf transparent;
  transform: rotate(45deg);
}

效果还不错,除了没有阴影,很不搭。那就把阴影加上?

  box-shadow: 0 0 5px gray;

结果嘛,不愧是叫 box-shadow,这阴影真就是个 box,不管你的边框,每一边都有的。我尝试调整 z-index 想让提示框把「无边阴影」给遮挡住,但是没成功。

于是又想办法。我记得 CSS 有个 clip 的功能来着?后来发现现在有个 clip-path,支持多边形,挺好的,我可以弄个三角形给剪裁一下,不用求助于行内嵌 SVG 了。

我尝试了一下,clip-path 是会随着 transform 一起旋转的,这似乎让火狐的 clip-path 多边形编辑功能很困惑,实际效果和显示的控制点之间我没能看出什么关联来。于是放弃可视化编辑,还是老老实实地算坐标点。也不复杂啦,右上、右下、左下,三个点就好了。然后放大两倍来容纳阴影。这样会正好切一半,在 Google Chrome 上没啥问题,但是在火狐上,不会完全遮挡住悬停元素的框,会漏出那么一丝丝出来。往上移一像素又太多,所以我把三角形底边上的两个端点稍微移动了一下,来挡住这一丝丝边框。最终规则是这样的:

  clip-path: polygon(145% -50%, 150% 150%, -50% 145%);

PS: 大家一直说 Google Chrome 更适合开发,但一些细节上火狐还是做得更多。比如火狐虽然没有角度编辑器,但是有多边形编辑器。火狐会在 DOM 树上把伪元素显示出来方便查看。火狐也会给元素标注事件、滚动、溢出、弹性盒,但 Google Chrome 只标注了弹性盒。话说 Google Chrome 最近终于加上了中文翻译了呢。另外 Google Chrome 的字体选择真不听话,难怪大家都喜欢强制指定一大串字体名。

哦对了,火狐可以用右键点击元素,然后按 q 键来检查元素。Google Chrome 没这个快捷键,得肉眼扫右键菜单。不知道有没有什么更方便的办法。

Category: Web前端 | Tags: web css blog
11
21
2017
28

我正在使用的火狐扩展

早就说了要介绍我在用的火狐扩展,现在终于来啦。

桌面版

Android 版

Android 版上使用的扩展比较少,大部分是桌面上用的扩展同时支持 Android,所以同步过来了。只有一个例外:Text Reflow WE

这个扩展是我移植到 Web Extensions 的。在点击内容时限制文本宽度,从而限制需要不断地横向滚动。原本是 Opera Mobile 的特色功能,后来我换到火狐时找了个替代品,结果它没更新了,不支持57+,我就移植了一下。代码十分简单,本来是一个 user script 就可以搞定的内容,但是 Android 上好像没 user script 扩展……


2017年11月25日更新:

装回了 cliget,一个为下载项生成 wget / curl / aria2 调用命令的工具。虽然因为没有 XUL API 可以修改保存对话框了,但是作者找到了一种不错的办法,把候选下载项保存到一个列表里方便取用。会有误判,忽略就好。这个列表是下载对话框弹出的时候就会更新,所以挺适合下载大的「百k盘」文件,下载链接超时失效之后可以获取一个新的让 wget 接着下。

暂时把 uBlock Origin 换回了 Adblock Plus。界面比前者好看许多,可惜还是没有规则使用计数和最后使用时间记录,不方便清理失效的规则。

启用了 ScrollAnywhere,因为妨碍 Foxy Gestures 使用右键的 bug 已经解决了。我使用的是 Nightly 版本所以很快就用上了,Linux 发行版如 Arch 也有做 backport。

考虑换回 GreaseMonkey,不过发现有一个 bug 导致它不能在特定网站上触发安装操作。

Category: 火狐 | Tags: 火狐 WebExtensions web
4
6
2015
10

GitHub 的一个小细节

这是偶然间发现的。在 GitHub 桌面版网页上,按第一下 Tab 时,会在左上角显示一个「Skip to content」的链接,并且键盘焦点就在这里:

GitHub "Skip to content"

我被这样的小小地惊艳了一下。这个链接可以用来跳过不怎么常用的导航栏上那排链接和按钮。

作为经常打字聊天和写码的人,在电脑前的大部分时间手当然是在键盘而不是鼠标上,所以使用鼠标来进行一些操作很常见。虽然我有 keynavVimFx 来辅助,但是见到 GitHub 这么贴心的细节还是挺喜欢的。

这让我想起了国内的网址,大部分都根本不考虑 accessibility。比如问答社交网站知乎。我早已不「逛」知乎了,只是收到感兴趣的邀请时去看看。因为知乎的体验实在是太差劲了。

知乎取消了所有链接在获取焦点时周围的虚线。这意味着根本没办法使用键盘导航,因为你不知道当然焦点在哪里。

知乎的提交按钮完全无法使用键盘操作。看看 GitHub,写好评论什么的,按一下 Tab 焦点就去了提交按钮上,并且有非常明显的反馈。按空格或者回车就可以提交。如果决定放弃,再按一下 Tab 就好。这两个按钮的顺序是按使用频率而不是相对位置来获取焦点的,因为提交显然比放弃用得更多。Twitter 发送新消息、Google+ 评论的提交按钮也是这样。不过 Twitter 偶尔会需要按两次 Tab 才能提交,大概是改页面的时候不小心给改坏了,过段时间会修好。Google+ 分享新信息时会比较讨厌,因为要跳过好大一堆「添加照片」什么的按钮。

类似的 accessibility 处理,国外著名网站上经常能看到很好的实践,博客上经常能看到大家在关心「少数用户」的使用便捷性。而国内很少有关注这方面的,大家都跟乔布斯一样想,「不管合不合理,我是这么设计的所以你应该这么用」。

比如验证码。不管需不需要,都是字符图。这样盲人就用不了。而国外广泛使用的 Google reCAPTCHA 就可以选择通过声音收听验证码。当然是英语的。反正这全球最大的网站之一已经消失在中国大陆人的视野之中了。我知道专门有人建立了一个 QQ 群,视力正常的人帮助盲人识别验证码用的。

这大概是发达国家与发展中国家的侧面写照的缩影了吧。

最后扔一堆链接:

Category: 用户体验 | Tags: web github 知乎 UX
3
23
2013
16

知乎,谢谢你让我知道 @ 补全可以做得这么烂

因为知乎为我这样的用户设下了许许多多不便的地方,我给他们提过多次然反应甚微。我累了、倦了,对知乎失去了热情。可是,知乎却不肯放过我,经常会收到来自知乎的邀请回答通知。现在新问题被提出来之后,知乎会推荐一些用户让提问者邀请。看来知乎是越来越害怕用户流失了。这和在用户回答之后弄个「分享到新浪微博」(还非常占空间)的行为一样,舍本逐末。知乎不去专心提升其核心竞争力,反而搞一些花哨的东西,不流失掉优质用户才怪呢。

好了,进入正题。为了方便用户,很多网站不但提供 @ 人的功能,而且在用户 @ 人时提供补全。我们来对比一下各网站的补全。

StackOverflow

首先是与知乎同为问答平台,但远比知乎著名和专业易用的 StackOverflow。它在回复评论时 @ 人可以补全。补全效果如下图:

它补全的是参与当前讨论的人的名字。补全提示位于输入框的上方,有点遮住上方的文字了。被 @ 到的人并不会因此收到通知。用户的输入并不会因此被打断,也不需要等待补全结果出现。

Twitter

下一个是 @ 的这个用法的创立者 Twitter。在很多地方均可以补全。Twitter 用户既有一个英文无空白字符串的 ID,也有一个限制更少的名字。补全时两者均会被搜索,如下图所示。

其补全框在输入框下方。补全提示中包含了用户头像、用户名字和用户 ID。最终有效的 @ 只能是用户 ID,因为可以有名字相同的人,但不会有 ID 相同的用户(虽然它也可以更改)。用户的输入并不会因为补全被打断,也不需要等待补全结果出现,只要完整输入要提到的人的 ID 即可通知到对方。

Github

为什么不在光标处显示补全呢?Github 向我们展示了原因:

Github 尝试将补全菜单放到光标处,但很不幸,在浏览器中目前没有准确定位用户光标的办法,所以成这样子了。

和 Twitter 不一样,Github 没有显示用户用户头像,所以没 Twitter 的那样容易识别。

Google+

Google+ 的补全显示也很容易识别,用户头像、名字、圈子都有。如果补全匹配自通讯录中联系人的电子邮件地址的话,此信息也会显示出来——

但是没有用户 ID。因为 Google+ 和 Twitter 不一样,它只有一个用于标识用户的数字 ID,而没有唯一指定某人的人可读 ID。所以,在 + 别人时,用户必须等待并从补全列表中选择要 + 的人。如果你的网络差了点就只能等等了,通常应该不会导致忘记要说的话吧,网络太差的话 Google+ 会没办法正常载入的。还有一点,你无法将事先写好的包含 + 的文本直接复制到输入框。如果你想 + 很多人的话,即使你有需要 + 的人的列表,你也不得不手动抄写一份。

知乎

最后,该知乎上场了!绝对秒杀以上四家的设计!!!

在输入 @ 的时候,知乎会弹一个小框出来——你的输入流被打断了,就不用想着复制的事情了。如果卡了你就只有等待了,但很不幸的是,知乎最近比较卡,一个操作花几秒才完成是常事。只有用户头像和用户名。看看截图里,两个默认头像、三个叫「江南」的用户。更囧的是,提交后我才通过生成的链接知道,他们都不是我要 @ 的那个「江南」!一个同名的不幸的人被打扰了。至于补全项挡住文字这问题可以忽视了,因为被挡住的是光标后边,你没办法接着输入。如果你要输入电子邮件地址,放心好了,补全框会出来烦你的。至于上方「想用 @ 提到谁?」那句废话,大家可以像知乎的其它问题一样暂且忽视。

Mastodon | Theme: Aeros 2.0 by TheBuckmaker.com