Modal de pré-visualização de tópico

Instalar este componente de tema

Modal de Pré-visualização de Tópicos – abra e interaja com tópicos sem sair da lista de tópicos

Criei um novo componente de tema do Discourse chamado Topic Preview Modal.

A ideia é bastante simples:

Abra um tópico diretamente da lista de tópicos em um modal nativo do Discourse, leia e interaja com o tópico e, em seguida, continue navegando pela lista sem sair dela.

Começou a partir de Facebook-style Topic Modal - Is it better? , mas acabou exigindo uma integração considerável com os sistemas de tópico, fluxo de posts, compositor, modal, marcador de posição, roteamento, presença, rastreamento de leitura e pré-busca do Discourse.


Por quê?

O fluxo normal do Discourse é:

  1. Você está navegando por uma lista de tópicos.
  2. Você clica em um tópico.
  3. O Discourse navega para /t/....
  4. Você lê/responde/interage com o tópico.
  5. Você volta para a lista de tópicos.

Para muitos fluxos de trabalho, isso é perfeitamente aceitável.

No entanto, ao navegar por uma lista de tópicos movimentada, às vezes eu só quero inspecionar rapidamente um tópico, ler alguns posts, verificar as últimas respostas, reagir a algo ou responder a uma pergunta rápida.

Para esse caso de uso, sair da lista de tópicos parece desnecessariamente custoso.

O objetivo deste componente foi, portanto, fazer com que a lista de tópicos se comportasse mais como uma caixa de entrada:

lista de tópicos → pré-visualização → interação → fechar → continuar exatamente de onde parou.


O que ele faz

A pré-visualização não é apenas um excerto estático.

Ela renderiza os componentes de post reais do Discourse dentro de um DModal nativo.

Isso significa que os usuários podem:

  • ler posts
  • rolar pelo tópico
  • carregar posts anteriores
  • carregar mais posts abaixo
  • reagir a posts
  • marcar posts com marcador de posição (bookmark)
  • citar texto
  • responder ao tópico
  • responder a posts individuais
  • editar posts quando permitido
  • excluir/recuperar posts quando permitido
  • sinalizar (flag) posts
  • ver o histórico do post
  • realizar várias ações normais de post
  • ver a presença no tópico
  • seguir links para outros posts dentro do mesmo tópico
  • pular diretamente para o post relevante
  • abrir o tópico completo quando necessário

A intenção é que a pré-visualização se sinta o mais próxima possível da abertura real do tópico.


Dois modos de acionamento

Há duas formas de abrir a pré-visualização.

1. Linha inteira da lista de tópicos

Este é o padrão.

A linha inteira da lista de tópicos se torna clicável, enquanto elementos interativos comuns, como:

  • cartões de usuário
  • participantes
  • links de categoria
  • tags
  • links de status do tópico
  • seleção em massa

são excluídos do acionamento do modal.

Isso torna a experiência muito rápida ao navegar por uma lista de tópicos.

2. Botão de expansão explícito

Alternativamente, o componente pode renderizar um pequeno ícone de expansão por meio de uma saída de plugin (plugin outlet) do Discourse. Temas personalizados podem simplesmente criar uma nova <PluginOutlet /> para mostrar o acionador.

Neste modo, o comportamento normal da lista de tópicos permanece completamente intacto.

O usuário clica no ícone de expansão para abrir a pré-visualização, enquanto clicar no título do tópico ainda executa a navegação normal do Discourse.

Isso é útil se um site quiser preservar o modelo de interação padrão da lista de tópicos.

A configuração é:

trigger_style:
  row

ou:

trigger_style:
  button

Ao usar o modo de botão, a saída (outlet) também é configurável.


A pré-visualização começa na posição não lida do usuário

Um dos detalhes importantes é que o modal não carrega simplesmente o primeiro post.

Quando um tópico já foi parcialmente lido, a pré-visualização calcula:

last_read_post_number + 1

e abre em torno desse post.

