Jump to content

InstagramBasicDisplayApi


nbcommunication

Recommended Posts

54 minutes ago, nbcommunication said:

No, I think echoing as you are doing would probably be faster if anything. Basically no difference

Cool! Thanks! ? 

54 minutes ago, nbcommunication said:

I'm going to look into making the pagination more available through the module tomorrow.

Beautiful!

55 minutes ago, nbcommunication said:

I think that may have been from the previous API. This one returns the first 24 items [...]

Good to know!

54 minutes ago, nbcommunication said:

<?php $images = $instagram->getMedia(89); echo count($images) . "<br>" . print_r($images, 1);

returns = 

ProcessWire\WireArray Object
(
    [count] =&gt; 89
    [items] =&gt; Array
        (
            [WireData:0] =&gt; 17909280568424854
            [WireData:1] =&gt; 18121444630076805
            [WireData:2] =&gt; 18099159694143228
            [WireData:3] =&gt; 17883854266519759
            [WireData:4] =&gt; 17854176994877232
            [WireData:5] =&gt; 18055223719211749
            [WireData:6] =&gt; 17865563617641437
            [WireData:7] =&gt; 17853880954804716
            [WireData:8] =&gt; 17914593256381694
            [WireData:9] =&gt; 17860300231719969
            [WireData:10] =&gt; 18017777869257089
            [WireData:11] =&gt; 18019319182253256
            [WireData:12] =&gt; 17847252025839832
            [WireData:13] =&gt; 18036204127233891
            [WireData:14] =&gt; 18122234449006372
            [WireData:15] =&gt; 17917004923367534
            [WireData:16] =&gt; 17854499389726168
            [WireData:17] =&gt; 17852987293735761
            [WireData:18] =&gt; 18086538826081818
            [WireData:19] =&gt; 17866962334577860
            [WireData:20] =&gt; 18120750871023389
            [WireData:21] =&gt; 18009153073268946
            [WireData:22] =&gt; 17849294431747827
            [WireData:23] =&gt; 17901084034396625
            [WireData:24] =&gt; 18094452511099675
            [WireData:25] =&gt; 17847189019719414
            [WireData:26] =&gt; 17854334599578989
            [WireData:27] =&gt; 18107613148049776
            [WireData:28] =&gt; 17909512951361240
            [WireData:29] =&gt; 18104916640032595
            [WireData:30] =&gt; 18105513970043998
            [WireData:31] =&gt; 18066704767130489
            [WireData:32] =&gt; 17881743565421950
            [WireData:33] =&gt; 17957414410288932
            [WireData:34] =&gt; 17957563855294908
            [WireData:35] =&gt; 18061218313179032
            [WireData:36] =&gt; 17845018267605780
            [WireData:37] =&gt; 17860652530488128
            [WireData:38] =&gt; 18008583064246673
            [WireData:39] =&gt; 18087603124064192
            [WireData:40] =&gt; 17849476189531758
            [WireData:41] =&gt; 18046166611199390
            [WireData:42] =&gt; 17848414930558047
            [WireData:43] =&gt; 17971295623301665
            [WireData:44] =&gt; 18089590891035103
            [WireData:45] =&gt; 17872427797427060
            [WireData:46] =&gt; 18087955213016216
            [WireData:47] =&gt; 17844902065536403
            [WireData:48] =&gt; 17844973564532788
            [WireData:49] =&gt; 17859331249452842
            [WireData:50] =&gt; 17849882830471152
            [WireData:51] =&gt; 18075170245064821
            [WireData:52] =&gt; 17942550430293736
            [WireData:53] =&gt; 17966881903273180
            [WireData:54] =&gt; 17965161424273612
            [WireData:55] =&gt; 17898185860336217
            [WireData:56] =&gt; 18041889235148605
            [WireData:57] =&gt; 18075502267046552
            [WireData:58] =&gt; 18007052467216993
            [WireData:59] =&gt; 17886482302359660
            [WireData:60] =&gt; 17871858511389658
            [WireData:61] =&gt; 17869022899360249
            [WireData:62] =&gt; 18036545284117191
            [WireData:63] =&gt; 17872542331346319
            [WireData:64] =&gt; 18008081158196147
            [WireData:65] =&gt; 18050794615051665
            [WireData:66] =&gt; 17861485243368787
            [WireData:67] =&gt; 17865307225357563
            [WireData:68] =&gt; 18039611095079744
            [WireData:69] =&gt; 18048228658019001
            [WireData:70] =&gt; 17986084408204328
            [WireData:71] =&gt; 17873339755334078
            [WireData:72] =&gt; 17880649264316699
            [WireData:73] =&gt; 18019533538130038
            [WireData:74] =&gt; 18020855698187180
            [WireData:75] =&gt; WireData
            [WireData:76] =&gt; WireData
            [WireData:77] =&gt; WireData
            [WireData:78] =&gt; WireData
            [WireData:79] =&gt; WireData
            [WireData:80] =&gt; WireData
            [WireData:81] =&gt; WireData
            [WireData:82] =&gt; WireData
            [WireData:83] =&gt; WireData
            [WireData:84] =&gt; WireData
            [WireData:85] =&gt; WireData
            [WireData:86] =&gt; WireData
            [WireData:87] =&gt; WireData
            [WireData:88] =&gt; WireData
        )

)

 

