:don: 2.0.0

ついに来ましたね、2.0。

リリースノート見ながら思い出話するやつです。

https://github.com/tootsuite/mastodon/releases/tag/v2.0.0

Breaking changes:

  • All id attributes in the REST API responses, including attributes that end in _id, are now returned as strings instead of integers. This is because large integers cannot be encoded in JSON losslessly, and all IDs in Mastodon are now bigint. Some apps will not work with this release until they are updated

新しいIDは最大で64bit、現時点でも61bitありますが、JavaScriptのNumber型は有効桁数が53bitほどしかないので、そのままでは下位ビットの情報が失なわれてしまいます。そこで文字列にしたわけですが、鳥さんのように新たに id_str を足したわけでもなく、しれっと型を変えてしまったのでさあ大変。それでも2.0.0のリリースまでにはPawooアプリも間に合せてきたのでえらい。

  • Mastodon will no longer deliver private and direct statuses to OStatus-based recipients (that means pre-1.6.0 Mastodon, too)

前々から言っていたことですね。ただ現状はプロフィール取得が発生しないと相手がAP対応であることに気付けないので、1.6になってから一度も発言してない人に@飛ばそうとするとあれです。というかだまって破棄してしまうので、エラーのひとつも出すべき(#5535)。

  • Stylesheet customizations now work differently due to the new theme feature. See upgrade notes for details.

後述。

Features:

Custom emoji (#4988, #5243, #5258, #5002)

現状の仕様はだいたいこんな感じ。

  • adminだけが登録・変更できます
  • 他の鯖(2.0以降)でも見れる
  • 投稿時ではなく表示時に適用されるので、過去の投稿もごそっと変わります
    • ローカルでは2.0より前の投稿にも適用されるし、登録解除すれば戻る
    • リモートでは変更後の絵文字を含む投稿を受けとると上書き、という形なので云々
  • 50KB以内のPNGならサイズ不問(表示サイズは固定だけども)
    • APNGを使えばアニメーションもいける(WebUIではGIFの自動再生をオンにしておかないと動かない)
  • :shortcode: で入力する関係で前後にスペースが必要(ZWSPでもOK)
  • リモートからの絵文字は個別に無効化でき、メディアブロックの対象にもなる

Add support for multiple themes (#4959, #5336)

ねんがんの テーマきのうをてにいれたぞ!

application.scss 相当のファイルを複数用意しておいて、themes.yml に書いてやるとテーマを追加できます。custom.scss は自動では読みこまなくなったので、自分でテーマとして登録するなりdefaultテーマを置き換えるなりする必要があります。

Replace EmojiOne emoji pack with Twemoji (#5046)

利点: tofu_on_fire 欠点: 猫がかわいくない

Add emoji autosuggestions (#5053)

  • 中身は後述する絵文字ピッカーの検索機能なので、
    • ハイフンやアンダースコアはAND検索の区切り文字として扱われます
    • shortcodeとは別の検索用キーワードにヒットする場合があります
    • この辺微妙
  • shortcodeではなく絵文字を直接入力します
    • Unicode絵文字についてはサーバー側でshortcodeの変換を行わなくなりました

New emoji picker (#5046, #5275)

  • よく使う絵文字は最初はおすすめ絵文字で埋まってます
  • カスタム絵文字も出るよ

New error page graphic. Other error page improvements (#5067, #5099)

500.html もRailsのビューとしてコンパイルするようになりました。具体的には assets:precompile でWebpackが走ったあとに assets:generate_static_pages がその仕事をしています。単体でも呼べるよ。

あとキーボードは叩かないように。

Better primary ID generation (#4801, #5260)

TwitterSnowflakeみたいな実装になりました。unixtime 48bit + sequence 16bit で最大64bit。これでURL検索、返信先やブースト対象の取得など、過去の投稿を取得した時に突如HTL/FTLの先頭に現われるということがなくなります。

ただし次のような場合はローカルの時計に基づいたIDになります。

  • APやOSで配信された場合: 最新の投稿が配信されるはずなので、多少遅れて届いてもHTLの先頭に表示されてほしいとか、Streaming API を使ってないと取りこぼすとか。
  • 未来の日付だった場合: TLの先頭に居座られても困るので…。

Hotkeys in web UI (#5164)

j/k で上下移動とか f でお気に入りとか n で投稿欄とかそういうやつです。割と多いですね。

Add ability to specify alternative text for media attachments (#5123)

いわゆる、imgタグのalt属性です。投稿欄でアップロードした画像にカーソルを乗せると、日本語では「視覚障害者のための説明」というテキストがふわっと出てきますが、そこがテキストボックスになっています。

Redesign public hashtag pages (#5237)

ハッシュタグページ(/tags/hogehoge)が /about のようにリッチになりました。幅が狭い?うん、まあ…。

Implement dynamic e-mail blacklist for admins (#5109)

.env.production等で設定できる環境変数のなかに EMAIL_DOMAIN_BLACKLIST というものがあったわけですが、似たようなものを管理画面で登録できるようになりました。環境変数も残っていて、両方適用されます。

Other:

  • After 7 days of repeated delivery failures, give up on inbox delivery to reduce wasted effort (#5131)

息してない鯖への配信が無限に積まれる件ですね。

  • APの配信は間隔を延ばしながら8回まで試行しますが、その8回目に計7日失敗するとこれが発動します。
  • 発動中はフォロワー宛の配信が止まりますが、メンションや通知は飛びます。
  • 一回でも配信に成功したり、当該アカウントから投稿を受信するとリセットされます。

なかなか再試行減らないんで機能してるんかこれ、と思っていたら、その大半は再購読によるものだったので、こっちは動いているんじゃないでしょうか。再購読ももうちょっとなんとかしたい。

  • Send streaming API delete to people mentioned in status, so they would get it even if they don't follow the author (#5103)
  • In detailed status view, display the attachment uncropped if there's only one of it (#5054)
  • When a streaming API status arrives, sort it into conversations live so you don't have to reload the conversation to see it (#5206)
  • New Material app icon for Chrome, new icons for iOS, Microsoft (#5291, #5321)
  • New API: GET /api/v1/apps/verify_credentials to confirm app works (#5112)
  • Reorganize preferences page (#5161, #4447)

見出しがついたり、通知関連の設定が別ページになったりしました。

  • Admins can now add moderation notes to accounts (#5240)
  • New preference for reducing animations in web UI to prevent motion sickness (#5393)

日本語では「アニメーションの動きを減らす」と書かれています。

これを設定すると、要素の大きさが変化したり、CW入力欄のようにスライドで現われるようなアニメーションが消えます。透明度が変化するようなものはそのままです。

Upgrade notes:

Non-Docker only:

  • The recommended Ruby version has been bumped to 2.4.2. However, it is only a recommendation. If you would like to stay with 2.4.1, simply overwrite the value in .ruby-version
  • Dependency updates: bundle install and yarn install

Both Docker and non-Docker:

  • This release includes database migrations, that means you need to run RAILS_ENV=production bundle exec rails db:migrate (in Docker: docker-compose run --rm web rails db:migrate). Depending on your database size, this migration may take a long while! It may also lead to some downtime. Make sure you have backups. This is because we are upgrading a multitude of database columns from int to bigint to make sure they're future-proof.

今回のmigrationの目玉はふたつあります。

  • 各種id列をbigint型に変更: テーブルをロックしない代わりに相当時間がかかります。例えユーザーが少なくても、リモートの投稿を大量に保持していたりすると注意したほうがいいかもしれません。進捗も表示されます。
  • Redisに保存されたHTLの変換: 64bit IDはRedisで扱うにも一悶着あり、ブーストの持ちかたを変えることになりました。で、これがバグもあったりしてそこそこ遅いです。大量にRedisの読み書きが発生するので、負荷とかレートリミットとかそういうあれもあるかも。 とはいえアクティブユーザーが5桁いるような鯖でなければ数分で済むと思いますが、進捗表示はないので根気よく待つか、2.0.1を待ちましょう(#5338)。

  • This release includes changes to assets, that means you need to run RAILS_ENV=production bundle exec rails assets:precompile (in Docker: docker-compose run --rm web rails assets:precompile)

Optionally:

  • custom.scss is no longer automatically loaded because the feature has been reworked into themes. Change to default: styles/custom.scss in config/themes.yml to restore old behaviour

Troubleshooting

  • If you have upgraded to the master branch before v2.0.0rc1 and your custom emoji now fail to load, perform this rake task: RAILS_ENV=production bundle exec rake paperclip:refresh:thumbnails CLASS=CustomEmoji

当初カスタム絵文字はoriginalひとつ保存していたのが、APNG対策でアニメーションしないstatic版も保存するようになりました。で、以前からあるものは後者がないので404になってしまいます。そこでoriginalを元にstaticを再生成するのがこれです。

Fixes:

  • Web UI: Make sure formatted numbers don't contain insignificant zeroes (#4993)
  • Bump recommended Ruby version to 2.4.2 (#4958)
  • Fix performance on stats queries (#4996)
  • OpenGraph: Fix error when generating OpenGraph tags for images without metadata (#4995)
  • ActivityPub: Add published property to activity for reblogs (#5000)
  • Re-allow final underscore in parsed URLs (#4999)

1.6.1でURLの自動リンク正規表現を変更した時に、これまで許容していた末尾アンダースコアが除外されてしまっていた件。一方でUnicodeの書記方向を指定するメタ文字が含まれてしまっていたり、なかなか難しい。

  • Web UI: Improve scrolling performance on Chrome (#5001)
  • Remove ubuntu-toolchain-r-test dependency (#5005)
  • Fix account records being read before processing finished (#4998)
  • Web UI: Hide sensitive image by default on the public pages (#5009)
  • ActivityPub: Use OrderedCollectionPage to return followers/following list (#4949)
  • Web UI: Improve scrolling performance in general (#5011, #5152)
  • Web UI: Fix remote statuses being html_encoded in public pages (#5012)
  • Fix race condition when processing incoming OStatus messages (#5013)
  • API: Change IDs to strings rather than numbers in API JSON output (#5019)
  • Web UI: Use file extensions in addition to MIME types for file picker (#5029)

Firefoxで .jpg 拡張子のファイルが選択できなかった件。image/jpeg を指定して推測された拡張子が .jfif とは…。

  • Disable private status federation over OStatus (#5027)
  • Web UI: Reduce wasted renders (#5021, #5036)
  • Web UI: Improve mobile style of /about/more (#5034)
  • Web UI: Make dropdowns render into portal, expand animation (#5018, #5140)
  • Document REDIS_NAMESPACE (#5038)
  • Do not filter statuses with unknown languages (#5045)

言語フィルタをひとつでも指定していると、判定結果が"不明"なものまでフィルタされてしまうというバグ。WHERE NOT language IN (...) で language が null なレコードが漏れていた。

  • Web UI: Fix overflowing tabs in account__action-bar (#5056)
  • Web UI: Fix media gallery CSS (#5064)
  • Web UI: Change mobile layout breakpoint from 1024px to 630px (#5063)

これは…結局好みだからなあ。基本的にはPC版はモバイル版の上位互換みたいなところはあるので、UserCSSでだいたい似せることはできると思うけど、それが適用できない・非表示にするだけではパフォーマンスに問題が出る環境もあるわけで…。特にPC版でたくさんカラムを並べている人はそのままだと微妙なのではという気がする。

せめてブレークポイントを手動で設定できるようにするぐらいしたほうがよさそう。

Please make it possible to force the single column view regardless of screen width · Issue #5341 · tootsuite/mastodon

  • Suppress backtrace when failed to communicate with a remote instance (#5076)
  • Thread notification e-mails for mentions by conversation (#5061)
  • Web UI: Increase max height of preview card image (#5092)

つまりはPixivの横長イラストを貼った時の解像度が上がります。縦長は…うんまあ。

  • Stop processing of payload if it originates from a local account (#5100)
  • API: When OAuth password verification fails, return 401 instead of redirect to login (#5111)

/oauth/tokengrant_type=password で叩いた時に、メールアドレスやパスワードが間違っている場合に401を返すべきところが、ログイン画面にリダイレクトしていた、というバグです。

で、これを修正したらなぜかAmaroqが死にました。

Amaroqが2.0rc1以降のMastodonインスタンスで使えなくなる理由についての技術的な詳細 - HackMD

すぐには修正できそうにないという話も出ていたわけですが、Amaroq 1.1.6で無事修正され、再びログインできるようになっています。

  • Web UI: Remove now redundant warnings about OStatus privacy (#5102)

リモートアカウントにDMを送ろうとするとなにやら長い注意文が出ていたかと思いますが、あれはMastodon以外のOStatus実装が公開範囲の指定を解釈しないということが前提にあったということで、そもそも配信しなくなった2.0では不要と削除されました。

  • Improve worker performance by flushing body when performing POST requests (#5128)
  • ActivityPub: If HTTP signature is wrong and webfinger cache is stale, retry with resolve (#5129)

現状APでのアカウント情報更新はほとんど相手からの通知に委ねており、その通知は基本的にフォロワーにしか送られません。のでインスタンスで誰もフォローしていないアカウントのプロフィールはなかなか更新されないという問題があります。(OStatusでは割と頻繁にアカウント情報を更新していました)

さて、リモートアカウントの公開鍵は変更される可能性があるわけですが、これが古いままだとメンション等で受け取ったデータの署名検証に失敗してしまいます。そこで、失敗したら一日一回まで(これはOStatusの頻度と同じ)アカウント情報の更新を試すようになりました。

まあそうでなくともプロフィール更新されないのはつらいので、これもなんとかしたいですね…。

  • Web UI: Improve performance of modal and swipe animations (#5135)
  • Change max redirects followed to 2 (#5136)
  • When using statsd to track Mastodon performance, it will now get more useful metrics (#5118)
  • Web UI: Upgrade to React 16 (#5119)
  • Web UI: Make emoji autosuggestions immediate, usernames appear sooner (#5149)
  • Fix bug with OpenStack v2 (#5155)

最初 OpenStack v2 のサポートが追加され、その後 v3 にも対応…と思いきや、そこで v2 対応が失われてしまっていました。

  • Fix order of paginated accounts on authorized followers page (#3357)
  • Mobile: Make Chrome splash screen the same color as web UI's background color for smoother transition (#5169)
  • Web UI: Toggle contain:strict on fullscreen (#5159)
  • Append confirmation link as plain text in e-mails (#5146)
  • Web UI: When muting someone, clear web UI of their content like for blocks (#5172)
  • Web UI: Fix emoji sequence bug in substring-trie (#5191)
  • Web UI: Compress and combine emoji data (#5201, #5229)
  • Improve HTTP responses for Salmon and ActivityPub inbox processing (#5200)
  • ActivityPub: Fix possible acct URI usurpation in account discovery (#5208)
  • Use separate workers to process imports, retry failures (#5207)

インポートを行う際に途中でエラーが起きるとそこで中止されてしまっていた件ですね。

  • ActivityPub: Validate id of objects (#5114)

ActivityPubの処理ではidとして渡されたURLからオブジェクトの実体をダウンロードする場面がいくつかありますが、もし何らかの理由でダウンロードしたものが想定と異なるオブジェクトであれば、それを処理すべきではありません。ということで、ダウンロードしたオブジェクトのidが当初の想定通り(つまりダウンロードしたURLと等しい)かを検証するというものです。

  • Web UI: Use own, shorter relative timestamps in web UI to save space (#5171)

投稿の右上に表示される日付が英語だと 5 hours ago といった感じで少々長い、ということで、 5d といった表記に変更されました。日本語では 5時間前 という表記のままですが、数日前などの場合に 10/31 といった形で表示されるようになりました。

  • OpenGraph: Use summary_large_image card only when media attachments present (#5219)
  • Web UI: Fix remote profile being displayed as HTML on remote follow page (#5249)
  • Improve error handling in LinkCrawlWorker (#5250)

例外の握りつぶしは最小限にしよう。その結果既知のバグがdeadキューにぽこぽこ現われたけど、まあそのためなので。

  • Web UI: Fix overflowing (#5246)
  • Web UI: Show buffering in video player (#5261)
  • Web UI: Dynamically calculate card height for embeds instead of using CSS padding trick (#5265)
  • ActivityPub: Use object URI only in Announce, instead of embedding (#5266)
  • Fix pagination in blocks API (#5285)
  • Web UI: Center error layout (#5289)
  • Fix offline-plugin warning in dev mode (#5411)
  • Disable reblog counter for private toots (#5397)
  • Fix unreblogged toot being at wrong position in the home timeline (#5418)

これはSnowflake導入後のmasterで起きていたバグなんですが、

  1. ブースト解除した時にブーストがあった位置(スコア)で挿入してしまっていた
  2. すると最新40件にやたら古い投稿が紛れている
  3. HTLはリクエストごとに投稿IDでソートして返すので、古い投稿は常に末尾に位置する
  4. クライアントがmax_idにその投稿のidを指定して続きを読みこむ
  5. めっちゃ飛んでない…?

というちょっと面白いはなし。ソートしてることに気づくまで時間がかかった。

  • Ensure that home feed regeneration after inactivity restores non-zero items (#5409)

しばらくログインしていないとHTLが空っぽになり、次にログインした時に再生成が行なわれますが、パフォーマンス上の理由からいくつかのフィルタ処理はDBから取得した後に行なっています。ということは、一回目の取得で得た投稿が全部フィルタされてしまう可能性もあり、その場合HTLは空っぽのままになっていた、というバグです。足りなければ何回か試行するようになりました。

  • Properly remove unreblogged toots from timelines by keeping references of all reblogs (#5419)

ブースト解除でTLに中身だけ残ってしまう問題に対する修正です。投稿ごとにそれ自身とブーストをまとめておき、TLからブーストが消える時にはそのセットの中から適当なものを選択してTLに挿入し、空っぽになったらTLから完全に消す、といった流れになります。

ブーストした順番は反映されないものの、元々なかった中身だけ残ってしまうという問題は解決できることになります。なおWebUIではこのセットを見ることはできず、それに相当する情報も管理していないので、そのような場合には既にTLにあった可能性があっても消してしまうようになりました。

  • Web UI: Replace newlines in desktop notifications with spaces instead of removing them (#5361)
  • Allow unreblogging pre-ActivityPub reblogs (#5376)

OStatusで配信したブーストをAPで削除できないバグ。こんなのがまだあったのです。

  • ActivityPub: Fix remote status fetching for ActivityPub-only WEB_ACCOUNT users (#5372)
  • Web UI: Avoid confusing messaging: When unfollowing, remove toots from home in web UI immediately (#5369)
  • Web UI: Avoid confusing messaging: Do not try to guess why home timeline is empty in web UI (#5370)
  • Fix user sign in count updating on every request, optimize some queries (#5368)
  • Optimize Status#permitted_for 500x (account timeline) (#5373)

以前は効果的だった最適化が今では逆効果になっていたというのはちょっとおもしろい話。

  • Make HTTP deliveries faster by closing connection right after posting (#5390)
  • Fix some failure cases when fetching link preview cards (#5347)
  • Web UI: Reduce discrepancies between server and client-side character count (#5360)
  • Fix reblog count increasing without reason (#5363)

1.6で発生していた、ブースト数が余分に増えるバグの修正です。ローカルの投稿を一度保存した後にuriを生成してもう一度保存する、といった挙動になった際に、その両方でインクリメントしていたようで。

  • Web UI: Fix React warning about tabIndex on status with CW (#5432)
  • Don't capture scheme-less URLs in the status (#5435)
  • When status is fetched instead of delivered, do not stream it (#5437)

Snowflakeが導入されてもWebUIはStreamingで流れてきた投稿を素直にTLの一番上に挿入してしまうので、通常の配信でなければStreamingに流さないようになりました。

  • Web UI: Fix unwanted content warning gap in CSS (#5436)
  • OpenGraph: OpenGraph tags on sign in and sign up pages (#5308)
  • Web UI: Only preload JS on /web pages (#5325)
  • Web UI: In thread view, only scroll on first update, and scroll to replied-to post (#5322)

会話を表示した際に対象の投稿の位置までスクロールしていたわけですが、あまりにピッタリの位置にスクロールしてしまうせいで返信先の存在に気付きにくい、ということで返信先の位置までスクロールすることに。