Portanto, se um tópico tem 200 posts e o usuário leu até o post #165, a abertura da pré-visualização começa em torno do #166.

Isso torna a pré-visualização muito mais útil para a navegação do mundo real.

Isso também significa que o componente precisa lidar com ambos os lados do fluxo de posts:

  • carregar posts anteriores quando necessário
  • carregar posts mais novos abaixo

O botão Posts anteriores é exibido quando há posts acima do intervalo atualmente carregado, enquanto um sentinela IntersectionObserver carrega automaticamente mais posts quando o usuário atinge o fundo.


Pré-busca (Prefetching)

Uma das maiores partes do componente é seu sistema de pré-busca.

O problema com um modal como este é que o usuário espera que ele se sinta instantâneo.

Se começarmos a carregar o tópico apenas após o usuário clicar, o modal ainda pode gastar tempo perceptível esperando pela rede.

Em vez disso, o componente pode pré-buscar tópicos proativamente enquanto o usuário navega pela lista.

Quando uma linha de tópico se aproxima da área de visualização (viewport), um IntersectionObserver pode agendar uma pré-busca.

Há várias salvaguardas para impedir que isso se torne tráfego de fundo descontrolado.

Debounce (Atraso)

Um tópico não dispara imediatamente uma solicitação apenas porque apareceu brevemente na área de visualização.

O componente espera pelo período de debounce configurado.

Padrão:

400 ms

Isso é particularmente útil ao rolar rapidamente por uma longa lista de tópicos.

Margem da raiz (Root margin)

A pré-busca pode começar um pouco antes que o tópico entre realmente na área de visualização.

Padrão:

50 px

Isso dá à solicitação uma pequena vantagem.

Limite de solicitações simultâneas

O número de pré-buscas simultâneas é limitado.

Padrão:

2

A configuração permite entre 1 e 6 pré-buscas simultâneas.

Orçamento por minuto

Há também um segundo mecanismo de proteção:

max_prefetches_per_minute

O padrão é:

15

Portanto, mesmo que o usuário continue rolando por centenas de tópicos, o componente não gerará continuamente solicitações especulativas.

0 desativa o limite.

A pré-busca pode ser desativada completamente

Se um site não quiser nenhum tráfego de rede especulativo:

enable_prefetch = false

O componente continua a funcionar normalmente. Os tópicos simplesmente carregam quando a pré-visualização é aberta.


Os dados de pré-busca são mantidos separados da navegação normal de tópicos

Há um importante detalhe de implementação aqui.

A resposta pré-buscada não é escrita imediatamente na chave de pré-carregamento normal topic_<id> do Discourse.

Em vez disso, o componente usa seu próprio namespace:

topic-preview-modal:prefetch:<topicId>

Apenas quando o usuário realmente abre a pré-visualização, a promessa (promise) pré-buscada é promovida para a chave de pré-carregamento do tópico principal.

Isso é intencional.

A pré-visualização pode estar carregando um tópico começando de last_read_post_number + 1, e não quero que essa resposta específica da pré-visualização vaze para uma navegação de rota de tópico normal.

Portanto, o ciclo de vida é essencialmente:

tópico entra na área de visualização
        ↓
pré-busca
        ↓
armazenamento de pré-carregamento privado
        ↓
usúário abre a pré-visualização
        ↓
promover pré-carregamento
        ↓
Topic.find()/PostStream usa a mesma promessa

Isso também significa que o modal não precisa esperar a solicitação de pré-busca terminar antes de abrir.

O modal pode abrir imediatamente com seu esqueleto (skeleton) enquanto a mesma promessa continua se resolvendo.


Suporte a dispositivos móveis

Na verdade, esta foi uma das razões pelas quais gastei consideravelmente mais tempo na implementação.

A ideia inicial funcionava razoavelmente bem no desktop, mas o mobile expôs vários problemas em torno de:

  • interação por toque
  • rolagem do modal
  • foco
  • menus aninhados
  • o compositor
  • visibilidade de posts
  • carregamento de imagens
  • desempenho

