Is there an event that fires when topic-lists are reloaded?

Excuse the butchered terminology :sunflower:


I’m trying to use masonry in combination with the topic list previews plugin to create a grid topic list like so:

When new items are added to a masonry grid or the topic-list in this case the current items need to be “reshuffled” and resized in some sense so that everything fits.

Masonry handles that with a native function or .layout() which recalculates the grid and arranges the items when called.

In order to make masonry aware of new items or topics being added to the topic list, I would like to trigger .layout() when this is clicked:

So here’s the question.

Is there a native Discourse event that fires when the the link to reload the topic list is clicked that I can bind masonry to?

3 Likes

Maybe you could use jQuery ajaxComplete ?

http://api.jquery.com/ajaxcomplete/

5 Likes

Another way is to add an observer in the topic-list component that observes topics.[] and re-runs masonry after render. i.e. something like:

withPluginApi(0.8.16, () api => {
  api.modifyClass('component:topic-list', {
     masonryObserver: function() {
        // update masonry here, probably wrapped in Ember.run.scheduleOnce('afterRender', () => {})
     }.observes('topics.[]')
  })
})
4 Likes

YES! :grin::champagne::boom:

That was amazingly helpful @Mittineague

thank you so much!

I ended up using:

$(document).ajaxComplete(function() {
	$(".topic-list").imagesLoaded(function() {
		$(".topic-list")
			.masonry("reloadItems")
			.masonry();
	});
});

and I would have stopped right there, however @angus was kind enough to provide what I believe is a more orthodox / targeted method for doing this in the context of Discourse here:


This feels like the right way to go about this, thank you so much @angus :grin::champagne:

I’m not sure how to go about this part:

probably wrapped in Ember.run.scheduleOnce('afterRender', () => {})

But will read further about Ember Voodoo and try again. :sweat_smile:

For now here’s what I ended up with based on your generous help and my basic understanding:

<script type="text/discourse-plugin" version="0.8.16">
    api.modifyClass("component:topic-list", {
	    masonryObserver: function() {
	    	$(".topic-list").imagesLoaded(function() {
		    	$(".topic-list")
			    	.masonry("reloadItems")
			    	.masonry();
	    	});
    	}.observes("topics.[]")
    });
</script>

And here’s the result:

https://giant.gfycat.com/FeistyFormalBoa.webm

Thank you so much :heart:

9 Likes

I’ve been messing with TLP and CSS to try and create a similar effect … but kept coming up against the limitation of the table layout (particularly the row alignment restriction). The use of masonry is great!

Are you able to share the complete inventory of changes for this look, @Johani?

Thanks!

Masonry theme has been deprecated in favor of Tiles Image Gallery.
You should be able to see the changes here https://meta.discourse.org/t/deprecated-discourse-masonry-gallery-theme-component/79076 and here https://github.com/hnb-ku/discourse-masonry-gallery

1 Like

This is a lot more than the images gallery (love that too, though, btw) This is an alternative for the topic list feed, no? Is there a public repository for what’s shown here?

I think the key thing here is that TLP uses a table, just like vanilla discourse, … so looks like I just have to modify topic-list-item and topic-list :slight_smile: :

<tbody>
  {{#each filteredTopics as |topic|}}
    {{topic-list-item topic=topic
<SNIP>
                      tagsForUser=tagsForUser}}
    {{raw "list/visited-line" lastVisitedTopic=lastVisitedTopic topic=topic}}
  {{/each}}
</tbody>

etc.

masonry uses css grid presumably, which uses div tags … so I’m going with the assumption these were altered to use div tags … having a go myself but all pointers appreciated! (but I did find this guide which is very handy!)

OK I’ve reached a bit of an impasse:

I’ve edited both

  • topic-list.hbs: (added to TLP plug-in so I can change tbody to div)
{{#if socialStyle}}
<div class='grid'>
  {{#each filteredTopics as |topic|}}
    {{topic-list-item topic=topic
                      bulkSelectEnabled=bulkSelectEnabled

and:

  • topic-list-item.raw.hbs (taken from TLP plug-in but edited)
{{#if socialStyle}}
<div class='grid-item'>
    {{raw "list/topic-list-title" topic=topic socialStyle=socialStyle showTopicPostBadges=showTopicPostBadges}}
    {{#if showThumbnail}}
      {{raw "list/topic-thumbnail" topic=topic thumbnails=thumbnails category=category}}
      {{/if}}

But I still end up with a <tr> tag being added between them and can’t see where it’s being generated?:

Could this be being added by the javascript in topic-list-item.js.es6? Most definitely.

Attempting to overwrite with this in the initialiser:

api.modifyClass('component:topic-list-item', {
  tagName: 'div'
});

So I now have this working …