Cambiar las páginas de grupo predeterminadas a /mensajes

Hola,

Al acceder a grupos desde la página /g, ¿hay alguna forma de que la URL del grupo a la que apunta sea /g/group-slug/messages en lugar de /g/group-slug/members?

Tenemos varios grupos que se utilizan para mensajes grupales. Sería útil dar a las personas un clic menos para llegar a los mensajes de su grupo. Esto es más importante para nosotros que la vista de los miembros del grupo.

Sé que puedo hacerlo mediante un enlace directo, pero quiero que sea desde la página /g?type=my, que es útilmente dinámica y centrada en el usuario.

4 Me gusta

No son enlaces normales. Se manejan con un componente Ember link-to y hay algo de enrutamiento involucrado.

La forma más fácil de hacerlo es secuestrar el clic en ese elemento y hacer tu trabajo allí. Esto va en el common > header de un 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`;

         // actualiza el título del navegador y maneja la nueva pestaña
         groupLink.href = newHref;

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

Si el usuario es miembro del grupo y el grupo tiene mensajes, redirigirá a la bandeja de entrada. De lo contrario, volverá a la página predeterminada /members.

7 Me gusta

¡Vaya, es increíble! Funciona de maravilla. Gracias.


más tarde…

Tengo un problema de seguimiento con el que necesito un poco de ayuda, ¡lo siento!

Varios de mis grupos todavía muestran /g/group-slug/messages a pesar de no tener ninguno.
\u003e

Tras una inspección más detallada, han tenido mensajes en el pasado, que se han convertido en Temas o se han eliminado. Data Explorer revela que estos grupos tienen True en has_messages en la tabla Groups.

He intentado cambiarlo para estos grupos a través de Rails, pero no parece que pueda lograrlo:
\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

¿Alguna sugerencia aparte de eliminar los grupos y volver a crearlos (lo cual no me entusiasma mucho)?

3 Me gusta

Solo necesitas ejecutar esta línea en la consola de Rails. Debería actualizar todos los grupos.

Group.refresh_has_messages!
1 me gusta

Eso funcionó para todos menos para dos. ¡Gracias! ¡Esos dos últimos molestos creo que tendré que eliminarlos y rehacerlos!

Al hacer esto, descubrí la razón, que es un Bug menor.

Al convertir mensajes privados de grupo en temas, se conserva la información del invitado. Si bien esto es bueno si el tema se convierte de nuevo, significa que se cuentan erróneamente cuando se ejecuta Group.refresh_has_messages!.

2 Me gusta

¿Es posible también secuestrar los enlaces que obtienes cuando haces clic en un grupo @mencionado y luego haces clic para ir al grupo? Creo que esas son las únicas dos formas de acceder a los grupos sin recurrir a las URL.

Lo que busco ahora (¿soy codicioso?) es que todos los enlaces a los grupos se comporten de la misma manera que tu código hace que los de la página /g lo hagan.

1 me gusta

@Johani, ¿es esto factible? He echado un vistazo y claramente está muy por encima de mis capacidades.

Claro, puedes probar algo como esto en la pestaña de encabezado de tu tema/componente. Dejé algunos comentarios en el fragmento si quieres seguirlo. Puedes eliminarlos una vez que estés listo para usarlo.

Se aplican las mismas reglas. Si el usuario es miembro del grupo y el grupo tiene mensajes, Discourse navegará a la bandeja de entrada del grupo. De lo contrario, el usuario aterrizará en el directorio de miembros.

<script type="text/discourse-plugin" version="0.8">
  // Parte 1: modifica la ruta de los enlaces en las tarjetas de grupo. Esto asegura que el título del enlace
  // refleje a dónde conduce y maneje la apertura del enlace en una nueva pestaña.
  const discourseComputed = require("discourse-common/utils/decorators").default;
  
  api.modifyClass("component:group-card-contents", {
    // La propiedad groupPath se utiliza para generar el href para los enlaces de grupo
    // en la tarjeta de grupo. Vamos a modificarla
    @discourseComputed("group")
    groupPath(group) {
      // obtén el valor predeterminado del núcleo
      let groupURL = this._super(...arguments);

      // si el usuario coincide con nuestro requisito, modifica la url para que vaya a la bandeja de entrada
      if (group.is_group_user && group.has_messages) {
        groupURL = `${groupURL}/messages/`;
      }

      // devuelve el valor predeterminado o modificado
      return groupURL;
    }
  });

  // Parte 2: modifica el enrutamiento dentro de la aplicación. Esto asegura que la navegación normal dentro de la aplicación
  // se maneje correctamente y lleve al usuario a la bandeja de entrada del grupo si cumple los
  // 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 aquí es una acción que pertenece al controlador user-card. 
    // Esto es lo que se llama cuando haces clic en el nombre/avatar del grupo dentro de las tarjetas de grupo
    @action
    showGroup(group) {
      // llama a super para asegurarte de que el código del núcleo se cargue primero
      this._super(...arguments);

      // group path es una función de ayuda de url de Discourse incorporada
      let groupURL = groupPath(group.name);

      // si el usuario cumple los requisitos, modifica la url
      if (group.is_group_user && group.has_messages) {
        groupURL = `${groupURL}/messages/`;
      }

      // llama a routeTo() con la url de grupo predeterminada o modificada 
      DiscourseURL.routeTo(groupURL);
    }
  });
</script>
2 Me gusta

¡Eres increíble! Funciona muy bien para cualquier caso que use las tarjetas.

Ahora hay un tipo de enlace que permanece sin dirección: el del grupo cuando está en un Mensaje Privado de Grupo. Esto es realmente útil para navegar al grupo (y, por lo tanto, a la bandeja de entrada) desde un Mensaje de Grupo.

¿Crees que podemos capturar eso también en la red?

(Por cierto, empaquetaré esto en un TC y haré un tema al respecto una vez que terminemos para que sea muy accesible para otros)

2 Me gusta

Esos enlaces utilizan un serializador ligeramente diferente, ya que no se necesitan todos los datos del grupo allí.

Aún así, puedes almacenar una lista filtrada de los grupos del usuario actual en la vista inicial de la página y utilizarlos como referencia para verificar la membresía. Esta información ya está disponible en la carga útil inicial, por lo que no hay sobrecarga en términos de solicitudes adicionales ni nada parecido. Algo como esto:

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

Mantén este fragmento en sus propias etiquetas de script y agrégalo al encabezado junto con los otros fragmentos. Lo mantienes separado porque realiza una salida rápida si el usuario no ha iniciado sesión.

1 me gusta

:partying_face: ¡Hemos llegado! Funciona de maravilla, también en el móvil.

Gracias Joe por tu increíble persistencia. Mejor cumpliré mi parte del trato y me pondré a trabajar en ese Theme component, ¿eh?

más tarde…
Aquí está:

1 me gusta

Tengo una cosa más con la que necesito ayuda para completar esto. Es un poco descarado pedirlo, lo sé.

Ahora estoy intentando modificar Pavilion para que también pueda admitir este comportamiento, utilizando la lógica simple de tus tres fragmentos geniales. Sin embargo, no puedo hacerlo funcionar debido a mi ineptitud con javascript. Esto es lo que estoy intentando 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`);
  },
});

¿Cómo aplico la parte de abajo a eso? He intentado todo lo que se me ocurrió en el último click(){etc} pero he fallado. Simplemente termino rompiendo el enlace por completo.

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

¡Olvídalo! @keegan lo ha solucionado:

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

Para algunos grupos donde hay ‘fantasmas de mensajes’, esto no funciona. Estos grupos se pueden identificar con esta consulta (siempre que se hayan restringido los mensajes en la configuración de interacción del 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

Puedes hacer un hack en la tabla groups para forzar que esto se restablezca también (en la consola de Rails, por supuesto, ¡haz una copia de seguridad primero!).

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

Si esto no funciona o se revierte, también podrías necesitar limpiar las tablas topic_groups y topic_allowed_groups:

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

Este tema se cerró automáticamente después de 30 días. Ya no se permiten nuevas respuestas.