Regular price$10.00
/
- Free worldwide shipping
${unmuteText}
`; const productTpl = (product, shopText) => { const thumbnailUrl = product.featuredImage && product.featuredImage.url; return `
${ product.title } ${ product.price } ${shopText}`; }; const reelTpl = ({ id, Video, product }, textsConfig, shouldHideLogo) => { return `
${product?.title ? productTpl(product, textsConfig.shopText) : ""} ${ !shouldHideLogo ? `Powered by SwipeUp` : "" }
${muteControlsTpl(textsConfig)}
`; }; let activeVideo; const sendAnalyticsEvent = (params) => { const qs = new URLSearchParams(params).toString(); return fetch(`/apps/swipeup/client-api/event?${qs}`).catch((e) => console.log("Fetch error", e) ); }; const initViewer = ({ activators, feed, overlayId, textsConfig }) => { // styles const styles = shadowRootEl.getElementById(`SwipeUp-overlay_styles_${overlayId}`); styles.remove(); shadowEl.appendChild(styles); const link = shadowRootEl.querySelector('link'); link.remove(); shadowEl.appendChild(link); // overlay const overlay = shadowRootEl.getElementById(`SwipeUp-overlay_${overlayId}`); overlay.remove(); shadowEl.appendChild(overlay); const overlayContent = overlay.querySelector(".SwipeUp-overlay-content"); const shouldHideLogo = Boolean(feed.shouldHideLogo); const reelsCount = feed.Reels.length; overlayContent.innerHTML = feed.Reels.map((item) => reelTpl(item, textsConfig, shouldHideLogo) ).join(""); function lockBodyScroll(locked) { if (!locked) { const offsetY = Math.abs(parseInt(document.body.style.top || 0, 10)); document.body.classList.remove("SwipeUpLockScroll"); document.body.style.removeProperty("top"); document.body.style.removeProperty("left"); document.body.style.removeProperty("right"); window.scrollTo(0, offsetY || 0); } else { // Lock body scroll (hack for iOS) const offsetY = window.pageYOffset; document.body.style.top = `${-offsetY}px`; document.body.style.left = "0"; document.body.style.right = "0"; document.body.classList.add("SwipeUpLockScroll"); } } const scrollFeed = (type, count = 1, instant = false) => { const height = firstReel.clientHeight; const scrollAmount = height * count; const scrollAmountVec = type === "next" ? scrollAmount : -scrollAmount; if (instant) { overlayContent.scrollTop += scrollAmountVec; overlayContent.style.opacity = 1; } else { overlayContent.scrollBy({ top: scrollAmountVec, behavior: "smooth", }); } }; const onNextPress = () => { scrollFeed("next"); }; const onPrevPress = () => { scrollFeed("prev"); }; const overlayCloseBtn = overlay.querySelector(".SwipeUp-overlay-close"); const firstReel = overlay.querySelector(".SwipeUp-reel"); const nextBtn = overlay.querySelector(".SwipeUp-next"); const prevBtn = overlay.querySelector(".SwipeUp-prev"); nextBtn.addEventListener("click", onNextPress); prevBtn.addEventListener("click", onPrevPress); const activatorClickHandler = (event) => { event.preventDefault(); lockBodyScroll(true); const reelIndex = Number(event.target.dataset.reelidx); if (reelIndex) { overlayContent.style.opacity = 0; } overlay.style.display = "block"; if (reelIndex) { scrollFeed("next", reelIndex, true); } if (reelsCount > 1 && localStorage.getItem('swipeup-viewer-tutorial-seen') !== 'true') { if (reelIndex === reelsCount - 1) { overlayContent.classList.add('SwipeUp-overlay-content_withTutorial_down') } else { overlayContent.classList.add('SwipeUp-overlay-content_withTutorial') } } function hideOverlay() { lockBodyScroll(false); overlayContent.scrollTop = 0; overlay.style.display = "none"; document.removeEventListener("keyup", keyPressHandler); overlay.removeEventListener("click", clickHandler); overlayCloseBtn.removeEventListener("click", closeBtnHandler); overlayContent.classList.remove('SwipeUp-overlay-content_withTutorial'); overlayContent.classList.remove('SwipeUp-overlay-content_withTutorial_down'); activeVideo = null; } function clickHandler(event) { if (event.target === event.currentTarget) { hideOverlay(); } } function closeBtnHandler() { hideOverlay(); } function keyPressHandler(event) { if (event.key === "Escape") { hideOverlay(); } } document.addEventListener("keyup", keyPressHandler); overlay.addEventListener("click", clickHandler); overlayCloseBtn.addEventListener("click", closeBtnHandler); localStorage.setItem('swipeup-viewer-tutorial-seen', 'true'); shadowRoot.SwipeUp.sendAnalyticsEvent({ type: 'widgetClick' }); }; // TODO: maybe a better check like instanceof NodeList if (activators.length) { activators.forEach((activator) => activator.addEventListener("click", activatorClickHandler) ); } else { activators.addEventListener("click", activatorClickHandler); } }; // Lazy loading code const initViewerVideos = (isDesignMode) => { let muted = true; const muteButtons = shadowEl.querySelectorAll(".SwipeUp-Mute"); const unmuteButtons = shadowEl.querySelectorAll(".SwipeUp-Unmute"); const productCards = shadowEl.querySelectorAll(".reel-product-link"); if (!isDesignMode) { productCards.forEach((card) => { card.addEventListener("click", () => { sendAnalyticsEvent({ type: "productClick" }); }); }); } muteButtons.forEach((btn) => btn.addEventListener("click", () => { if (activeVideo) { activeVideo.muted = true; } muted = true; muteButtons.forEach((btn) => (btn.style.display = "none")); unmuteButtons.forEach((btn) => (btn.style.display = "flex")); }) ); unmuteButtons.forEach((btn) => btn.addEventListener("click", () => { if (activeVideo) { activeVideo.muted = false; } muted = false; muteButtons.forEach((btn) => (btn.style.display = "flex")); unmuteButtons.forEach((btn) => (btn.style.display = "none")); }) ); const reelVideos = shadowEl.querySelectorAll(".reel-video-full"); if (reelVideos[0]) { reelVideos[0].autoplay = "true"; reelVideos[0].preload = "auto"; } const reportVideoView = (id) => sendAnalyticsEvent({ type: "reelView", id }); const observer = new IntersectionObserver( (entries) => { for (const entry of entries) { if (entry.intersectionRatio > 0.9) { if (entry.target !== activeVideo && !isDesignMode) { reportVideoView(entry.target.dataset.reelid); } entry.target.play(); entry.target.muted = muted; activeVideo = entry.target; const sibling = entry.target.parentNode.parentNode.nextElementSibling; if (sibling) { const nextVideo = sibling.querySelector("video"); if (nextVideo) { nextVideo.preload = "auto"; } } } else { entry.target.pause(); entry.target.currentTime = 0; } } }, { threshold: 0.9 } ); for (const reel of reelVideos) { observer.observe(reel); reel.addEventListener("canplay", (e) => { reel.parentNode.parentNode.querySelector( ".SwipeUpReel-Skeleton" ).style.display = "none"; reel.parentNode.querySelector( ".reel-bubble-product-card" ).style.display = "flex"; }); reel.addEventListener("click", (e) => { const videoEl = e.target; if (!videoEl.paused) { videoEl.pause(); } else { videoEl.play(); } }); } }; // viewer in shadowDom shadowRoot.SwipeUp = window.SwipeUp || {}; shadowRoot.SwipeUp.viewerLoaded = true; shadowRoot.SwipeUp.initViewer = initViewer; shadowRoot.SwipeUp.initViewerVideos = initViewerVideos; shadowRoot.SwipeUp.sendAnalyticsEvent = sendAnalyticsEvent; shadowRoot.dispatchEvent(new Event("SwipeUp::ViewerLoaded")); } }); })();
${limitProductName(reelProductName)}
${reelProductPrice}