FKB Pro - ソーシャルテーマ

SCSSコードの唯一の小さな問題は、自動改行がされないため、単語が途中で切れてしまうことです。:wink:

どういう意味ですか?スクリーンショットを送ってもらえますか?

私のスマートフォンのスクリーンショットです。カテゴリ名が完全に表示されていないことがわかります。

「いいね!」 1

これはコアの意図的な動作ですが、カテゴリ名を切り詰めずに改行して表示したい場合は、以下を試してみてください:

.category-heading {
  &.--has-logo {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--space-4);
  }
  &__content {
    min-width: 0;
    .badge-category__wrapper {
      max-width: 100%;
      white-space: normal;
      overflow-wrap: anywhere;
      .badge-category {
        &.--style-emoji,
        &.--style-icon {
          align-items: baseline;
        }
      }
    }
  }
}
「いいね!」 3

最高だ、ちゃんと動くよ @Don 君は天才だ :clap:

「いいね!」 1

タブレット版ではカテゴリの説明が表示されていませんが、モバイル版では表示されています。モバイル版でも同じように表示する方が適切ではないかと思います。:thinking:

また、ネストされた返信を使うと、アバターの表示に少し不具合があり、少し大きくなってしまいます。

私だけでしょうか?

@gilles ありがとう!これらについて更新をマージしました…

「いいね!」 2

テストしてみましたが、問題ありませんでした。@Don さん、迅速な対応ありがとうございます :clap: :+1:

「いいね!」 1

@Don デスクトップモードで、サイドバーなしの環境で、表示に関する小さなバグを発見しました。参考までに :wink:

「いいね!」 1

ありがとうございます。こちらで修正しました:FIX: Enhance category heading styles in SCSS · VaperinaDEV/fkb-pro-theme@95a3c25 · GitHub

「いいね!」 4

テスト済み、問題ありません :+1:

「いいね!」 1

これをインストールしたばかりです。インストール直後に右側にfakebookのパネルがあったはずですが、私の環境ではそれが消えてしまいました。何が原因で消えたのか、またどうすれば元に戻せるのかがわかりません。

こんにちは :waving_hand: このセクションを切り替えるボタンが右下にあります。

テーマを更新しました: DEV: Improve FKB panel and right sidebar layout handling - Pull Request #78 - VaperinaDEV/fkb-pro-theme - GitHub

「いいね!」 2

あ、ここにあったのね――ありがとう!うーん、たまたま押してしまったのかな?それとも、モバイルで表示したときにオフになってしまったの?いくつか試して、結果を報告するね。

「いいね!」 1

うん、モバイルでは表示されないよ。

そうですよね、もちろんです。

モバイルでフォーラムを読んだ際、デスクトップ版では私の設定でオフにされた可能性があると考えていました。ただ、さっきそのテストをしてみましたが、パネルはオフになっていませんでした。つまり、デスクトップ版のパネルがなぜ無効化されたのかは謎です。おそらく無効化の矢印を誤ってクリックしてしまったのだと思います。

「いいね!」 1

ドン、こんにちは!FKB Pro テーマが本当に気に入っています。

ちょっとお願いがあります。トピックカードに最後の投稿者だけでなく、複数の参加者のアバターを表示する設定を追加することは可能でしょうか?

1つのアバターだけだととてもすっきりしていますが、複数の参加者を表示すると、議論が活発であることがよりよく伝わります。この機能を切り替えられるトグルがあれば最高です!

素晴らしい作業、ありがとうございます!レオ

@Don さん、こんにちは!FKB pro テーマ用に、タブレットとデスクトップでは右下、モバイルでは左下にチャットのフローティングボタンを表示するよう、独自に少しカスタマイズしました。新規トピック作成ボタンと同じエフェクトも付けています。コードとしてはもっと良い方法があるかもしれませんが、とりあえずこれで動いています :rofl:

コンポーネントのコード(CSS)はこちらです:


// 1. メインのフローティングボタン 
.header-dropdown-toggle.chat-header-icon {
    position: fixed !important;
    bottom: 60px !important;
    right: 20px !important;
    z-index: 9999 !important;
    
    /* 完璧な寸法(円形) */
    width: 60px !important;
    height: 60px !important;
    min-width: 60px !important;
    min-height: 60px !important;
    border-radius: 50% !important;
    
    /* 鮮やかな青色とカラー付きの影 */
    background: #0084ff !important;
    box-shadow: 0 4px 14px rgba(0, 132, 255, 0.4), 0 2px 4px rgba(0, 0, 0, 0.1) !important;
    
    /* マージンの整理 */
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    padding: 0 !important;
    margin: 0 !important;
    border: none !important;
    
    /* スムーズなトランジション */
    transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275), opacity 0.3s ease, box-shadow 0.2s ease !important;
}

/* モバイル(画面幅 <= 640px)での特定位置 */
@media (max-width: 640px) {
    .header-dropdown-toggle.chat-header-icon {
        bottom: 80px !important; 
        left: 20px !important;   /* 右側に戻したい場合は right: 20px に変更 */
    }
}

/* ホバー時のエフェクト(わずかな拡大) */
.header-dropdown-toggle.chat-header-icon:hover {
    transform: scale(1.08) !important;
    box-shadow: 0 6px 20px rgba(0, 132, 255, 0.5), 0 4px 8px rgba(0, 0, 0, 0.15) !important;
}


/* 2. DISCOURSE 標準のグレー背景の整理                 */

.header-dropdown-toggle.chat-header-icon .icon,
.header-dropdown-toggle.chat-header-icon span:not(.badge-notification):not(.chat-badge):not([class*="unread"]):not([class*="count"]) {
    background-color: transparent !important;
    box-shadow: none !important;
    border: none !important;
}


/* 3. アイコン(吹き出し)の完璧な中央揃え                  */

.header-dropdown-toggle.chat-header-icon .d-icon,
.header-dropdown-toggle.chat-header-icon svg {
    position: absolute !important;
    top: 50% !important;
    left: 50% !important;
    transform: translate(-50%, -50%) !important; 
    
    margin: 0 !important;
    padding: 0 !important;
    width: 32px !important;
    height: 32px !important;
    color: #ffffff !important;
    
    filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.1)) !important;
}


/* 4. 通知バッジ(緑のカウント + 数字の表示) */

.header-dropdown-toggle.chat-header-icon .badge-notification,
.header-dropdown-toggle.chat-header-icon .chat-badge,
.header-dropdown-toggle.chat-header-icon .unread-notifications,
.header-dropdown-toggle.chat-header-icon [class*="badge"],
.d-header-icons .header-dropdown-toggle.chat-header-icon .badge-notification {
    position: absolute !important;
    top: -4px !important;
    right: -4px !important;
    left: auto !important;
    margin: 0 !important;
    z-index: 10 !important; 
    
    /* 緑色の強制指定 */
    background-color: #53A548 !important;  
    background: #53A548 !important;
    color: #ffffff !important;
    
    /* 数字を表示するためのフォントの強制指定 */
    font-size: 13px !important;
    font-weight: bold !important;
    line-height: 18px !important;
    letter-spacing: normal !important;
    text-indent: 0 !important;
    
    /* 寸法と形状 */
    padding: 0 6px !important;
    min-width: 22px !important;
    height: 22px !important;
    border-radius: 50px !important;
    border: 2px solid #ffffff !important;
    box-sizing: border-box !important;
    
    /* 数字の中央揃え */
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    white-space: nowrap !important;
    overflow: visible !important;
    
    /* 緑のパルスアニメーション(キーフレームに関連付け) */
    animation: badge-pulse 2s infinite !important; 
}

/* 子要素(Discourse が数字を span でラップする場合)すべてに表示を強制 */
.header-dropdown-toggle.chat-header-icon .badge-notification *,
.header-dropdown-toggle.chat-header-icon .chat-badge *,
.header-dropdown-toggle.chat-header-icon [class*="badge"] * {
    color: #ffffff !important;
    background: transparent !important;
    display: inline-block !important;
    visibility: visible !important;
    opacity: 1 !important;
    font-size: inherit !important;
}

/* 5. 修正済みアニメーション(レーダー効果とバウンド)            */


/* 5.1 - 赤いバッジ周りのレーダー波(パルス) */
.header-dropdown-toggle.chat-header-icon .badge-notification,
.header-dropdown-toggle.chat-header-icon .chat-badge,
.header-dropdown-toggle.chat-header-icon .chat-channel-unread-indicator {
    animation: badge-pulse 2s infinite !important;
    transform-origin: center !important;
}

/* 5.2 - メッセージがある場合、青いボタン全体にバウンドエフェクト */
.header-dropdown-toggle.chat-header-icon:has(.badge-notification),
.header-dropdown-toggle.chat-header-icon:has(.chat-badge),
.header-dropdown-toggle.chat-header-icon:has(.chat-channel-unread-indicator) {
    animation: chat-bounce 3s infinite !important;
}

/* --- KEYFRAMES の定義(変更しないでください) --- */

/* 波の定義:表示バグを避けるため box-shadow のみを使用 */
@keyframes badge-pulse {
    0% {
        box-shadow: 0 0 0 0 rgba(250, 62, 62, 0.8);
    }
    70% {
        box-shadow: 0 0 0 10px rgba(250, 62, 62, 0);
    }
    100% {
        box-shadow: 0 0 0 0 rgba(250, 62, 62, 0);
    }
}

