プロジェクト

全般

プロフィール

提案 #1607

未完了

mastodon のトゥート添付の動画をクリックしたときは内蔵ビューアではなくブラウザで開くようにする

Izumi Tsutsui さんが11日前に追加. 7日前に更新.

ステータス:
パッチ適用待ち
優先度:
通常
担当者:
-
対象バージョン:
プラグイン名:
mastodon
ブランチ:

説明

チケット題名のとおりですが、
現状の動作は以下になっていると思います

  • トゥート添付の画像をクリックしたとき
    →内蔵ビューアで開く
  • トゥート添付の動画 (mp4 など) をクリックしたとき
    →内蔵ビューアで開こうとして error になって、ビューアの開くボタン(?)を押すと「画像ビューア」か「外部ブラウザで開く」かの選択ウインドウが出る

これを以下のようにしたい。

  • トゥート添付の画像をクリックしたとき
    →従来どおり内蔵ビューアで開く
  • トゥート添付の動画 (mp4 など) をクリックしたとき
    →いきなりブラウザで開きたい

次でパッチ投げます


ファイル

0001-refs-1607.patch (2.47 KB) 0001-refs-1607.patch Izumi Tsutsui, 2026-04-07 23:12

Izumi Tsutsui さんが11日前に更新

手元差分 0001-refs-1607.patch

  • source:plugin/mastodon/parser.rb@94718b49c3260c8478355cbddcc1d142b3322283 の以下で
    reference: に無条件で Plugin.collect(:photo_filter, url).first を渡しているが、
    これを attachment.type が画像のときだけ渡すようにする
        # 添付ファイル用のwork around
        # TODO: mikutter本体側が添付ファイル用のNoteを用意したらそちらに移行する
        media_attachments.reject { |a|
          appeared_urls.include?(a.url.to_s) || appeared_urls.include?(a.text_url.to_s)
        }.each do |attachment|
          url = attachment.url
          score <<
            Plugin::Score::TextNote.new(description: "\n") <<
            Plugin::Score::HyperLinkNote.new(
              description: attachment.text_url || url,
              uri: url,
              reference: Plugin.collect(:photo_filter, url).first
            )
        end
    

「URIに拡張子がないが画像を返してくるケース」ではビューアで表示できなくなってしまいますが、これをどう考えるかですね。
mastodon でもリモートサーバーのメッセージで末尾が /original で終わっているケースがあるようですが、発現条件がわかっていません。
plugin/mastodon/parser.rb だけの修正にすべきかも?

Izumi Tsutsui さんが9日前に更新

「URIに拡張子がないが画像を返してくるケース」ではビューアで表示できなくなってしまいますが、これをどう考えるかですね。
mastodon でもリモートサーバーのメッセージで末尾が /original で終わっているケースがあるようですが、発現条件がわかっていません。
plugin/mastodon/parser.rb だけの修正にすべきかも?

そもそもの問題として `openimg_photo` に拡張子判定を入れるのは以下の2点からNGでした。

  • `intent_selector` の画像を開く方法でユーザー指定された URL の情報が反映されなくなる
  • `photo_support` で指定されるサービスの URL も画像ビューアで開かなくなる

`openimg_photo` が上記2つのプラグインからそれぞれの情報を取るようにすれば回避できますが、
なんかもっと根本的に設計を考えるべきなんですかね。

とりあえずは `plugin/mastodon/parser.rb` だけ修正するしかなさそうですが。

toshi_a 初音 さんが7日前に更新

根本的に解決しようとすると、おそらく

  • MastodonなどのWorld系プラグインがPhoto, Video, Soundなどマルチメディアの種類毎に異なるModelにする
  • IntentはModelを見てルーティングできるので、Videoはブラウザで即開くようにする

みたいな感じかなぁ。Video Modelを用意するだけでインライン再生しないならそれほど大変ではないかもしれない…?

Izumi Tsutsui さんが7日前に更新

toshi_a 初音 さんは #note-3 で書きました:

根本的に解決しようとすると、おそらく

  • MastodonなどのWorld系プラグインがPhoto, Video, Soundなどマルチメディアの種類毎に異なるModelにする
  • IntentはModelを見てルーティングできるので、Videoはブラウザで即開くようにする

みたいな感じかなぁ。Video Modelを用意するだけでインライン再生しないならそれほど大変ではないかもしれない…?

雑に ChatGPT に分析および現状解析してもらうと以下みたいな感じでした。

ちゃんと見てるというか、元の階層分離が奏功しているというか、実行時ログを含め実装設計意図ベースで見ていて分析としては妥当っぽいですが、
score_hyperlink"Link Text" intent の実装動作」が意図通りなのか暫定なのか成り行きなのか、
および、下手にこのへんをいじると既存プラグインの互換性問題が出ないか、というところがさすがに読み切れていません。