A implementação final, portanto, evita tratar o modal como um fórum miniatura completamente separado.

Em vez disso, ele reutiliza o máximo possível da infraestrutura existente do Discourse.


Componentes de post reais do Discourse

O modal não recria posts usando um modelo personalizado simplificado.

Ele renderiza os componentes reais do Discourse:

Post
PostSmallAction

Isso é importante, pois, caso contrário, a pré-visualização se tornaria rapidamente uma segunda implementação da interface de post.

O componente passa as ações relevantes para os componentes de post normais, incluindo coisas como:

  • responder
  • editar
  • excluir
  • recuperar
  • sinalizar (flag)
  • histórico
  • marcador de posição (bookmark)
  • wiki
  • bloquear/desbloquear
  • tipo de post
  • mudanças de propriedade
  • badges
  • posts ocultos
  • citação
  • etc.

O resultado é que a pré-visualização pode se comportar muito mais como um tópico normal do que um componente de “pré-visualização” tradicional.


Respostas e o compositor

O compositor é uma das partes mais complicadas.

A pré-visualização pode abrir o compositor normal do Discourse para:

Responder ao tópico

O compositor do tópico é aberto com o modelo do tópico e as informações de rascunho corretas.

Responder a um post específico

O post é passado para o compositor para que a resposta se comporte como uma resposta de post normal.

Citar texto selecionado

O componente também se integra ao PostTextSelection.

Isso significa que os usuários podem selecionar texto dentro da pré-visualização e usar o fluxo normal de citação/resposta do Discourse.


Modais aninhados

Outra parte complicada foi o sistema de modais do Discourse.

Posts podem abrir outros modais e diálogos:

  • sinalização (flagging)
  • histórico
  • diálogos relacionados a badges
  • mudanças de propriedade
  • confirmações de exclusão
  • etc.

Se esses fossem permitidos a interagir normalmente com o serviço global de modais, a abertura de um deles poderia fechar toda a pré-visualização do tópico.

Para evitar isso, o componente cria um mecanismo de sub-modal local.

Conceitualmente:

Modal de Pré-visualização de Tópico
        │
        ├── Modal de Sinalização
        ├── Modal de Histórico
        ├── Confirmação de Exclusão
        ├── Modal de Badge
        └── outro modal relacionado a post

A pré-visualização permanece montada (mounted) abaixo.

O componente aplica temporariamente patches (patches) nos métodos relevantes do serviço de modal enquanto está ativo e os restaura quando é destruído.


Roteamento dentro do modal

Outro detalhe importante são os links para posts dentro do mesmo tópico.

Por exemplo, se um post contiver um link para:

/t/my-topic/123

a pré-visualização não precisa fechar e navegar para fora.

Em vez disso, o componente intercepta a navegação do mesmo tópico e pula para o post solicitado dentro do modal.

O mesmo se aplica a links que apontam para o tópico sem um número de post específico.

Isso mantém o usuário dentro da pré-visualização.

Se o link apontar para um tópico genuinamente diferente, o componente primeiro restaura seus patches temporários de serviço e se fecha antes de permitir a transição de rota normal do Discourse.

Essa limpeza é importante, pois, caso contrário, as assinaturas e o rastreador de tempo da pré-visualização poderiam permanecer ativos enquanto a rota real do tópico está sendo inicializada.


Rastreamento de leitura e rastreamento de tempo

Também quis que a pré-visualização se comportasse corretamente do ponto de vista do Discourse.

Abrir uma pré-visualização não deve significar que o rastreamento de leitura é completamente ignorado.

O componente, portanto, lida com:

  • rastreamento de visitas ao tópico
  • rastreamento de posts visíveis
  • tempo do tópico
  • atualizações do último post lido

O rastreador de tempo usa um IntersectionObserver para determinar quais posts estão realmente visíveis.

A cada 5 segundos, o tempo de posts visíveis é enviado (flushed) para:

