@loafmarkets/ui 0.1.413 → 0.1.414

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -2550,6 +2550,66 @@ function MobileDepthRow({
2550
2550
  }
2551
2551
  );
2552
2552
  }
2553
+ var isHlsManifest = (url) => /\.m3u8(\?|$)/i.test(url);
2554
+ var HLS_MIME = "application/vnd.apple.mpegurl";
2555
+ var MANIFEST_FAILURES = /* @__PURE__ */ new Set(["manifestLoadError", "manifestLoadTimeOut", "manifestParsingError"]);
2556
+ var HlsVideo = React5.forwardRef(
2557
+ ({ src, capLevelToPlayerSize = true, onError, ...videoProps }, ref) => {
2558
+ const videoRef = React5.useRef(null);
2559
+ React5.useImperativeHandle(ref, () => videoRef.current, []);
2560
+ const primary = typeof src === "string" ? src : src.src;
2561
+ const fallbackSrc = typeof src === "string" ? void 0 : src.fallbackSrc;
2562
+ const [failedSrc, setFailedSrc] = React5.useState(null);
2563
+ const usingFallback = fallbackSrc != null && failedSrc === primary;
2564
+ const activeSrc = usingFallback ? fallbackSrc : primary;
2565
+ const failPrimary = React5.useCallback(() => {
2566
+ if (fallbackSrc == null) return;
2567
+ setFailedSrc(primary);
2568
+ }, [fallbackSrc, primary]);
2569
+ React5.useEffect(() => {
2570
+ const video = videoRef.current;
2571
+ if (!video || !activeSrc) return;
2572
+ if (!isHlsManifest(activeSrc) || video.canPlayType(HLS_MIME)) {
2573
+ video.src = activeSrc;
2574
+ return;
2575
+ }
2576
+ let hls = null;
2577
+ let cancelled = false;
2578
+ void import('hls.js').then(({ default: Hls }) => {
2579
+ if (cancelled) return;
2580
+ if (!Hls.isSupported()) {
2581
+ video.src = activeSrc;
2582
+ return;
2583
+ }
2584
+ const instance = new Hls({
2585
+ capLevelToPlayerSize,
2586
+ startLevel: -1,
2587
+ enableWorker: true,
2588
+ startFragPrefetch: true
2589
+ });
2590
+ hls = instance;
2591
+ instance.on(Hls.Events.ERROR, (_evt, data) => {
2592
+ if (data?.fatal && MANIFEST_FAILURES.has(String(data.details))) failPrimary();
2593
+ });
2594
+ instance.loadSource(activeSrc);
2595
+ instance.attachMedia(video);
2596
+ });
2597
+ return () => {
2598
+ cancelled = true;
2599
+ hls?.destroy();
2600
+ };
2601
+ }, [activeSrc, capLevelToPlayerSize, failPrimary]);
2602
+ const handleError = React5.useCallback(
2603
+ (e) => {
2604
+ if (!usingFallback) failPrimary();
2605
+ onError?.(e);
2606
+ },
2607
+ [usingFallback, failPrimary, onError]
2608
+ );
2609
+ return /* @__PURE__ */ jsx("video", { ref: videoRef, onError: handleError, ...videoProps });
2610
+ }
2611
+ );
2612
+ HlsVideo.displayName = "HlsVideo";
2553
2613
  var PropertyTour = React5.forwardRef(
2554
2614
  ({
2555
2615
  className,
@@ -2564,11 +2624,6 @@ var PropertyTour = React5.forwardRef(
2564
2624
  ...props
2565
2625
  }, ref) => {
2566
2626
  const videoRef = React5.useRef(null);
2567
- React5.useEffect(() => {
2568
- if (videoRef.current && src) {
2569
- videoRef.current.load();
2570
- }
2571
- }, [src]);
2572
2627
  React5.useEffect(() => {
2573
2628
  const video = videoRef.current;
2574
2629
  if (!video) return;
@@ -2633,10 +2688,11 @@ var PropertyTour = React5.forwardRef(
2633
2688
  display: none !important;
2634
2689
  }
2635
2690
  ` }),
2636
- /* @__PURE__ */ jsxs(
2637
- "video",
2691
+ /* @__PURE__ */ jsx(
2692
+ HlsVideo,
2638
2693
  {
2639
2694
  ref: videoRef,
2695
+ src,
2640
2696
  className: "loaf-muted-video absolute inset-0 h-full w-full object-cover object-center",
2641
2697
  controls,
2642
2698
  controlsList: "nodownload noplaybackrate",
@@ -2650,10 +2706,7 @@ var PropertyTour = React5.forwardRef(
2650
2706
  muted,
2651
2707
  playsInline,
2652
2708
  poster,
2653
- children: [
2654
- /* @__PURE__ */ jsx("source", { src }),
2655
- "Your browser does not support the video tag."
2656
- ]
2709
+ children: "Your browser does not support the video tag."
2657
2710
  }
2658
2711
  )
2659
2712
  ] }) })
@@ -9772,8 +9825,9 @@ function GalleryMapSection({
9772
9825
  isMobile ? /* @__PURE__ */ jsx(StackedGallery, { images, onPhotoClick }) : /* @__PURE__ */ jsxs(Fragment, { children: [
9773
9826
  /* @__PURE__ */ jsxs(Carousel, { children: [
9774
9827
  showVideo && videoUrl && /* @__PURE__ */ jsx(VideoOverlay, { children: /* @__PURE__ */ jsx(
9775
- "video",
9828
+ HlsVideo,
9776
9829
  {
9830
+ src: videoUrl,
9777
9831
  autoPlay: true,
9778
9832
  loop: true,
9779
9833
  playsInline: true,
@@ -9782,8 +9836,7 @@ function GalleryMapSection({
9782
9836
  onVolumeChange: (e) => {
9783
9837
  if (!e.currentTarget.muted) e.currentTarget.muted = true;
9784
9838
  },
9785
- style: { width: "100%", height: "100%", objectFit: "cover", borderRadius: 8 },
9786
- children: /* @__PURE__ */ jsx("source", { src: videoUrl, type: "video/mp4" })
9839
+ style: { width: "100%", height: "100%", objectFit: "cover", borderRadius: 8 }
9787
9840
  }
9788
9841
  ) }),
9789
9842
  /* @__PURE__ */ jsx(Track, { style: { transform: `translateX(-${carouselIndex * 100}%)` }, children: images.map((img, idx) => /* @__PURE__ */ jsxs(Slide, { onClick: () => onPhotoClick?.(idx), children: [
@@ -9899,7 +9952,7 @@ function GalleryMapSection({
9899
9952
  showFullVideo && videoUrl && /* @__PURE__ */ jsxs(FullVideoOverlay, { onClick: () => setShowFullVideo(false), children: [
9900
9953
  /* @__PURE__ */ jsx(FullVideoClose, { onClick: () => setShowFullVideo(false), "aria-label": "Close video", children: "\u2715" }),
9901
9954
  /* @__PURE__ */ jsx(
9902
- "video",
9955
+ HlsVideo,
9903
9956
  {
9904
9957
  src: videoUrl,
9905
9958
  autoPlay: true,
@@ -19629,8 +19682,9 @@ function GalleryContent({ galleryImages, startIndex, startWithVideo, title, subt
19629
19682
  }
19630
19683
  ),
19631
19684
  showVideo && videoUrl ? /* @__PURE__ */ jsx(GalleryVideoWrap, { children: /* @__PURE__ */ jsx(
19632
- "video",
19685
+ HlsVideo,
19633
19686
  {
19687
+ src: videoUrl,
19634
19688
  autoPlay: true,
19635
19689
  loop: true,
19636
19690
  playsInline: true,
@@ -19639,8 +19693,7 @@ function GalleryContent({ galleryImages, startIndex, startWithVideo, title, subt
19639
19693
  onVolumeChange: (e) => {
19640
19694
  if (!e.currentTarget.muted) e.currentTarget.muted = true;
19641
19695
  },
19642
- style: { objectFit: "contain", borderRadius: 12, boxShadow: "0 30px 80px rgba(0,0,0,0.55)" },
19643
- children: /* @__PURE__ */ jsx("source", { src: videoUrl, type: "video/mp4" })
19696
+ style: { objectFit: "contain", borderRadius: 12, boxShadow: "0 30px 80px rgba(0,0,0,0.55)" }
19644
19697
  }
19645
19698
  ) }) : galleryImages.map((image, idx) => /* @__PURE__ */ jsx(MainImage, { src: image.src, alt: image.alt, $visible: idx === currentIndex }, image.alt)),
19646
19699
  galleryImages[currentIndex]?.hotspots?.map((hotspot) => /* @__PURE__ */ jsx(
@@ -20650,6 +20703,6 @@ var SparklineChart = React5__default.memo(function SparklineChart2({ data, width
20650
20703
  );
20651
20704
  });
20652
20705
 
20653
- export { AssetSelectorBar, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ContactPopup, Header, HousePositionSlider, HousePositionSliderMobile, LoafLiquidityBadge, LoafLiquidityLogo, LoginPopup, MobileTradeNav, OfferingProgressCard, OnboardingGuide, Orderbook, owner_booking_default as OwnerBooking, PaymentPopup, PortfolioActivityPanel, PortfolioSummary, PriceChart, PropertyBuy, PropertyCompareBar, PropertyDocuments, PropertyHeroHeader, PropertyHistory, PropertyInspectionTimes, PropertyMediaRow, PropertyNewsUpdates, PropertyOffers, PropertyOverview, PropertyPhotoGallery, PropertySubheader, PropertyTour, PropertyValuation, SiteFooter, Skeleton, SlideDigit, SparklineChart, ToastProvider, TradeConfirmationModal, TradingSlider, YourOrders, badgeVariants, buttonVariants, extractSparkline, hasPendingActivity, useAdaptivePolling, useToast };
20706
+ export { AssetSelectorBar, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ContactPopup, Header, HlsVideo, HousePositionSlider, HousePositionSliderMobile, LoafLiquidityBadge, LoafLiquidityLogo, LoginPopup, MobileTradeNav, OfferingProgressCard, OnboardingGuide, Orderbook, owner_booking_default as OwnerBooking, PaymentPopup, PortfolioActivityPanel, PortfolioSummary, PriceChart, PropertyBuy, PropertyCompareBar, PropertyDocuments, PropertyHeroHeader, PropertyHistory, PropertyInspectionTimes, PropertyMediaRow, PropertyNewsUpdates, PropertyOffers, PropertyOverview, PropertyPhotoGallery, PropertySubheader, PropertyTour, PropertyValuation, SiteFooter, Skeleton, SlideDigit, SparklineChart, ToastProvider, TradeConfirmationModal, TradingSlider, YourOrders, badgeVariants, buttonVariants, extractSparkline, hasPendingActivity, useAdaptivePolling, useToast };
20654
20707
  //# sourceMappingURL=index.mjs.map
20655
20708
  //# sourceMappingURL=index.mjs.map