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.
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.
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)?
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!.
¿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.
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>
¡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.
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:
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.
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:
¿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/`;
}
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!).