jonatan Posted March 25, 2020 Share Posted March 25, 2020 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] => 89 [items] => Array ( [WireData:0] => 17909280568424854 [WireData:1] => 18121444630076805 [WireData:2] => 18099159694143228 [WireData:3] => 17883854266519759 [WireData:4] => 17854176994877232 [WireData:5] => 18055223719211749 [WireData:6] => 17865563617641437 [WireData:7] => 17853880954804716 [WireData:8] => 17914593256381694 [WireData:9] => 17860300231719969 [WireData:10] => 18017777869257089 [WireData:11] => 18019319182253256 [WireData:12] => 17847252025839832 [WireData:13] => 18036204127233891 [WireData:14] => 18122234449006372 [WireData:15] => 17917004923367534 [WireData:16] => 17854499389726168 [WireData:17] => 17852987293735761 [WireData:18] => 18086538826081818 [WireData:19] => 17866962334577860 [WireData:20] => 18120750871023389 [WireData:21] => 18009153073268946 [WireData:22] => 17849294431747827 [WireData:23] => 17901084034396625 [WireData:24] => 18094452511099675 [WireData:25] => 17847189019719414 [WireData:26] => 17854334599578989 [WireData:27] => 18107613148049776 [WireData:28] => 17909512951361240 [WireData:29] => 18104916640032595 [WireData:30] => 18105513970043998 [WireData:31] => 18066704767130489 [WireData:32] => 17881743565421950 [WireData:33] => 17957414410288932 [WireData:34] => 17957563855294908 [WireData:35] => 18061218313179032 [WireData:36] => 17845018267605780 [WireData:37] => 17860652530488128 [WireData:38] => 18008583064246673 [WireData:39] => 18087603124064192 [WireData:40] => 17849476189531758 [WireData:41] => 18046166611199390 [WireData:42] => 17848414930558047 [WireData:43] => 17971295623301665 [WireData:44] => 18089590891035103 [WireData:45] => 17872427797427060 [WireData:46] => 18087955213016216 [WireData:47] => 17844902065536403 [WireData:48] => 17844973564532788 [WireData:49] => 17859331249452842 [WireData:50] => 17849882830471152 [WireData:51] => 18075170245064821 [WireData:52] => 17942550430293736 [WireData:53] => 17966881903273180 [WireData:54] => 17965161424273612 [WireData:55] => 17898185860336217 [WireData:56] => 18041889235148605 [WireData:57] => 18075502267046552 [WireData:58] => 18007052467216993 [WireData:59] => 17886482302359660 [WireData:60] => 17871858511389658 [WireData:61] => 17869022899360249 [WireData:62] => 18036545284117191 [WireData:63] => 17872542331346319 [WireData:64] => 18008081158196147 [WireData:65] => 18050794615051665 [WireData:66] => 17861485243368787 [WireData:67] => 17865307225357563 [WireData:68] => 18039611095079744 [WireData:69] => 18048228658019001 [WireData:70] => 17986084408204328 [WireData:71] => 17873339755334078 [WireData:72] => 17880649264316699 [WireData:73] => 18019533538130038 [WireData:74] => 18020855698187180 [WireData:75] => WireData [WireData:76] => WireData [WireData:77] => WireData [WireData:78] => WireData [WireData:79] => WireData [WireData:80] => WireData [WireData:81] => WireData [WireData:82] => WireData [WireData:83] => WireData [WireData:84] => WireData [WireData:85] => WireData [WireData:86] => WireData [WireData:87] => WireData [WireData:88] => 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 More sharing options...
jonatan Posted March 26, 2020 Share Posted March 26, 2020 .. well ok just a minor update: With the API call restriction all maxed out I'm still getting this: 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 More sharing options...
nbcommunication Posted March 26, 2020 Author Share Posted March 26, 2020 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 1 Link to comment Share on other sites More sharing options...
nbcommunication Posted March 26, 2020 Author Share Posted March 26, 2020 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 1 Link to comment Share on other sites More sharing options...
nbcommunication Posted March 26, 2020 Author Share Posted March 26, 2020 Hi @jonatan, 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. Cheers, Chris 1 Link to comment Share on other sites More sharing options...
jonatan Posted March 27, 2020 Share Posted March 27, 2020 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 More sharing options...
nbcommunication Posted March 27, 2020 Author Share Posted March 27, 2020 Hi @jonatan, I'm making good progress on this but not finished yet. Discovered that there's a hidden "limit" API option which has necessitated a bit of a rewrite. May get to it this weekend (weather is looking good though, so might be out in the garden!), if not on Monday. Cheers, Chris 1 Link to comment Share on other sites More sharing options...
jonatan Posted March 27, 2020 Share Posted March 27, 2020 @nbcommunication Hi Criss! Sounds interesting! ? No worries though. Nothing very urgent ? If so, enjoy the garden! ?? It's been great in Denmark as well lately! ☀️ All the very best, Jonatan Link to comment Share on other sites More sharing options...
nbcommunication Posted March 29, 2020 Author Share Posted March 29, 2020 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 instagram-basic-display-api-lazy-2020-03-29.mp4 Link to comment Share on other sites More sharing options...
jonatan Posted April 2, 2020 Share Posted April 2, 2020 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" Any ideas? ? All the best, Jonatan. Link to comment Share on other sites More sharing options...
jonatan Posted April 3, 2020 Share Posted April 3, 2020 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 More sharing options...
jonatan Posted April 3, 2020 Share Posted April 3, 2020 On the bright side!: It seems though that now the cache function is working. whenever refreshing the page, it doesn't seem to generate a new API call on the Rate Limiting page! ? Link to comment Share on other sites More sharing options...
jonatan Posted April 3, 2020 Share Posted April 3, 2020 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 More sharing options...
nbcommunication Posted April 3, 2020 Author Share Posted April 3, 2020 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 More sharing options...
jonatan Posted April 3, 2020 Share Posted April 3, 2020 Yup! ? That did it @nbcommunication Criss! As said my JSON / AJAX knowledge is pretty much equal zero. 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 ? Link to comment Share on other sites More sharing options...
nbcommunication Posted April 3, 2020 Author Share Posted April 3, 2020 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 More sharing options...
jonatan Posted April 3, 2020 Share Posted April 3, 2020 Got it all working pretty good now actually! ? rec sasha website instafeed-Broadband High-Broadband Low.mp4 <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?? ? (– 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 More sharing options...
nbcommunication Posted April 6, 2020 Author Share Posted April 6, 2020 Hi @jonatan, It is probably related to the listener - when I get a chance I'll fire up the code and see if I can figure out a solution. Cheers, Chris Link to comment Share on other sites More sharing options...
jonatan Posted April 6, 2020 Share Posted April 6, 2020 Beautiful! Best, Jonatan Link to comment Share on other sites More sharing options...
nbcommunication Posted April 7, 2020 Author Share Posted April 7, 2020 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 More sharing options...
houseofdeadleg Posted April 7, 2020 Share Posted April 7, 2020 I've installed this module, gone through the directions, generated my token, etc, but when I come to try and add the account I get an error message – "InstagramBasicDisplayApi: Could not add user account". Link to comment Share on other sites More sharing options...
nbcommunication Posted April 7, 2020 Author Share Posted April 7, 2020 Hi @houseofdeadleg, Seems to be an issue on the APIs end with the "account_type" field. There's an open bug report: https://developers.facebook.com/support/bugs/1127960260870980/ I've updated the module to remove this field for the time being. If you update, it should work for you. Cheers, Chris 1 Link to comment Share on other sites More sharing options...
houseofdeadleg Posted April 8, 2020 Share Posted April 8, 2020 @nbcommunication seems to have sorted it, got it up and running. Cheers:) Link to comment Share on other sites More sharing options...
jonatan Posted April 8, 2020 Share Posted April 8, 2020 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 More sharing options...
nbcommunication Posted April 9, 2020 Author Share Posted April 9, 2020 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now