/topics/timings

Quando o modal fecha, um envio final é realizado para que os últimos segundos não sejam perdidos.

A implementação também limita um único intervalo de tempo a 60 segundos.


Mantendo o estado não lido da lista de tópicos sincronizado

Havia outro problema sutil aqui.

Atualizar apenas o estado de rastreamento de tópicos do Discourse não é suficiente para atualizar o distintivo de não lidos exibido diretamente em uma linha da lista de tópicos.

O componente, portanto, atualiza o objeto de tópico real associado à linha após as informações de tempo terem sido enviadas.

Ele atualiza valores como:

last_read_post_number
unread_posts
unread
new_posts

quando apropriado.

Isso significa que, após ler um tópico dentro do modal, a lista de tópicos pode refletir imediatamente o novo estado de leitura, em vez de exigir uma atualização completa da página.


Visibilidade de posts

A pré-visualização usa um IntersectionObserver compartilhado para determinar quando posts individuais se tornam visíveis.

Também há uma verificação de visibilidade síncrona quando o observador é anexado.

Isso lida com um caso extremo em que um post já está visível quando é montado, mas o primeiro callback assíncrono do IntersectionObserver ainda não foi disparado.

Isso é especialmente relevante para tópicos muito curtos, onde o tópico inteiro pode já estar visível quando o modal abre.


Considerações de desempenho

Um objetivo principal foi evitar transformar o modal em uma página de tópico miniatura pesada em desempenho.

Algumas coisas são feitas especificamente para isso.

Renderização progressiva

O carregamento inicial não renderiza imediatamente todos os posts.

O componente primeiro renderiza posts suficientes para alcançar a posição alvo.

Os posts restantes são então renderizados progressivamente usando:

requestIdleCallback

quando disponível, com um fallback para setTimeout.

Isso é particularmente útil ao abrir um tópico longo em torno de um post muito abaixo no fluxo.

Contenção CSS

Os posts usam:

contain: layout;
content-visibility: auto;
contain-intrinsic-size: 1px 180px;

Isso permite que o navegador evite fazer trabalho de renderização desnecessário para posts que não estão atualmente visíveis.

Imagens preguiçosas (Lazy images)

Imagens que ainda não especificaram um modo de carregamento recebem automaticamente:

loading="lazy"
decoding="async"

Isso impede que um tópico longo com muitas imagens carregue tudo imediatamente.


Estado de carregamento

O modal não mostra apenas uma área branca/vazia enquanto a solicitação está sendo feita.

Ele tem uma interface de esqueleto (skeleton UI) com:

  • placeholders de avatar
  • placeholders de nome de usuário/nome
  • placeholders de corpo do post
  • animação shimmer

O shimmer respeita:

prefers-reduced-motion

para que a animação seja desativada para usuários que solicitaram movimento reduzido.


Mantendo a posição de rolagem estável

Há alguns lugares onde o componente precisa manipular a posição de rolagem manualmente.

Por exemplo, ao carregar posts anteriores, o conteúdo recém-inserido aumenta a altura de rolagem.

Simplesmente adicionar os posts no início faria com que a posição atual do usuário saltasse.

O componente, portanto, registra a altura de rolagem anterior e compensa a diferença após a inserção dos posts.

Isso mantém o conteúdo atualmente visível aproximadamente no mesmo lugar.

O mesmo se aplica ao pular para um post específico.

O componente executa uma etapa de posicionamento pós-renderização e verifica a posição novamente em quadros subsequentes para levar em conta o conteúdo que ainda pode estar se assentando.


Presença no tópico

Quando os dados relevantes do tópico estão disponíveis, a pré-visualização também pode exibir as informações de presença do tópico do Discourse na parte inferior do modal.

Assim, os usuários podem ver quem mais está atualmente visualizando o tópico sem precisar sair da pré-visualização.


Interação com menus móveis e foco

O mobile introduziu outra categoria de problemas.

