0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【第048回】狭いスマホ画面を有効活用!参加メンバー一覧のドロワー式トグルボタン実装

0
Posted at

こんにちは!2ちゃんねる互換掲示板システム「 つゔぁいちゃんねる(2ch.biz) 」の開発録、第48回です。

前回(第47回)では、ルーム名の二重同期パイプラインとIndexedDB v2へのローカル保存により、愛着の湧くコミュニティ体験を実現しました。

機能が充実し、いよいよスマートフォンからの利用者がPCを上回る勢いで増加する中、モバイルUIにおける 「最後の大物レイアウト問題」 が浮上しました。

「スマホの画面幅(375px〜400px前後)で、 右側の参加者リスト(ニックネームサイドバー)をどう表示すべきか? 」

PCと同じように横並びにすると本文が1行あたり数文字しか入らず、完全にUIが破綻する。しかし、スマホだからといって参加者リストを完全に消してしまうと、 「今誰がいるのか分からない」「荒らしのキックやホスト権限の移譲ができない」 という致命傷に繋がります。

本稿では、画面の表示領域を100%本文に明け渡しつつ、ワンタップでメンバー確認と管理操作を行える 「ドロワー式トグルボタン」 の実装を解説します!


1. モバイルにおける「サイドバーのジレンマ」

デスクトップ版のXChatスタイルでは、左にメッセージログ、右に参加者一覧が並ぶ2ペイン構成が非常に便利でした。

しかし、画面幅が400px未満のスマートフォンで同じことをやろうとすると、以下のような地獄絵図になります。

かといって、メディアクエリで display: none; にして消し去ってしまうと、モバイルユーザーは「誰がこの部屋にいるのか」を知る術を失い、第32回で作った「👑 ホスト移譲(なすりつけ)」や「× キック」のボタンも押せなくなってしまいます。

私たちが目指したのは、 「通常時は画面の横幅を 100% メッセージログに使い、見たい時だけスッと上から引き出せるトグルUI」 でした。


2. 解決策:リアルタイム人数バッジ付き「👥 参加者」トグルボタン

画面を圧迫しない最も自然な場所として、私たちは上部のトピックバー内に 「👥 参加者 (人数)」ボタン(#p2p-toggle-peers-btn) を組み込みました。


3. 実装の全貌

(1) トピックバーのマークアップ

トピックバーの右側アクション群の中に、人数の動的バッジを内包したボタンを新設しました。

<div class="p2p-xchat-topic-bar">
    <div class="p2p-topic-left">
        <span class="p2p-topic-channel">#</span>
        <span class="p2p-topic-text" id="p2p-topic-text">名称未設定ルーム</span>
    </div>
    <div class="p2p-topic-right">
        <!-- ★新設: モバイル向け参加者トグルボタン -->
        <button type="button" id="p2p-toggle-peers-btn" class="btn btn-sm btn-outline p2p-btn-peers-toggle">
            👥 <span id="p2p-mobile-peers-count">1</span>
        </button>
        <!-- その他のボタン (設定、退室等) -->
    </div>
</div>

(2) リアルタイム人数カウントの連動

ピアが入室・退室するたびに、WebRTCのピアマップから総人数を計算し、ボタンの数値をリアルタイムに更新します。

/**
 * 参加者一覧の更新とバッジ同期
 */
function handlePeersUpdate() {
    // 既存の参加者リストDOM再描画...
    renderNicknameList();

    // ★モバイルボタンのバッジ数値を更新 (自分自身 + 接続ピア数)
    const countEl = document.getElementById('p2p-mobile-peers-count');
    if (countEl) {
        const totalPeers = 1 + Object.keys(activePeers).length;
        countEl.textContent = totalPeers;
    }
}

/**
 * トグルボタンのクリックハンドラ
 */
document.getElementById('p2p-toggle-peers-btn').addEventListener('click', () => {
    const sidebar = document.getElementById('p2p-sidebar');
    if (!sidebar) return;

    // 開閉クラスをトグル
    sidebar.classList.toggle('p2p-sidebar-shown');
});

(3) モバイルCSSとスライドダウンアニメーション

デスクトップでは右側に固定表示し、モバイル(max-width: 768px)では絶対配置のアコーディオン・ドロワーへと切り替えます。

/* デスクトップ表示: 右側に常時表示 */
.p2p-xchat-sidebar {
    width: 200px;
    border-left: 1px solid var(--border-color, #d0d7de);
    background: var(--bg-secondary, #f6f8fa);
}

/* ★モバイル最適化 (768px以下) */
@media (max-width: 768px) {
    /* PC用リサイズスプリッターは非表示 */
    .p2p-sidebar-resizer {
        display: none !important;
    }

    /* 通常時は非表示(スライド格納状態) */
    .p2p-xchat-sidebar {
        display: none;
        position: absolute;
        top: 80px; /* ヘッダー + トピックバーの直下 */
        left: 0;
        right: 0;
        width: 100% !important;
        max-height: 180px; /* メッセージを完全に隠さない絶妙な高さ */
        overflow-y: auto;
        border-left: none;
        border-bottom: 2px solid var(--border-color, #0969da);
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
        z-index: 20;
    }

    /* トグル展開時: スルッとスライドダウン */
    .p2p-xchat-sidebar.p2p-sidebar-shown {
        display: block;
        animation: p2pSlideDown 0.2s cubic-bezier(0.16, 1, 0.3, 1);
    }
}

@keyframes p2pSlideDown {
    from {
        opacity: 0;
        transform: translateY(-8px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

[!TIP]
ドロワーの最大高さを max-height: 180px; に抑えておくことで、参加者リストを開いた状態でも下側に最新メッセージがチラ見えし、チャットの流れを見失わないように工夫しています。


4. 自動テストと実機操作の検証

自動テストスクリプトおよび iPhone Safari 実機で検証を行いました。

  • 開閉アニメーションの滑らかさ :
    • transform: translateY を使用しているため、GPU支援により60fpsで吸い付くようにヌルヌル開閉することを確認。
  • 人数カウントの即時連動 :
    • 別のブラウザが入室した瞬間、ボタンのバッジが「👥 1」から「👥 2」へ瞬時に切り替わることを確認。
  • 管理操作の完全性 :
    • モバイル画面上でもドロワーを展開することで、「👑 ホスト移譲」や「× キック」のボタンが問題なくタップ可能であることを実証。

5. まとめと次回予告

参加者リストをドロワー式トグルメニューへと昇華させたことで、スマートフォンの限られた画面幅の中で「メッセージの圧倒的な読みやすさ」と「管理操作の完全性」を両立させることができました。

UIの完成度がいよいよ極限に達したP2Pチャットですが、アクセス集中テスト(多人数同時接続テスト)を実施していたチームから、 「非常に厄介な通信バグ」 が報告されました。

「10人以上のユーザーが一斉に部屋に入ろうとすると、 何人かのブラウザが『接続中…』のまま固まって部屋に入れない! 」
「コンソールを見ると、WebRTCのOfferとAnswerが同時に飛び交って衝突(Glare)している!」

WebRTCの分散接続における最大の難関「シグナリング状態の競合」。

次回は、 【第049回】「部屋に入れない」謎のフリーズを追え!シグナリング状態の競合解消とコネクションリトライ をお届けします。お楽しみに!

本番サービス : https://2ch.biz/

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?