ansonphong / postworld

Wordpress Theme Development Framework
GNU General Public License v2.0
7 stars 0 forks source link

ng-infinite-scroll with Multiple Parellel Feeds #53

Closed ansonphong closed 10 years ago

ansonphong commented 10 years ago

Hi Michel, The layout for many of the implementations for load-feed and live-feed will display two infinitely scrolling feeds in parallel columns.

I have run into an issue whereby I'm unable to make two parallel column feeds both execute getNext() effectively.

Here are the scenarios:


Scenario 1

image


Scenario 2

image


Scenario 3

image


What do you suggest to solve this?

michelhabib commented 10 years ago

I have tested this scenario of having 2 or 3 feeds, either live-feed or load-feed or a combination of them. the directives are designed with isolated scopes and should be completely independent. let me try to reproduce it and get back to you shortly.

michelhabib commented 10 years ago

Phong, i made 2 tests - let me share them with you - they are already placed on github in the latest commit.

First one, loading 2 live feeds in parallel. postworld\templates\samples\pwLiveFeed3Widget.html

<script>
    feed_settings['feed2009'] = {
        title: 'Feed of 2009',
        preload : 14,
        load_increment : 5,
        offset: 0,
        max_posts:100,
        view : {
            current : 'list',
            options : ['list','detail', 'grid','full']
        },
        feed_template: 'load_feed_2',   // Optional, needed in case of different widgets [having different panels for example] 
    };
    feed_settings['feed2012'] = {
        title: 'Feed of 2012',
        preload : 14,
        load_increment : 5,
        offset: 0,
        max_posts:100,
        view : {
            current : 'list',
            options : ['list','detail', 'grid','full']
        },
        feed_template: 'load_feed_2',   // Optional, needed in case of different widgets [having different panels for example] 
    };
</script>

<div class="row">
    <div class="col-md-6">
        <div load-feed='feed2009' ng-include="templateUrl"></div>
    </div>      
    <div class="col-md-6">
        <div load-feed='feed2012' ng-include="templateUrl"></div>
    </div>      
</div>

Where the feed template looks like this:- postworld\templates\panels\live_feed_2.html

<div>
    <div class="row" >
            <div class="form-group input-group col-md-12">      
                <h2>{{title}} </h2>
                <div ng-show="message" class="alert alert-warning">{{message}}</div>
            </div>
    </div>
    <div class="row" >
            <div class="form-group input-group col-md-12">      
                <div filter-feed="panel2" ng-include="templateUrl" feed-id="args.feed_id" feed_query="args.feed_query" submit="pwRestart()"></div>
            </div>
    </div>  
    <input type="hidden">   
    <div id="scrollMe"  class="infinite-scroll">
      <div infinite-scroll='getNext()' infinite-scroll-disabled='busy' infinite-scroll-parent>
        <div ng-repeat='post in items' >
            <div feed-item ng-include="templateUrl" post="post" feed-id='args.feed_id'></div>
            <hr>
          <div style='clear: both;'></div>
        </div>
        <div ng-show='busy' class="text-center"><img src="http://www.showoffimports.nl/sandbox/live/ajaxLoad.gif"></div>
        <div ng-show='!busy' class="text-center"><strong>{{scrollMessage}}</strong></div>
      </div>
    </div>
</div>

sicne i am using the search-results.php template, i am loading the widget using ngRoute/ngView, you will find it links for both routes in the menu. The results look like this screen shot. and can be seen here http://localhost/wordpress/search/#/live-feed-2-feeds/ 2livefeeds

michelhabib commented 10 years ago

for load feed, i used the same approach, the files are located at: postworld\templates\samples\pwLoadFeed3Widget.html

<script>
    feed_settings['feed2009'] = {
        title: 'Feed of 2009',
        preload : 14,
        load_increment : 5,
        offset: 0,
        max_posts:100,
        view : {
            current : 'list',
            options : ['list','detail', 'grid','full']
        },
        feed_template: 'load_feed_2',   // Optional, needed in case of different widgets [having different panels for example] 
    };
    feed_settings['feed2012'] = {
        title: 'Feed of 2012',
        preload : 14,
        load_increment : 5,
        offset: 0,
        max_posts:100,
        view : {
            current : 'list',
            options : ['list','detail', 'grid','full']
        },
        feed_template: 'load_feed_2',   // Optional, needed in case of different widgets [having different panels for example] 
    };
</script>

<div class="row">
    <div class="col-md-6">
        <div load-feed='feed2009' ng-include="templateUrl"></div>
    </div>      
    <div class="col-md-6">
        <div load-feed='feed2012' ng-include="templateUrl"></div>
    </div>      
</div>

and postworld\templates\panels\load_feed_1.html