Alguns elementos de interface do Discourse usam serviços compartilhados de modal/menu, e esses serviços nem sempre sabem que a pré-visualização do tópico está atualmente atuando como um contexto de navegação aninhado.

O componente, portanto, tem tratamento adicional em torno de:

  • modal.close()
  • menus do Float Kit
  • restauração de foco
  • o compositor
  • controles de teclado do lightbox
  • bloqueios de rolagem do corpo (body scroll locks)

Por exemplo, se um menu tentar internamente chamar o método de fechamento global do modal, isso não deve acidentalmente fechar toda a pré-visualização do tópico.

Da mesma forma, quando o compositor está aberto, o foco precisa permanecer dentro do compositor, em vez de ser puxado de volta para o contexto de foco da pré-visualização.


Configuração

O componente atualmente expõe as seguintes configurações:

Configuração Padrão Descrição
trigger_style row Tornar a linha inteira clicável ou usar um botão explícito
plugin_outlet topic-list-after-title Saída (outlet) usada pelo acionador de botão
enable_prefetch true Ativar/desativar pré-busca de tópicos em segundo plano
max_concurrent_prefetches 2 Número máximo de solicitações de pré-busca simultâneas
prefetch_debounce_ms 400 Atraso antes de iniciar uma pré-busca
prefetch_root_margin_px 50 Iniciar a pré-busca este número de pixels antes que a linha entre na área de visualização
max_prefetches_per_minute 15 Número máximo de solicitações especulativas por minuto

Os controles de pré-busca são intencionalmente configuráveis porque comunidades diferentes podem ter padrões de tráfego e características de hospedagem/rede muito diferentes.


Um dos principais objetivos de design: não quebrar o Discourse normal

Tentei manter o componente o mais próximo possível da arquitetura existente do Discourse.

Ele não implementa seu próprio renderizador de posts, seu próprio compositor, seu próprio modelo de tópico ou seu próprio fluxo de posts completamente separado.

Em vez disso, ele constrói um contexto de navegação temporário em torno dos componentes e serviços existentes do Discourse.

É por isso que algumas partes da implementação são mais complicadas do que podem parecer inicialmente.

O desafio mais interessante foi:

Um tópico pode se comportar quase como um tópico normal do Discourse enquanto está sendo exibido dentro de outro contexto de interface?

Isso exigiu lidar com as fronteiras entre os serviços globais do Discourse e a pré-visualização local.

18 curtidas

Para sua informação:

Ele tem problemas com matemática. Mas isso pode ser outro caso extremo, embora.

1 curtida

Absoluto lendário :slight_smile: agora preciso descobrir como fazer isso funcionar com minha configuração :slight_smile: @awesomerobot de que depende o seu tema para o clique na linha inteira

api.renderInOutlet("topic-list-before-link", TopicListItemClick);
2 curtidas

Para quem usa o tema Reddit-ish, aqui está uma correção que funcionou para mim.

Compatibilidade com o tema Reddit-ish

Apenas um aviso para quem usa o tema Reddit-ish: o botão do modal funciona, mas o gatilho de linha padrão não.

O problema é que o Reddit-ish substitui o comportamento padrão da linha da lista de tópicos e trata cliques em todo o cartão do tópico. Por isso, o tratamento normal de clique na linha do modal não funciona como esperado.

Alterar a configuração do Modal de Pré-visualização do Tópico para:

Estilo de gatilho: botão
Saída do plugin: topic-list-after-title

funciona corretamente, porque o Reddit-ish já inclui a saída topic-list-after-title.

Para manter o comportamento de clique em todo o cartão, deixei o Modal de Pré-visualização do Tópico no modo botão e alterei a ação openTopic() existente do Reddit-ish para que ela acione o botão funcional do modal.

A ação original do Reddit-ish é:

