diff --git a/app/components/modal.gjs b/app/components/modal.gjs
index 8ae2fd7..e673e05 100644
--- a/app/components/modal.gjs
+++ b/app/components/modal.gjs
@@ -1,9 +1,39 @@
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { on } from '@ember/modifier';
+import config from 'marco/config/environment';
import Icon from './icon';
+const ModalContent =
+
+;
+
export default class Modal extends Component {
+ get isTesting() {
+ return config.environment === 'test';
+ }
+
+ get destinationElement() {
+ return document.getElementById('modal-portal') || document.body;
+ }
+
@action
stopProp(e) {
e.stopPropagation();
@@ -18,28 +48,24 @@ export default class Modal extends Component {
}
-
+
+ {{else}}
+ {{#in-element this.destinationElement}}
+
+ {{yield}}
+
+ {{/in-element}}
+ {{/if}}
}
diff --git a/app/components/photo-carousel.gjs b/app/components/photo-carousel.gjs
index 866e764..e2a24f9 100644
--- a/app/components/photo-carousel.gjs
+++ b/app/components/photo-carousel.gjs
@@ -8,6 +8,7 @@ import Icon from './icon';
import fadeInImage from '../modifiers/fade-in-image';
import { on } from '@ember/modifier';
import { modifier } from 'ember-modifier';
+import config from 'marco/config/environment';
export default class PhotoCarousel extends Component {
@tracked canScrollLeft = false;
@@ -55,6 +56,8 @@ export default class PhotoCarousel extends Component {
}
});
+ isProgrammaticScroll = false;
+
scrollToNewPhoto = modifier((element, [eventId]) => {
if (eventId && eventId !== this.lastEventId) {
const isInitial = !this.lastEventId;
@@ -65,6 +68,8 @@ export default class PhotoCarousel extends Component {
return;
}
+ this.isProgrammaticScroll = true;
+
const scrollAction = () => {
const targetSlide = element.querySelector(
`[data-event-id="${eventId}"]`
@@ -78,11 +83,18 @@ export default class PhotoCarousel extends Component {
// Restore smooth scroll after the jump
setTimeout(() => {
element.style.scrollBehavior = originalScrollBehavior;
+ this.isProgrammaticScroll = false;
}, 50);
} else {
// Use native CSS smooth scrolling for subsequent clicks
element.scrollLeft = targetSlide.offsetLeft;
+ // Clear programmatic scroll flag after a delay to let scroll finish
+ setTimeout(() => {
+ this.isProgrammaticScroll = false;
+ }, 500);
}
+ } else {
+ this.isProgrammaticScroll = false;
}
};
@@ -111,10 +123,16 @@ export default class PhotoCarousel extends Component {
}
let intersectionObserver;
- if (this.args.onVisiblePhotoChange && window.IntersectionObserver) {
+ if (
+ this.args.onVisiblePhotoChange &&
+ window.IntersectionObserver &&
+ config.environment !== 'test'
+ ) {
// Set up intersection observer to track which photo is currently "most" visible
intersectionObserver = new IntersectionObserver(
(entries) => {
+ if (this.isProgrammaticScroll) return;
+
for (let entry of entries) {
if (entry.isIntersecting && entry.intersectionRatio >= 0.5) {
const eventId = entry.target.dataset.eventId;
diff --git a/app/components/photo-gallery.gjs b/app/components/photo-gallery.gjs
index 95de195..9bcd07d 100644
--- a/app/components/photo-gallery.gjs
+++ b/app/components/photo-gallery.gjs
@@ -1,17 +1,91 @@
import Component from '@glimmer/component';
-import { tracked } from '@glimmer/tracking';
-import { inject as service } from '@ember/service';
import { action } from '@ember/object';
+import { tracked } from '@glimmer/tracking';
import { on } from '@ember/modifier';
-import { modifier } from 'ember-modifier';
import { fn } from '@ember/helper';
+import { inject as service } from '@ember/service';
+import { modifier } from 'ember-modifier';
import { task } from 'ember-concurrency';
-import { EventFactory } from 'applesauce-core';
-import Icon from '#components/icon';
+import { EventFactory } from 'applesauce-factory';
+import config from 'marco/config/environment';
+import DropdownMenu from './dropdown-menu';
import PhotoCarousel from './photo-carousel';
-import DropdownMenu from '#components/dropdown-menu';
+import Icon from './icon';
+
+const GalleryContent =
+
+ {{! template-lint-disable no-invalid-interactive }}
+
+
+
+
+ {{#if @isCreator}}
+
+ {{/if}}
+
+
+
+
+
+
+
+
+
+
+;
export default class PhotoGallery extends Component {
+ get isTesting() {
+ return config.environment === 'test';
+ }
+
+ get destinationElement() {
+ return document.getElementById('modal-portal') || document.body;
+ }
+
@service toast;
@service nostrAuth;
@service nostrData;
@@ -174,67 +248,38 @@ export default class PhotoGallery extends Component {
});
-
- {{! template-lint-disable no-invalid-interactive }}
-
-
-
-
- {{#if this.isCreator}}
-
- {{/if}}
-
-
-
-
-
-
-
-
-
-
+ {{#if this.isTesting}}
+
+ {{else}}
+ {{#in-element this.destinationElement}}
+
+ {{/in-element}}
+ {{/if}}
}
diff --git a/index.html b/index.html
index 1dff21f..30eae7e 100644
--- a/index.html
+++ b/index.html
@@ -42,6 +42,7 @@
+