1 hour ago, nbcommunication said:

How many carousels do you have?

A lot... Out of the 80 showed posts, 46 are carousels.

1 hour ago, nbcommunication said:

Will have another look at this tomorrow. I think it may be useful to have an option to not get the full carousel when using getMedia() as this does seem to be the issue.

Hm.. But I guess that showing carousels shouldn't be an issue? ? Shouldn't it be problemfree to display all of the users carousels?

1 hour ago, nbcommunication said:

getUserAccount() should have the same value for media_count, but it is only updated when getProfile() is called (and an API request is made) [...] I can't think of a situation where it should be used over getProfile().

– Thank you for clearing that up!!  I've adapted my code to your version  ? 

Goodnight from Denmark ? ??

Link to comment
Share on other sites

.. well ok just a minor update:

With the API call restriction all maxed out I'm still getting this:

367006132_Skrmbillede2020-03-26kl_01_21_59.thumb.png.59be4e4db2831c0cbd4f60d6822ce87b.png      2139544411_Skrmbillede2020-03-26kl_01_21_42.thumb.png.b92cf18e0eae1e35067f263874a485ec.png

 

Even though It's now

$images = $instagram->getMedia(89);
                    echo count($images) . "<br>" . print_r($images, 1);
                    if(count($images)) { // Should avoid errors if there's no API response?
                        foreach($images as $post) {

 

Link to comment
Share on other sites

Hi @jonatan,

Thanks for the debug array. Yep there's definitely an issue with asking for more items than there actually is. Will get that sorted.

8 hours ago, jonatan said:

A lot... Out of the 80 showed posts, 46 are carousels.

Each carousel requires a separate API call. That means each request for 80 items (that isn't cached) uses up 50 API calls.

7 hours ago, jonatan said:

With the API call restriction all maxed out I'm still getting this:

The error isn't at that point. Try this:

<?php

switch($post->type) {
  case "VIDEO":
    // ...
    break;
  case "CAROUSEL_ALBUM":
    
    // If the post does not have children, continue without rendering
    if(!$post->children) break;
    
    // ...
    break;
  // ...
}

Cheers,

Chris

  • Like 1
Link to comment
Share on other sites

Hi @jonatan,

I've managed to get access to an account with 20 items for testing. The "counting" in the module is actually correct, I think the issue is maybe that after the limit is reached the API just returns blank records? Anyway, I've added a little bit of code that removes any items without a media_url before they are returned, which should fix your issue. Code not pushed yet, should be later today.

Cheers,

Chris

  • Thanks 1
Link to comment
Share on other sites

On 3/26/2020 at 8:31 AM, nbcommunication said:

That means each request for 80 items (that isn't cached) uses up 50 API calls.

Hm but shouldn't the caching be activated by default? It seems that it keeps using API calls... even within the same hour (3600 seconds)?

On 3/26/2020 at 8:31 AM, nbcommunication said:

if(!$post->children) break;

– Implemented! Thanks!!!

21 hours ago, nbcommunication said:

Anyway, I've added a little bit of code that removes any items without a media_url

Nice! The module's updated now.

19 hours ago, nbcommunication said:

Aye lazy loading is proving to be a little tricky, mainly because of caching. I need to think through this more and will get back to it tomorrow.

So happy that you're on it! Can't wait to see what you come up with. Fingers crossed ??

All the very best,

Jonatan

Link to comment
Share on other sites

Hi @jonatan,

I've been able to pick away at this over the weekend... too cold yet to plant tatties!

With the discovery of the hidden limit option in the API, I had to rewrite some of the module, but everything should just work the same, if not even better...

However, I'm not sure it'll help too much with API rate limiting in your case, as each carousel album is still a separate API call. There is now the option to prevent the "children" (the rest of the album carousel images) from being retrieved:

<?php
$instagram = $modules->get("InstagramBasicDisplayApi");
$items = $instagram->getMedia(["children" => false]);

When working with this over the weekend, I kept an eye on the rate limiting page and it did get nudged frequently, but didn't go beyond 30% used. The account I was using for testing only had a few carousels though.

I've also been able to implement "lazy loading". The example I've added to the README is based on the getMedia() example, using UIkit's javascript utilities. I've attached a short clip of how this looks.

Here's how it might work using Bootstrap/jQuery:

In your template file:

<?php

$instagram = $modules->get("InstagramBasicDisplayApi"); // The pagination cursor is reset if the request is not AJAX, e.g. when the page is loaded.

if($config->ajax) {
	header("Content-Type: application/json");
	echo $instagram->getMedia(); // ["json" => true] is inferred by $config->ajax
	die();
}

echo "<div id='instagram' class='row'></div>";

In your javascript:

// Totally untested!!!!
var instagram = {

	$el: {}, // Where the items go
	$loading: {}, // The loading spinner
	total: 0, // The total number of items

	init: function() {

		this.$el = $("#instagram");
		if(!this.$el.length) return;

		// Add the spinner
		this.$el.after("<div id='instagram-loading'>...Your choice of spinner!</div>");
		this.$loading = $("#instagram-loading");
		this.$loading.hide();

		// Get the first batch of items
		this.get();
	},

	get: function() {

		var this$1 = this;

		// Show spinner
		this$1.$loading.show();

		// Request
		$.getJSON(window.location.href, function(data) {

			// Hide spinner
			this$1.$loading.hide();

			if(!$.isArray(data) || !data.length) return; // If no items do not render

			var items = [];
			data.forEach(function(item, index) {

				switch(item.type) {
					case "VIDEO":
						items.push(this$1.renderItem(item.poster, item.alt, item.src, index));
						break;
					case "CAROUSEL_ALBUM":
						
						var out = "";
						for(var i = 0; i < item.children.length; i++) {
							var src = item.children[i].src;
							out += "<a class='carousel-item' data-fancybox='gallery-ig' data-height='600'  data-caption='" + item.alt + "' href='" + src + "'>" +
								"<div style='background-image: url(" + src + ")' class='pics'></div>" + 
							"</a>";
						}

						items.push(
							"<div data-interval='3000' class='carousel slide carousel-fade col-4 p-3 pics' data-ride='carousel' id='instagram-item-" + (this$1.total + index) + "'>" + 
								"<div class='carousel-inner'>" + 
									out + 
									"<a class='carousel-control-prev' href='#_{$post->id}' role='button' data-slide='prev'>" +
										"<span class='carousel-control-icon-bg' aria-hidden='true'></span>" +
										"<span class='carousel-control-prev-icon' aria-hidden='true'></span>" +
										"<span class='sr-only'>Previous</span>" +
									"</a>" +
									"<a class='carousel-control-next' href='#_{$post->id}' role='button' data-slide='next'>" +
										"<span class='carousel-control-icon-bg' aria-hidden='true'></span>" +
										"<span class='carousel-control-next-icon' aria-hidden='true'></span>" +
										"<span class='sr-only'>Next</span>" +
									"</a>" +
								"</div>" + 
							"</div>"
						);	
									  
						break;
					default: // IMAGE
						items.push(this$1.renderItem(item.src, item.alt, item.src, index));
						break;
				}
			});

			var count = items.length;
			if(count) {

				// Append items to the container
				this$1.$el.append(items.join(""));

				// Attach listener 
				// No idea if this works!!!
				$(window).on("resize scroll", function() {
					var next = $("#instagram-item-" + (this$1.total + count - (count < 5 ? 1 : 6)));
					if(!next.hasClass("seen") && this$1.inViewport()) {
						next.addClass("seen");
						this$1.get();
					}
				});

				// Update total
				this$1.total = this$1.total + count;
			}
		}, function(e) {
			this$1.$loading.hide();
			console.log(e); // ERROR
		})
	},

	inViewport: function(el) {

		// Untested, got the code from
		// https://medium.com/talk-like/detecting-if-an-element-is-in-the-viewport-jquery-a6a4405a3ea2

		var elementTop = el.offset().top;
		var elementBottom = elementTop + el.outerHeight();
		var viewportTop = $(window).scrollTop();
		var viewportBottom = viewportTop + $(window).height();
		return elementBottom > viewportTop && elementTop < viewportBottom;
	},

	renderItem: function(src, alt, href, index) {
		return "<div class='col-4 p-3 pics' id='instagram-item-" + (this.total + index) + "'>" + 
			"<a data-fancybox='gallery-ig' data-height='600' data-caption='" + alt + "' href='" + href + "'>" + 
				"<div style='background-image: url(" + src + ")' class='pics'>" +
					(src !== href ? "<div class='overlay-video-icon'></div>" : "") +         
				"</div>" + 
			"</a>" +
		"</div>";
	}
};

$(document).ready(function() {
	instagram.init();
});

I've just done the jQuery from memory with the addition of an inViewport function I found online. No idea if it works!

Let me know how you get on!

Cheers,

Chris

Link to comment
Share on other sites

Hi @nbcommunication Criss! ? Well hopefully better luck with them tatties a bit later then! ☀️?

Your video preview looks just fabulous! ? Just what I need ? And I must say I'm continuously impressed by your enthusiasm put into this module!

I've updated the module and crossed my fingers...

But.. I tried your suggested code and not that much happened though ? 

<body>
        <?php
        include "../templates/main/bgimg.php";
        ?>
            <div class="container">
                    <?php
                    $itm1act = "active";
                    include '../templates/main/nav.php';
                    ?>
                    <?php
                    $instagram = $modules->get("InstagramBasicDisplayApi");
                    $username = "sasha_lindegaard";
                    $account = $instagram->getProfile($username);
                    $postsnum = $account["media_count"] ?? 0;
                    ?>
                    <div class="row">
                                <div class="col-12 text-center mb-3">
                                        <a href="https://instagram.com/<?= $username ?>/"  target="_blank" class="marked"><h3 class="marked my-5 instalink">
                                                @<?= $username ?></h3>
                                        </a>
                                            <?php if($postsnum): ?><h5 class="marked-dark"><?= $postsnum ?> POSTS / OPSLAG </h5><?php endif; ?>
                                </div>

                    <?php
                    $instagram = $modules->get("InstagramBasicDisplayApi"); // The pagination cursor is reset if the request is not AJAX, e.g. when the page is loaded.

                    if($config->ajax) {
                        header("Content-Type: application/json");
                        echo $instagram->getMedia(); // ["json" => true] is inferred by $config->ajax
                        die();
                    }

                    echo "<div id='instagram' class='row'></div>";?>
                    </div>
            </div>

                        <script>
                            var instagram = {

                            $el: {}, // Where the items go
                            $loading: {}, // The loading spinner
                            total: 10, // The total number of items

                            init: function() {

                                this.$el = $("#instagram");
                                if(!this.$el.length) return;

                                // Add the spinner
                                this.$el.after("<div id='instagram-loading'>...Your choice of spinner!</div>");
                                this.$loading = $("#instagram-loading");
                                this.$loading.hide();

                                // Get the first batch of items
                                this.get();
                            },

                            get: function() {

                                var this$1 = this;

                                // Show spinner
                                this$1.$loading.show();

                                // Request
                                $.getJSON(window.location.href, function(data) {

                                    // Hide spinner
                                    this$1.$loading.hide();

                                    if(!$.isArray(data) || !data.length) return; // If no items do not render

                                    var items = [];
                                    data.forEach(function(item, index) {

                                        switch(item.type) {
                                            case "VIDEO":
                                                items.push(this$1.renderItem(item.poster, item.alt, item.src, index));
                                                break;
                                            case "CAROUSEL_ALBUM":

                                                var out = "";
                                                for(var i = 0; i < item.children.length; i++) {
                                                    var src = item.children[i].src;
                                                    out += "<a class='carousel-item' data-fancybox='gallery-ig' data-height='600'  data-caption='" + item.alt + "' href='" + src + "'>" +
                                                        "<div style='background-image: url(" + src + ")' class='pics'></div>" +
                                                    "</a>";
                                                }

                                                items.push(
                                                    "<div data-interval='3000' class='carousel slide carousel-fade col-4 p-3 pics' data-ride='carousel' id='instagram-item-" + (this$1.total + index) + "'>" +
                                                        "<div class='carousel-inner'>" +
                                                            out +
                                                            "<a class='carousel-control-prev' href='#_{$post->id}' role='button' data-slide='prev'>" +
                                                                "<span class='carousel-control-icon-bg' aria-hidden='true'></span>" +
                                                                "<span class='carousel-control-prev-icon' aria-hidden='true'></span>" +
                                                                "<span class='sr-only'>Previous</span>" +
                                                            "</a>" +
                                                            "<a class='carousel-control-next' href='#_{$post->id}' role='button' data-slide='next'>" +
                                                                "<span class='carousel-control-icon-bg' aria-hidden='true'></span>" +
                                                                "<span class='carousel-control-next-icon' aria-hidden='true'></span>" +
                                                                "<span class='sr-only'>Next</span>" +
                                                            "</a>" +
                                                        "</div>" +
                                                    "</div>"
                                                );

                                                break;
                                            default: // IMAGE
                                                items.push(this$1.renderItem(item.src, item.alt, item.src, index));
                                                break;
                                        }
                                    });

                                    var count = items.length;
                                    if(count) {

                                        // Append items to the container
                                        this$1.$el.append(items.join(""));

                                        // Attach listener
                                        // No idea if this works!!!
                                        $(window).on("resize scroll", function() {
                                            var next = $("#instagram-item-" + (this$1.total + count - (count < 5 ? 1 : 6)));
                                            if(!next.hasClass("seen") && this$1.inViewport()) {
                                                next.addClass("seen");
                                                this$1.get();
                                            }
                                        });

                                        // Update total
                                        this$1.total = this$1.total + count;
                                    }
                                }, function(e) {
                                    this$1.$loading.hide();
                                    console.log(e); // ERROR
                                })
                            },

                            inViewport: function(el) {

                                // Untested, got the code from
                                // https://medium.com/talk-like/detecting-if-an-element-is-in-the-viewport-jquery-a6a4405a3ea2

                                var elementTop = el.offset().top;
                                var elementBottom = elementTop + el.outerHeight();
                                var viewportTop = $(window).scrollTop();
                                var viewportBottom = viewportTop + $(window).height();
                                return elementBottom > viewportTop && elementTop < viewportBottom;
                            },

                            renderItem: function(src, alt, href, index) {
                                return "<div class='col-4 p-3 pics' id='instagram-item-" + (this.total + index) + "'>" +
                                    "<a data-fancybox='gallery-ig' data-height='600' data-caption='" + alt + "' href='" + href + "'>" +
                                        "<div style='background-image: url(" + src + ")' class='pics'>" +
                                            (src !== href ? "<div class='overlay-video-icon'></div>" : "") +
                                        "</div>" +
                                    "</a>" +
                                "</div>";
                            }
                        };

                        $(document).ready(function() {
                            instagram.init();
                        });
                        </script>

        <?php include "../templates/scripts/fancybox-settings.php"?>

        <?php include "../templates/main/footer.php"; ?>

    </body>

Only got me as far as the "Your choice of spinner part" 

78642641_Skrmbillede2020-04-03kl_00_41_48.thumb.png.733dfc7ccb0ee8bf861a14b8ea3399b4.png

Any ideas? ?

All the best,

Jonatan.

Link to comment
Share on other sites

Update: I tried including the UIKIt css & js CDN and copy pasting your exact php & javascript lazy load code from the readme, and also then it only got me to the spinning / loader part of the script.. hm..

(Warning: javascript, ajax and json is not really my game though – can't really say that php is either though haha)

Link to comment
Share on other sites

It wouldn't be possible to do something like "getMedia(next(10))" sort-of thing?  A module function call that would serve the next x images?
(And then it'd ofc not serve anything if it's the last pagination page)

And then I could maybe just do some simple javascript like "if page is scrolled to bottom -> php media = getMedia(next(10));  echo (media);" - if you get that drift?
Or maybe this kind approach would have a lot of flaws that I can't see? (Maybe some caching problems or something like that?)

All the best, Jonatan

Link to comment
Share on other sites

Hi @jonatan,

Try putting the if($config->ajax) code at the top of your template file, before anything else is being output. This will ensure that what is being returned is purely JSON. You can log failed requests like so:

$.getJSON(window.location.href, function(data) {
  // ...
}).fail(function(jqXHR, textStatus, errorThrown) {
  console.log(jqXHR, textStatus, errorThrown);
});

I think what you'd probably be getting is a JSON parse error due to the html being output prior to the AJAX response.

The reason for the next results to not be explicit in the way you've suggested is that the "next" link provided by the API is tied to the original request, and since pagination is likely to be handled by AJAX requests, it makes sense to just build this in as I've done.

Cheers,

Chris

Link to comment
Share on other sites

1 minute ago, jonatan said:

The scroll to bottom load function is not quite working though but I'll try and look into that and see if I can figure anything out ?

Nice one. Yeah, my implementation using UIkit's Scrollspy component isn't great to be honest, but I didn't want to use a 3rd-party plugin for the example.

Your best bet would be to look for a jQuery plugin for handling the scroll-to-bottom thing, I'm sure something will exist! Basically, when the scroll-to-bottom is triggered, you need to call the get() function. This should replace the // Attach Listener part of my example.

Cheers,

Chris

Link to comment
Share on other sites

Got it all working pretty good now actually! ?

<script>
    var instagram = {

    $el: {}, // Where the items go
    $loading: {}, // The loading spinner
    total: 0, // The total number of items

    init: function() {

        this.$el = $("#instagram");
        if(!this.$el.length) return;

        // Add the spinner
        this.$el.after("<div id='instagram-loading'><span class='loadertextcontainer'><b class='loadertext'>loading<span>_</span><span>_</span><span>_</span></b></span></div>");
        this.$loading = $("#instagram-loading");
        this.$loading.hide();

        // Get the first batch of items
        this.get();
    },

    get: function() {

        var this$1 = this;

        // Show spinner
        this$1.$loading.show();

        // Request
        $.getJSON(window.location.href, function(data) {

            // Hide spinner
            this$1.$loading.hide();

            if(!$.isArray(data) || !data.length) return; // If no items do not render

            var items = [];
            data.forEach(function(item, index) {

                switch(item.type) {
                    case "VIDEO":
                        items.push(this$1.renderItemVideo(item.src, item.alt, item.href, index, item.poster));
                        break;
                    case "CAROUSEL_ALBUM":

                        var out = "";
                        for(var i = 0; i < item.children.length; i++) {
                            var src = item.children[i].src;
                            if (i <= 0) {
                            out += "<a class='carousel-item active fb-gallery-ig' data-height='600'  data-caption='" + item.href + "' href='" + src + "'>" +
                                "<div style='background-image: url(" + src + ")' class='pics'></div>"
                            }
                            else {
                            out += "<a class='carousel-item fb-gallery-ig' data-height='600'  data-caption='" + item.href + "' href='" + src + "'>" +
                                "<div style='background-image: url(" + src + ")' class='pics'></div>"
                            }
                            +"</a>";
                        }

                        items.push(
                            "<div data-interval='3000' class='carousel slide carousel-fade col-12 col-sm-6 col-md-4 p-3 pics' data-ride='carousel' id='instagram-item-" + (this$1.total + index) + "'>" +
                                "<div class='carousel-inner'>" +
                                    out +
                                    "<a class='carousel-control-prev' href='#instagram-item-" + (this$1.total + index) + "' role='button' data-slide='prev'>" +
                                        "<span class='carousel-control-icon-bg' aria-hidden='true'></span>" +
                                        "<span class='carousel-control-prev-icon' aria-hidden='true'></span>" +
                                        "<span class='sr-only'>Previous</span>" +
                                    "</a>" +
                                    "<a class='carousel-control-next' href='#instagram-item-" + (this$1.total + index) + "' role='button' data-slide='next'>" +
                                        "<span class='carousel-control-icon-bg' aria-hidden='true'></span>" +
                                        "<span class='carousel-control-next-icon' aria-hidden='true'></span>" +
                                        "<span class='sr-only'>Next</span>" +
                                    "</a>" +
                                "</div>" +
                            "</div>"
                        );



                        break;
                    default: // IMAGE
                        items.push(this$1.renderItem(item.src, item.alt, item.href, index));
                        break;
                }
            });

            var count = items.length;
            if(count) {

                // Append items to the container
                this$1.$el.append(items.join(""));

                // Attach listener
                $(window).scroll(function() {
                if($(window).scrollTop() == $(document).height() - $(window).height()) {
                        this$1.get();
                        $(window).scrollTop($(window).scrollTop()-1);

                }

                });


                // Update total
                this$1.total = this$1.total + count;
            }
        }, function(e) {
            this$1.$loading.hide();
            console.log(e); // ERROR
        })
    },


    renderItem: function(src, alt, href, index, poster) {
        return "<div class='col-12 col-sm-6 col-md-4 p-3 pics' id='instagram-item-" + (this.total + index) + "'>" +
            "<a class='fb-gallery-ig' data-height='600' data-caption='" + href + "' href='" + src + "' data-alt='" + alt + "'>" +
                "<div style='background-image: url(" + src + ")' class='pics'>" +
                "</div>" +
            "</a>" +
        "</div>";
    },
    renderItemVideo: function(src, alt, href, index, poster) {
        return "<div class='col-12 col-sm-6 col-md-4 p-3 pics' id='instagram-item-" + (this.total + index) + "'>" +
            "<a class='fb-gallery-ig' data-height='600' data-caption='" + href + "' href='" + src + "'>" +
                "<div style='background-image: url(" + poster + ")' class='pics'>" +
                    (src !== poster ? "<div class='overlay-video-icon'></div>" : "") +
                "</div>" +
            "</a>" +
        "</div>";
    }
};
  
  $(document).ready(function() {
    instagram.init();
  });

</script>

Only problem now is that every second "batch" of the pagination is not shown...  Maybe some (to the quite so much more trained eye) obvious mistake in my poor copy of your code?? ?

instafeedprob.thumb.png.9cb020d30aec70a90353084e249ea33c.png 

 

1065116454_Skrmbillede2020-04-04kl_00_56_06.png.ea913afaa437ab14a893063fee00baee.png (– the limit is set to 9 btw – guess it shouldn't really make a difference though?) 

And... then when it gets to the last "batch" it keeps showing the loading section. Not quite sure how to make it not show when the last batch has been loaded?

Hope that you might have some brilliant input once again! Thank you so much once again!

 

All the very best,

Jonatan

Link to comment
Share on other sites

Hi @jonatan,

Aye it is the listener. Try the following:

var instagram = {

	$el: {}, // Where the items go
	$loading: {}, // The loading spinner
	total: 0, // The total number of items
	busy: false,

	init: function() {

		this.$el = $("#instagram");
		if(!this.$el.length) return;

		// Add the spinner
		this.$el.after("<div id='instagram-loading'><span class='loadertextcontainer'><b class='loadertext'>loading<span>_</span><span>_</span><span>_</span></b></span></div>");
		this.$loading = $("#instagram-loading");
		this.$loading.hide();

		// Get the first batch of items
		this.get();

		var this$1 = this;

		// Attach listener
		$(window).scroll(this.debounce(function() {
			if(!this$1.busy && $(window).scrollTop() == $(document).height() - $(window).height()) {
				this$1.get();
			}
		}, 256));
	},

	debounce: function(func, wait, immediate) {

		var timeout;
		if(wait === void 0) wait = 256;
		return function() {

			var context = this;
			var args = arguments;
			var later = function() {
				timeout = null;
				if(!immediate) func.apply(context, args);
			};
			var callNow = immediate && !timeout;

			clearTimeout(timeout);
			timeout = setTimeout(later, wait);

			if(callNow) func.apply(context, args);
		};
	},

	get: function() {

		var this$1 = this;

		// Show spinner
		this$1.$loading.show();

		// Prevent requests while this one is running
		this$1.busy = true;

		// Request
		$.getJSON(window.location.href, function(data) {

			// Hide spinner
			this$1.$loading.hide();

			if(!$.isArray(data) || !data.length) return; // If no items do not render

			var items = [];
			data.forEach(function(item, index) {

				switch(item.type) {
					case "VIDEO":
						items.push(this$1.renderItemVideo(item.src, item.alt, item.href, index, item.poster));
						break;
					case "CAROUSEL_ALBUM":

						var out = "";
						for(var i = 0; i < item.children.length; i++) {
							var src = item.children[i].src;
							if (i <= 0) {
							out += "<a class='carousel-item active fb-gallery-ig' data-height='600'  data-caption='" + item.href + "' href='" + src + "'>" +
								"<div style='background-image: url(" + src + ")' class='pics'></div>"
							}
							else {
							out += "<a class='carousel-item fb-gallery-ig' data-height='600'  data-caption='" + item.href + "' href='" + src + "'>" +
								"<div style='background-image: url(" + src + ")' class='pics'></div>"
							}
							+"</a>";
						}

						items.push(
							"<div data-interval='3000' class='carousel slide carousel-fade col-12 col-sm-6 col-md-4 p-3 pics' data-ride='carousel' id='instagram-item-" + (this$1.total + index) + "'>" +
								"<div class='carousel-inner'>" +
									out +
									"<a class='carousel-control-prev' href='#instagram-item-" + (this$1.total + index) + "' role='button' data-slide='prev'>" +
										"<span class='carousel-control-icon-bg' aria-hidden='true'></span>" +
										"<span class='carousel-control-prev-icon' aria-hidden='true'></span>" +
										"<span class='sr-only'>Previous</span>" +
									"</a>" +
									"<a class='carousel-control-next' href='#instagram-item-" + (this$1.total + index) + "' role='button' data-slide='next'>" +
										"<span class='carousel-control-icon-bg' aria-hidden='true'></span>" +
										"<span class='carousel-control-next-icon' aria-hidden='true'></span>" +
										"<span class='sr-only'>Next</span>" +
									"</a>" +
								"</div>" +
							"</div>"
						);



						break;
					default: // IMAGE
						items.push(this$1.renderItem(item.src, item.alt, item.href, index));
						break;
				}
			});

			var count = items.length;
			if(count) {

				// Append items to the container
				this$1.$el.append(items.join(""));

				// Allow more requests
				this$1.busy = false;

				// Update total
				this$1.total = this$1.total + count;
			}
		}, function(e) {
			this$1.$loading.hide();
			console.log(e); // ERROR
		})
	},


	renderItem: function(src, alt, href, index, poster) {
		return "<div class='col-12 col-sm-6 col-md-4 p-3 pics' id='instagram-item-" + (this.total + index) + "'>" +
			"<a class='fb-gallery-ig' data-height='600' data-caption='" + href + "' href='" + src + "' data-alt='" + alt + "'>" +
				"<div style='background-image: url(" + src + ")' class='pics'>" +
				"</div>" +
			"</a>" +
		"</div>";
	},
	renderItemVideo: function(src, alt, href, index, poster) {
		return "<div class='col-12 col-sm-6 col-md-4 p-3 pics' id='instagram-item-" + (this.total + index) + "'>" +
			"<a class='fb-gallery-ig' data-height='600' data-caption='" + href + "' href='" + src + "'>" +
				"<div style='background-image: url(" + poster + ")' class='pics'>" +
					(src !== poster ? "<div class='overlay-video-icon'></div>" : "") +
				"</div>" +
			"</a>" +
		"</div>";
	}
};
  
$(document).ready(function() {
	instagram.init();
});

I've added a "busy" variable which prevents requests when one is already being made, and a debounce function to control the scroll handler which has been moved to init(). Works for me.

Cheers,

Chris

Link to comment
Share on other sites

On 4/7/2020 at 4:48 PM, nbcommunication said:

Hi @jonatan,

Aye it is the listener.
I've added a "busy" variable which prevents requests when one is already being made, and a debounce function to control the scroll handler which has been moved to init(). Works for me.

Cheers,
Chris

Hi @nbcommunication Criss! ?  Thank you so much once again! I updated the module, cleared the module cache, and pasted in your new code. But.. It's still the same.. It loads every second "batch", and the last batch is not loaded (and it just keeps showing the loading).

 

Any ideas what might be wrong? ?

All the best,

Jonatan

Link to comment
Share on other sites

Hi @jonatan,

I'm not sure what more I'd be able to do to directly help here. At this point your best bet is to add a bunch of logging to try and determine where the problem is occurring.

For example:

// Attach listener
console.log("Should only log once on init");
$(window).scroll(this.debounce(function() {
  console.log("Probably not needed, this will log during scrolling");
  if(!this$1.busy && $(window).scrollTop() == $(document).height() - $(window).height()) {
    console.log("User has reached the bottom.");
    // When this is logged I should really only see one at the time due to the debounce function and the 'busy' switch.
    this$1.get();
    // Similar logging to be added to get()
  }
}, 256));
<?php

$instagram = $modules->get("InstagramBasicDisplayApi");

// The next url is stored in session. The code below will log it.
$instagram->log($session->getFor($instagram, "next$page->id"));

if($config->ajax) {
    $instagram->log("You may want to log here to test how often AJAX requests are made");
    header("Content-Type: application/json");
    echo $instagram->getMedia(); // ["json" => true] is inferred by $config->ajax
    die();
}

By using logging to trace the process, you will hopefully be able to figure out what is causing the issue. I suspect it is still the listener.

Cheers,

Chris

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...