/* バウンドの定義:ボタンが 3 秒ごとにわずかに跳ねる */
@keyframes chat-bounce {
    0%, 20%, 50%, 80%, 100% { 
        transform: translateY(0); 
    }
    40% { 
        transform: translateY(-6px); 
    }
    60% { 
        transform: translateY(-3px); 
    }
}

/* 6. チャネルリストとプライベートメッセージ内のパルス  */


/* 6.1 - リストコンテナのオーバーフローを許可 */
.chat-channel-row,
.chat-channel-list-item,
.chat-drawer-container .chat-channel-unread-indicator,
.chat-channel-row .chat-channel-unread-indicator {
    overflow: visible !important;
}

/* 6.2 - 指示点のスタイルとマージン */
.chat-channel-row .chat-channel-unread-indicator,
.chat-channel-row .badge-notification,
.chat-channel-row .unread-indicator,
.chat-drawer-container .chat-channel-unread-indicator,
.chat-full-page .chat-channel-unread-indicator,
.chat-channel-list-item .chat-channel-unread-indicator {
    animation: list-dot-pulse 1.8s infinite !important;
    border-radius: 50% !important;
    position: relative !important;
    overflow: visible !important;
    margin: 0 6px !important; /* テキストや日付に張り付かないためのスペース */
}

/* 6.3 - 調整済みアニメーション(最大 6px のよりコンパクトな波) */
@keyframes list-dot-pulse {
    0% {
        box-shadow: 0 0 0 0 rgba(0, 132, 255, 0.7); /* 点の色に合わせて調整 */
    }
    70% {
        box-shadow: 0 0 0 6px rgba(0, 132, 255, 0); /* 行内に収めるため半径を縮小 */
    }
    100% {
        box-shadow: 0 0 0 0 rgba(0, 132, 255, 0);
    }
}

そして JS です:

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
    let lastScrollTop = 0;
    let isHiddenByScroll = false;

    // 1. スクロールハンドラー(モバイルでのみ有効)
    window.addEventListener("scroll", () => {
        const isMobile = window.innerWidth <= 640;
        const floatBtn = document.querySelector('.header-dropdown-toggle.chat-header-icon');

        if (!floatBtn) return;

        // PC の場合、ボタンが常に表示されるようにする
        if (!isMobile) {
            if (isHiddenByScroll) {
                floatBtn.style.setProperty('transform', 'translateY(0) scale(1)', 'important');
                floatBtn.style.setProperty('opacity', '1', 'important');
                isHiddenByScroll = false;
            }
            return;
        }

        const currentScrollTop = window.pageYOffset || document.documentElement.scrollTop;

        // 下方向にスクロールした場合(100px を超えた場合)
        if (currentScrollTop > lastScrollTop && currentScrollTop > 100) {
            if (!isHiddenByScroll) {
                floatBtn.style.setProperty('transform', 'translateY(100px) scale(0.8)', 'important');
                floatBtn.style.setProperty('opacity', '0', 'important');
                isHiddenByScroll = true;
            }
        } 
        // 上方向にスクロールした場合
        else if (currentScrollTop < lastScrollTop) {
            if (isHiddenByScroll) {
                floatBtn.style.setProperty('transform', 'translateY(0) scale(1)', 'important');
                floatBtn.style.setProperty('opacity', '1', 'important');
                isHiddenByScroll = false;
            }
        }
        lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop;
    }, { passive: true });

    // 2. 基本表示を管理するための MutationObserver
    const observer = new MutationObserver(() => {
        const chatOpen = document.querySelector('.chat-drawer, .d-chat-floating-panel, .chat-widget, .chat-panel, .chat-out-of-container, .chat-full-page');
        const isChatRoute = window.location.pathname.startsWith('/chat');
        const hasFullPageClass = document.body.classList.contains('has-full-page-chat');
        
        const isMobile = window.innerWidth <= 640;
        const isTopicRoute = window.location.pathname.includes('/t/') || document.body.classList.contains('archetype-regular');
        const hideOnMobileTopic = isMobile && isTopicRoute;

        const floatBtn = document.querySelector('.header-dropdown-toggle.chat-header-icon');
        
        if (floatBtn) {
            if (chatOpen || isChatRoute || hasFullPageClass || hideOnMobileTopic) {
                floatBtn.style.setProperty('display', 'none', 'important');
            } else {
                floatBtn.style.setProperty('display', 'flex', 'important');
                
                // モバイル / デスクトップの位置の適切な管理
                if (isMobile) {
                    floatBtn.style.setProperty('left', '10px', 'important'); // ずらしたい場合は値を変更
                    floatBtn.style.removeProperty('right');
                } else {
                    floatBtn.style.setProperty('right', '20px', 'important');
                    floatBtn.style.removeProperty('left');
                }
            }
        }
    });

    observer.observe(document.body, { childList: true, subtree: true, attributes: true });
});