またまた掲示板作りました。「The Lounge ラウンジ」
以前、「懐かし掲示板 BBS」という掲示板を作っていた。「ポケ熱同盟掲示板」2023年1月から2026年1月まで開設していて、当時の Cloudflare Pages Functions で動かしていた。
- 過去記事 : 2023-01-01 あのサイトっぽい掲示板を Cloudflare Pages Functions と D1 SQLite で作った
- コード (Archive 済) : Neos21/legacy-of-bbs: Legacy of BBS
また、2024年には「Favoriya」という SNS を作っていた。その場で絵を描いてアップできたり、「携帯百景」風のテロップを乗せた画像がアップロードできるような面白機能を盛り込んでいたが、OCI の IaaS 上で動かしてるのがダルくなり、急に閉鎖した。w
- 過去記事 : 2024-12-19 Favoriya という SNS を作っている
- コード (Archive 済) : Neos21/favoriya: Favoriya
2026年1月に「懐かし掲示板 BBS」も閉鎖して、簡素なゲストブックを作って半年ほど置いておいたが、コチラは一切書き込みがなかったので、「Neo's World に掲示板は要らないな」と判断し、コチラも先日削除した。
- コード (Archive 済) : Neos21/neos-guest-book: Neo's Guest Book
今年2026年5月に、「個人サイトウェブリング」というサイトを公開した。ほとんど宣伝していないにも関わらず、現在30サイトご登録いただいており、アクセス数は少ないものの、ウェブリングというモノを面白がってくれる人はまだこの世界に存在するのだ、ということを感じている。
- 過去記事 : 2026-05-25 「個人サイトウェブリング」を開設した
自分が2003~2005年頃に入り浸っていた「ポケモン熱狂的ファンはココがちがう!」というサイトにあった「ポケ熱同盟掲示板」は、Tacky's Room の「挨拶しちゃ朗」という CGI 掲示板が使用されていた。一方、「メイン掲示板」として設置されていた掲示板には、同じく Tacky's Room の「もっと書き込み隊」が使用されていた。
この「もっと書き込み隊」という CGI 掲示板には、文字色・アイコンなどを設定できる機能があり、コレが個性を演出できるユニークな機能だったと思う。同じ CGI を設置しているサイトは当時たくさんあったと記憶している。
今回はコレを再現してみたくなったので、作った。その名も「The Lounge : ラウンジ」。
ユーザ登録なしで書き込みできる掲示板サイト。スレッドの絵文字や背景色を任意で決められ、各投稿は文字色やアバターアイコンを自由に設定できる。
また、各投稿に対して Fedibird や Misskey のように「リアクション絵文字」を付けられる。
内部的には Cookie を利用して同一端末かどうかを判別しており、同一 Cookie が有効な間は「投稿回数」もカウントアップされていくようになっている。
ユーザ登録をすることで、アバターアイコンとして任意の画像をアップロードできるようになる。アバターに画像を利用できるのはユーザ登録した人の特権w。また、ログインすればブラウザや端末をまたいでも文字色の設定などを引き継げる他、「投稿回数」のカウントアップもユーザ単位で集計するようになる。
構成はかなりいつもどおり。
- フロントエンド : React Router (SPA)
- Tailwind CSS・daisyUI
- ky・Zustand
- バックエンド : Hono
- Zod
- Cloudflare Workers・Cloudflare D1・Cloudflare R2
Hono で Cookie をコレだけ活用したのは初めてだった。hono/jwt はよく使ってきたが、hono/cookie もとても便利。hono/utils/crypto には SHA-256 ハッシュを作る sha256 などの便利関数があって、自前で実装しなくて良くてホント色々便利だった。
ログインユーザがアップロードしたアバター画像を置くのに R2 オブジェクトストレージを使った。R2 は以前も Misskey サーバを立ててた時にちょっと使ったが、お手軽・便利でございますね。
Tailwind にもだいぶ慣れてきた。daisyUI が程よくコンポーネントを用意してくれてるので基本はそれに乗っかってるが、今回はデザインの細かいところを生の daisyUI からカスタマイズした。
アバター画像の処理は Canvas を使うことで、ライブラリなし・クライアントのみでトリミングから圧縮まで実装してある。バックエンドではサイズと形式チェックくらい。便利な時代ですな~。
絵文字やアバターアイコンを選択するピッカー部分の実装が苦労したな。「絵文字一覧って、どうやって用意しよう…?」というので色々調べて Emojibase に行き着くも、素直に一覧表示したら DOM 数が多すぎて重くてガクガクになっちゃったので、TanStack Virtual という仮想スクロールのライブラリを導入して…。いや、ライブラリがあるだけありがたいけどもw。
アバターアイコンに関しては、Iconify というフレームワークを見つけて、Material Design から Phosphor から Tabler から Font Awesome に至るまで、200以上の「アイコンセット」、アイコン単位でいえば40万以上のアイコンを、同一の方式でインポートして利用できるようになる。開発元が異なるアイコンでも、Iconify が提供する <Icon> という React コンポーネントで挿入できるので、実装がとっても楽だった。
ツールチップは daisyUI にも簡単なモノはあるのだが、要素の位置とページ幅などを考慮してくれないので、以前もどこかで使ったことのある Floating UI を今回も使った。どこで使ったんだっけな、仕事で使ったのかな、最初にどこで知ったかは忘れちゃった。
Favoriya の時ほどイカレた機能は入れてないけど、「ココに集まる人同士が、のんびり会話できる空間になればいいな」と考えているので、文字色とアバターアイコンで個性を表現する程度でちょうどいいのかな~と思っている。「川柳になってないと書き込めない」みたいなアホモードは要らんやろ……?w
今回も、「独り言を延々と好き勝手書いていい場所」とは定めてないです。「ラウンジ」という名前にしたのも、公園などと同じ「公共の場」にしたいという思いからです。私物化・私有地化はしてほしくないからこその「匿名でも書き込める」仕様です。「誰でも書き込める」ことは「何を書いても良い」を意味しません。
「昔ながらの掲示板」を目指しているのであって「SNS」ではないので、ユーザアカウントを作っても「自分のプロフィールページ」は作られません。簡単なプロフィール文を設定できる項目はありますが、コレもアバターアイコンにマウスホバーした時だけ表示されるオマケ機能に過ぎません。自己アピール・自己主張を繰り広げてもらうための空間ではなく、利用者同士のゆるい交流が狙いです。「そういう使い方じゃねえんだよ」と思ったら管理人の権限で容赦なく投稿削除・アクセスブロック等していきますので、節度をもってご利用ください。
治外法権のデモ会場でもなければ、煩いばかりの居酒屋でもありません。「空港のラウンジ」って静かでオシャレ、でも居ると楽しいじゃないですか。アレですよアレ。ああいう空間にしたいのです。
とゆーワケで、The Lounge : ラウンジ、ヨロシクお願いします。