Décorez un sujet sur les dernières nouveautés mobiles

Je travaille sur un composant de thème pour bloquer les publications qui contiennent un mot-clé présent dans un champ utilisateur personnalisé. J’ai réussi à masquer les réponses ainsi que les sujets lorsqu’ils sont listés dans les plus récents ou les meilleurs en vue de bureau, mais lorsqu’ils sont consultés dans l’application ou sur mobile, cela ajoute la notification que le sujet a été bloqué, mais n’applique pas la classe bloquée au contenu. Le blocage des réponses au sein d’un sujet fonctionne très bien sur mobile ou dans l’application.

En examinant les composants, il ne semblait pas qu’un fichier .hbs différent était utilisé pour le mobile, est-ce que je manque quelque chose d’autre ?

const discourseComputed = require("discourse-common/utils/decorators").default;

function addIgnoredTopicClass() {
    if (currentUser) {
        api.container.lookup('store:main').find('user', currentUser.username).then((user) => {
            const blocklist = user.user_fields[1];
            const case_sensitive = user.user_fields[2];
            const whole_words = user.user_fields[3];
    
            const blocked = blocklist.split(",").map(function(item) {
                if (case_sensitive) {
                    return item.trim();
                } else {
                    return item.trim().toLowerCase();
                }
            });
            let classList = this._super(...arguments);
            let elem = document.querySelectorAll("[data-topic-id='" + this.topic.id.toString() + "']")[0];
            console.log(elem);
            const title = (case_sensitive) ? this.topic.fancy_title : this.topic.fancy_title.toLowerCase();
            const excerpt = (case_sensitive) ? this.topic.excerpt : this.topic.excerpt.toLowerCase();
            let result = "";
            
            for (let index = 0; index < blocked.length; ++index) {
                    let pattern = (whole_words) ? new RegExp('(?:\\b|\\s|^)' + blocked[index] + '(?:\\b|\\s|$)') : new RegExp(blocked[index]);
                    // console.log(pattern)
                    if (pattern.test(title)) {
                        classList += "blocker-blocked"
                        const found = blocked.filter(text => title.includes(text));
                        if (found.length >= 2) {
                            const last = found.pop();
                            result = found.join(', ') + ' and ' + last;
                        } else {
                            result = found.join(', ');
                        }
                        const newNode = document.createElement("a");
                        const textNode = document.createTextNode("Blocked for containing " + result + ".");
                        newNode.classList.add("block-notice")
                        newNode.appendChild(textNode);
                        newNode.onclick = function() { showComment(this); };
                        elem.children[0].insertBefore(newNode, elem.children[0].children[0]);
                        for (let index = 0; index < elem.children.length; ++index) {
                            if (elem.children[index].classList.contains('main-link')) {
                                elem.children[index].classList.add("blocker-blocked");
                            }
                        }
                        newNode.classList.remove("blocker-blocked");
                    }
                }
            
            // console.log(classList);
            return classList;
        });
    }
}

api.modifyClass("component:topic-list-item", {
    @discourseComputed()
    unboundClassNames() {
        return addIgnoredTopicClass.call(this);
    }
});
    
api.modifyClass("component:latest-topic-list-item", {
    
    @discourseComputed()
    unboundClassNames() {
        return addIgnoredTopicClass.call(this);
    }
});

Ou du moins, je pensais que cela fonctionnait. Je suis allé travailler sur autre chose pendant un moment et maintenant cela ne fonctionne plus :thinking: Peut-être que j’ai ce problème avec api.modifyClass ?

Par curiosité, en quoi cela diffère-t-il de la fonctionnalité intégrée Mots surveillés ?

1 « J'aime »

Autant que je sache, les Mots Surveillés (Watched Words) sont un paramètre d’administrateur qui s’applique à tous les utilisateurs, n’est-ce pas ? Ce que j’essaie de faire, c’est de permettre aux utilisateurs d’avoir leur propre filtre de mots surveillés qui peut masquer les publications qui respectent les règles du forum, mais que l’utilisateur pourrait ne pas vouloir voir pour ses propres raisons.

Faux scénario : un forum sur les animaux de compagnie pourrait avoir un fil de discussion général sur la façon de gérer les poils d’animaux où le sujet principal n’est pas étiqueté avec un type d’animal spécifique. L’utilisateur A répond à propos de son chien, l’utilisateur B répond à propos de son chat, mais l’utilisateur A ne veut rien voir à propos des chats. Ce composant de thème permet à l’utilisateur A de mettre « chat » dans sa liste de blocage, et ensuite partout où « chat » apparaît dans un sujet ou une réponse, il est remplacé par « Bloqué car contient des chats » avec un clic pour afficher quand même.

Il est destiné aux choses qui sont dans le sujet et respectent les règles générales du forum, mais qui pourraient ne pas être étiquetées ou apparaître dans les réponses d’un fil de discussion étiqueté avec quelque chose que l’utilisateur A veut voir. Le forum que je suis en train de migrer utilisait un petit script utilisateur de navigateur pour analyser la page après le chargement, et l’une des attractions de Discourse était la possibilité d’intégrer la fonction de blocage directement afin qu’elle fonctionne aussi sur mobile (le script utilisateur que nous utilisions ne fonctionne pas sur les navigateurs mobiles). Cela réduit les signalements et les arguments sur ce qui appartient aux fils de discussion généraux si les utilisateurs peuvent simplement décider qu’ils ne veulent pas voir X sans que cela constitue une violation des règles.

Je ne pense pas que je publierai cela comme un composant de thème approprié car cela nécessite la création de trois champs utilisateur dans le panneau d’administration (ce qui nécessiterait un plugin pour être créé automatiquement ?). Je suis sur un plan d’hébergement de base ici et je ne touche pas aux plugins, mais je peux publier le code du composant de thème terminé et les paramètres des champs utilisateur une fois que j’aurai terminé.

4 « J'aime »

Cela semble génial. :slight_smile: Je peux penser à quelques forums qui trouveraient cela utile.

3 « J'aime »

Ouais, je vois le potentiel. Pour même utiliser une version modifiée pour étendre la fonction de mise en sourdine de l’utilisateur. Comme j’ai un utilisateur qui se plaint :man_facepalming: qu’il peut toujours voir les réponses des autres aux personnes qu’il a mises en sourdine. lol

Beaucoup de potentiel intéressant. Je garderai un œil sur votre projet.
:vulcan_salute::smiling_face_with_sunglasses::+1:

1 « J'aime »

Comment puis-je déterminer où se situe le problème ? En utilisant le mode mobile via les outils de développement Chrome, cela fonctionne correctement, mais sur Chrome sur un téléphone réel et dans l’application Android, cela ne fonctionne pas. En utilisant le composant de thème Plugin Outlets, il ne semble pas y avoir de sortie pertinente car j’essaie de modifier un élément de liste de sujets lui-même.

Désolé si c’est une question basique, c’est la première fois que je travaille avec Ember.

1 « J'aime »

J’ai réussi à faire fonctionner cela sur mobile et je posterai sur Theme component une fois que j’aurai été approuvé pour rejoindre. Le problème sur mobile était que j’ajoutais une classe à l’élément enfant de topic-list qui avait une classe “main-link”, mais sur mobile, cet élément enfant main-link est quelques étapes plus bas dans la hiérarchie que sur ordinateur.

1 « J'aime »