<div>
    <h2>{{title}} </h2> 
    <div ng-show="message" class="alert alert-warning">{{message}}</div>

    <div id="scrollMe"  class="infinite-scroll">
      <div infinite-scroll='getNext()' infinite-scroll-disabled='busy' infinite-scroll-parent>
        <div ng-repeat='post in items' >
            <div feed-item ng-include="templateUrl" post="post" feed-id='args.feed_id'></div>
            <hr>
          <div style='clear: both;'></div>
        </div>
        <div ng-show='busy' class="text-center"><img src="http://www.showoffimports.nl/sandbox/live/ajaxLoad.gif"></div>
        <div ng-show='!busy' class="text-center"><strong>{{scrollMessage}}</strong></div>
      </div>
    </div>
</div>

Then i used the Feed Register Page http://localhost/wordpress/search/#/register-feed/ to registerd 2 feeds feed2009 and feed2012, just filtered with the year.

The output is shown here http://localhost/wordpress/search/#/load-feed-2-feeds/

this is a screenshot of the output 2loadfeeds

michelhabib commented 10 years ago

Looking at your samples, let me give that guess again, are you using the infinite scrolling styles?

.infinite-scroll {
    height: 400px;
    overflow-y: scroll;
}

This is actually crucial for allowing the scrolling to be triggered. because it forces the scrolling on the parent div to work, and it shows the vertical scrollbar on the right side of each div, which i dont see in the screenshot.

Let me explain what infinite-scroll-parent does, to explain the behavior you are watching above. this directive, if it doesnt exist, the ngInfiniteScroll will simply depend on the whole browser window and its rightside scroller for triggering the scrolling. When i added it, it depends on the div that includes the scroller.

When removing infinite-scroll-parent, only one feed will be active, because naturally only one feed would be touching the bottom of the screen, and that would be the one that is scrolling with you.

Let's first see if the scrolling bars appear first, then take it from there.

ansonphong commented 10 years ago

The important thing here to note is re-creating the same conditions which are the context of the issue. I'm currently implementing on a design where the .infinite-scroll{} class has height:auto, so that it scrolls like a normal feed, like facebook for instance (not in a height limited window). So it was working fine to put the infinite-scroll-parent on the page wrapper, but that only works for one feed. I've been able to re-create the conditions you showed and they both work, though the scenario context is different.

image

Can you get a prototype working like this? Essentially we want the infinite scrolling for both feeds to be triggered by scrolling near the bottom of the entire page (not just the fixed-height div)

ansonphong commented 10 years ago

It needs to work like a Facebook feed with two feeds / columns (not in a fixed height div). Does this make sense?

ansonphong commented 10 years ago

I like the theme you made there for testing Postworld - I haven't been able to get the theme or routing to work at all on my end, just loading the panels in individually. Can you email me the latest version of the theme you're using? Then I can make a seperate repo for that then we can be on the same page.

On Sun, Oct 20, 2013 at 6:31 AM, michelhabib notifications@github.comwrote:

Looking at your samples, let me give that guess again, are you using the infinite scrolling styles?

.infinite-scroll { height: 400px; overflow-y: scroll;}

This is actually crucial for allowing the scrolling to be triggered. because it forces the scrolling on the parent div to work, and it shows the vertical scrollbar on the right side of each div, which i dont see in the screenshot.

Let me explain what infinite-scroll-parent does, to explain the behavior you are watching above. this directive, if it doesnt exist, the ngInfiniteScroll will simply depend on the whole browser window and its rightside scroller for triggering the scrolling. When i added it, it depends on the div that includes the scroller.

When removing infinite-scroll-parent, only one feed will be active, because naturally only one feed would be touching the bottom of the screen, and that would be the one that is scrolling with you.

Let's first see if the scrolling bars appear first, then take it from there.

— Reply to this email directly or view it on GitHubhttps://github.com/phongmedia/postworld/issues/53#issuecomment-26673024 .

michelhabib commented 10 years ago

Phong, what you are saying is making sense for one feed, but for 2 feeds, i would find it confusing for the user. There would be many possible racing scenarios between the 2 feeds if they are not moving at the same vertical increments [in pixel size, not in post count]. At least from the infinite scrolling component perspective, it is designed for a single feed to be scrolling on a single container. What you are suggesting means that we need to keep looking if the container is not filled in both feeeds to keep loading data.

Anyways, i had done some enhancements previously to the infinite scroller to allow for flexibility with defining the container. The trick i did here is to create a container, called scrollDiv, and put both feeds inside it, like this:- postworld\templates\samples\pwLoadFeed4Widget.html

<div id="scrollDiv" class="row">
    <div class="col-md-6">
        <div live-feed='feed1' ng-include="templateUrl"></div>
    </div>      
    <div class="col-md-6">
        <div live-feed='feed2' ng-include="templateUrl"></div>
    </div>      