分析に出てきていますが、Mastodon プラグインにある

TODO: mikutter本体側が添付ファイル用のNoteを用意したらそちらに移行する

のコメントのとおり、ここをターゲットにすべきなんですかね。


実装前の確認点

ここは一つだけ確認が必要です。
現在の score_hyperlink に対する "Link Text" intent が、 reference を優先して open する前提で動いているかどうかです。

設計的にはそうであってほしいし、実際そうならこの案はきれいに収まります。
逆に reference を見ずに常に uri へ落とす実装だと、この案の効果が薄れます。


リバースで見える現状設計

  • 1. open はまず「Model を持っていれば Model 優先」
    • intent プラグインでは、 on_open で対象が Diva::Model なら open_model(object) を呼び、そうでなければ open_uri(...) に行きます。つまり、Model があるなら URI ではなく Model を起点に開くのが設計です。
  • 2. open_model は「その Model の slug に対する intent」を探す
    • open_model(model)model.class.slug に対する intent を集め、候補が 0 なら open_uri(model.uri) にフォールバックし、1 個ならそれを実行し、複数なら chooser を出します。
      つまり Model routing → ダメなら URI routing という二段構えです。
  • 3. Mastodon 添付は今は HyperLinkNote で表現されている
    • mastodon/parser.rb では、添付は Plugin::Score::HyperLinkNote.new(...) で作られており、uri は添付 URL、 reference には photo_filter(url).first を入れています。
      ただし、Model 自体は HyperLinkNote のままで、動画専用 Model などへの分岐はしていません。
  • 4. 画像ビューア intent は Plugin::Openimg::Photo:photo に対してだけ登録されている
    • openimg_gtkPlugin::Openimg::Photo:photo に intent を登録しています。
      少なくとも見えている範囲では、 score_hyperlink に対して画像ビューア intent を登録してはいません。
  • 5. 外部ブラウザ intent は Plugin::Web::Web に対して登録されている
    • web プラグインは Plugin::Web::Web 用の intent を 外部ブラウザで開く として登録し、その handler は openurl(intent_token.model.perma_link.to_s) を呼びます。
      つまりブラウザ側も URI そのものではなく Web model に紐づく intent です。

ここから推定できる「現状の設計仕様」

かなり高い確度で、今の設計仕様は次のようなものです。

  • 現状仕様A: score_hyperlink は「リンク文字列をクリック可能にするための包み」
    • HyperLinkNote は、クリック可能なテキスト表現のための Model であり、添付の本来のメディア種別を表す Model ではない。
  • 現状仕様B: reference は少なくとも一次ルーティングの主語ではない
    • reference は存在しても、クリック直後に open_model(reference) している形跡は、あなたのログには出ていません。
      もし reference を最優先していたなら、最初の open_model の次に Video/Photo 側の Model が見えるはずですが、実際には 同じ score_hyperlink がもう一度開かれ、その後 open_uri に落ちているからです。
  • 現状仕様C: chooser の根本原因は URI routing 側の多重解決
    • 動画添付で chooser が出るのは、 score_hyperlink の段階ではなく、 open_uri(uri) に落ちたあとに model_of_uri(uri):openimg_photo:web の両方を返すためです。

なので、作者案をそのまま適用して効くか

ここが重要です。

「Mastodon 側で Video Model を reference に入れるだけ」では、効かない可能性が高い

理由は、現状のクリック経路では reference が一次ルーティングの入力になっていないように見えるからです。

つまり、単に

  • image → Photo reference
  • video → Video reference

と parser 側で分けただけでは、クリック時に依然として

  • まず score_hyperlink
  • つぎに "Link Text"
  • 最後に open_uri(uri)

という流れなら、Video Model は使われません。


逆に、作者案が効く条件

作者案を成立させるには、少なくとも次のどちらかが必要です。

1. score_hyperlink"Link Text" intent を変える
今の "Link Text" intent が、最終的に URI routing に流しているなら、そこを
  • reference があれば Plugin.call(:open, reference)
  • なければ Plugin.call(:open, uri)

という設計に変える
必要があります。

この形なら、Mastodon parser で reference に Video Model を入れれば、クリック直後に open_model(video_model) に行けます。

2. そもそも score_hyperlink を通さない添付専用 Note/Model を作る

これは大きめですが、設計としてはもっと明快です。
ただ、今の Mastodon parser の TODO コメントを見ると、添付は「本体側が添付ファイル用 Note を用意したら移行」とあるので、まだそこまでは本体設計が整っていないようです。


他の形式にエクスポート: Atom PDF