Topic: Remove photos dynamically/ through API

Hello,

I currently am using the gallery on a page for Real Estate listings, and occasionally I do not know how many images are in the gallery, so the XML file that's generated is simply generated out to 50 images. This causes a problem if there's less than 50 images for the listing. For example: http://prntscr.com/mwhb8p

I was looking at the API here: https://www.juicebox.net/support/api/, and I can use .onImageChange to detect if the image is valid or not, however I don't see a way to remove an image index from the gallery.

I could use some JS to remove the image containers/ thumbnails when an invalid photo is viewed, but it will come back when switching thumbnail pages, for example. Is there any API or functionality for removing an image from the gallery after the page has loaded?

Thanks,
Tony.

Re: Remove photos dynamically/ through API

Even if the gallery's configuration file is generated dynamically (on-the-fly when the gallery is displayed), it will be complete (and cannot be changed) as soon as the gallery loads (and the API can only be used client-side after the gallery has loaded, i.e. after the gallery's configuration file has been generated server-side).

The only way to remove an image from a gallery that has already loaded would be to re-generate a new configuration file and then reload the gallery (using the new configuration file).

I can't quite wrap my head around exactly what you are doing (where the images are coming from and how you would determine if an image is valid or not) so, at the moment, I can't figure out how I might set about solving your problem.

It looks like you'd need to validate your images within the script that generates the gallery's configuration file (the file that stores the image data).

Maybe if you could explain exactly how your gallery's configuration file is generated (and how the problem arises), I might be able to help further. Thank you.

Re: Remove photos dynamically/ through API

Hello Steven,

It sounds like that I probably can't do what I'm looking for specifically, however here's generally how the 'XML' is generated. Also note that I have slightly modified the JuiceBox code so that the configUrl can directly take the normal 'XML' files contents inline and load it with the page (to avoid an AJAX request, and because the content is dynamic):

  • WordPress page is loaded for a Real Estate listing

  • Our plugin makes a call to our API server to load listing data

  • Listing data includes the photo count for the listing, and the photo base URL

  • Plugin takes photo count and photo base to build 'XML', like this: http://prntscr.com/mwxtfu

  • Without including the XML inline, it's normally a AJAX request to the site that builds the file dynamically with PHP, checking with the API server to get details

The issue however is that occasionally (because of caching) the API server reports 0 photos available, even if we do have photos available. When it reports 0, I have a quick check if the base image (for example: https://images.marketleader.com/HouseIm … 04168.jpg) exists. If it does, I have it switch from 0 photos available to 50, and build the XML with that.

I can then have the page check back in to validate how many images actually exist, but I don't do that when generating the 'XML' config to reduce loading time.

The only way that I can think of to really validate if an image exists is to get the response headers from the image, and look at the 'content type'. If it's not valid, a SVG image is returned. Otherwise, it should be JPG (for SVG example: https://images.marketleader.com/HouseIm … hoto.jpg).

Currently my solution to this is to check every 10 images, and if we encounter a SVG, count down until we find the correct image. So it'll check f_photo_10.jpg, if it's a jpg, check f_photo_20.jpg, etc. When it encounters a SVG, say at _40.jpg, it checks the headers counting back down: _39.jpg > SVG > _38.jpg > SVG > etc, until it finds the last valid image, say _33.jpg. I now know that there's 34 images (starts at 0), and I could either build a new configUrl, or simply send the real photo count back to the site.

Ideally I would want to just send the real photo count back to the site (though AJAX to avoid affecting initial page load), and have the site/ JuiceBox simply remove image indexes 35 - 50, as they're not valid. Sounds like that I would have to send a new configUrl however and reload the Juicebox gallery.

I can also detect on the page if the image is invalid as the SVG image is naturally 300x131, which most real images are not (not a great solution, but best I could come up with myself in JS).

Overall obviously the best option is to simply make sure that the server is sending the correct photo count, but unfortunately the database team that I'm working with isn't willing to make changes to the caching/ data. So I'm trying to workaround it with what I have access to.

If something here doesn't make sense or you'd like more information, just let me know.

Thanks,
Tony.

Re: Remove photos dynamically/ through API

Many thanks for the information.
Unfortunately, I'm still not entirely sure how I'd approach the problem myself.

It certainly isn't possible to dynamically remove images after a gallery has loaded.
You'd really need to catch the problem at the time the configuration data is generated or recreate fresh configuration data and reload the gallery.
If you go down the reload route (which might be preferable to having ghost images at the end of a gallery), you could perhaps hide the gallery container using CSS and show it only when everything is ready (after the first load if everything is OK or after the reload if necessary).
This is by no means ideal but it would at least look better to the site visitor.

I can then have the page check back in to validate how many images actually exist, but I don't do that when generating the 'XML' config to reduce loading time.

Have you tried this and timed it in a real-world example? Maybe the time taken would be acceptable (to produce a gallery which does not need to be reloaded).

If your server reports that 0 images are available, could you maybe create configuration data, one image at a time, checking each image's existence as you go (but only if 0 images are reported)?

Also, might you be able to store your configuration data in a variable and perform some string manipulation on it (to check and remove any SVG images) before feeding it to your configUrl?

I'm really just thinking aloud here.
I don't expect to come up with a great solution for you (your workflow is quite complex and I'm not sure I completely understand all the intricacies of it) but maybe my notes above will somehow help.

5 (edited by dsTony 2019-03-18 13:55:53)

Re: Remove photos dynamically/ through API

Thanks Steven, I didn't see that there was a reply earlier (no email that I saw).

I appreciate the thinking out loud.

