UX: improve lightbox gallery zoom/navigation (#13500)

UX: improve lightbox gallery zoom/navigation (#13500)

This PR improves navigation within lightboxes that contain multiple images for both touch and non-touch devices.

Currently, if a gallery contains multiple large images, and you click on the one currently displayed, two things happen.

  1. we zoom in
  2. we navigate to the next image

https://github.com/discourse/discourse/blob/a0bbc346cb5d5b89d1a3efdfa89869349a8b067f/app/assets/javascripts/discourse/app/lib/lightbox.js#L43-L49

So, you get taken to the next image, and it shows zoomed in, even when the intention was to zoom in on the previous image.

Magnific popup has an option to disable image-click navigation in galleries. This PR toggles that on for non-touch devices.

The result is that if you click on an image in a gallery on a non-touch device, we zoom in on that image instead of navigating to the next one.

This has no impact on arrow/keyboard navigation.

Magnific popup also has an API when images change; we reset the zoom class when that happens. So, when you navigate to the next image, it won’t be zoomed in.

For touch devices, clicking on the image will navigate to the next one without zooming in. Users can pinch-zoom if they want to see more details on touch devices.

I used jQuery for this because both Magnific popup and our implementation for this are based on jQuery. No point making a few lines use vanilla for this when the rest doesn’t.

diff --git a/app/assets/javascripts/discourse/app/lib/lightbox.js b/app/assets/javascripts/discourse/app/lib/lightbox.js
index 28563fb..a4d2e52 100644
--- a/app/assets/javascripts/discourse/app/lib/lightbox.js
+++ b/app/assets/javascripts/discourse/app/lib/lightbox.js
@@ -8,16 +8,21 @@ import User from "discourse/models/user";
 import loadScript from "discourse/lib/load-script";
 import { renderIcon } from "discourse-common/lib/icon-library";
 import { spinnerHTML } from "discourse/helpers/loading-spinner";
+import { helperContext } from "discourse-common/lib/helpers";
 
 export default function (elem, siteSettings) {
   if (!elem) {
     return;
   }
 
+  const caps = helperContext().capabilities;
+  const imageClickNavigation = caps.touch;
+
   loadScript("/javascripts/jquery.magnific-popup.min.js").then(function () {
     const lightboxes = elem.querySelectorAll(
       "*:not(.spoiler):not(.spoiled) a.lightbox"
     );
+
     $(lightboxes).magnificPopup({
       type: "image",
       closeOnContentClick: false,
@@ -31,6 +36,7 @@ export default function (elem, siteSettings) {
         tPrev: I18n.t("lightbox.previous"),
         tNext: I18n.t("lightbox.next"),
         tCounter: I18n.t("lightbox.counter"),
+        navigateByImgClick: imageClickNavigation,
       },
 
       ajax: {
@@ -39,17 +45,19 @@ export default function (elem, siteSettings) {
 
       callbacks: {
         open() {
-          const wrap = this.wrap,
-            img = this.currItem.img,
-            maxHeight = img.css("max-height");
+          if (!imageClickNavigation) {
+            const wrap = this.wrap,
+              img = this.currItem.img,
+              maxHeight = img.css("max-height");
 
-          wrap.on("click.pinhandler", "img", function () {
-            wrap.toggleClass("mfp-force-scrollbars");
-            img.css(
-              "max-height",
-              wrap.hasClass("mfp-force-scrollbars") ? "none" : maxHeight
-            );
-          });
+            wrap.on("click.pinhandler", "img", function () {
+              wrap.toggleClass("mfp-force-scrollbars");
+              img.css(
+                "max-height",
+                wrap.hasClass("mfp-force-scrollbars") ? "none" : maxHeight
+              );
+            });
+          }
 
           if (isAppWebview()) {
             postRNWebviewMessage(
@@ -58,6 +66,9 @@ export default function (elem, siteSettings) {
             );
           }
         },
+        change() {
+          this.wrap.removeClass("mfp-force-scrollbars");
+        },
         beforeClose() {
           this.wrap.off("click.pinhandler");
           this.wrap.removeClass("mfp-force-scrollbars");

GitHub sha: 7e5ad9aaaa988a990890bfaea75659953b43d1b6

This commit appears in #13500 which was approved by pmusaraj. It was merged by hnb-ku.