@action
openTopic(event) {
  if (
    (event.target.nodeName === "A" && !event.target.closest(".raw-link")) ||
    event.target.closest(".badge-wrapper")
  ) {
    return;
  }

  const { navigateToTopic, topic } = this.args.outletArgs;

  if (wantsNewWindow(event)) {
    window.open(topic.lastUnreadUrl, "_blank");
  } else {
    navigateToTopic(topic, topic.lastUnreadUrl);
  }
}

Eu a alterei para:

@action
openTopic(event) {
  if (
    (event.target.nodeName === "A" && !event.target.closest(".raw-link")) ||
    event.target.closest(".badge-wrapper") ||
    event.target.closest(".topic-preview-modal__trigger-wrapper")
  ) {
    return;
  }

  const { navigateToTopic, topic } = this.args.outletArgs;

  if (wantsNewWindow(event)) {
    window.open(topic.lastUnreadUrl, "_blank");
    return;
  }

  const previewButton = event.currentTarget.querySelector(
    ".topic-preview-modal__trigger-wrapper--button"
  );

  if (previewButton) {
    event.preventDefault();
    event.stopPropagation();
    previewButton.click();
    return;
  }

  navigateToTopic(topic, topic.lastUnreadUrl);
}

O gatilho do botão do modal é renderizado como:

<div class="topic-preview-modal__trigger-wrapper">
  <span
    role="button"
    class="topic-preview-modal__trigger-wrapper--button"
  >

Portanto, isso não recria nenhuma lógica do modal. Ele simplesmente faz com que o clique no cartão do Reddit-ish acione o botão de pré-visualização existente e funcional.

O resultado é:

  • O clique no cartão do tópico abre o modal de pré-visualização.

  • O clique no título do tópico abre o modal de pré-visualização.

  • O botão de pré-visualização continua funcionando.

  • O clique com Cmd/Ctrl ainda abre o tópico normal em uma nova aba.

  • A categoria e outros links normais continuam se comportando normalmente.

  • Se o botão de pré-visualização não estiver presente, o Reddit-ish volta à navegação de tópicos normal.

Portanto, o modal subjacente funciona bem com o Reddit-ish; a incompatibilidade é especificamente com o gatilho de linha padrão.

Eu também escondi o botão usando

.topic-preview-modal__trigger-wrapper {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
}
3 curtidas

Agora, vamos tentar fazer as respostas aninhadas funcionarem no modal :slight_smile:

1 curtida

Você, meu amigo, é incrível. Este deve ser o componente de tema mais fantástico que vi há muito tempo.

A única coisa que sinto falta é uma largura maior / configurável, seria bom se pudéssemos torná-lo da mesma largura que as publicações na visualização do tópico.

2 curtidas

Ajustei a largura máxima para 800px

    .d-modal {
        --modal-max-width: 600px;
        --modal-width: 30em;
        --modal-min-width: 400px;
    }
1 curtida

Isso se aplicaria a todos os modais…
Fiz isso também para que o ícone se destacasse menos

.topic-preview-modal__trigger-wrapper--button .d-icon {
    fill: #888;
}

@media (width >= 40rem) {
  .d-modal.topic-preview-modal {
      --modal-max-width: 800px;
  }
}
2 curtidas

@Don Estou curioso: por que você não reutilizou o componente <PostList> do core?

1 curtida

Olá @Jagster, obrigado pelo relatório! Aqui está a correção: FIX: Replace visibility:hidden to allow MathJax rendering · VaperinaDEV/discourse-topic-preview-modal@f9eb70f · GitHub


Obrigado @RGJ, adicionei uma configuração para isso.


Essa é uma boa pergunta.

PostList/PostListItem foi projetado para listas de resumo baseadas em trechos (rascunhos, favoritos, feeds de atividade), não para renderizar o fluxo de posts interativo real de um tópico.

Ele renderiza @post.excerpt/expandedExcerpt através de DDecoratedHtml, além de um cabeçalho com avatar/título e um botão para expandir para o trecho. Não há ações de curtir, citar, responder, editar ou denunciar — nenhuma das funcionalidades interativas de post que o modal precisa.

