diff --git a/packages/polymech/src/components/GalleryK.astro b/packages/polymech/src/components/GalleryK.astro index 98b4b34..7b1ce85 100644 --- a/packages/polymech/src/components/GalleryK.astro +++ b/packages/polymech/src/components/GalleryK.astro @@ -1,17 +1,17 @@ --- import { Img } from "imagetools/components"; -import Translate from "./i18n.astro" +import Translate from "./i18n.astro"; import { translate } from "../base/i18n"; -import { I18N_SOURCE_LANGUAGE, IMAGE_SETTINGS } from "../app/config.js" +import { I18N_SOURCE_LANGUAGE, IMAGE_SETTINGS } from "../app/config.js"; interface Image { - alt: string - src: string - title?: string - description?: string - hash?: string + alt: string; + src: string; + title?: string; + description?: string; + hash?: string; } export interface Props { @@ -37,282 +37,620 @@ export interface Props { const { images, gallerySettings = {}, lightboxSettings = {}, s } = Astro.props; const mergedGallerySettings = { - SIZES_REGULAR: gallerySettings.SIZES_REGULAR || IMAGE_SETTINGS.gallery.sizes_regular, - SIZES_THUMB: gallerySettings.SIZES_THUMB || IMAGE_SETTINGS.gallery.sizes_thumb, + SIZES_REGULAR: + gallerySettings.SIZES_REGULAR || IMAGE_SETTINGS.gallery.sizes_regular, + SIZES_THUMB: + gallerySettings.SIZES_THUMB || IMAGE_SETTINGS.gallery.sizes_thumb, SHOW_TITLE: gallerySettings.SHOW_TITLE ?? IMAGE_SETTINGS.gallery.show_title, - SHOW_DESCRIPTION: gallerySettings.SHOW_DESCRIPTION ?? IMAGE_SETTINGS.gallery.show_description, + SHOW_DESCRIPTION: + gallerySettings.SHOW_DESCRIPTION ?? IMAGE_SETTINGS.gallery.show_description, }; const mergedLightboxSettings = { - SIZES_LARGE: lightboxSettings.SIZES_LARGE || IMAGE_SETTINGS.lightbox.sizes_large, + SIZES_LARGE: + lightboxSettings.SIZES_LARGE || IMAGE_SETTINGS.lightbox.sizes_large, SHOW_TITLE: lightboxSettings.SHOW_TITLE ?? IMAGE_SETTINGS.lightbox.show_title, - SHOW_DESCRIPTION: lightboxSettings.SHOW_DESCRIPTION ?? IMAGE_SETTINGS.lightbox.show_description, + SHOW_DESCRIPTION: + lightboxSettings.SHOW_DESCRIPTION ?? + IMAGE_SETTINGS.lightbox.show_description, }; const locale = Astro.currentLocale || "en"; +// Pre-calculate translations to allow await usage (which isn't allowed effectively in synchronous JSX map) +const translatedImages = await Promise.all( + images.map(async (img) => ({ + ...img, + localizedAlt: await translate(img.alt, I18N_SOURCE_LANGUAGE, locale), + // We can also pre-calculate description if we wanted to avoid the component for consistency, + // but component is likely handling it fine. + // However, for JS safety let's assume raw string access in logic might benefit from it if we moved it to vanilla, + // but here it's about the 'attributes' prop in Img. + })), +); ---
1) return; // Disable swipe when zoomed - const swipeDistance = this.touchEndX - this.touchStartX; - if (Math.abs(swipeDistance) >= this.minSwipeDistance) { - if (swipeDistance > 0 && this.currentIndex > 0) { - // Swiped right, show previous image - this.currentIndex--; - this.resetZoom(); - } else if (swipeDistance < 0 && this.currentIndex < this.total - 1) { - // Swiped left, show next image - this.currentIndex++; - this.resetZoom(); - } - } - this.isSwiping = false; - }, - preloadAndOpen() { - if (this.isSwiping) return; - this.lightboxLoaded = false; - this.resetZoom(); - let img = new Image(); - img.src = this.images[this.currentIndex].src; - img.onload = () => { - this.lightboxLoaded = true; - this.open = true; - }; - }, - preloadImage(index) { - // Preload without affecting lightboxLoaded state (for navigation within lightbox) - this.resetZoom(); - let img = new Image(); - img.src = this.images[index].src; - // No need to wait for load when navigating within lightbox - }, - handleImageInteraction(index) { - const currentTime = Date.now(); - const timeDiff = currentTime - this.lastTapTime; - - if (timeDiff < this.doubleTapDelay) { - // Double tap/click detected - open lightbox - this.currentIndex = index; - this.preloadAndOpen(); - } else { - // Single tap/click - just change current image - this.currentIndex = index; - } - - this.lastTapTime = currentTime; - }, - resetZoom() { - this.scale = 1; - this.panX = 0; - this.panY = 0; - this.isPanning = false; - }, - handleWheel(e) { - e.preventDefault(); - const zoomSpeed = 0.1; - const newScale = this.scale - Math.sign(e.deltaY) * zoomSpeed; - this.scale = Math.min(Math.max(1, newScale), 5); // Limit zoom between 1x and 5x - - if (this.scale === 1) { - this.panX = 0; - this.panY = 0; - } - }, - handlePanStart(e) { - if (this.scale <= 1) return; - this.isPanning = true; - this.startPanX = e.clientX - this.panX; - this.startPanY = e.clientY - this.panY; - e.preventDefault(); - }, - handlePanMove(e) { - if (!this.isPanning) return; - e.preventDefault(); - this.panX = e.clientX - this.startPanX; - this.panY = e.clientY - this.startPanY; - }, - handlePanEnd(e) { - this.isPanning = false; - }, - toggleZoom(e) { - if (this.scale > 1) { - this.resetZoom(); - } else { - this.scale = 2; // Zoom to 2x on double click - } - } - } - `} - @keydown.escape.window="open = false" - @keydown.window="if(open){ - if($event.key === 'ArrowRight' && currentIndex < total - 1){ - currentIndex++; - preloadImage(currentIndex); - } else if($event.key === 'ArrowLeft' && currentIndex > 0){ - currentIndex--; - preloadImage(currentIndex); - } - }" - class="product-gallery bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden">
+ class="product-gallery bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden" + data-images={JSON.stringify(translatedImages)} + data-total={translatedImages.length} +> +
-
- {images.map((image, index) => ( -
- {image.alt,I18N_SOURCE_LANGUAGE,locale} -
- ))} -
- - { (images.some(img => (mergedGallerySettings.SHOW_TITLE && img.title && img.title.trim().length > 0) || (mergedGallerySettings.SHOW_DESCRIPTION && img.description && img.description.trim().length > 0))) && ( -
- {images.map((image, index) => ( -
- { mergedGallerySettings.SHOW_TITLE && image.title && image.title.trim().length > 0 && (

{image.title}

)} - { mergedGallerySettings.SHOW_DESCRIPTION && image.description && image.description.trim().length > 0 && (

{ image.description}

)} -
- ))} -
- )} - -
-
- {images.map((image, index) => ( - - ))} +
+ )) + } +
+ + + { + translatedImages.some( + (img) => + (mergedGallerySettings.SHOW_TITLE && + img.title && + img.title.trim().length > 0) || + (mergedGallerySettings.SHOW_DESCRIPTION && + img.description && + img.description.trim().length > 0), + ) && ( + + ) + } + + +
+
+ { + translatedImages.map((image, index) => ( + + )) + }
- + + +
+ + diff --git a/packages/polymech/src/components/store/Checkout.astro b/packages/polymech/src/components/store/Checkout.astro index b150e88..60b038c 100644 --- a/packages/polymech/src/components/store/Checkout.astro +++ b/packages/polymech/src/components/store/Checkout.astro @@ -315,11 +315,10 @@ const products = [
    + { { products.map((product) => ( -
  • +
  • @@ -405,3 +403,16 @@ const products = [
    + +