mirror of
https://github.com/photoprism/photoprism.git
synced 2026-07-17 16:49:04 +00:00
Lightbox: Stop slideshow on sphere gestures
This commit is contained in:
parent
d52554fc50
commit
75b007b502
2 changed files with 51 additions and 4 deletions
|
|
@ -757,11 +757,17 @@ export default {
|
|||
// reveals the prev/next arrows and top bar on touch devices. To restore that, a short
|
||||
// press without a pan toggles the controls here. Only touch/pen taps do so — mouse
|
||||
// users still get the controls via mousemove, so desktop behavior is unchanged.
|
||||
//
|
||||
// Grabbing or wheel-zooming the sphere also stops a running slideshow, matching flat
|
||||
// slides (whose pointer events reach captureDialogPointerDown — this container swallows
|
||||
// them first). When a tap is what paused it, the tap-toggle is skipped so the controls
|
||||
// revealed by the pause stay visible and the user lands on the paused view.
|
||||
trapSphereGestures(el) {
|
||||
const stop = (e) => e.stopPropagation();
|
||||
let tapX = 0;
|
||||
let tapY = 0;
|
||||
let tapping = false;
|
||||
let pausedByGesture = false;
|
||||
el.addEventListener(
|
||||
"pointerdown",
|
||||
(e) => {
|
||||
|
|
@ -769,6 +775,10 @@ export default {
|
|||
tapping = e.pointerType !== "mouse";
|
||||
tapX = e.clientX;
|
||||
tapY = e.clientY;
|
||||
pausedByGesture = this.slideshow.active;
|
||||
if (pausedByGesture) {
|
||||
this.pauseSlideshow();
|
||||
}
|
||||
},
|
||||
{ capture: false }
|
||||
);
|
||||
|
|
@ -776,10 +786,11 @@ export default {
|
|||
"pointerup",
|
||||
(e) => {
|
||||
e.stopPropagation();
|
||||
if (tapping && Math.abs(e.clientX - tapX) < SPHERE_TAP_SLOP && Math.abs(e.clientY - tapY) < SPHERE_TAP_SLOP) {
|
||||
if (tapping && !pausedByGesture && Math.abs(e.clientX - tapX) < SPHERE_TAP_SLOP && Math.abs(e.clientY - tapY) < SPHERE_TAP_SLOP) {
|
||||
this.toggleControls();
|
||||
}
|
||||
tapping = false;
|
||||
pausedByGesture = false;
|
||||
},
|
||||
{ capture: false }
|
||||
);
|
||||
|
|
@ -788,12 +799,21 @@ export default {
|
|||
(e) => {
|
||||
e.stopPropagation();
|
||||
tapping = false;
|
||||
pausedByGesture = false;
|
||||
},
|
||||
{ capture: false }
|
||||
);
|
||||
el.addEventListener("pointermove", stop, { capture: false });
|
||||
el.addEventListener(
|
||||
"wheel",
|
||||
(e) => {
|
||||
e.stopPropagation();
|
||||
if (this.slideshow.active) {
|
||||
this.pauseSlideshow();
|
||||
}
|
||||
},
|
||||
{ capture: false }
|
||||
);
|
||||
["pointermove", "wheel"].forEach((type) => {
|
||||
el.addEventListener(type, stop, { capture: false });
|
||||
});
|
||||
},
|
||||
// setSphereClass toggles the `pswp--sphere` marker on the PhotoSwipe root element so
|
||||
// CSS can keep the prev/next arrows reachable on touch devices for 360° slides, where
|
||||
|
|
|
|||
|
|
@ -1404,6 +1404,8 @@ describe("PLightbox (low-mock, jsdom-friendly)", () => {
|
|||
const trap = () => {
|
||||
const wrapper = mountLightbox();
|
||||
wrapper.vm.toggleControls = vi.fn();
|
||||
wrapper.vm.pauseSlideshow = vi.fn();
|
||||
wrapper.vm.slideshow = { active: false };
|
||||
const registered = [];
|
||||
const el = { addEventListener: (type, handler, opts) => registered.push({ type, handler, opts }) };
|
||||
wrapper.vm.$options.methods.trapSphereGestures.call(wrapper.vm, el);
|
||||
|
|
@ -1453,6 +1455,31 @@ describe("PLightbox (low-mock, jsdom-friendly)", () => {
|
|||
fire("pointerup", { pointerType: "touch", clientX: 100, clientY: 100 });
|
||||
expect(vm.toggleControls).not.toHaveBeenCalled();
|
||||
});
|
||||
it("pauses an active slideshow when the sphere is grabbed", () => {
|
||||
const { vm, fire } = trap();
|
||||
vm.slideshow.active = true;
|
||||
fire("pointerdown", { pointerType: "touch", clientX: 100, clientY: 100 });
|
||||
expect(vm.pauseSlideshow).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
it("does NOT pause when no slideshow is running", () => {
|
||||
const { vm, fire } = trap();
|
||||
fire("pointerdown", { pointerType: "mouse", clientX: 100, clientY: 100 });
|
||||
expect(vm.pauseSlideshow).not.toHaveBeenCalled();
|
||||
});
|
||||
it("pauses an active slideshow when zooming the sphere with the wheel", () => {
|
||||
const { vm, fire } = trap();
|
||||
vm.slideshow.active = true;
|
||||
fire("wheel", {});
|
||||
expect(vm.pauseSlideshow).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
it("keeps the controls shown when a touch tap pauses the slideshow", () => {
|
||||
const { vm, fire } = trap();
|
||||
vm.slideshow.active = true;
|
||||
fire("pointerdown", { pointerType: "touch", clientX: 100, clientY: 100 });
|
||||
fire("pointerup", { pointerType: "touch", clientX: 102, clientY: 101 });
|
||||
expect(vm.pauseSlideshow).toHaveBeenCalledTimes(1);
|
||||
expect(vm.toggleControls).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
// setSphereClass marks the PhotoSwipe root so CSS can keep the prev/next arrows
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue