TwitterそっくりなMastodonクライアントを作った。Webクライアント制作でハマったことなど

  • 103
    いいね
  • 0
    コメント

 ここなんかを見てる方だと既にご存知かもしれませんが、最近HalcyonハルシオンというTwitter風のマストドンWebクライアントを作りました。

スクリーンショット 2017-05-28 16.27.55.jpg
Halcyon

 フル機能のWebクライアントというと、今のところ私が作らせていただいたコレと、UEIさんが制作されたNaumanniというクライアントの2つくらいしか見かけないですが(Apps.md調べ)、Webクライアントもこれから更に充実していったらいいなあと思っているので拙い文章ですが何かの参考になればと思います。

 といってもやはりあのTwitterを1から10まで一人でコピーするのには限界がありまして、いくつか妥協させていただいた点もあります。あと筆者は学生なので所詮素人だと思って見ていただけるとありがたいです。

ログイン

 ログイン部分です。ここはTwitter風ではありませんが、デザインには割りとこだわりました。

スクリーンショット 2017-06-02 19.46.48.jpg

 クライアントを制作するにあたって覚えておくべきなのはTwitterなどと違い、インスタンスごとにアプリケーションの認証をしないといけないことでしょう。ですから、

  1. ユーザーからユーザーのインスタンスのURLを受け取る
  2. インスタンスにアプリケーションの情報などをPOSTし、client_id, client_secretなどを受け取る。
  3. 任意のデータベースにインスタンスのURL, client_id, client_secretを書き込む。
  4. ユーザーにOauth認証用URLを開かせる。認証用URLにclient_idなどを入れる部分があるので上記に方法で取得したものを使用
  5. 認証後、authorization_codeが取得できるのでそれを用いてユーザーのaccess_tokenを取得できる。

という感じになります。

 尚、1で複数のユーザーから同じインスタンスのURLを受け取った場合、2と3がスキップされ、そのかわりデータベースからそのインスタンスのclient_id, client_secretを取得する必要があります。

 ちなみになんですが、HalcyonでもOauth認証を使おうとしたところ無効なリダイレクトURIが含まれています。と言われてしまい、Oauthが実装できていません(大問題)。何かわかり次第追記します。
 追記:できました。

 ログイン後はlocalStorageを用いてaccess_tokenや現在のID、プロフィールや設定諸々をブラウザに保存して再利用できるようになっています。

タイムライン

 タイムラインは上手く真似できたと思っております。

スクリーンショット 2017-05-30 12.12.00.png

 この辺は特にハマりませんでしたが、スクロールで前後の投稿を参照するのはHTTPレスポンスのヘッダーにprevnextのURLがありますのでその辺で面倒なことはしなくても平気です。

通知

 通知欄のCSSはほとんどタイムラインと同じものを使っています。

スクリーンショット 2017-05-30 12.21.17.png

 ただしタイムラインと違い、通知はフォロー、お気に入り、ブースト、メンションの4種類あるのでtypeで条件分岐してCSSクラスを変更しています。

ユーザーページ

 痛々しいプロフィールで申し訳ないです

スクリーンショット 2017-05-30 12.32.43.jpg

 こっちも真ん中はタイムラインを再利用したもので、あとのCSSも適当に書きました。ハマったポイントとしては、実はMastodonはお気に入り登録したトゥートの一覧がユーザー自身しか見れないようになっているので、そこにも条件分岐が必要だったという点でしょうか、

スクリーンショット 2017-05-30 12.37.49.png

 同じくお気に入り登録した投稿のカウントも存在しませんので、ラベル部分も一つだけ「Show」となっています。きもちわるい。

あとTwitterを再現する上で致命的だったのがユーザーページのURLなのですが、Mastodonは@username@instanceの形式でアカウントの情報を取得することが出来ない仕様で、やむを得ずURLの末尾にユーザーのidを付与しました。

スクリーンショット 2017-05-30 16.35.57.png

idが付与されていない場合はそのユーザー名でMastodon内を検索し、最初にヒットしたアカウントのacctが合致していたら表示、そうでない場合は404にリンクするようになっています。

フォロー/フォロワー

 ここもさくっと作れました。

スクリーンショット 2017-05-30 12.39.31.jpg

 1点だけ妥協したポイントは、Mastodonはアカウント情報を取得してもそのアカウントをフォローしているか否かの情報は取得できず、/relationshipに別にリクエストを送ることが必要なようでした。それをしてしまうとHTTPリクエストの数が2倍になってしまい、UXにも、サーバーにも良くないので今回は妥協させていただき、全て「Follow」になっています。

追記:どうやら/relationshiparrayが扱えるようなので、ユーザーの一覧を読み込んだ後にそれを取得してボタンのラベルを変更するということができそうです。

Compose new toot

 かなり苦労しました。

スクリーンショット 2017-05-30 12.54.29.png

 入力欄全体はform要素で組んであるのですが、添付した画像をアップロードするためにFormDataをそのまま送信する必要があり、<form>内の<input type='file'>からファイルの情報を取得し、forループで一件ずつ擬似的に画像のみが添付されたFormを生成し、送信させるようにしております。(おそらくもっといい方法があるはず)

 あと、その擬似的に作ったformのinput要素のname属性がfileじゃないとエラーになったり、リクエストヘッダーのprocessDataをfalseにしないと自動的に何かがされてしまって上手く送信できなかったりしました。

 Twitterでは一度添付したファイルを消去する機能があったようでしたが、上記の通り複雑なのでとりあえずは見送りました。

What to follow

 こちらはタイムラインで読み込んだことのあるユーザーをランダムで表示する仕様になっています。

スクリーンショット 2017-05-30 12.51.36.png

 ただ、フォロー/フォロワーと同じ理由でフォローしているかどうかが把握できないため、フォロー済みのユーザーも関係なしに表示されてしまうようになっています。


 主なポイントは以上です。ほとんどのことがWebクライアント以外でも言えることだったと思いますが、参考になれば幸いでございます。また何か思い出したら追記します。