</div>

Then, use the new directive called infinite-scroll-container and assign it to that div, like this:- postworld\templates\panels\live_feed_3.html that directive defines the div that triggers the scrolling. it is assigned to an angular Model named scrollDiv, and that scrollDiv is then intialized to #scrollDiv. We always used infinite-scroll-parent, which defines the scrolling trigger based on the parent div of the scrolling element - automatically - so that you don't need to set it yourself everytime.

<div>
    <div class="row" >
            <div class="form-group input-group col-md-12">      
                <h2>{{title}} </h2>
                <div ng-show="message" class="alert alert-warning">{{message}}</div>
            </div>
    </div>
    <div class="row" >
            <div class="form-group input-group col-md-12">      
                <div filter-feed="panel2" ng-include="templateUrl" feed-id="args.feed_id" feed_query="args.feed_query" submit="pwRestart()"></div>
            </div>
    </div>  
    <input type="hidden">   
    <div id="scrollMe"  class="infinite-scroll1">
      <div infinite-scroll='getNext()' infinite-scroll-disabled='busy' infinite-scroll-container='scrollDiv' ng-init="scrollDiv='#scrollDiv';">
        <div ng-repeat='post in items' >
            <div feed-item ng-include="templateUrl" post="post" feed-id='args.feed_id'></div>
            <hr>
          <div style='clear: both;'></div>
        </div>
        <div ng-show='busy' class="text-center"><img src="http://www.showoffimports.nl/sandbox/live/ajaxLoad.gif"></div>
        <div ng-show='!busy' class="text-center"><strong>{{scrollMessage}}</strong></div>
      </div>
    </div>
</div>

all of this can be seen here http://localhost/wordpress/search/#/live-feed-2-feeds-auto/ and it is now pushed to github. Let me know if that effect works for this scenario, which i am sorry i didn't digest the first time.

ansonphong commented 10 years ago

OK your demo is working for me in the dev environment - looks good.

ansonphong commented 10 years ago

Hi Michel, OK, now I have it working with two feeds.

Now I noticed a bug, which is also occurring on your development demo, whereby the infinite scroll is loading far ahead of where it needs to. The scroll is being triggered early sometimes.

To test this:

  1. Scroll to the bottom until it loads one set of new posts.
  2. Now scroll down just a tiny bit. Even one pixel. Do a tiny scroll down.
  3. Here I can see that it's triggering the getNext() prematurely, so it's loading far ahead of where it needs to be.
  4. Continue scrolling down slowly, and see how it continues to load posts until they're loaded, even if you haven't gotten near to the bottom.

I noticed that the infinite-scroll-distance="3" wasn't appearing on the infinite scroll directive div, although that didn't seem to fix it.

Any ideas?

ansonphong commented 10 years ago

I am able to re-create this bug on here : #/live-feed-2-feeds-auto/

michelhabib commented 10 years ago

Yes, please check latest commit now. i fixed that and had to tweak a bit the infinite scrolling directive to allow for multiple feeds touching on the main window. you only need to remove any infinite-scroll-parent or infinite-scroll-container, and it will default to using window as the container. now, whenever any of the feeds reaches the bottom while you scroll, it will try to get more posts.

<style>
.infinite-scroll-auto {
    height: auto;
    overflow-y: scroll;
}
</style>

<div>
    <div class="row" >
            <div class="form-group input-group col-md-12">      
                <h2>{{title}} </h2>
                <div ng-show="message" class="alert alert-warning">{{message}}</div>
            </div>
    </div>
    <div class="row" >
            <div class="form-group input-group col-md-12">      
                <div filter-feed="panel2" ng-include="templateUrl" feed-id="args.feed_id" feed_query="args.feed_query" submit="pwRestart()"></div>
            </div>
    </div>  
    <input type="hidden">   
    <div id="scrollMe"  class="infinite-scroll1">
      <div infinite-scroll='getNext()' infinite-scroll-disabled='busy' >
        <div ng-repeat='post in items' >
            <div feed-item ng-include="templateUrl" post="post" feed-id='args.feed_id'></div>
            <hr>
          <div style='clear: both;'></div>
        </div>
        <div ng-show='busy' class="text-center"><img src="http://www.showoffimports.nl/sandbox/live/ajaxLoad.gif"></div>
        <div ng-show='!busy' class="text-center"><strong>{{scrollMessage}}</strong></div>
      </div>
    </div>
</div>
michelhabib commented 10 years ago

and it's updated in my sample http://localhost/wordpress/search/#/live-feed-2-feeds-auto/

ansonphong commented 10 years ago

Affirmative - the infinite scrolling is working correctly with two feeds. Nice one.