FKB Pro - Tema social

O único pequeno problema com o código scss é que não há quebra de linha automática, então as palavras ficam cortadas :wink:

O que você quer dizer? Pode enviar um screenshot?

Aqui está uma captura de tela do meu celular. Note que o nome da categoria não está completo.

1 curtida

Esse é um comportamento intencional no núcleo, mas, se você preferir que o nome da categoria quebre para uma nova linha em vez de ser truncado, você pode tentar:

.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 curtidas

Incrível, funciona! @Don, você é demais :clap:

1 curtida

Notei que na versão para tablet não há a descrição da categoria, mas no celular sim. Acho que seria sensato fazer o mesmo na versão mobile. :thinking:

Também notei que, ao usar respostas aninhadas, há um pequeno defeito de exibição do avatar, que fica um pouco grande.

Não sei se sou o único?

Obrigado @gilles! Mergiei uma atualização para isso…

2 curtidas

Testei e está tudo certo, obrigado @Don pela rapidez :clap: :+1:

1 curtida

@Don encontrei um pequeno bug de exibição no modo desktop em computadores sem a barra lateral, apenas para informar :wink:

1 curtida

Obrigado, corrigi aqui: FIX: Enhance category heading styles in SCSS · VaperinaDEV/fkb-pro-theme@95a3c25 · GitHub

4 curtidas

Testado e aprovado :+1:

1 curtida

Acabei de instalar isso. Tenho quase certeza de que havia um painel do Fakebook no lado direito logo após a instalação, mas ele parece ter desaparecido para mim. Não tenho certeza do que eu mudei para fazê-lo sumir, nem como trazê-lo de volta.

Olá :waving_hand: Há um botão no canto inferior direito para alternar esta seção.

Atualizei o tema: DEV: Improve FKB panel and right sidebar layout handling - Pull Request #78 - VaperinaDEV/fkb-pro-theme - GitHub

2 curtidas

Ah, é aqui – obrigado! Hm, deve ter sido acionado por acidente? Ou foi desativado quando abri isso no celular? Vou fazer alguns experimentos e retorno com o resultado.

1 curtida

É, não vai renderizar no mobile.

É, claro.

Eu estava pensando que era possível que tivesse sido desativado para mim no desktop quando eu lia nosso fórum no celular. Mas acabei de fazer esse teste e o painel não foi desativado. Então é um mistério como meu painel foi desativado no desktop — devo ter clicado acidentalmente na seta de desativar.

1 curtida

Oi, Don! Estou adorando o tema FKB Pro.

Pequeno pedido: seria possível adicionar uma configuração para exibir vários avatares de participantes nos cartões de tópico, em vez de apenas o do último post?

O avatar único fica muito limpo, mas mostrar vários participantes realmente destaca o quão ativa é uma discussão. Um alternador (toggle) para isso seria incrível!

Obrigado pelo seu ótimo trabalho! Leo

Olá @Don, fiz uma pequena modificação pessoal no tema FKB pro para adicionar um botão flutuante de chat no canto inferior direito para tablet e desktop, e no canto inferior esquerdo no mobile, com o mesmo efeito no botão de criar tópico. Acho que existe algo melhor em código, mas isso funciona :rofl:

aqui está meu código de componente: css


// 1. BOTÃO FLUTUANTE PRINCIPAL 
.header-dropdown-toggle.chat-header-icon {
    position: fixed !important;
    bottom: 60px !important;
    right: 20px !important;
    z-index: 9999 !important;
    
    /* Dimensões perfeitas (círculo) */
    width: 60px !important;
    height: 60px !important;
    min-width: 60px !important;
    min-height: 60px !important;
    border-radius: 50% !important;
    
    /* Cor azul vibrante e sombra colorida */
    background: #0084ff !important;
    box-shadow: 0 4px 14px rgba(0, 132, 255, 0.4), 0 2px 4px rgba(0, 0, 0, 0.1) !important;
    
    /* Limpeza das margens */
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    padding: 0 !important;
    margin: 0 !important;
    border: none !important;
    
    /* Transição suave */
    transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275), opacity 0.3s ease, box-shadow 0.2s ease !important;
}

/* Posição específica no Mobile (Telas <= 640px) */
@media (max-width: 640px) {
    .header-dropdown-toggle.chat-header-icon {
        bottom: 80px !important; 
        left: 20px !important;   /* Mude para right: 20px se preferir colocá-lo à direita novamente */
    }
}

/* Efeito ao passar o mouse (ampliação leve) */
.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. LIMPEZA DO FUNDO CINZA NATIVO DO 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. CENTRAGEM PERFEITA DO ÍCONE (A bolha)                  */

.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. BADGE DE NOTIFICAÇÃO (Contador verde + Número visível) */

.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; 
    
    /* Cor verde forçada */
    background-color: #53A548 !important;  
    background: #53A548 !important;
    color: #ffffff !important;
    
    /* Tipografia forçada para tornar o número visível */
    font-size: 13px !important;
    font-weight: bold !important;
    line-height: 18px !important;
    letter-spacing: normal !important;
    text-indent: 0 !important;
    
    /* Dimensões e forma */
    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;
    
    /* Centralização do número */
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    white-space: nowrap !important;
    overflow: visible !important;
    
    /* Animação Pulse Verde (ligada aos seus keyframes) */
    animation: badge-pulse 2s infinite !important; 
}

/* Força todos os elementos filhos (se o Discourse envolver o número em um span) a serem exibidos */
.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. ANIMAÇÕES CORRIGIDAS (Efeito Radar & Quicada)            */


/* 5.1 - A onda de radar (pulso) ao redor do badge vermelho */
.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 - O efeito de quicada no botão azul inteiro quando há uma mensagem */
.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;
}

/* --- DEFINIÇÃO DOS KEYFRAMES (Não modificar) --- */

/* Definição da onda: usamos apenas o box-shadow para evitar bugs de exibição */
@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);
    }
}

/* Definição da quicada: o botão salta levemente a cada 3 segundos */
@keyframes chat-bounce {
    0%, 20%, 50%, 80%, 100% { 
        transform: translateY(0); 
    }
    40% { 
        transform: translateY(-6px); 
    }
    60% { 
        transform: translateY(-3px); 
    }
}

/* 6. PULSAÇÃO NA LISTA DE CANAIS E MENSAGENS PRIVADAS  */


/* 6.1 - Permitimos o estouro nos contêineres de lista */
.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 - Estilo e margens do ponto indicador */
.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; /* Espaço para não colar no texto e na data */
}

/* 6.3 - Animação ajustada (onda mais compacta de no máximo 6px) */
@keyframes list-dot-pulse {
    0% {
        box-shadow: 0 0 0 0 rgba(0, 132, 255, 0.7); /* Adapta-se à cor do ponto */
    }
    70% {
        box-shadow: 0 0 0 6px rgba(0, 132, 255, 0); /* Raio reduzido para permanecer na linha */
    }
    100% {
        box-shadow: 0 0 0 0 rgba(0, 132, 255, 0);
    }
}

e o JS:

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

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

    // 1. Manipulador de scroll (Ativo APENAS no mobile)
    window.addEventListener("scroll", () => {
        const isMobile = window.innerWidth <= 640;
        const floatBtn = document.querySelector('.header-dropdown-toggle.chat-header-icon');

        if (!floatBtn) return;

        // Se estivermos no computador, garantimos que o botão permaneça sempre visível
        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;

        // Se estivermos rolando para baixo (e tivermos passado de 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;
            }
        } 
        // Se estivermos rolando para cima
        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 para gerenciar a exibição base
    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');
                
                // Gerenciamento limpo da posição mobile / desktop
                if (isMobile) {
                    floatBtn.style.setProperty('left', '10px', 'important'); // Mude o valor se quiser deslocar mais
                    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 });
});