unified-video-framework
Version:
Cross-platform video player framework supporting iOS, Android, Web, Smart TVs (Samsung/LG), Roku, and more
77 lines • 4.37 kB
JavaScript
import React, { useState, useEffect } from "react";
export default function ProductBadge({ product, overlay, onClick }) {
console.log('[COMMERCE] 🎨 Rendering ProductBadge:', product.id, product.title);
const [isPaused, setIsPaused] = useState(false);
const [controlsVisible, setControlsVisible] = useState(false);
const showPrice = overlay.style?.badge?.showPrice !== false;
const showThumb = overlay.style?.badge?.showThumb !== false;
useEffect(() => {
const checkPauseState = () => {
const video = document.querySelector('.uvf-video');
if (video) {
const newPausedState = video.paused;
setIsPaused(newPausedState);
console.log('[COMMERCE] Video paused state:', newPausedState, 'video element:', !!video);
}
};
const checkControlsVisible = () => {
const wrapper = document.querySelector('.uvf-player-wrapper');
const visible = (wrapper?.classList.contains('controls-visible') ?? false) || (wrapper?.matches(':hover') ?? false);
setControlsVisible(visible);
};
const video = document.querySelector('.uvf-video');
const wrapper = document.querySelector('.uvf-player-wrapper');
console.log('[COMMERCE] Setup - video element found:', !!video, 'wrapper found:', !!wrapper);
const pausePollInterval = setInterval(checkPauseState, 100);
const controlsPollInterval = setInterval(checkControlsVisible, 100);
let observer = null;
if (wrapper) {
observer = new MutationObserver(checkControlsVisible);
observer.observe(wrapper, { attributes: true, attributeFilter: ['class'] });
checkControlsVisible();
}
checkPauseState();
return () => {
clearInterval(pausePollInterval);
clearInterval(controlsPollInterval);
if (observer) {
observer.disconnect();
}
};
}, []);
console.log('[COMMERCE] Rendering - isPaused:', isPaused, 'controlsVisible:', controlsVisible);
const placementMode = overlay.placement?.mode ?? "dock";
const placementEdge = overlay.placement?.mode === "dock" ? (overlay.placement?.edge ?? "bottom") : undefined;
const base = {
position: "fixed",
bottom: placementMode === "dock" && placementEdge === "bottom"
? ((isPaused || controlsVisible) ? 155 : 16)
: placementMode !== "anchor" ? ((isPaused || controlsVisible) ? 155 : 16)
: undefined,
top: placementMode === "dock" && placementEdge === "top" ? 25 : undefined,
left: placementMode === "dock" && placementEdge === "left" ? 25 : (placementMode === "anchor" ? undefined : 25),
right: placementMode === "dock" && placementEdge === "right" ? 25 : undefined,
background: "rgba(0,0,0,0.6)",
backdropFilter: "blur(8px)",
border: "1px solid rgba(255,255,255,0.2)",
borderRadius: 12,
padding: "8px 12px",
display: "flex",
alignItems: "center",
gap: 8,
cursor: "pointer",
pointerEvents: "auto",
zIndex: overlay.behavior?.zIndex ?? 300,
transition: "bottom 0.3s ease",
};
if (placementMode === "anchor" && overlay.placement && 'x' in overlay.placement && 'y' in overlay.placement) {
base.left = `calc(${overlay.placement.x}% - 60px)`;
base.top = `calc(${overlay.placement.y}% - 20px)`;
}
return (React.createElement("div", { style: base, onClick: () => onClick(product), "aria-label": `View ${product.title}` },
showThumb && product.thumbnails.square && (React.createElement("img", { src: product.thumbnails.square, alt: "", width: 32, height: 32, style: { borderRadius: 6, objectFit: "cover" } })),
React.createElement("div", { style: { display: "grid", gap: 2 } },
React.createElement("div", { style: { color: "#fff", fontSize: 13, fontWeight: 600, lineHeight: 1.1 } }, product.title),
showPrice && (React.createElement("div", { style: { color: "#FFD166", fontSize: 12 } }, product.pricing.priceText ?? `${product.pricing.currency} ${product.pricing.amount}`)))));
}
//# sourceMappingURL=ProductBadge.js.map