Alterar as páginas de grupo padrão para /mensagens

Olá,

Ao acessar grupos da página /g, existe uma maneira de fazer com que o URL do grupo aponte para /g/group-slug/messages em vez de /g/group-slug/members?

Temos vários grupos que são usados para mensagens em grupo. Seria útil dar às pessoas um clique a menos para chegar às mensagens de seu grupo. Isso é mais importante para nós do que a visualização dos membros do grupo.

Eu sei que posso fazer isso com um link direto, mas quero que seja a partir da página /g?type=my, que é dinamicamente e centrada no usuário.

4 curtidas

Eles não são links regulares. Eles são tratados com um componente Ember link-to, e há um pouco de roteamento envolvido.

A maneira mais fácil de fazer isso é sequestrar o clique nesse elemento e fazer seu trabalho lá. Isso vai em common > header de um tema

<script
  type="text/x-handlebars"
  data-template-name="/connectors/group-index-box-after/link-to-group-inbox"></script>

<script type="text/discourse-plugin" version="0.8">
  const DiscourseURL = require("discourse/lib/url").default;
  api.registerConnectorClass('group-index-box-after', 'link-to-group-inbox', {
    setupComponent(args) {
      const group = args.model;

       if (group.is_group_user && group.has_messages) {
         const groupLink = document.querySelector(`.group-box.${group.name}`);
         const newHref = `/g/${group.name}/messages`;

         // atualiza o título do navegador e lida com nova aba
         groupLink.href = newHref;

         // redireciona o link
         groupLink.addEventListener("click", (event) => {
            DiscourseURL.routeTo(newHref);
            event.preventDefault();
         }, {once: true})
       }
     }
  });
</script>

Se o usuário for membro do grupo e o grupo tiver mensagens, ele redirecionará para a caixa de entrada. Caso contrário, ele voltará para a página padrão /members.

7 curtidas

Uau - isso é incrível!!! Funciona perfeitamente. Obrigado.


mais tarde…

Tenho um problema de acompanhamento com o qual preciso de um pouco de ajuda, desculpe!

Vários dos meus grupos ainda exibem /g/group-slug/messages, apesar de não terem nenhum.
\u003e

Em uma inspeção mais detalhada, eles tiveram mensagens no passado, que foram convertidas em Tópicos ou excluídas. O Data Explorer revela que esses grupos têm True em has_messages na tabela Groups.

Tentei alterá-lo para esses grupos via Rails, mas não consigo alcançar:
\u003e[2] pry(main)\u003e Group.find_by_name("group-slug").has_messages
=\u003e true
[3] pry(main)\u003e Group.find_by_name("group-slug").has_messages = false
=\u003e false
[4] pry(main)\u003e Group.find_by_name("group-slug").has_messages
=\u003e true

Alguma sugestão além de excluir os grupos e recriá-los (o que não estou muito animado para fazer)?

3 curtidas

Você só precisa executar esta linha no console do Rails. Ela deve atualizar todos os grupos.

Group.refresh_has_messages!
1 curtida

Isso funcionou para todos, exceto dois - obrigado. Esses dois últimos, que são chatos, acho que terei que excluir e recriar!

Ao fazer isso, descobri o motivo - que é um pequeno Bug.

Ao converter Mensagens Privadas de Grupo em Tópicos, as informações do convidado são retidas. Embora isso seja bom se o Tópico for convertido de volta, isso significa que eles são contados erroneamente quando Group.refresh_has_messages! é executado.

2 curtidas

É possível também sequestrar os links que você recebe ao clicar em um grupo @mencionado e depois clicar para ir ao grupo? Acho que essas são as únicas duas maneiras de acessar grupos sem recorrer a URLs.

O que estou buscando agora (ganancioso, não é?) é, na verdade, fazer com que todos os links para os grupos se comportem da mesma forma que seu código faz com os da página /g.

1 curtida

@Johani, isso é factível? Dei uma olhada e está claramente acima das minhas capacidades.

Claro, você pode tentar algo como isto na aba de cabeçalho do seu tema/componente. Deixei alguns comentários no trecho se você quiser acompanhar. Você pode excluí-los quando estiver pronto para usá-lo.

As mesmas regras se aplicam. Se o usuário for membro do grupo e o grupo tiver mensagens, o Discourse navegará para a caixa de entrada do grupo. Caso contrário, o usuário acessará o diretório de membros.

