pb-sxp-ui 1.20.43 → 1.20.44

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.cjs CHANGED
@@ -2224,7 +2224,7 @@ const EditorCore = React.forwardRef(({ children, resolver, isSsr, schema, enable
2224
2224
  * @returns isVisible 是否可见
2225
2225
  */
2226
2226
  function useAdvancedOnScreen(ref, options = {}) {
2227
- const { threshold = 0, delay = 0, onVisible, onHidden } = options;
2227
+ const { threshold = 0, delay = 0, onVisible, onHidden, name = 'unknown' } = options;
2228
2228
  const observerRef = React.useRef(null);
2229
2229
  const [isVisible, setIsVisible] = React.useState(false);
2230
2230
  const timerRef = React.useRef(null);
@@ -2250,7 +2250,7 @@ function useAdvancedOnScreen(ref, options = {}) {
2250
2250
  var _a, _b;
2251
2251
  const isIntersecting = entry.isIntersecting;
2252
2252
  const intersectionRatio = entry.intersectionRatio;
2253
- console.log('[useAdvancedOnScreen] IntersectionObserver callback:', {
2253
+ console.log(`[useAdvancedOnScreen ${name}] IntersectionObserver callback:`, {
2254
2254
  isIntersecting,
2255
2255
  threshold,
2256
2256
  delay,
@@ -2262,18 +2262,18 @@ function useAdvancedOnScreen(ref, options = {}) {
2262
2262
  if (isIntersecting && intersectionRatio >= threshold) {
2263
2263
  // 元素进入可视区域且达到阈值
2264
2264
  setIsVisible(true);
2265
- // 如果已经在等待中,不要重复设置定时器
2265
+ // 如果已经在等待中,清除旧的定时器,重新开始计时
2266
2266
  if (isWaitingRef.current) {
2267
- console.log('[useAdvancedOnScreen] 已在等待中,跳过');
2268
- return;
2267
+ console.log(`[useAdvancedOnScreen ${name}] 已在等待中,清除旧定时器并重新计时`);
2268
+ clearTimer();
2269
2269
  }
2270
2270
  // 如果设置了延迟时间
2271
2271
  if (delay > 0) {
2272
- console.log(`[useAdvancedOnScreen] 设置延迟定时器: ${delay}ms`);
2272
+ console.log(`[useAdvancedOnScreen ${name}] 设置延迟定时器: ${delay}ms`);
2273
2273
  isWaitingRef.current = true;
2274
2274
  timerRef.current = setTimeout(() => {
2275
2275
  var _a;
2276
- console.log('[useAdvancedOnScreen] 延迟时间到,触发 onVisible');
2276
+ console.log(`[useAdvancedOnScreen ${name}] 延迟时间到,触发 onVisible`);
2277
2277
  isWaitingRef.current = false;
2278
2278
  timerRef.current = null;
2279
2279
  (_a = onVisibleRef.current) === null || _a === void 0 ? void 0 : _a.call(onVisibleRef);
@@ -2281,13 +2281,13 @@ function useAdvancedOnScreen(ref, options = {}) {
2281
2281
  }
2282
2282
  else {
2283
2283
  // 没有延迟,立即触发
2284
- console.log('[useAdvancedOnScreen] 无延迟,立即触发 onVisible');
2284
+ console.log(`[useAdvancedOnScreen ${name}] 无延迟,立即触发 onVisible`);
2285
2285
  (_a = onVisibleRef.current) === null || _a === void 0 ? void 0 : _a.call(onVisibleRef);
2286
2286
  }
2287
2287
  }
2288
2288
  else if (!isIntersecting || intersectionRatio < threshold) {
2289
2289
  // 元素离开可视区域或未达到阈值
2290
- console.log('[useAdvancedOnScreen] 元素离开可视区域或未达到阈值,清除定时器');
2290
+ console.log(`[useAdvancedOnScreen ${name}] 元素离开可视区域或未达到阈值,清除定时器`);
2291
2291
  setIsVisible(false);
2292
2292
  clearTimer();
2293
2293
  (_b = onHiddenRef.current) === null || _b === void 0 ? void 0 : _b.call(onHiddenRef);
@@ -19624,32 +19624,54 @@ const ProductView = ({ children, onExposure }) => {
19624
19624
  });
19625
19625
  return (React.createElement("div", { ref: productRef, style: { width: '100%' } }, children));
19626
19626
  };
19627
- const PostView = ({ children, videoRef, isVideo, onExposure, onVideoAutoPlay }) => {
19627
+ const PostView = ({ children, videoRef, isVideo, onExposure, autoPlayTriggerRef, onVideoPlay, onVideoPause }) => {
19628
19628
  const postRef = React.useRef(null);
19629
19629
  // 使用高级曝光检测:2/3区域(threshold=0.67)+ 1000ms延迟
19630
19630
  useAdvancedOnScreen(postRef, {
19631
19631
  threshold: 0.67,
19632
19632
  delay: 1000,
19633
19633
  onVisible: () => {
19634
+ console.log('[PostView onVisible] 触发,isVideo:', isVideo, 'hasVideoRef:', !!(videoRef === null || videoRef === void 0 ? void 0 : videoRef.current));
19634
19635
  // 每次进入2/3区域并停留1秒后都触发曝光上报
19635
19636
  if (onExposure) {
19636
19637
  onExposure();
19637
19638
  }
19638
19639
  // 如果是视频,自动播放
19639
19640
  if (isVideo && (videoRef === null || videoRef === void 0 ? void 0 : videoRef.current)) {
19640
- videoRef.current.play().catch(err => {
19641
+ console.log('[PostView onVisible] 准备播放视频');
19642
+ // 标记这次播放是自动触发的
19643
+ if (autoPlayTriggerRef) {
19644
+ autoPlayTriggerRef.current = true;
19645
+ console.log('[PostView onVisible] 已设置自动播放标记');
19646
+ }
19647
+ videoRef.current.play().then(() => {
19648
+ console.log('[PostView onVisible] 视频 play() 成功');
19649
+ // 触发播放回调,更新暂停图标状态
19650
+ if (onVideoPlay) {
19651
+ onVideoPlay();
19652
+ }
19653
+ }).catch(err => {
19641
19654
  console.warn('[PostView] Video autoplay failed:', err);
19655
+ // 播放失败时重置标记
19656
+ if (autoPlayTriggerRef) {
19657
+ autoPlayTriggerRef.current = false;
19658
+ }
19642
19659
  });
19643
- // 触发自动播放回调(用于上报 playVideo 事件)
19644
- onVideoAutoPlay === null || onVideoAutoPlay === void 0 ? void 0 : onVideoAutoPlay();
19645
19660
  }
19646
19661
  },
19647
19662
  onHidden: () => {
19663
+ console.log('[PostView onHidden] 触发,isVideo:', isVideo, 'hasVideoRef:', !!(videoRef === null || videoRef === void 0 ? void 0 : videoRef.current));
19648
19664
  // 如果是视频,离开2/3区域时自动暂停
19649
19665
  if (isVideo && (videoRef === null || videoRef === void 0 ? void 0 : videoRef.current)) {
19666
+ console.log('[PostView onHidden] 暂停视频');
19650
19667
  videoRef.current.pause();
19668
+ // 触发暂停回调,更新暂停图标状态
19669
+ if (onVideoPause) {
19670
+ onVideoPause();
19671
+ }
19651
19672
  }
19652
- }
19673
+ },
19674
+ name: 'PostView(Hero)'
19653
19675
  });
19654
19676
  return (React.createElement("div", { ref: postRef, style: { width: '100%', height: '100%' } }, children));
19655
19677
  };
@@ -20015,6 +20037,11 @@ const StructurePage = (_a) => {
20015
20037
  const isFirstPlay = React.useRef({});
20016
20038
  const videoLoadTime = React.useRef({});
20017
20039
  const videoAutoPlayReported = React.useRef(new Set()); // 追踪哪些视频已通过自动播放上报
20040
+ // 自动播放触发标记(用于区分自动播放和用户手动播放)
20041
+ const heroAutoPlayTrigger = React.useRef(false);
20042
+ const carouselAutoPlayTriggers = React.useRef({});
20043
+ // 追踪当前正在播放的 Carousel 视频索引(用于 onHidden 回调)
20044
+ const currentPlayingCarouselIndex = React.useRef(-1);
20018
20045
  // 调试日志
20019
20046
  console.log('[StructurePage] Props:', {
20020
20047
  editorMode,
@@ -20251,17 +20278,35 @@ const StructurePage = (_a) => {
20251
20278
  ctaEvent === null || ctaEvent === void 0 ? void 0 : ctaEvent(Object.assign({ eventSubject: 'ctaExposure', eventDescription: 'The cta was shown to the user' }, (viewPosition && { viewPosition })), rec, productData, sectionIndex !== undefined ? sectionIndex : 0);
20252
20279
  }, [ctaEvent, data]);
20253
20280
  // 视频播放事件处理
20254
- const handleVideoPlay = React.useCallback((videoData, viewPosition, sectionIndex, videoRef, isAutoPlay = false) => {
20255
- if (!videoRef || !videoRef.duration)
20281
+ const handleVideoPlay = React.useCallback((videoData, viewPosition, sectionIndex, videoRef) => {
20282
+ console.log('[handleVideoPlay] 调用,viewPosition:', viewPosition, 'sectionIndex:', sectionIndex, 'hasDuration:', !!(videoRef === null || videoRef === void 0 ? void 0 : videoRef.duration));
20283
+ if (!videoRef || !videoRef.duration) {
20284
+ console.log('[handleVideoPlay] 返回:没有 videoRef 或 duration');
20256
20285
  return;
20286
+ }
20257
20287
  const videoId = `${videoData === null || videoData === void 0 ? void 0 : videoData.itemId}-${viewPosition}-${sectionIndex}`;
20258
- // 如果是自动播放调用,标记为已上报
20288
+ // 检查是否是自动播放触发的
20289
+ let isAutoPlay = false;
20290
+ if (viewPosition === 'heroSection' && heroAutoPlayTrigger.current) {
20291
+ isAutoPlay = true;
20292
+ console.log('[handleVideoPlay] Hero Section 自动播放标记为 true');
20293
+ heroAutoPlayTrigger.current = false; // 重置标记
20294
+ }
20295
+ else if (viewPosition === 'carouselSection' && sectionIndex !== undefined && carouselAutoPlayTriggers.current[sectionIndex]) {
20296
+ isAutoPlay = true;
20297
+ console.log('[handleVideoPlay] Carousel Section 自动播放标记为 true, index:', sectionIndex);
20298
+ carouselAutoPlayTriggers.current[sectionIndex] = false; // 重置标记
20299
+ }
20300
+ console.log('[handleVideoPlay] isAutoPlay:', isAutoPlay, 'videoId:', videoId);
20301
+ // 如果是自动播放,标记为已上报
20259
20302
  if (isAutoPlay) {
20260
20303
  videoAutoPlayReported.current.add(videoId);
20304
+ console.log('[handleVideoPlay] 标记为已通过自动播放上报');
20261
20305
  }
20262
20306
  else {
20263
20307
  // 如果不是自动播放,但已经通过自动播放上报过,则跳过
20264
20308
  if (videoAutoPlayReported.current.has(videoId)) {
20309
+ console.log('[handleVideoPlay] 跳过上报:已经通过自动播放上报过');
20265
20310
  // 只记录播放时间,不上报
20266
20311
  videoStartTime.current[videoId] = videoRef.currentTime || 0;
20267
20312
  return;
@@ -20274,6 +20319,14 @@ const StructurePage = (_a) => {
20274
20319
  isFirstPlay.current[videoId] = false;
20275
20320
  const videoDuration = videoRef.duration.toFixed(2);
20276
20321
  const startTime = videoRef.currentTime.toFixed(2);
20322
+ console.log('[handleVideoPlay] 准备上报 playVideo 事件:', {
20323
+ videoId,
20324
+ isAutoPlay,
20325
+ playType,
20326
+ viewPosition,
20327
+ sectionIndex,
20328
+ duration: videoDuration
20329
+ });
20277
20330
  bffEventReport === null || bffEventReport === void 0 ? void 0 : bffEventReport({
20278
20331
  eventInfo: Object.assign({ eventSubject: 'playVideo', eventDescription: 'User played the video', sceneId: '', contentId: (videoData === null || videoData === void 0 ? void 0 : videoData.itemId) || '', contentName: (videoData === null || videoData === void 0 ? void 0 : videoData.title) || '', playType,
20279
20332
  startTime,
@@ -20584,13 +20637,18 @@ const StructurePage = (_a) => {
20584
20637
  // 2. propMultiCTAConfig 只是样式配置,不是数据源
20585
20638
  // 3. 数据获取只应该在组件挂载时执行一次(除非 apiUrl/storyId 等关键参数变化)
20586
20639
  // Hero Section 视频自动播放
20587
- React.useEffect(() => {
20588
- var _a;
20589
- if (heroVideoRef.current && ((_a = data === null || data === void 0 ? void 0 : data.heroSection) === null || _a === void 0 ? void 0 : _a.url)) {
20590
- heroVideoRef.current.play().catch((err) => console.log('Video autoplay failed:', err));
20591
- setIsHeroVideoPaused(false);
20592
- }
20593
- }, [data === null || data === void 0 ? void 0 : data.heroSection]);
20640
+ // 注意:视频的自动播放逻辑由 PostView 组件处理(进入2/3可视区域并停留1秒后播放)
20641
+ // 移除了初始播放逻辑,避免与 PostView 冲突,确保视频加载完成后再播放
20642
+ // useEffect(() => {
20643
+ // if (heroVideoRef.current && data?.heroSection?.url) {
20644
+ // heroAutoPlayTrigger.current = true;
20645
+ // heroVideoRef.current.play().catch((err) => {
20646
+ // console.log('Video autoplay failed:', err);
20647
+ // heroAutoPlayTrigger.current = false;
20648
+ // });
20649
+ // setIsHeroVideoPaused(false);
20650
+ // }
20651
+ // }, [data?.heroSection]);
20594
20652
  // 初始化 carousel 视频暂停状态
20595
20653
  React.useEffect(() => {
20596
20654
  if (data === null || data === void 0 ? void 0 : data.carouselSection) {
@@ -20635,7 +20693,7 @@ const StructurePage = (_a) => {
20635
20693
  }, []);
20636
20694
  // Post 图片/视频曝光上报(用于 Hero Section 等非轮播的 Post)
20637
20695
  const postExposureReported = React.useRef(new Set());
20638
- const handlePostExposure = React.useCallback((postData, viewPosition, sectionIndex) => {
20696
+ React.useCallback((postData, viewPosition, sectionIndex) => {
20639
20697
  var _a;
20640
20698
  const postId = `${postData === null || postData === void 0 ? void 0 : postData.itemId}-${viewPosition}-${sectionIndex}`;
20641
20699
  // 防止重复上报
@@ -20732,26 +20790,87 @@ const StructurePage = (_a) => {
20732
20790
  // Carousel Section 的曝光检测 ref
20733
20791
  const carouselSectionRef = React.useRef(null);
20734
20792
  const hasCarouselReported = React.useRef(false);
20735
- // Carousel Section 进入可视区域时上报第一张图片的浏览事件
20793
+ // Carousel Section 进入可视区域时的回调
20794
+ const handleCarouselVisible = React.useCallback(() => {
20795
+ if (!(data === null || data === void 0 ? void 0 : data.carouselSection) || data.carouselSection.length === 0)
20796
+ return;
20797
+ const currentItem = data.carouselSection[carouselIndex];
20798
+ console.log('[Carousel onVisible] 当前索引:', carouselIndex, '是否是视频:', !!(currentItem === null || currentItem === void 0 ? void 0 : currentItem.url));
20799
+ // 只在首次进入可视区域时上报第一张图片
20800
+ if (!hasCarouselReported.current) {
20801
+ hasCarouselReported.current = true;
20802
+ // 只对图片类型上报(不包括视频)
20803
+ if (!currentItem.url) {
20804
+ handleCarouselImageStartEvent(carouselIndex);
20805
+ }
20806
+ }
20807
+ // 如果当前项是视频,自动播放
20808
+ if ((currentItem === null || currentItem === void 0 ? void 0 : currentItem.url) && carouselVideoRefs.current[carouselIndex]) {
20809
+ const currentVideo = carouselVideoRefs.current[carouselIndex];
20810
+ if (currentVideo) {
20811
+ console.log('[Carousel onVisible] 开始播放视频,索引:', carouselIndex);
20812
+ // 更新当前正在播放的视频索引
20813
+ currentPlayingCarouselIndex.current = carouselIndex;
20814
+ // 标记这次播放是自动触发的
20815
+ carouselAutoPlayTriggers.current[carouselIndex] = true;
20816
+ currentVideo.play().catch(err => {
20817
+ console.warn('[Carousel] Video autoplay failed (onVisible):', err);
20818
+ // 播放失败时重置标记
20819
+ carouselAutoPlayTriggers.current[carouselIndex] = false;
20820
+ });
20821
+ // 更新播放状态
20822
+ setCarouselVideoPausedStates(prev => {
20823
+ const newStates = [...prev];
20824
+ newStates[carouselIndex] = false;
20825
+ return newStates;
20826
+ });
20827
+ }
20828
+ }
20829
+ }, [data === null || data === void 0 ? void 0 : data.carouselSection, carouselIndex, handleCarouselImageStartEvent]);
20830
+ // Carousel Section 离开可视区域时的回调
20831
+ const handleCarouselHidden = React.useCallback(() => {
20832
+ // Carousel Section 离开可视区域时,暂停当前正在播放的视频
20833
+ // 使用 ref 来获取当前正在播放的视频索引,避免闭包问题
20834
+ const playingIndex = currentPlayingCarouselIndex.current;
20835
+ console.log('[Carousel onHidden] 被调用');
20836
+ console.log('[Carousel onHidden] 正在播放的视频索引:', playingIndex);
20837
+ console.log('[Carousel onHidden] carouselVideoRefs.current 长度:', carouselVideoRefs.current.length);
20838
+ console.log('[Carousel onHidden] carouselVideoRefs.current[playingIndex] 存在:', !!carouselVideoRefs.current[playingIndex]);
20839
+ if (playingIndex >= 0 && carouselVideoRefs.current[playingIndex]) {
20840
+ const currentVideo = carouselVideoRefs.current[playingIndex];
20841
+ if (currentVideo) {
20842
+ console.log('[Carousel onHidden] 准备暂停视频,索引:', playingIndex, '当前播放状态:', !currentVideo.paused);
20843
+ currentVideo.pause();
20844
+ console.log('[Carousel onHidden] 已调用 pause()');
20845
+ // 更新暂停状态
20846
+ setCarouselVideoPausedStates(prev => {
20847
+ const newStates = [...prev];
20848
+ newStates[playingIndex] = true;
20849
+ return newStates;
20850
+ });
20851
+ }
20852
+ else {
20853
+ console.log('[Carousel onHidden] currentVideo 为空');
20854
+ }
20855
+ }
20856
+ else {
20857
+ console.log('[Carousel onHidden] 条件不满足,不暂停视频');
20858
+ }
20859
+ }, []);
20860
+ // Carousel Section 进入可视区域时上报第一张图片的浏览事件,并自动播放视频
20736
20861
  useAdvancedOnScreen(carouselSectionRef, {
20737
20862
  threshold: 0.67,
20738
20863
  delay: 1000,
20739
- onVisible: () => {
20740
- // 只在首次进入可视区域时上报第一张图片
20741
- if (!hasCarouselReported.current && (data === null || data === void 0 ? void 0 : data.carouselSection) && data.carouselSection.length > 0) {
20742
- hasCarouselReported.current = true;
20743
- const currentItem = data.carouselSection[carouselIndex];
20744
- // 只对图片类型上报(不包括视频)
20745
- if (!currentItem.url) {
20746
- handleCarouselImageStartEvent(carouselIndex);
20747
- }
20748
- }
20749
- }
20864
+ onVisible: handleCarouselVisible,
20865
+ onHidden: handleCarouselHidden,
20866
+ name: 'Carousel'
20750
20867
  });
20751
- // Carousel 切换时自动播放/暂停视频(Post 2/3/4)
20868
+ // Carousel 切换时暂停其他视频
20869
+ // 注意:不再在切换时立即播放当前视频,而是由 PostView 组件处理(进入2/3可视区域并停留1秒后播放)
20752
20870
  React.useEffect(() => {
20753
20871
  if (!(data === null || data === void 0 ? void 0 : data.carouselSection) || data.carouselSection.length === 0)
20754
20872
  return;
20873
+ console.log('[Carousel useEffect] 切换到索引:', carouselIndex);
20755
20874
  // 暂停所有其他视频
20756
20875
  carouselVideoRefs.current.forEach((videoRef, index) => {
20757
20876
  if (videoRef && index !== carouselIndex) {
@@ -20764,22 +20883,6 @@ const StructurePage = (_a) => {
20764
20883
  });
20765
20884
  }
20766
20885
  });
20767
- // 如果当前项是视频,自动播放
20768
- const currentItem = data.carouselSection[carouselIndex];
20769
- if ((currentItem === null || currentItem === void 0 ? void 0 : currentItem.url) && carouselVideoRefs.current[carouselIndex]) {
20770
- const currentVideo = carouselVideoRefs.current[carouselIndex];
20771
- if (currentVideo) {
20772
- currentVideo.play().catch(err => {
20773
- console.warn('[Carousel] Video autoplay failed:', err);
20774
- });
20775
- // 更新播放状态
20776
- setCarouselVideoPausedStates(prev => {
20777
- const newStates = [...prev];
20778
- newStates[carouselIndex] = false;
20779
- return newStates;
20780
- });
20781
- }
20782
- }
20783
20886
  }, [carouselIndex, data]);
20784
20887
  // 触摸滑动处理
20785
20888
  const handleTouchStart = (e) => {
@@ -20904,15 +21007,7 @@ const StructurePage = (_a) => {
20904
21007
  return textStyle;
20905
21008
  })()) }, data.heroSection.text))),
20906
21009
  React.createElement("div", { style: baseStyles.heroImageContainer },
20907
- React.createElement(PostView, { videoRef: heroVideoRef, isVideo: !!data.heroSection.url, onExposure: () => {
20908
- // 图片或视频的曝光上报
20909
- handlePostExposure(data.heroSection, 'heroSection', 0);
20910
- }, onVideoAutoPlay: () => {
20911
- // 视频自动播放时上报 playVideo 事件(2/3区域 + 300ms后)
20912
- if (heroVideoRef.current) {
20913
- handleVideoPlay(data.heroSection, 'heroSection', 0, heroVideoRef.current, true);
20914
- }
20915
- } }, data.heroSection.url ? (React.createElement("div", { style: { position: 'relative', width: '100%', height: '100%' }, onClick: handleHeroVideoClick },
21010
+ React.createElement(PostView, { videoRef: heroVideoRef, isVideo: !!data.heroSection.url, autoPlayTriggerRef: heroAutoPlayTrigger }, data.heroSection.url ? (React.createElement("div", { style: { position: 'relative', width: '100%', height: '100%' }, onClick: handleHeroVideoClick },
20916
21011
  React.createElement("video", { ref: heroVideoRef, src: data.heroSection.url, style: baseStyles.heroVideo, muted: true, loop: true, playsInline: true, controls: false, onLoadedMetadata: () => {
20917
21012
  var _a;
20918
21013
  const videoId = `${(_a = data.heroSection) === null || _a === void 0 ? void 0 : _a.itemId}-heroSection-0`;
@@ -20920,6 +21015,7 @@ const StructurePage = (_a) => {
20920
21015
  const initTime = videoLoadTime.current[videoId] || loadTime;
20921
21016
  videoLoadTime.current[videoId] = loadTime - initTime;
20922
21017
  }, onPlay: (e) => {
21018
+ // 视频真正开始播放时才上报(考虑网速问题)
20923
21019
  handleVideoPlay(data.heroSection, 'heroSection', 0, e.currentTarget);
20924
21020
  }, onPause: (e) => {
20925
21021
  handleVideoPlayOver(data.heroSection, 'heroSection', 0, e.currentTarget);
@@ -20932,7 +21028,52 @@ const StructurePage = (_a) => {
20932
21028
  React.createElement("div", { style: baseStyles.carouselImageContainer, onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchEnd: handleTouchEnd },
20933
21029
  React.createElement("div", { style: Object.assign(Object.assign({}, baseStyles.carouselContainer), { transform: `translateX(-${carouselIndex * 100}%)` }) }, data.carouselSection.map((item, index) => {
20934
21030
  var _a;
20935
- return (React.createElement("div", { key: item.itemId, style: baseStyles.carouselSlide }, item.url ? (React.createElement("div", { style: { position: 'relative', width: '100%', height: '100%' }, onClick: () => handleCarouselVideoClick(index) },
21031
+ // 只有当前显示的 slide 才应用曝光检测
21032
+ const isCurrentSlide = index === carouselIndex;
21033
+ return (React.createElement("div", { key: item.itemId, style: baseStyles.carouselSlide }, item.url ? (
21034
+ // 视频:使用 PostView 包裹,但只在当前显示时生效
21035
+ isCurrentSlide ? (React.createElement(PostView, { videoRef: { current: carouselVideoRefs.current[index] }, isVideo: true, autoPlayTriggerRef: {
21036
+ get current() {
21037
+ return carouselAutoPlayTriggers.current[index] || false;
21038
+ },
21039
+ set current(value) {
21040
+ carouselAutoPlayTriggers.current[index] = value;
21041
+ }
21042
+ }, onVideoPlay: () => {
21043
+ // 视频开始播放,隐藏暂停图标
21044
+ console.log('[Carousel PostView] onVideoPlay 回调,索引:', index);
21045
+ setCarouselVideoPausedStates(prev => {
21046
+ const newStates = [...prev];
21047
+ newStates[index] = false;
21048
+ return newStates;
21049
+ });
21050
+ }, onVideoPause: () => {
21051
+ // 视频暂停,显示暂停图标
21052
+ console.log('[Carousel PostView] onVideoPause 回调,索引:', index);
21053
+ setCarouselVideoPausedStates(prev => {
21054
+ const newStates = [...prev];
21055
+ newStates[index] = true;
21056
+ return newStates;
21057
+ });
21058
+ } },
21059
+ React.createElement("div", { style: { position: 'relative', width: '100%', height: '100%' }, onClick: () => handleCarouselVideoClick(index) },
21060
+ React.createElement("video", { ref: (el) => {
21061
+ carouselVideoRefs.current[index] = el;
21062
+ }, src: item.url, style: baseStyles.carouselVideo, muted: true, loop: true, playsInline: true, controls: false, draggable: false, onDragStart: (e) => e.preventDefault(), onLoadedMetadata: () => {
21063
+ const videoId = `${item.itemId}-carouselSection-${index}`;
21064
+ const loadTime = Date.now();
21065
+ const initTime = videoLoadTime.current[videoId] || loadTime;
21066
+ videoLoadTime.current[videoId] = loadTime - initTime;
21067
+ }, onPlay: (e) => {
21068
+ handleVideoPlay(item, 'carouselSection', index, e.currentTarget);
21069
+ }, onPause: (e) => {
21070
+ handleVideoPlayOver(item, 'carouselSection', index, e.currentTarget);
21071
+ }, onEnded: (e) => {
21072
+ handleVideoPlayOver(item, 'carouselSection', index, e.currentTarget);
21073
+ } }),
21074
+ carouselVideoPausedStates[index] && (React.createElement(FormatImage$1, { className: 'clc-pb-video-pause', src: videoPlayIcon, alt: 'play' }))))) : (
21075
+ // 非当前 slide,不使用 PostView
21076
+ React.createElement("div", { style: { position: 'relative', width: '100%', height: '100%' }, onClick: () => handleCarouselVideoClick(index) },
20936
21077
  React.createElement("video", { ref: (el) => {
20937
21078
  carouselVideoRefs.current[index] = el;
20938
21079
  }, src: item.url, style: baseStyles.carouselVideo, muted: true, loop: true, playsInline: true, controls: false, draggable: false, onDragStart: (e) => e.preventDefault(), onLoadedMetadata: () => {
@@ -20947,7 +21088,7 @@ const StructurePage = (_a) => {
20947
21088
  }, onEnded: (e) => {
20948
21089
  handleVideoPlayOver(item, 'carouselSection', index, e.currentTarget);
20949
21090
  } }),
20950
- carouselVideoPausedStates[index] && (React.createElement(FormatImage$1, { className: 'clc-pb-video-pause', src: videoPlayIcon, alt: 'play' })))) : ((_a = item.imgUrls) === null || _a === void 0 ? void 0 : _a[0]) ? (React.createElement("img", { src: item.imgUrls[0], alt: item.text || 'Carousel', style: baseStyles.carouselImage, draggable: false, onDragStart: (e) => e.preventDefault(), onLoad: () => {
21091
+ carouselVideoPausedStates[index] && (React.createElement(FormatImage$1, { className: 'clc-pb-video-pause', src: videoPlayIcon, alt: 'play' }))))) : ((_a = item.imgUrls) === null || _a === void 0 ? void 0 : _a[0]) ? (React.createElement("img", { src: item.imgUrls[0], alt: item.text || 'Carousel', style: baseStyles.carouselImage, draggable: false, onDragStart: (e) => e.preventDefault(), onLoad: () => {
20951
21092
  // 记录图片加载完成时间
20952
21093
  if (!carouselImageLoadTime.current[index]) {
20953
21094
  carouselImageLoadTime.current[index] = Date.now();