Decora un argomento nelle ultime novità su mobile

Sto lavorando su un componente del tema per bloccare i post che contengono una parola chiave contenuta in un campo utente personalizzato. Ci sono riuscito a nascondere le risposte e gli argomenti quando elencati in “ultimi” o “migliori” nella visualizzazione desktop, ma quando visualizzati nell’app o su dispositivi mobili, aggiungerà l’avviso che l’argomento è stato bloccato, ma non applicherà la classe “blocked” al contenuto. Il blocco delle risposte all’interno di un argomento funziona bene su mobile o sull’app.

Dando un’occhiata a components, non sembrava che venisse utilizzato un file .hbs diverso per il mobile, mi sto perdendo qualcos’altro?

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);
    }
});

O almeno, pensavo di averlo fatto funzionare. Sono andato a lavorare su qualcos’altro per un po’ e ora non funziona più :thinking: Forse ho questo problema con api.modifyClass?

Per curiosità, in cosa differisce dalla funzionalità integrata Parole monitorate?

1 Mi Piace

Per quanto ne so, Watched Words è un’impostazione amministrativa che si applica a tutti gli utenti, corretto? Quello che sto cercando di fare è consentire agli utenti di avere essenzialmente il proprio filtro per le parole monitorate che possa escludere post che rientrano nelle regole del forum, ma che l’utente potrebbe non voler vedere per ragioni proprie.

Scenario fittizio: un forum sugli animali domestici potrebbe avere una discussione generale su come affrontare il pelo degli animali, dove l’argomento principale non è etichettato con un tipo specifico di animale. L’utente A risponde riguardo al proprio cane, l’utente B risponde riguardo al proprio gatto, ma l’utente A non vuole vedere nulla riguardo ai gatti. Quello che fa questo componente del tema è permettere all’utente A di inserire “gatto” nella propria lista di blocco, e poi ovunque “gatto” appaia in un argomento o in una risposta, lo sostituisce con “Bloccato perché contiene gatti” con un clic per mostrarlo comunque.

È pensato per cose che sono pertinenti e rientrano nelle regole generali del forum, ma che potrebbero non essere etichettate o apparire nelle risposte di un thread etichettato con qualcosa che l’utente A desidera vedere. Il forum da cui sto migrando utilizzava un piccolo userscript del browser per scansionare la pagina dopo il caricamento, e una delle attrattive di Discourse era la possibilità di integrare la funzione di blocco direttamente in modo che funzioni anche su mobile (lo userscript che stavamo usando non funziona sui browser mobili). Riduce le segnalazioni e le discussioni su ciò che appartiene ai thread generali se gli utenti possono semplicemente decidere di non voler vedere X senza che ciò costituisca una violazione delle regole.

Non credo che pubblicherò questo come un vero componente del tema perché richiede la creazione di tre campi utente nel pannello di amministrazione (che credo richiederebbe un plugin per essere creato automaticamente?). Sono su un piano ospitato di base qui e quindi non sto armeggiando con i plugin, ma posso pubblicare il codice finito del componente del tema e le impostazioni dei campi utente quando avrò finito.

4 Mi Piace

Sembra fantastico. :slight_smile: Posso pensare a un paio di forum che lo troverebbero utile.

3 Mi Piace

Sì, vedo il potenziale. Per persino usare una versione modificata per estendere la funzione di silenziamento utente. Dato che ho un singolo utente che si lamenta :man_facepalming: che può ancora vedere le risposte di altre persone a persone che ha silenziato. lol

Un sacco di potenziale interessante. Terrò d’occhio il tuo progetto.
:vulcan_salute::smiling_face_with_sunglasses::+1:

1 Mi Piace

Come potrei fare per capire dov’è il problema? Usando la modalità mobile tramite gli strumenti per sviluppatori di Chrome, funziona correttamente, ma su Chrome su un telefono effettivo e nell’app Android non funziona. Usando il componente tema Plugin Outlets, non sembra esserci un outlet pertinente poiché sto cercando di modificare all’interno di un topic-list-item stesso.

Mi scuso se questa è una domanda elementare, è la prima volta che lavoro con Ember.

1 Mi Piace

Sono riuscito a farlo funzionare su mobile e pubblicherò su Theme component una volta che mi sarà approvato l’accesso. Il problema su mobile era che stavo aggiungendo una classe all’elemento figlio di topic-list che aveva una classe “main-link”, ma su mobile quell’elemento figlio main-link si trova qualche livello più in basso nella gerarchia rispetto al desktop.

1 Mi Piace