Mastodon Misskey Share button https://web.gnusocial.jp/post/2024/02/26/10363/

SENOO, Ken d5ed4a496b First commit 1 year ago
README.md d5ed4a496b First commit 1 year ago
image.jpg d5ed4a496b First commit 1 year ago
index.html d5ed4a496b First commit 1 year ago

README.md

MaMiShare

About

image

MaMiShareはMastodon/Misskeyに対応したSNSへの共有ボタンだ。

左側のテキストボックにサーバーホスト名を入力して [MaMiShare] を選ぶと、QP <記事タイトル> <URL> の形式のテキストで編集画面が開かれワンクリックで投稿できる。

以下が特徴となる。

  1. 中継サーバーを使わない最低限の依存関係。
  2. わずか数KB、数十行以内のシンプルな軽量実装。自己改変も簡単。
  3. 画面遷移なしのワンクリック共有。
  4. localStorageを利用した前回の選択サーバーの記憶。

Service - GNU social JP Wiki」に記した通り、既存の類似共有ボタンを検討した結果、以下の点で満足いかなかったので自作した。

  • 外部サーバー依存。
  • モーダルなどの余計な画面遷移。
  • ファイルサイズ。
  • 無駄に長くて複雑な実装。

mastodon-share-button-scalajsは基本的な考え方は問題なかったのだが、モーダルの余計な画面遷移と利用時のmstdn-share.jsのファイルサイズ (1 MB!以上) が気に入らなかったので自作した。

本質的にはせいぜい100行以内程度の処理のために1 MB以上の巨大ファイルは大袈裟過ぎる。

なお、MaMiShareの名前の由来は、Mastodon Misskey Share button。長いので最低限意味が分かる範囲で短縮しただけ。

MastodonもMisskeyも <host>/share?text= のWeb Intent URLのパスが共通していることを利用している。

Usage

1 index.htmlに記載している以下のコードを共有ボタンを設置したい場所にHTMLとして記述する (iframeで参照するのもあり)。WordPressだとWidgetの [Custom HTML] などで配置できる。

<fieldset>
  <style>
  /* @scope { */
    fieldset input, fieldset button {
      width: 100%;
      color: white;
      font-size: 2em;
    }
  /* } */
  </style>
  <div style="display:flex; width:100%;">
    <button style="background-color:#333"
      onclick="navigator.clipboard.writeText(
        document.title+' '+location.href);">Copy</button>
    <button style="background-color:#2c6ebd"
      onclick="location.href='https://b.hatena.ne.jp/entry/s/'
        +location.host+'/'+location.pathname">Hatena</button>
    <button style="background-color:#3b5998"
      onclick="location.href='https://www.facebook.com/sharer/sharer.php?t='
        +encodeURIComponent('QP '+document.title)
        +'&u='+encodeURIComponent(location.href);">Facebook</button>
    <button style="background-color:#1da1f2"
      onclick="location.href='https://twitter.com/intent/tweet?text='
        +encodeURIComponent('QP '+document.title)
        +'&url='+encodeURIComponent(location.href);">X/Twitter</button>
    <button style="background-color:black"
      onclick="location.href='https://www.threads.net/intent/post?text='
        +encodeURIComponent('QP '
        +document.title+' '+location.href);">Threads</button>
  </div>
  <form novalidate="novalidate" onformdata="
      event.formData.set('text', 'QP ' +document.title+' '+location.href);"
    style="display:flex;" >
    <input id="MaMiShare.host" list="MaMiList" type="email" inputmode="email"
      autocomplete="on" autocorrect="off" autocapitalize="off"
      placeholder="mstdn.jp misskey.io"
      style="background-color:rgb(158,194,63)" />
    <button style="background-color:rgb(99,100,255);"
      onclick="this.parentElement.action =
        `https://${this.previousElementSibling.value}/share`;
        localStorage.setItem('MaMiShare.host',
          this.previousElementSibling.value);
      ">MaMiShare</button>
    <script>
      window.addEventListener('load', () => {
        document.getElementById('MaMiShare.host').value =
          localStorage.getItem('MaMiShare.host');
      });
    </script>
    <datalist id="MaMiList">
      <option value="fedibird.com"></option>
      <option value="gp.tsukimi.club"></option>
      <option value="mastodon.social"></option>
      <option value="mattyaski.co"></option>
      <option value="meisskey.one"></option>
      <option value="misskey-square.net"></option>
      <option value="misskey.04.si"></option>
      <option value="misskey.backspace.fm"></option>
      <option value="misskey.cloud"></option>
      <option value="misskey.gg"></option>
      <option value="misskey.io"></option>
      <option value="misskey.niri.la"></option>
      <option value="misskey.one"></option>
      <option value="misskey.secinet.jp"></option>
      <option value="misskey.systems"></option>
      <option value="mk2.toyoko.in"></option>
      <option value="msk.ilnk.info"></option>
      <option value="mstdn.jp"></option>
      <option value="nijimiss.moe"></option>
      <option value="novelskey.tarbin.net"></option>
      <option value="pawoo.net"></option>
      <option value="submarin.online"></option>
      <option value="sushi.ski"></option>
    </datalist>
  </form>
</fieldset>

datalist要素はなくても問題ない。div要素内のFacebookなどの共有ボタンはおまけでこれもなくても問題ない。

2 続いて、左側のフォームにMastodon/Misskeyサーバーのホスト名 (例: mstdn.jp) を記入し、[MaMiShare] を選ぶ。datalist要素で固定になるが候補サーバーの候補を必要に応じて設定しておくとユーザーには親切だろう。

3 選択したサーバーホスト/share?text=[QP ページタイトル URL] のURLを開くので、自分のアカウントでログインする。編集画面に該当文字列が入力された状態で開かれる。必要に応じて自分の意見などを追記編集して投稿する。

4 フォームに一度入力した内容はlocalStorageに保存されているので、次回表示時は入力された状態になっている。

必要に応じて、スタイルやHTMLコード片を修正して自分の用途に合わせる。

style要素内の@scopeは使えない環境もあるだろうから、被ることが少ないと思うfieldsetのセレクターをひとまず利用した。@scopeが使えるなら[fieldset input]の [fieldset ] の前置は不要になる。

Attribute

  • Author: SENOO, Ken
  • License: GPLv3 or late
  • Created: 2024-02-24 Sat

GPLの採用理由は他人の改善内容をこのコードに取り込みたいから。GPLの影響範囲はせいぜいfieldsetやform要素内がこのコードの範囲内の想定。それ以外の部分とは連結しているとは思っていないし、あまりうるさく言うつもりはない。

TODO

  • Bluesky。アプリ側でWeb Intent URL相当にそもそも対応していない。
  • Nostr。Bluesky対応時に一緒にv1.1.0で対応予定。Bluesky/Nostr対応時に名前を変えるかもしれない。
  • GNU social。たぶん実装がないので作る必要がある。

CHANGELOG

2024-02-25 Sun: v1.0.0 公開

2024-02-24 Sat: v0.0.0 誕生