How to target only globally pinned topics via CSS

I want to target only globally pinned topics via CSS in topic lists. Unfortunately, the <tr> for the list items have only the pinned class, not a globally_pinned class.

Anybody?

If you want to add a CSS class to topics that have been globally pinned, you can try something like this in the header tab of your theme / component

<script type="text/discourse-plugin" version="0.8">
api.modifyClass("component:topic-list-item", {
  didInsertElement() {
    this._super(...arguments);

    const topic = this.topic;

    if (topic.pinned && topic.pinned_globally) {
      // change global-pin to any class you prefer
      this.element.classList.add("global-pin");
    }
  }
});
</script>

This should add a global-pin class to those topics which you can then target with CSS like so

.global-pin {
  background:red;
}
2 Likes

Hi @joe

That worked, at least for the initial view of the page. However, if I scroll down on the latest page until more topics are loaded and then scroll up again, the classes that have been added to the initial elements via classList.add are all gone (or respectively are not reapplied again).

It seems the initially loaded topics in the topics lists are somehow overwritten in the dom, once more topics are loaded when you scroll down.

Any idea of how to mitigate this problem?

Hey :wave:

I can’t reproduce the issue you described. The class is added and persists even when you scroll up and down the topic list. I think the issue might be that the topic got unpinned for you. To confirm, take a look at the pin icon to the left of the topic title. Is it facing up or down?

The snippet above has two conditions. First, the topic must be pinned for you, second the topic must be pinned globally. If you read to the end of the topic, it will be unpinned for you and so the class won’t be added. It will still be be pinned and globally pinned for others who have not finished reading the topic - and they’ll see whatever styles you applied to that class.

This is intentional to avoid adding too much emphasis in the topic list for globally pinned topics that you already read. Otherwise you get something like this

where globally pinned topics that are unpinned for you are still styled differently in the middle of the list. If you still want to do that. All you need to do is remove topic.pinned from the conditional above, but I wouldn’t recommend it.

1 Like

Beg my pardon @Johani. The issue is slightly different. Works for pins, but I also used your code to add a play symbol based on tags for topic thumbnails, the code is basically the same:

<script type="text/discourse-plugin" version="0.8">
api.modifyClass("component:topic-list-item", {
  didInsertElement() {
    this._super(...arguments);

    const topic = this.topic;
    
    if (Array.isArray(topic.thumbnails) && topic.thumbnails.length && Array.isArray(topic.tags) && topic.tags.length && topic.tags.includes("video")) {
        this.element.classList.add("play-symbol");
    }
    
  }
});
</script>

But the issue is the same, on first page view the class is added for topics that are tagged with “video”, when I scroll down until more nodes are loaded and scroll up again the class is gone from the upper topics tagged with “video”.

It’s even more weird, the classes disappear only after 2x more topics nodes have been loaded, not the first time when new nodes are loaded.

@Johani here is a video of what is going on:

2 Likes

No worries, thanks for the video :+1:

Can you post a link to the site you’re having trouble with so I can take a quick look?

1 Like

Unfortunately, I’m still unable to reproduce the issue you’re facing - even when logged in.

I added a small console.log in your conditional and it works constantly for me. It logs “class added” every time the conditions you set are met.

The class also persists if I scroll back up after more topics load at the bottom.

That’s strange, I just checked on two more computers, one Mac and one Linux. It happens on all. I even tried different users with TL0 and no group assigned. Always the classes are taken away from the first ones loaded, not from the ones loaded after the first one, just from the inital ones.

But I found a workaround, the whole code might not be needed as “tag-video” is available in the class list, and I can use it for the play-symbol, instead of adding another class altogether. Anyways thanks for your help!

3 Likes

This topic was automatically closed after 38 hours. New replies are no longer allowed.