Typically, here's how the loading time looks:

  • WordPress generates the page content, typically about 0.3s

  • Our API gets listing data, if not server (API) cached, ~4-5s, if server cached, ~0.9s - ~2s, if locally cached, ~0.1s

  • Any other API requests run, but for the sake of this, let's say there's none (0s, though usually there's some other cached things, or if you're registered, some calls to record visit/ get notes/favorite status of listing)

I have timed my image checker on something with ~36 images (probably above avg image count, and inbetween my blocks of 10 checking), and it was ~1.3s - ~2.7s (and I added caching for it, so if we HAVE checked for the image count before, it gets cached in WordPress, ~0.1s. It seems like that getting responses from the server about images can also be server cached, so running the same query again without local caching takes as low as ~0.4s). Not bad, but because this is WordPress/PHP, there's no page output until everything is done.

So adding it all up, we get anywhere from ~0.5s (everything cached) - ~8.1s (nothing cached). So, quite a range, but my focus is going to be on reducing the top end. In this case, 8.1s for a page to START loading content is just too high. This is why I wanted to see about dynamically adjusting the photo count later. Most listings (if they have photos) are going to probably have more than 6 (our max thumbnail count), and by the time a user got to photo 7+ would have been more than enough time to get the correct photo count.

I'll have to play around with just refreshing the gallery, and see how (maybe) jarring it is, but I should be able to get what image they're on, and return them to that.

What you've suggested with CSS, is almost how it was originally before my initial edits, where the page would load, and JS on the page would send back to the site, which would send to the API to build the XML, and then back to the site and back to JS before the gallery loaded. This was also sent with several other AJAX requests, and usually was stalled until those finished first. When this was the behavior, we just used the JuiceBox loading icon (.gif) until that request completed.

On a quick note about the loading icon, when I was initially looking at reducing the amount of requests on our pages, I replaced the .gif file with a CSS animated loading icon, modeled after the .gif (saves some KB, and a request, just to share):

<style>
div#jb-custom-loading div.ds-spin-container{width:100px;height:100px;background:#000;position:absolute;transform:translate(-50%,-50%);top:230px;left:50%;border-radius:10px;border:1px solid #000;z-index:0}
div#jb-custom-loading div.ds-spin-teardrop{position:absolute;top:50%;left:50%;background-color:#000;display:block;width:12px;padding:3px 2px 5px!important;height:8px;border-top-left-radius:9px;border-bottom-left-radius:9px;border-bottom-right-radius:9px;box-shadow:0 0 8px gray;transform:translate(-50%,-50%) rotate(-45deg);margin:0;box-sizing:content-box!important;z-index:0}
div#jb-custom-loading div.ds-spin-hexagon{position:absolute;width:60px;height:34.642px;background-color:#fff;margin:0!important;padding:0!important;top:33px;left:20px;z-index:0}
div#jb-custom-loading div.ds-spin-hexagon:before,div#jb-custom-loading div.ds-spin-hexagon:after{content:"";position:absolute;width:0;height:0;transform:translate(-50%,-50%);border-left:30px solid transparent;border-right:30px solid transparent}
div#jb-custom-loading div.ds-spin-hexagon:before{top:-24%;left:50%;border-bottom:17.32px solid #fff}
div#jb-custom-loading div.ds-spin-hexagon:after{bottom:-74%;left:50%;border-top:17.32px solid #fff}
div#jb-custom-loading div.ds-spin-spin{-webkit-animation:ds-spin 4s linear infinite;-moz-animation:ds-spin 4s linear infinite;animation:ds-spin 4s linear infinite}
@-moz-keyframes ds-spin { 100%{-moz-transform:rotate(360deg)} }
@-webkit-keyframes ds-spin { 100%{-webkit-transform:rotate(360deg)} }
@keyframes ds-spin { 100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)} }
</style>
<div id="jb-custom-loading">
    <div class="ds-spin-container">
        <div class="ds-spin-hexagon ds-spin-spin"> </div>
        <div class="ds-spin-teardrop"> </div>
    </div>
</div>

As for performing a string manipulation on the configuration data, that's not specifically possible because all images that you request from the server are .jpg, whether they exist or not. You have to look at the image/ response headers to know if it's an SVG or not.

But as I mentioned, I'll likely just have to go back to either delaying the gallery from loading for a couple seconds after the page loads, or experiment with just refreshing the gallery when I know the correct photo count.

Thanks,
Tony.

Re: Remove photos dynamically/ through API

In this case, 8.1s for a page to START loading content is just too high.

Agreed. However, it sounds like you've got things under control and are doing all you can to optimize things.
Unfortunately, I don't think I can add anything which would help further. I'll certainly post back here if I think of anything.

Thanks for sharing your CSS animated loading icon, though. Very interesting... works well and looks good!

Re: Remove photos dynamically/ through API

Thanks Steven, I appreciate the time looking into it. Just to give you an update on what I'm doing currently, I'm just loading the first image (if it exists) where the gallery would be, with the loading icon. That's displayed until the page communicates back to the site with AJAX to have the plugin check for the correct number of images. It then loads the JB gallery, replacing the image/loading icon.

Here's what that looks like: http://prntscr.com/n00ws7 (initial page load) -> http://prntscr.com/n00y33 (few seconds later). At least with this way, the user won't have possibly switched images when the gallery re/loads.

Re: Remove photos dynamically/ through API

Having your own custom placeholder for the gallery as it loads is certainly a wise decision.
I'm sure that visitors to you site will be willing to wait a few seconds if they know that resource files are still being loading in the background.
There's nothing worse than a blank space and not knowing if the web page has stalled or not!