A paginação do PostList também é unidirecional (fetchMorePosts apenas adiciona posts seguindo para baixo), enquanto o modal precisa abrir no último post lido e carregar posts anteriores e posteriores ao redor dele — isso exige o carregamento por intervalos do serviço real postStream, não apenas um callback simples de “carregar mais”.

Portanto, reutilizar PostList significaria reimplementar a maior parte do comportamento interativo de Post e o carregamento bidirecional do postStream em cima de um componente projetado para uma função diferente. Usar o componente real Post do núcleo + postStream diretamente garante que o modal se comporte de forma idêntica à página real do tópico.

3 curtidas

Consegui fazer isso funcionar com views aninhadas, precisa de mais testes e provavelmente adicionar uma opção no admin. Algumas pessoas estão usando isso, Don, e isso faz as pessoas requisitarem mais e permanecerem no site por mais tempo, já que é tão fluido e fácil de rolar, etc. Você fez um trabalho incrível com isso

4 curtidas

Testando agora! Melhoria muito impressionante na interface do usuário

2 curtidas

Precisamos desesperadamente de reforços aqui, mas com esse tempo de resposta estou um pouco preocupado agora — vocês estão vivos? :laughing:

Obrigado :sign_of_the_horns:

3 curtidas

Dúvida: por que o border-top do .topic-avatar acaba aparecendo como um separador entre a parte da postagem anterior que permanece visível durante o scrolling e o início da postagem atual? A intenção desse border-top é realmente essa, ou existe alguma regra de posicionamento/overflow fazendo com que ele tenha esse comportamento?

@media (width >= 40rem) {
    .topic-avatar {
        border-top: 1px solid var(--content-border-color);
        padding-top: var(--space-4);
        width: var(--topic-avatar-width);
        float: left;
        z-index: 2;
        height: 100%;
        overflow-anchor: none;
    }
}
1 curtida

Acho que isso poderia ser muito útil para revisar rapidamente as postagens quando você não quer esperar pelo carregamento completo da página. Adoraria se houvesse uma opção para que os cliques nas notificações abrissem o modal em vez da lista de tópicos.

1 curtida

Olá @Don, depois de brincar com este componente incrível por 24 horas, uma coisa que adorei foi deslizar para baixo para fechar, pois percebi que não precisava mover o polegar e a mão, e parecia muito fácil de usar o site. No entanto, em tópicos mais longos, rolar de volta para cima não era a melhor opção.

Para combater isso, adicionei um deslize para a direita para fechar no celular. Isso faz muito sentido e, para quem quer rolagem rápida etc., funciona maravilhosamente, na minha opinião. O que você acha?

O link para testar é https://www.carptalk-online.co.uk/ e, obviamente, só funciona no celular.

3 curtidas

Testei seu fórum, Damian, e essa ação de deslizar é realmente perfeita. Bom trabalho, como sempre!

Me pergunto se esse componente de tema deveria funcionar no Horizon? Tentei em duas versões e ele exibe um erro para os administradores no topo. Parece não ser compatível?

Espero que funcione; eu realmente gosto dessa nova perspectiva para explorar.

2 curtidas

Qual é o erro que você está recebendo?

2 curtidas

Olá :waving_hand:

Adicionei uma nova configuração chamada: open_all_topic_links.

Quando ativada, QUALQUER link que aponte para um tópico em qualquer parte da página (conteúdo da postagem, notificações, cartão do usuário, resultados de busca, tópicos sugeridos/relacionados, barra lateral, etc.) abre o modal de pré-visualização em vez de navegar para outra página - e não apenas as linhas da lista de tópicos. Um link para uma postagem específica abre o modal rolado até essa postagem. Os links dentro da lista de tópicos e dentro de um modal de pré-visualização já aberto mantêm seu comportamento atual.

5 curtidas

Você é o GOAT dos modais :slight_smile: há alguma chance de adicionar o gesto de deslizar para a direita para fechar no mobile ao core e de incluir suporte a views aninhadas :eyes:

2 curtidas