mikutter 3.7の新機能
mikutter 3.7の季節がやってきました。
現在、mikutter 4を目標にしており、MiraclePainterの大幅な改善や、Gtk3やGtk4への対応を予定しています。mikutter 3.7はその準備の最初の段階なので、今回はわりと地味ではありますが、前回からわずか4ヶ月しか開いていないことを感じさせないボリュームです。
Score
Entityとは
mikutterがTwitterに8年間寄り添ってきた間にいろいろな変化がありました。APIレスポンスの変化だけでも大きなものがたくさんありましたが、「n文字目からm文字目は http://○○
へのリンクである」という情報が付与されるようになったのは小さい出来事ではありませんでした。
この情報はEntityと呼ばれていて、mikutterはこの情報を有効活用するためにこれをオブジェクト化したEntityクラスというものを定義し、その後のEntityの様々な仕様変更をこのクラスに引き受けさせてきました。しかし、予想しない方向への度重なる変更のせいで、Entityのコードはメンテナンスしづらいものになってしまいました。
プラグイン開発者が「独自のMessage ModelをMiraclePainterが表示する時に、任意の文字列にリンクを貼りたい」と思ったら、無理やり別のWorldのルールをTwitterに最適化されたEntityに適合させるのは大変です。さらに言えば、Twitterの変更を後追いしてきたEntitiyクラスの構造はTwitterにすら適したものではなくなっていました。
Scoreとは
様々なWorldの状況を考慮しながら、Entityのようなデータを提供しやすく、利用しやすい形式にまとめようという試みがScoreです。名前の由来は、Divaに関わる機能なので音楽用語にしたかったことです。Scoreは条件さえ合えば同じデータを全く違うレンダラが解釈することができるのを、楽曲と楽器と楽譜の関係に喩えてこの名前になりました。
できるようになったこと
今までのEntityよりいろいろな部分が簡略化されており、コードを読むにしても分量が1/3程度になったりTwitter依存がTwitterプラグインに分離されるなど理解しやすくなりました。ここではEntityにはできなかったことで、Scoreにしかできないことを紹介するにとどめておきます。
全てのModelに適用するScoreを提供できるようになった
Entityは、それぞれのModelの中にEntityの定義を持っていました。
そのため、たとえば 🎟1234
のような文字列をmikutterのRedmineのチケットへのハイパーリンクにするといったルールを全てのModelに対して適用するということは不可能でした。
Scoreはただのイベントフィルタで実装されているため、Modelを提供しているプラグイン以外からでも拡張することができますから、そういったこともできます。
サードパーティプラグインがルールをカスタマイズ
上記の話とほとんど一緒ですが、特定のModelに対してのみ、そのようなルールを適用することもできます。
EntityでもModelごとに定義することはできましたが、Modelを提供しているプラグイン以外が拡張できるのはScoreの特長です。
カスタム絵文字
以上は内部のデータ構造の変更なので、エンドユーザが直接メリットを享受することはないです。mikutter 3.7ではこれが一番大きな機能になってしまったので、見た目にわかりやすいメリットを用意しようと思い、Scoreを利用してカスタム絵文字を表示できるようにしました。
既にWorld系プラグインがサードパーティで提供されているSlackやMastodonには、アップロードした画像を絵文字として利用する機能があります。mikutterでこれを表示できるというのは、わかりやすい変化です。
Twitterにはカスタム絵文字に相当する機能はありませんが、全く関係のない話ではありません。今挙げた3つの特長を活かした mikutter-twemoji というプラグインは、通常のUnicode絵文字が出現する箇所をカスタム絵文字が行うのと同じ方法で絵文字画像に置き換えるものです。絵文字フォントを入れていない、入れることができない環境でも絵文字を表示できるようになる画期的なプラグインです。
今後
添付ファイル
Message Modelには添付ファイルの概念がありませんが、Score機能は添付ファイルを表現することも想定して設計されています。
画像をタイムライン上でインライン展開する mikutter-sub-parts-image という有名なプラグインがありますが、これと似たようなことをMiraclePainterが標準で行えるようにしたいと思っています。
TL上のクリッカブルな要素でマウスカーソルの形状を変える
タイムライン上のURLや、 @screen_name
のような、クリックすると何かが開く場所ではマウスカーソルの形状が変わるようになりました。また、ドラッグして文字列を選択できる場合には、アイビームになります。
アイコンボタンが表示されている間、自動スクロールしない
このボタンを使っていると、クリックしようとした瞬間に新たなMessageを受信してしまい、一つ上のMessageをふぁぼってしまうということがしばしば起こります。
これを使っている人は、少し下にスクロールしておいて自動スクロールしないようにするなどのライフハック(?)で乗り切っていると思いますが、今回からアイコン上にマウスカーソルがある間は自動スクロールしないようになったので、このような事故が発生しにくくなると思います。
ファイル選択ダイアログの改善
Form DSLのfileselectに、ショートカットディレクトリ、拡張子フィルタ、プレビューを設定することができるようになりました。
追加された項目
ショートカットディレクトリ
ユーザが利用すると予想されるディレクトリをサイドバーに表示しておけます。 今までもファイル選択ダイアログが最初から開いておくディレクトリを設定できましたが、ショートカットディレクトリは複数設定でき、ユーザは一度別のディレクトリに訪れても、サイドバーをクリックすればいつでも戻ってくることができます。
標準プラグインでは、画像や音声を選択させるとき、Skinディレクトリがショートカットディレクトリに登録された状態にしています。
拡張子フィルタ
ファイル選択ダイアログに表示するファイルの拡張子を絞り込む機能です。ユーザがファイルを見つける手がかりになるほか、入力させるファイルの拡張子を限定することもできます。
何も指定しなければ、従来通りフィルタがない状態になります。
プレビュー
サイドバーに画像のプレビュー領域を表示するフラグを設定できるようになりました。デフォルトでは表示しません。
photoselect
fileselectとよく似たコンポーネントで、画像に特化したphotoselectでも、上記のようなことができるようになりました。
二点だけ違いがあります。拡張子フィルタはデフォルトで、GdkPixbufがその環境でサポートしている画像形式をデフォルトのフィルタとして登録しています。だいたいの画像はこれで網羅できているので、特に困ることはなさそうです。
画像プレビューのフラグのデフォルト値は真に変えてあります。
Photo Variant
mikutter 3.6の新機能としてアナウンスしたものです。結局mergeできておらず、3.7でのデビューとなりました。
mikutter 3.6の新機能 で詳しいことは説明していますが、要するに:
- 完全な後方互換性があり、既存のプラグインに手を入れる必要はない。
- 画像を取得するときに要求する最低の幅と高さを明示することができるようになって、それを満たす最小の画像が取得されるようになった。
- Twitterプラグインでは、いままで標準(medium)の画像しか見れなかったが、最大(orig)のものを扱えるようになった。
- プラグインがPhoto Modelを作るときに、このようなサイズバリエーションを持つことができるようになった。
というのがこの機能のアピールポイントです。今まで画像をクリックして開いても標準サイズの画像しか見ることができませんでしたが、オリジナルサイズで見ることができるようになります。
書き忘れていること
思い出したら追記します。
いつ
ちょうどゴールデンウィークが終わる5/7のリリースを目標にしています。
記事を書こうと思って書けていないのですが、OSC 2018 Nagoyaに参加します。そのセミナーでmikutter 3.7をネタにしようと思っています。位置づけとしてもmikutter 4の準備となる最初のリリースなので、早いタイミングでやってしまおうというわけです。
ゴールデンウィークにぶつけていますが、私はGWはわりと忙しくてmikutterにフルコミットするわけにはいきません。5/7までバグ報告を受け付けて、3.6同様α版は出さず、7日にいきなりリリースという流れです。
試して
リリースまでに3.7を試してくださる人は、gitの develop ブランチを使ってください。
また、3.7に関するバグ報告はRedmine にお願いします。リリース前後は、バグ報告が集中することが予想されるので、リプライを貰っても反応できないことが多いです。リプライでのバグ報告は原則受け付けないことにしています。前述の通りゴールデンウィークはあまり時間が取れないため、ご協力お願いします。