Extending/adding lightbox listeners?

Created on 3 April 2024, 3 months ago
Updated 17 April 2024, 2 months ago

Problem/Motivation

I'd like to add some custom UI to the lightbox, but ideally I'd need to listen to some lightbox events like init as well. I'm not seeing a great place to hook into any of that, and I'm wondering if you have suggestions? Or I could come up with some sort of registration system similar to how Splide works?

I've tried a couple of things so far and I'm hitting some problems:

  1. Drupal.behaviors attaching isn't working well because of the promise used to load the PhotoSwipeLightbox library. I was hoping to attach events to the lighbox object assigned to Drupal.blazyPhotoSwipe.beforeInit (with the comment "Exposes lightbox object"), but the sequence is blazyPhotoSwipe attach is called and starts loading, then my custom JS attach is called, but nothing is ready yet until the module import promise resolves (Drupal.blazyPhotoSwipe.init.then()).
  2. The only other option I could find is piggypacking off of Drupal.blazyPhotoSwipe.ui. That happens to exist to add the custom caption, so if I add my custom item there (which I would need to do either way) I'll at least get registered, but there's no opportunity to clean up or listen to other events.

Do you have any thoughts or ideas?

✨ Feature request
Status

Fixed

Version

1.0

Component

Code

Created by

🇺🇸United States KarlShea Minneapolis, 🇺🇸

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @KarlShea
  • 🇮🇩Indonesia gausarts

    Thank you.

    Registering UI appears to work, however the current implementation is not really working well to accommodate events due to empty pswp.pswp object as per this writing.

         var bps = Drupal.blazyPhotoSwipe || false;
    
          // DOM ready fix.
          setTimeout(function () {
            if (bps && bps.init) {
              // Merge other UI providers, if any.
              Drupal.blazyPhotoSwipe.ui = bps.ui || {};
    
              bps.init.finally(function () {
                // @todo this object has empty pswp object.
                var pswp = bps.beforeInit;
                console.log('pswp', pswp);
    
                if (pswp) {
                  Drupal.blazyPhotoSwipe.ui.test = {
                    name: 'test-button',
                    ariaLabel: 'Toggle zoom',
                    order: 9,
                    isButton: true,
                    html: 'Test',
                    onClick: (event, el) => {
                      if (confirm('Do you want to toggle zoom?')) {
                        // @todo pswp.pswp.toggleZoom();
                      }
                    }
                  };
                }
              });
            }
          });
    

    Conclusion, we need to inject pswp object manually, or refactor to use gallery element to support multiple instances rather than relying on global Drupal.blazyPhotoSwipe.beforeInit.

  • 🇮🇩Indonesia gausarts

    This is another sample for download link:
    https://www.drupal.org/project/blazy_photoswipe/issues/3389181#comment-1... ✨ Photoswipe 5: provide a download link Fixed

  • Status changed to Needs review 3 months ago
  • 🇮🇩Indonesia gausarts

    The patch will make immutable pswp object available globally, while make it possible to work with individual elements.
    The last was taken from Slick convention which stores JS instance in the individual gallery element.

    This sample will go to Drupal.behaviors.attach block:

    var bps = Drupal.blazyPhotoSwipe || false;
    
          // DOM ready fix.
          setTimeout(function () {
            var items = context.querySelectorAll('[data-photoswipe-gallery]');
            if (items.length) {
              items.forEach(function (el) {
                var pswp = el.pswp;
                console.log('pswp', pswp);
    
                if (bps && bps.init) {
                  Drupal.blazyPhotoSwipe.ui = bps.ui || {};
                  var lightbox = bps.lightbox;
    
                  console.log('lightbox', lightbox);
    
                  if (lightbox) {
                    Drupal.blazyPhotoSwipe.ui.test = {
                      name: 'test-button',
                      ariaLabel: 'Toggle zoom',
                      order: 9,
                      isButton: true,
                      html: 'Test',
                      onClick: (event, el) => {
                        if (confirm('Do you want to toggle zoom?')) {
                          console.log('event', event);
                          lightbox.pswp.toggleZoom();
                        }
                      }
                    };
    
                    pswp.on('beforeOpen', function (item) {
                      console.log('beforeOpen', item);
                    });
    
                    pswp.on('initialLayout', function (item) {
                      console.log('initialLayout', item);
                    });
                  }
                }
              });
            }
          });

    Adjust ES6 mix above accordingly, but fine though.
    Also works fine with sample from #3.

    Let me know if any betterment for this?

  • 🇮🇩Indonesia gausarts

    IIRC, previously using non-indices keys for UI objects appeared to fail, but now works.

    But then indices caused duplicated elements on subsequent launches, so I changed:
    Drupal.blazyPhotoSwipe.ui[0] = {}, etc.

    to non-indices keys:
    Drupal.blazyPhotoSwipe.ui.customCaption = {}, etc.

  • Status changed to Fixed 3 months ago
  • 🇮🇩Indonesia gausarts

    This would do for now.

    Improvements are welcome.

    Thank you.

  • 🇺🇸United States KarlShea Minneapolis, 🇺🇸

    Awesome, thank you so much! I'll give it a shot.

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.69.0 2024