<script type="text/discourse-plugin" version="0.8">
  // Parte 1: modificar o caminho para os links nos cartões de grupo. Isso garante que o título do link
  // reflita para onde ele leva e lida com a abertura do link em uma nova aba.
  const discourseComputed = require("discourse-common/utils/decorators").default;

  api.modifyClass("component:group-card-contents", {
    // A propriedade groupPath é usada para gerar o href para os links de grupo
    // no cartão de grupo. Vamos modificá-la
    @discourseComputed("group")
    groupPath(group) {
      // obtém o valor padrão do núcleo
      let groupURL = this._super(...arguments);

      // se o usuário corresponder ao nosso requisito, modifica a url para que ela vá para a caixa de entrada
      if (group.is_group_user && group.has_messages) {
        groupURL = `${groupURL}/messages/`;
      }

      // retorna o valor padrão ou modificado
      return groupURL;
    }
  });

  // Parte 2: modificar o roteamento dentro do aplicativo. Isso garante que a navegação normal dentro do aplicativo
  // seja tratada corretamente e leve o usuário para a caixa de entrada do grupo se ele atender aos
  // requisitos

  const DiscourseURL = require("discourse/lib/url").default;
  const { groupPath } = require("discourse/lib/url");
  const { action } = require("@ember/object");

  api.modifyClass("controller:user-card", {

    // showGroup aqui é uma ação que pertence ao controller user-card.
    // Isso é o que é chamado quando você clica no nome/avatar do grupo dentro dos cartões de grupo
    @action
    showGroup(group) {
      // chama super para garantir que o código do núcleo seja carregado primeiro
      this._super(...arguments);

      // group path é uma função auxiliar de url integrada do Discourse
      let groupURL = groupPath(group.name);

      // se o usuário corresponder aos requisitos, modifica a url
      if (group.is_group_user && group.has_messages) {
        groupURL = `${groupURL}/messages/`;
      }

      // chama routeTo() com a groupURL padrão ou modificada
      DiscourseURL.routeTo(groupURL);
    }
  });
</script>
2 curtidas

Você é incrível! Funciona muito bem para qualquer caso que use os cartões.

Agora existe um tipo de link que permanece sem direcionamento: o do grupo quando em uma Mensagem Privada de Grupo. Isso é realmente muito útil para navegar até o grupo (e, portanto, para a caixa de entrada) a partir de uma Mensagem de Grupo.

Podemos capturar isso na rede também, você acha?

(A propósito, vou empacotar isso em um TC e fazer um tópico para isso assim que terminarmos, para que seja muito acessível para outras pessoas)

2 curtidas

Esses links usam um serializador ligeiramente diferente - porque nem todos os dados do grupo são necessários lá.

Ainda assim, você pode armazenar uma lista filtrada dos grupos do usuário atual na visualização inicial da página e usá-los como referência para verificar a associação. Essas informações já estão disponíveis na carga útil inicial, portanto, não há sobrecarga em termos de solicitações extras ou algo assim. Algo como isto

<script type="text/discourse-plugin" version="0.8">
  const user = api.getCurrentUser();

  if (!user) {
    return;
  }

  const userGroups = user.groups.map(group => group.name);

  api.reopenWidget("pm-map-user-group", {
    transform(attrs) {

      const group = attrs.group;
      const isGroupUser = Object.values(userGroups).includes(group.name);

      // {href: "/g/foo"};
      let groupURL = this._super(...arguments);

      if (isGroupUser && group.has_messages) {
        groupURL.href = `${groupURL.href}/messages/`;
      }

      return groupURL;
    }
  });
</script>

Mantenha este trecho em suas próprias tags de script e adicione-o ao cabeçalho junto com os outros trechos. Você o mantém separado porque ele sai rapidamente se o usuário não estiver logado.

1 curtida

:partying_face: chegamos! Funciona muito bem, inclusive no celular.

Obrigado Joe pela sua incrível persistência. É melhor eu cumprir minha parte do acordo e começar a trabalhar naquele Theme component, né?

mais tarde…
Aqui está:

1 curtida

Tenho mais uma coisa com a qual preciso de ajuda para concluir isso. É um pouco atrevido pedir, eu sei.

Estou agora tentando modificar o Pavilion para que ele também possa suportar esse comportamento, usando a lógica simples dos seus três trechos incríveis. No entanto, não consigo fazer funcionar devido à minha inépcia com javascript. É isso que estou tentando modificar:

createWidget('layouts-group-link', {
  tagName: 'li.layouts-group-link',
  buildKey: (attrs) => `layouts-group-link-${attrs.id}`,

  getGroupTitle(group) {
    return h('span.group-title', group.name);
  },

  isOwner(group) {
    if (group.owner) {
      return h('span.group-owner-icon', iconNode('shield-alt'));
    }
  },

  html(attrs) {
    const contents = [this.getGroupTitle(attrs), this.isOwner(attrs)];
    return contents;
  },

  click() {
      DiscourseURL.routeTo(`/g/${this.attrs.name}/messages`);
  },
});

Como aplico o trecho abaixo a isso? Tentei tudo o que pude pensar na última parte click(){etc} mas falhei. Acabo quebrando o link completamente.

      if (group.is_group_user && group.has_messages) {
        groupURL = `${groupURL}/messages/`;
      }
1 curtida

Não se preocupe!!! O @keegan resolveu:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.

Para alguns grupos onde existem ‘fantasmas de mensagens’, isso não funciona. Esses grupos podem ser identificados por esta consulta (desde que a troca de mensagens tenha sido restrita nas configurações de interação do grupo):

SELECT id, name, has_messages, messageable_level
From groups
Where messageable_level < 10
AND messageable_level <> 3
AND has_messages = true
ORDER by id

Você pode fazer um “hack” na tabela groups para forçar a redefinição também (no console do Rails, é claro, faça backup primeiro!).

Group.where(id: XXX).update_all(has_messages: false)

Se isso não funcionar ou reverter, você também pode precisar limpar as tabelas topic_groups e topic_allowed_groups:

TopicGroup.where(group_id: XXX).destroy_all
TopicAllowedGroup.where(group_id: XXX).destroy_all

Este tópico foi fechado automaticamente após 30 dias. Novas respostas não são mais permitidas.