Funciona tanto en móvil como en escritorio como se esperaba, pero también causa que la lista de temas no se actualice después de hacer clic en la alerta de nuevo tema/respuesta.
Tengo una grabación de pantalla de cómo reproducir este error.
En el video, estaba mirando la vista móvil en mi escritorio y creando una nueva respuesta a ‘test new topic alert 3’ desde mi teléfono celular, luego hago clic en la alerta en el escritorio, en el caso normal, el tema impulsado debería aparecer en la parte superior de los temas, pero no lo hace en este caso.
Pensé que el método que usé anteriormente se activaba por error, pero no se llama al hacer clic en una alerta de tema.
¿Alguien tiene alguna sugerencia sobre por qué ocurrió este error? Muchas gracias.
Actualización: Descubrí que también causa que la carga automática de más temas al desplazarse ya no funcione en la vista móvil.
¿Si quitas el código anterior que no muestra a los usuarios ignorados, se soluciona el problema? Si se soluciona, supongo que tu código está filtrando los temas de todos los usuarios (o de más usuarios de los que debería), lo que hace que no se muestren.
No sé de dónde se rellena ignored, pero podría rellenarse con el nombre de usuario del usuario que creó el nuevo tema que mostró la alerta en la parte superior. ¿Quizás se está rellenando con usuarios que no deberían ser ignorados? ¿Puedes registrar los valores presentes en ignored?
Creo que no es el caso ya que este problema solo ocurrió en la vista móvil/móvil. (no se impulsó y no se puede cargar más)
Establecí manualmente const ignored = ['david', 'pekka_gaiser', 'sam']; para probar en el sitio del creador de temas, ya que supuse que aún no había alcanzado el nivel de confianza que puede usar la función de ignorar o que estaba deshabilitada.
No, el error desaparece si cambio el bloque a lo que proporcionas. Pensé que tal vez la función de filtro rompía el ciclo de actualización de los datos del tema, pero este error solo ocurre en dispositivos móviles, no puedo entender qué causa la diferencia entre el escritorio y el móvil…
Entonces, lo único que se me ocurre es que la variable ignored se está poblando incorrectamente, como dije anteriormente. Quizás en otro lugar se esté cambiando el valor. Intenta cambiar el código a:
En el código anterior, he puesto la variable ignored en el mismo ámbito en el que se está aplicando el filtro, y he cambiado el nombre de la variable para evitar cambios no intencionados en los valores de la matriz (por ejemplo, si algún lugar llama a ignored.push(...), podría cambiar sus valores en otro lugar).
Estás redefiniendo esa propiedad a otra cosa. Esto está bien si nada más está observando esa propiedad, pero en este caso, varias cosas están observando el array topics.
Por ejemplo
Si haces esto en una instalación de desarrollo, Ember lanzará errores en la consola como estos.
Así que esto debería decirte algo. El array topics se está utilizando en muchos lugares diferentes. Por lo tanto, no es una buena idea manipularlo, especialmente porque tu caso de uso es principalmente visual y no hay implicaciones de seguridad involucradas.
Aquí tienes lo que sugiero: da un paso atrás y prueba un enfoque diferente. En lugar de intentar modificar el array, haz algo mucho más simple. Si un usuario ignorado creó el tema, agrega una clase CSS y ocúltalo con CSS.
Lo haces con algo como esto: dejé algunos comentarios si quieres seguirlo, pero puedes eliminarlos cuando estés listo para usarlo.
Esto va en el archivo inicializador:
import { apiInitializer } from "discourse/lib/api";
import discourseComputed from "discourse-common/utils/decorators";
export default apiInitializer("0.11.1", api => {
// establece un id para tus modificaciones
const PLUGIN_ID = "hide-ignored-op-topics";
// El nombre de la clase que quieres añadir. El espacio al principio es obligatorio
const IGNORED_TOPIC_CLASS_STRING = " ignored-op-topic";
// obtener el usuario actual
const user = api.getCurrentUser();
// no está conectado, sal
if (!user) {
return;
}
// obtener una lista de usuarios ignorados
const ignored = user.ignored_users;
// función auxiliar para evitar duplicar código
const addIgnoredTopicClass = context => {
// obtener clases del núcleo / otros plugins y temas
let classList = context._super(...arguments);
// crea tu condición
const shouldAddClass = ignored.includes(
context.topic.posters[0].user.username
);
// añade la clase ignorada si la condición es verdadera
if (shouldAddClass) {
classList += IGNORED_TOPIC_CLASS_STRING;
}
// devuelve la lista de clases más las modificaciones si las hay
return classList;
};
// añade la clase a la lista de temas predeterminada, como en la página "latest"
api.modifyClass("component:topic-list-item", {
pluginId: PLUGIN_ID,
@discourseComputed()
unboundClassNames() {
return addIgnoredTopicClass(this);
}
});
// haz lo mismo para la lista de temas de la página de categorías
api.modifyClass("component:latest-topic-list-item", {
pluginId: PLUGIN_ID,
@discourseComputed()
unboundClassNames() {
return addIgnoredTopicClass(this);
}
});
});
y esto va en /common/common.css
// no usamos display: none; aquí porque no queremos interferir con load-more
.ignored-op-topic {
height: 0;
width: 0;
position: fixed;
bottom: 0;
}
¿Es posible añadir una clase adicional al elemento hijo del componente?
Por ejemplo, me gustaría ocultar el avatar del usuario ignorado en la lista de avatares de escritorio en el lado derecho del título del tema, ¿al añadir una clase al elemento de la lista de temas, se podrá añadir una clase al componente del avatar?
El método unboundClassNames() que usamos anteriormente es responsable de las clases añadidas al elemento del componente. En otras palabras, los elementos HTML .topic-list-item o .latest-topic-list-item. Puedes verlo aquí
y aquí
Ember toma cualquier cadena que devuelva ese método y la añade como el atributo class en el propio elemento.
Tendrás que usar algo más si quieres añadir clases a los hijos de ese elemento.
Cada publicador en la propiedad posters tiene una propiedad llamada extras. Esta propiedad se utiliza como un indicador para clases adicionales que se añadirán al avatar cuando se renderice.
Se establece aquí
y se consume aquí
Por lo tanto, puedes añadir clases a los avatares en la lista de temas basándote en una condición si extiendes esa propiedad.
Puedes usar el decorador @on cuando el componente reciba sus atributos para llamar a un método que haga eso. Dado que ya estamos modificando esas Clases de componente, podemos incorporar ese nuevo comportamiento al código anterior.
Esto te dará una clase CSS ignored-op-topic en los elementos de la lista de temas iniciados por un usuario ignorado y una clase CSS ignored-user-avatar en cada avatar de usuario ignorado en la columna de publicadores.
Ya tenemos el CSS para .ignored-op-topic de arriba.
// no usamos display: none; aquí porque no queremos interferir con load-more
.ignored-op-topic {
height: 0;
width: 0;
position: fixed;
bottom: 0;
}
Ahora, quieres ocultar los avatares de los usuarios ignorados en la columna de publicadores.
No hagas eso. Esto creará mucha confusión.
¿Qué pasa si un usuario ignorado responde a un tema, y este se actualiza, pero tienes su avatar oculto? Parecerá que alguien más ha actualizado el tema.
Además, solo hay un avatar en la página de categorías junto a los títulos de los temas. ¿Qué pasa si la última respuesta es de un usuario ignorado? ¿Sin avatar?
Puedes ver cómo tales casos crearían una experiencia desagradable para tus usuarios.
En lugar de ocultar los avatares de los usuarios ignorados, puedes sustituirlos por un icono SVG. Todos los usuarios ignorados tendrán el mismo avatar. Puedes hacerlo con CSS
y lo mismo en latest-topic-list-item. Cambia el SVG por cualquier icono que quieras usar.
Con eso fuera de camino…
Respondí a tu pregunta porque es una buena oportunidad para hablar sobre la personalización de la lista de temas y cómo lo harías. Sin embargo, tengo muchas reservas sobre tu caso de uso. La necesidad de ocultar los avatares de los usuarios ignorados indica un problema subyacente. Una cosa es decir
“esta persona escribe sobre temas que no me interesan. La ignoraré para reducir el ruido.”
pero es algo completamente diferente decir
“incluso ver el avatar de esta persona me provoca una respuesta emocional. Nunca más quiero volver a ver su avatar.”
Conoces tu comunidad más que nadie… pero probablemente sea algo que valga la pena investigar.
Entendido. Estaba tratando de imitar la función de bloqueo como Mastodon o Twitter tanto como fuera posible, de esa manera, cuando ignoras a un usuario, nunca volverás a ver contenido de él. Estoy de acuerdo en que la mayoría de las comunidades pueden no necesitar este tipo de función. Ya que mis usuarios lo están pidiendo, me gustaría hacer mi mejor esfuerzo.