pb-sxp-ui 1.20.46 → 1.20.48
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 +438 -64
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +438 -64
- package/dist/index.js.map +1 -1
- package/dist/index.min.cjs +7 -7
- package/dist/index.min.cjs.map +1 -1
- package/dist/index.min.js +8 -8
- package/dist/index.min.js.map +1 -1
- package/dist/pb-ui.js +438 -64
- package/dist/pb-ui.js.map +1 -1
- package/dist/pb-ui.min.js +7 -7
- package/dist/pb-ui.min.js.map +1 -1
- package/es/core/components/StructurePage/index.js +364 -46
- package/lib/core/components/StructurePage/index.js +364 -46
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -19648,18 +19648,23 @@ const PostView = ({ children, videoRef, isVideo, onExposure, autoPlayTriggerRef,
|
|
|
19648
19648
|
autoPlayTriggerRef.current = true;
|
|
19649
19649
|
console.log('[PostView onVisible] 已设置自动播放标记');
|
|
19650
19650
|
}
|
|
19651
|
+
// 立即更新暂停图标状态,不等待 play() Promise
|
|
19652
|
+
// 这样可以确保图标状态与视频播放状态同步
|
|
19653
|
+
if (onVideoPlay) {
|
|
19654
|
+
onVideoPlay();
|
|
19655
|
+
}
|
|
19651
19656
|
videoRef.current.play().then(() => {
|
|
19652
19657
|
console.log('[PostView onVisible] 视频 play() 成功');
|
|
19653
|
-
// 触发播放回调,更新暂停图标状态
|
|
19654
|
-
if (onVideoPlay) {
|
|
19655
|
-
onVideoPlay();
|
|
19656
|
-
}
|
|
19657
19658
|
}).catch(err => {
|
|
19658
19659
|
console.warn('[PostView] Video autoplay failed:', err);
|
|
19659
|
-
//
|
|
19660
|
+
// 播放失败时重置标记和图标状态
|
|
19660
19661
|
if (autoPlayTriggerRef) {
|
|
19661
19662
|
autoPlayTriggerRef.current = false;
|
|
19662
19663
|
}
|
|
19664
|
+
// 播放失败,恢复暂停图标
|
|
19665
|
+
if (onVideoPause) {
|
|
19666
|
+
onVideoPause();
|
|
19667
|
+
}
|
|
19663
19668
|
});
|
|
19664
19669
|
}
|
|
19665
19670
|
},
|
|
@@ -20011,7 +20016,7 @@ const baseStyles = {
|
|
|
20011
20016
|
}
|
|
20012
20017
|
};
|
|
20013
20018
|
const StructurePage = (_a) => {
|
|
20014
|
-
var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
|
20019
|
+
var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
20015
20020
|
var { containerStyle, containerHeight = 664, containerWidth = 375, className = '', apiUrl = 'https://bff-be-dev.chatlabs.net/api/v1/recommend/list', requestBody, editorMode = false, multiCTAConfig: propMultiCTAConfig, videoPlayIcon: propVideoPlayIcon, isCmsMode = false, storyId, customHeaders } = _a, rest = __rest(_a, ["containerStyle", "containerHeight", "containerWidth", "className", "apiUrl", "requestBody", "editorMode", "multiCTAConfig", "videoPlayIcon", "isCmsMode", "storyId", "customHeaders"]);
|
|
20016
20021
|
const [data, setData] = React.useState(null);
|
|
20017
20022
|
const [loading, setLoading] = React.useState(true);
|
|
@@ -20024,24 +20029,28 @@ const StructurePage = (_a) => {
|
|
|
20024
20029
|
// 视频暂停状态管理
|
|
20025
20030
|
const [isHeroVideoPaused, setIsHeroVideoPaused] = React.useState(false);
|
|
20026
20031
|
const [carouselVideoPausedStates, setCarouselVideoPausedStates] = React.useState([]);
|
|
20027
|
-
// 引入事件上报 hooks
|
|
20028
|
-
const { ctaEvent, bffFbReport, bffEventReport } = useSxpDataSource();
|
|
20032
|
+
// 引入事件上报 hooks 和 Session 刷新功能
|
|
20033
|
+
const { ctaEvent, bffFbReport, bffEventReport, refreshFeSession, curTime } = useSxpDataSource();
|
|
20029
20034
|
// 防止重复上报的标记
|
|
20030
20035
|
const h5EnterReportedRef = React.useRef(false);
|
|
20031
|
-
//
|
|
20032
|
-
const
|
|
20036
|
+
// 全局事件管理:用于追踪弹窗打开时间和状态
|
|
20037
|
+
const popupCurTimeRef = React.useRef(new Date());
|
|
20038
|
+
const currentPopupDataRef = React.useRef(null);
|
|
20039
|
+
// CTA 曝光时间追踪(允许重复上报)
|
|
20040
|
+
const ctaExposureTime = React.useRef({});
|
|
20033
20041
|
// Carousel 图片浏览时间追踪
|
|
20034
20042
|
const carouselImageStartTime = React.useRef(0);
|
|
20035
20043
|
const carouselImageLoadTime = React.useRef({});
|
|
20036
|
-
//
|
|
20037
|
-
|
|
20044
|
+
// 产品浏览状态追踪(记录每次浏览的开始时间)
|
|
20045
|
+
// 注意:不使用 Set 来避免重复,因为用户每次浏览都应该上报
|
|
20038
20046
|
const productViewStartTime = React.useRef({});
|
|
20039
20047
|
// 视频播放状态追踪
|
|
20040
20048
|
const videoStartTime = React.useRef({});
|
|
20041
20049
|
const isFirstPlay = React.useRef({});
|
|
20042
20050
|
const videoLoadTime = React.useRef({});
|
|
20043
|
-
|
|
20051
|
+
// 注释:移除 videoAutoPlayReported,允许视频重复上报
|
|
20044
20052
|
const videoPlayReportTime = React.useRef({}); // 追踪视频播放上报的时间戳,防止短时间内重复上报
|
|
20053
|
+
const videoLastCurrentTime = React.useRef({}); // 追踪视频的上一次播放时间,用于检测循环
|
|
20045
20054
|
// 自动播放触发标记(用于区分自动播放和用户手动播放)
|
|
20046
20055
|
const heroAutoPlayTrigger = React.useRef(false);
|
|
20047
20056
|
const carouselAutoPlayTriggers = React.useRef({});
|
|
@@ -20061,6 +20070,11 @@ const StructurePage = (_a) => {
|
|
|
20061
20070
|
var _a;
|
|
20062
20071
|
return propMultiCTAConfig || ((_a = schema === null || schema === void 0 ? void 0 : schema.sxpPageConf) === null || _a === void 0 ? void 0 : _a.multiCTAConfig) || {};
|
|
20063
20072
|
}, [propMultiCTAConfig, (_b = schema === null || schema === void 0 ? void 0 : schema.sxpPageConf) === null || _b === void 0 ? void 0 : _b.multiCTAConfig]);
|
|
20073
|
+
// 获取 globalConfig 中的 session 配置
|
|
20074
|
+
const globalConfig = React.useMemo(() => {
|
|
20075
|
+
var _a;
|
|
20076
|
+
return (_a = schema === null || schema === void 0 ? void 0 : schema.sxpPageConf) === null || _a === void 0 ? void 0 : _a.globalConfig;
|
|
20077
|
+
}, [(_c = schema === null || schema === void 0 ? void 0 : schema.sxpPageConf) === null || _c === void 0 ? void 0 : _c.globalConfig]);
|
|
20064
20078
|
// 默认播放图标 URL(直接使用 CDN 地址作为后备)
|
|
20065
20079
|
const DEFAULT_PAUSE_ICON = 'https://sxph5-uat.chatlabs.net/pb_static/06f28a2025c74c1cb49be6767316d827.png';
|
|
20066
20080
|
// 获取视频播放图标
|
|
@@ -20084,7 +20098,7 @@ const StructurePage = (_a) => {
|
|
|
20084
20098
|
}
|
|
20085
20099
|
// 最后使用默认图标
|
|
20086
20100
|
return DEFAULT_PAUSE_ICON;
|
|
20087
|
-
}, [propVideoPlayIcon, (
|
|
20101
|
+
}, [propVideoPlayIcon, (_e = (_d = schema === null || schema === void 0 ? void 0 : schema.sxpPageConf) === null || _d === void 0 ? void 0 : _d.globalConfig) === null || _e === void 0 ? void 0 : _e.videoPlayIcon]);
|
|
20088
20102
|
// 处理 CTA 点击
|
|
20089
20103
|
const handleCtaClick = React.useCallback((link, interaction, productData, ctaData, viewPosition, sectionIndex) => {
|
|
20090
20104
|
// 判断是否为外部链接
|
|
@@ -20135,6 +20149,46 @@ const StructurePage = (_a) => {
|
|
|
20135
20149
|
if (interaction) {
|
|
20136
20150
|
const { linkType, popupType, popupAni } = interaction;
|
|
20137
20151
|
if (linkType === 'popup' && popupType) {
|
|
20152
|
+
// ========== 打开弹窗前:记录弹窗数据和时间 ==========
|
|
20153
|
+
// 重置弹窗时间
|
|
20154
|
+
popupCurTimeRef.current = new Date();
|
|
20155
|
+
// 保存当前弹窗的产品数据,用于全局事件监听
|
|
20156
|
+
currentPopupDataRef.current = {
|
|
20157
|
+
productData,
|
|
20158
|
+
ctaData,
|
|
20159
|
+
viewPosition,
|
|
20160
|
+
sectionIndex,
|
|
20161
|
+
popupType
|
|
20162
|
+
};
|
|
20163
|
+
console.log('[StructurePage] 打开弹窗,记录数据:', {
|
|
20164
|
+
productId: productData === null || productData === void 0 ? void 0 : productData.itemId,
|
|
20165
|
+
viewPosition,
|
|
20166
|
+
sectionIndex,
|
|
20167
|
+
popupType
|
|
20168
|
+
});
|
|
20169
|
+
// ========== 弹窗打开时:立即上报 ProductView 和 PageView 事件 ==========
|
|
20170
|
+
// 这与非 multi-cta 的 CommodityDetail 组件行为一致
|
|
20171
|
+
const recData = Object.assign(Object.assign({}, rec), { video: (rec === null || rec === void 0 ? void 0 : rec.video) ? Object.assign(Object.assign({}, rec.video), { title: '', imgUrls: (productData === null || productData === void 0 ? void 0 : productData.homePage) || rec.video.imgUrls, url: rec.video.url || null }) : null });
|
|
20172
|
+
// 上报 ProductView 事件
|
|
20173
|
+
bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
|
|
20174
|
+
eventName: 'ProductView',
|
|
20175
|
+
product: productData ? [productData] : undefined,
|
|
20176
|
+
contentType: 'product',
|
|
20177
|
+
rec: recData,
|
|
20178
|
+
position: sectionIndex !== undefined ? sectionIndex : 0
|
|
20179
|
+
});
|
|
20180
|
+
// 上报 PageView 事件
|
|
20181
|
+
bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
|
|
20182
|
+
eventName: 'PageView',
|
|
20183
|
+
product: productData ? [productData] : undefined,
|
|
20184
|
+
contentType: 'product',
|
|
20185
|
+
rec: recData,
|
|
20186
|
+
position: sectionIndex !== undefined ? sectionIndex : 0
|
|
20187
|
+
});
|
|
20188
|
+
console.log('[StructurePage] 上报弹窗打开事件 (ProductView + PageView)', {
|
|
20189
|
+
productId: productData === null || productData === void 0 ? void 0 : productData.itemId,
|
|
20190
|
+
position: sectionIndex
|
|
20191
|
+
});
|
|
20138
20192
|
// 设置弹窗要显示的产品数据
|
|
20139
20193
|
if (productData && typeof window !== 'undefined' && window.setPopupDetailData) {
|
|
20140
20194
|
// 构造与原有系统一致的数据结构
|
|
@@ -20243,16 +20297,19 @@ const StructurePage = (_a) => {
|
|
|
20243
20297
|
const finalStyle = Object.assign(Object.assign({}, baseStyle), customStyle);
|
|
20244
20298
|
return finalStyle;
|
|
20245
20299
|
}, [multiCTAConfig]);
|
|
20246
|
-
// CTA
|
|
20300
|
+
// CTA 曝光事件处理(允许重复上报)
|
|
20247
20301
|
const handleCtaExposure = React.useCallback((ctaData, productData, viewPosition, sectionIndex, buttonKey) => {
|
|
20248
|
-
//
|
|
20302
|
+
// 生成唯一标识
|
|
20249
20303
|
const ctaId = `${buttonKey}-${viewPosition}-${sectionIndex}`;
|
|
20250
|
-
//
|
|
20251
|
-
|
|
20304
|
+
// 记录本次曝光时间(允许重复上报)
|
|
20305
|
+
const now = Date.now();
|
|
20306
|
+
const lastExposureTime = ctaExposureTime.current[ctaId];
|
|
20307
|
+
// 防抖:如果距离上次曝光不到 1 秒,跳过(避免同一次曝光重复触发)
|
|
20308
|
+
if (lastExposureTime && (now - lastExposureTime) < 1000) {
|
|
20252
20309
|
return;
|
|
20253
20310
|
}
|
|
20254
|
-
//
|
|
20255
|
-
|
|
20311
|
+
// 更新曝光时间
|
|
20312
|
+
ctaExposureTime.current[ctaId] = now;
|
|
20256
20313
|
// 获取当前 section 的 post/image 数据(用于 contentId 和 sceneId)
|
|
20257
20314
|
let postData = null;
|
|
20258
20315
|
if (viewPosition === 'heroSection' && (data === null || data === void 0 ? void 0 : data.heroSection)) {
|
|
@@ -20313,20 +20370,8 @@ const StructurePage = (_a) => {
|
|
|
20313
20370
|
carouselAutoPlayTriggers.current[sectionIndex] = false; // 重置标记
|
|
20314
20371
|
}
|
|
20315
20372
|
console.log('[handleVideoPlay] isAutoPlay:', isAutoPlay, 'videoId:', videoId);
|
|
20316
|
-
//
|
|
20317
|
-
|
|
20318
|
-
videoAutoPlayReported.current.add(videoId);
|
|
20319
|
-
console.log('[handleVideoPlay] 标记为已通过自动播放上报');
|
|
20320
|
-
}
|
|
20321
|
-
else {
|
|
20322
|
-
// 如果不是自动播放,但已经通过自动播放上报过,则跳过
|
|
20323
|
-
if (videoAutoPlayReported.current.has(videoId)) {
|
|
20324
|
-
console.log('[handleVideoPlay] 跳过上报:已经通过自动播放上报过');
|
|
20325
|
-
// 只记录播放时间,不上报
|
|
20326
|
-
videoStartTime.current[videoId] = videoRef.currentTime || 0;
|
|
20327
|
-
return;
|
|
20328
|
-
}
|
|
20329
|
-
}
|
|
20373
|
+
// 记录播放上报(允许重复上报,已通过 videoPlayReportTime 防抖)
|
|
20374
|
+
console.log('[handleVideoPlay] 视频播放上报,isAutoPlay:', isAutoPlay);
|
|
20330
20375
|
// 记录视频开始播放时间
|
|
20331
20376
|
videoStartTime.current[videoId] = videoRef.currentTime || 0;
|
|
20332
20377
|
// 记录本次上报时间
|
|
@@ -20352,8 +20397,48 @@ const StructurePage = (_a) => {
|
|
|
20352
20397
|
}))
|
|
20353
20398
|
});
|
|
20354
20399
|
}, [bffEventReport]);
|
|
20400
|
+
// 视频时间更新事件处理(用于检测循环播放)
|
|
20401
|
+
const handleVideoTimeUpdate = React.useCallback((videoData, viewPosition, sectionIndex, videoRef) => {
|
|
20402
|
+
if (!videoRef || !videoRef.duration)
|
|
20403
|
+
return;
|
|
20404
|
+
const videoId = `${videoData === null || videoData === void 0 ? void 0 : videoData.itemId}-${viewPosition}-${sectionIndex}`;
|
|
20405
|
+
const currentTime = videoRef.currentTime;
|
|
20406
|
+
const lastTime = videoLastCurrentTime.current[videoId] || 0;
|
|
20407
|
+
// 检测视频循环(当前时间明显小于上次时间,说明视频重新开始了)
|
|
20408
|
+
if (lastTime > 0 && currentTime < lastTime && lastTime > videoRef.duration * 0.9) {
|
|
20409
|
+
console.log('[handleVideoTimeUpdate] 检测到视频循环,currentTime:', currentTime, 'lastTime:', lastTime);
|
|
20410
|
+
// 上报 playOverVideo(循环结束)
|
|
20411
|
+
const videoDuration = videoRef.duration.toFixed(2);
|
|
20412
|
+
const startTime = videoStartTime.current[videoId] || 0;
|
|
20413
|
+
const playDuration = (lastTime - startTime).toFixed(2);
|
|
20414
|
+
if (parseFloat(playDuration) >= 0.1) {
|
|
20415
|
+
console.log('[handleVideoTimeUpdate] 上报循环结束的 playOverVideo 事件');
|
|
20416
|
+
bffEventReport === null || bffEventReport === void 0 ? void 0 : bffEventReport({
|
|
20417
|
+
eventInfo: {
|
|
20418
|
+
eventSubject: 'playOverVideo',
|
|
20419
|
+
eventDescription: 'User finished playing the video',
|
|
20420
|
+
sceneId: '',
|
|
20421
|
+
contentId: (videoData === null || videoData === void 0 ? void 0 : videoData.itemId) || '',
|
|
20422
|
+
contentName: (videoData === null || videoData === void 0 ? void 0 : videoData.title) || '',
|
|
20423
|
+
endTime: videoDuration,
|
|
20424
|
+
videoDuration,
|
|
20425
|
+
playDuration,
|
|
20426
|
+
contentTags: (videoData === null || videoData === void 0 ? void 0 : videoData.tags) ? JSON.stringify(videoData.tags) : '[]',
|
|
20427
|
+
position: `${sectionIndex || 0}`,
|
|
20428
|
+
contentFormat: 'video',
|
|
20429
|
+
rtc: '',
|
|
20430
|
+
traceInfo: (videoData === null || videoData === void 0 ? void 0 : videoData.traceInfo) || ''
|
|
20431
|
+
}
|
|
20432
|
+
});
|
|
20433
|
+
}
|
|
20434
|
+
// 重置上次上报时间,让下次 play 事件可以上报
|
|
20435
|
+
delete videoPlayReportTime.current[videoId];
|
|
20436
|
+
}
|
|
20437
|
+
// 更新上次播放时间
|
|
20438
|
+
videoLastCurrentTime.current[videoId] = currentTime;
|
|
20439
|
+
}, [bffEventReport]);
|
|
20355
20440
|
// 视频播放结束/暂停事件处理
|
|
20356
|
-
const handleVideoPlayOver = React.useCallback((videoData, viewPosition, sectionIndex, videoRef) => {
|
|
20441
|
+
const handleVideoPlayOver = React.useCallback((videoData, viewPosition, sectionIndex, videoRef, isEndedEvent) => {
|
|
20357
20442
|
if (!videoRef || !videoRef.duration)
|
|
20358
20443
|
return;
|
|
20359
20444
|
const videoId = `${videoData === null || videoData === void 0 ? void 0 : videoData.itemId}-${viewPosition}-${sectionIndex}`;
|
|
@@ -20362,6 +20447,18 @@ const StructurePage = (_a) => {
|
|
|
20362
20447
|
// 计算播放时长
|
|
20363
20448
|
const startTime = videoStartTime.current[videoId] || 0;
|
|
20364
20449
|
const playDuration = (videoRef.currentTime - startTime).toFixed(2);
|
|
20450
|
+
// 如果播放时长过短(小于100ms),可能是误触发,不上报
|
|
20451
|
+
if (parseFloat(playDuration) < 0.1) {
|
|
20452
|
+
console.log('[handleVideoPlayOver] 播放时长过短,跳过上报:', playDuration);
|
|
20453
|
+
return;
|
|
20454
|
+
}
|
|
20455
|
+
console.log('[handleVideoPlayOver] 上报 playOverVideo 事件:', {
|
|
20456
|
+
videoId,
|
|
20457
|
+
isEndedEvent,
|
|
20458
|
+
endTime,
|
|
20459
|
+
playDuration,
|
|
20460
|
+
videoDuration
|
|
20461
|
+
});
|
|
20365
20462
|
bffEventReport === null || bffEventReport === void 0 ? void 0 : bffEventReport({
|
|
20366
20463
|
eventInfo: {
|
|
20367
20464
|
eventSubject: 'playOverVideo',
|
|
@@ -20406,11 +20503,7 @@ const StructurePage = (_a) => {
|
|
|
20406
20503
|
const handleProductViewExposure = React.useCallback((productData, viewPosition, sectionIndex) => {
|
|
20407
20504
|
// 生成唯一标识
|
|
20408
20505
|
const productId = `${productData === null || productData === void 0 ? void 0 : productData.itemId}-${viewPosition}-${sectionIndex}`;
|
|
20409
|
-
//
|
|
20410
|
-
if (productViewStartTime.current[productId]) {
|
|
20411
|
-
return;
|
|
20412
|
-
}
|
|
20413
|
-
// 记录开始浏览时间
|
|
20506
|
+
// 每次进入可视区域都记录新的开始时间(允许重复浏览)
|
|
20414
20507
|
productViewStartTime.current[productId] = Date.now();
|
|
20415
20508
|
console.log('[handleProductViewExposure] 记录产品开始浏览时间:', {
|
|
20416
20509
|
productId,
|
|
@@ -20422,10 +20515,6 @@ const StructurePage = (_a) => {
|
|
|
20422
20515
|
var _a;
|
|
20423
20516
|
// 生成唯一标识
|
|
20424
20517
|
const productId = `${productData === null || productData === void 0 ? void 0 : productData.itemId}-${viewPosition}-${sectionIndex}`;
|
|
20425
|
-
// 如果已经上报过,不再重复上报
|
|
20426
|
-
if (exposedProductRefs.current.has(productId)) {
|
|
20427
|
-
return;
|
|
20428
|
-
}
|
|
20429
20518
|
// 获取开始浏览时间
|
|
20430
20519
|
const startTime = productViewStartTime.current[productId];
|
|
20431
20520
|
if (!startTime) {
|
|
@@ -20434,8 +20523,8 @@ const StructurePage = (_a) => {
|
|
|
20434
20523
|
}
|
|
20435
20524
|
// 计算停留时长(秒)
|
|
20436
20525
|
const timeOnSite = Math.floor((Date.now() - startTime) / 1000);
|
|
20437
|
-
//
|
|
20438
|
-
|
|
20526
|
+
// 清除开始时间记录,以便下次进入时能再次记录
|
|
20527
|
+
delete productViewStartTime.current[productId];
|
|
20439
20528
|
// 根据 viewPosition 确定 fromKName
|
|
20440
20529
|
let fromKName = 'productPage';
|
|
20441
20530
|
if (viewPosition === 'heroSection') {
|
|
@@ -20733,16 +20822,20 @@ const StructurePage = (_a) => {
|
|
|
20733
20822
|
}
|
|
20734
20823
|
}
|
|
20735
20824
|
}, []);
|
|
20736
|
-
// Post
|
|
20737
|
-
const
|
|
20825
|
+
// Post 图片/视频曝光时间追踪(允许重复上报)
|
|
20826
|
+
const postExposureTime = React.useRef({});
|
|
20738
20827
|
React.useCallback((postData, viewPosition, sectionIndex) => {
|
|
20739
20828
|
var _a;
|
|
20740
20829
|
const postId = `${postData === null || postData === void 0 ? void 0 : postData.itemId}-${viewPosition}-${sectionIndex}`;
|
|
20741
|
-
//
|
|
20742
|
-
|
|
20830
|
+
// 记录本次曝光时间(允许重复上报)
|
|
20831
|
+
const now = Date.now();
|
|
20832
|
+
const lastExposureTime = postExposureTime.current[postId];
|
|
20833
|
+
// 防抖:如果距离上次曝光不到 1 秒,跳过(避免同一次曝光重复触发)
|
|
20834
|
+
if (lastExposureTime && (now - lastExposureTime) < 1000) {
|
|
20743
20835
|
return;
|
|
20744
20836
|
}
|
|
20745
|
-
|
|
20837
|
+
// 更新曝光时间
|
|
20838
|
+
postExposureTime.current[postId] = now;
|
|
20746
20839
|
// 判断是图片还是视频
|
|
20747
20840
|
const contentFormat = (postData === null || postData === void 0 ? void 0 : postData.url) ? 'video' : 'image';
|
|
20748
20841
|
const eventSubject = contentFormat === 'video' ? 'viewVideo' : 'viewImage';
|
|
@@ -20959,6 +21052,270 @@ const StructurePage = (_a) => {
|
|
|
20959
21052
|
setTouchStart(null);
|
|
20960
21053
|
setTouchEnd(null);
|
|
20961
21054
|
};
|
|
21055
|
+
// ==================== 全局事件监听:visibilitychange ====================
|
|
21056
|
+
// 监听页面可见性变化(最小化、切换标签页、返回等)
|
|
21057
|
+
// 参考 SxpPageRender 的实现
|
|
21058
|
+
React.useEffect(() => {
|
|
21059
|
+
const handleVisibilityChange = () => {
|
|
21060
|
+
var _a, _b;
|
|
21061
|
+
if (document.visibilityState === 'hidden') {
|
|
21062
|
+
// ========== 页面隐藏时 ==========
|
|
21063
|
+
console.log('[StructurePage] Page hidden - 触发全局事件');
|
|
21064
|
+
// 1. 发送 PAGE_DID_HIDE 事件到事件总线
|
|
21065
|
+
SXP_EVENT_BUS.emit(SXP_EVENT_TYPE.PAGE_DID_HIDE, data);
|
|
21066
|
+
// 2. 如果有打开的弹窗,上报 ExitFeed 事件
|
|
21067
|
+
if (currentPopupDataRef.current) {
|
|
21068
|
+
const { productData, viewPosition, sectionIndex } = currentPopupDataRef.current;
|
|
21069
|
+
// 获取当前 section 的 post 数据
|
|
21070
|
+
let postData = null;
|
|
21071
|
+
if (viewPosition === 'heroSection' && (data === null || data === void 0 ? void 0 : data.heroSection)) {
|
|
21072
|
+
postData = data.heroSection;
|
|
21073
|
+
}
|
|
21074
|
+
else if (viewPosition === 'carouselSection' && (data === null || data === void 0 ? void 0 : data.carouselSection) && sectionIndex !== undefined) {
|
|
21075
|
+
postData = data.carouselSection[sectionIndex];
|
|
21076
|
+
}
|
|
21077
|
+
const rec = {
|
|
21078
|
+
video: {
|
|
21079
|
+
bindProduct: productData,
|
|
21080
|
+
bindProducts: productData ? [productData] : [],
|
|
21081
|
+
itemId: (postData === null || postData === void 0 ? void 0 : postData.itemId) || '',
|
|
21082
|
+
tags: (postData === null || postData === void 0 ? void 0 : postData.tags) || null,
|
|
21083
|
+
scene: (postData === null || postData === void 0 ? void 0 : postData.scene) || null,
|
|
21084
|
+
url: (postData === null || postData === void 0 ? void 0 : postData.url) || null,
|
|
21085
|
+
imgUrls: (postData === null || postData === void 0 ? void 0 : postData.imgUrls) || null
|
|
21086
|
+
},
|
|
21087
|
+
product: null
|
|
21088
|
+
};
|
|
21089
|
+
const viewTime = new Date() - popupCurTimeRef.current;
|
|
21090
|
+
bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
|
|
21091
|
+
eventName: 'ExitFeed',
|
|
21092
|
+
product: productData ? [productData] : undefined,
|
|
21093
|
+
contentType: 'product',
|
|
21094
|
+
rec: rec,
|
|
21095
|
+
position: sectionIndex !== undefined ? sectionIndex : 0,
|
|
21096
|
+
view_time: viewTime,
|
|
21097
|
+
content_id: (productData === null || productData === void 0 ? void 0 : productData.itemId) || ''
|
|
21098
|
+
});
|
|
21099
|
+
console.log('[StructurePage] 上报 ExitFeed 事件', { viewTime, productId: productData === null || productData === void 0 ? void 0 : productData.itemId });
|
|
21100
|
+
}
|
|
21101
|
+
// 3. 刷新 Session(处理 Session 过期)
|
|
21102
|
+
// 只有在非 organic menu 模式下才刷新 Session(与非 multi-cta 逻辑一致)
|
|
21103
|
+
if ((globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.playbook) !== 'organic menu' && refreshFeSession && curTime) {
|
|
21104
|
+
const isExpire = refreshFeSession(false, (reason) => {
|
|
21105
|
+
console.log('[StructurePage] Session expired:', reason);
|
|
21106
|
+
// Session 过期时的回调处理
|
|
21107
|
+
bffEventReport === null || bffEventReport === void 0 ? void 0 : bffEventReport({
|
|
21108
|
+
eventInfo: {
|
|
21109
|
+
eventSubject: 'sessionExpired',
|
|
21110
|
+
eventDescription: 'User session has expired',
|
|
21111
|
+
reason
|
|
21112
|
+
}
|
|
21113
|
+
});
|
|
21114
|
+
});
|
|
21115
|
+
// 只有当明确返回 false 时才上报 sessionCompleted
|
|
21116
|
+
if (typeof isExpire !== 'undefined' && !isExpire) {
|
|
21117
|
+
// Session 未过期,上报正常的 Session 完成事件
|
|
21118
|
+
const sessionDuration = (new Date() - curTime.current) / 1000;
|
|
21119
|
+
bffEventReport === null || bffEventReport === void 0 ? void 0 : bffEventReport({
|
|
21120
|
+
eventInfo: {
|
|
21121
|
+
eventSubject: 'sessionCompleted',
|
|
21122
|
+
eventDescription: 'User session completed normally',
|
|
21123
|
+
duration: `${sessionDuration}`
|
|
21124
|
+
}
|
|
21125
|
+
});
|
|
21126
|
+
}
|
|
21127
|
+
}
|
|
21128
|
+
}
|
|
21129
|
+
else if (document.visibilityState === 'visible') {
|
|
21130
|
+
// ========== 页面可见时 ==========
|
|
21131
|
+
console.log('[StructurePage] Page visible - 触发全局事件');
|
|
21132
|
+
// ⚠️ 重要:必须先刷新 Session,再上报事件(使用最新的 Session ID)
|
|
21133
|
+
// 1. 刷新 Session(根据配置决定)
|
|
21134
|
+
if (refreshFeSession) {
|
|
21135
|
+
refreshFeSession(false);
|
|
21136
|
+
}
|
|
21137
|
+
// 2. 如果未启用 session 配置,则强制刷新 Session ID(与非 multi-cta 逻辑一致)
|
|
21138
|
+
// ⚠️ 必须在上报事件之前刷新,这样上报的事件才会使用最新的 Session ID
|
|
21139
|
+
if (!((_a = globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.session) === null || _a === void 0 ? void 0 : _a.enable)) {
|
|
21140
|
+
refreshFeSessionId();
|
|
21141
|
+
console.log('[StructurePage] Session 未启用,强制刷新 Session ID');
|
|
21142
|
+
}
|
|
21143
|
+
// 3. 上报 h5LinkEnterFeed 事件(现在使用的是刷新后的 Session ID)
|
|
21144
|
+
const getUrlParamByKey = (key) => {
|
|
21145
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
21146
|
+
return urlParams.get(key) || '';
|
|
21147
|
+
};
|
|
21148
|
+
const time = new Date();
|
|
21149
|
+
if (curTime) {
|
|
21150
|
+
curTime.current = time;
|
|
21151
|
+
}
|
|
21152
|
+
bffEventReport === null || bffEventReport === void 0 ? void 0 : bffEventReport({
|
|
21153
|
+
eventInfo: {
|
|
21154
|
+
eventSubject: 'h5LinkEnterFeed',
|
|
21155
|
+
eventDescription: 'User enter h5 link',
|
|
21156
|
+
utmSource: getUrlParamByKey('utm_source'),
|
|
21157
|
+
utmMedium: getUrlParamByKey('utm_medium'),
|
|
21158
|
+
utmCampaign: getUrlParamByKey('utm_campaign'),
|
|
21159
|
+
utmId: getUrlParamByKey('utm_id'),
|
|
21160
|
+
utmContent: getUrlParamByKey('utm_content'),
|
|
21161
|
+
enterTime: Math.floor(time / 1000) + '',
|
|
21162
|
+
requestId: '',
|
|
21163
|
+
enterUrl: ((_b = window === null || window === void 0 ? void 0 : window.location) === null || _b === void 0 ? void 0 : _b.href) || ''
|
|
21164
|
+
},
|
|
21165
|
+
reportLayId: false
|
|
21166
|
+
});
|
|
21167
|
+
// 3. 发送 PAGE_DID_SHOW 事件到事件总线(延迟 100ms,与 SxpPageRender 保持一致)
|
|
21168
|
+
setTimeout(() => {
|
|
21169
|
+
SXP_EVENT_BUS.emit(SXP_EVENT_TYPE.PAGE_DID_SHOW, data);
|
|
21170
|
+
}, 100);
|
|
21171
|
+
// 4. 如果有打开的弹窗,重置弹窗时间
|
|
21172
|
+
if (currentPopupDataRef.current) {
|
|
21173
|
+
popupCurTimeRef.current = new Date();
|
|
21174
|
+
console.log('[StructurePage] 重置弹窗计时器');
|
|
21175
|
+
}
|
|
21176
|
+
}
|
|
21177
|
+
};
|
|
21178
|
+
// 添加事件监听
|
|
21179
|
+
document.addEventListener('visibilitychange', handleVisibilityChange);
|
|
21180
|
+
// 清理函数
|
|
21181
|
+
return () => {
|
|
21182
|
+
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
21183
|
+
};
|
|
21184
|
+
}, [data, bffFbReport, bffEventReport, refreshFeSession, curTime, globalConfig]);
|
|
21185
|
+
// ==================== 初始化弹窗时间记录 ====================
|
|
21186
|
+
React.useEffect(() => {
|
|
21187
|
+
const initTime = () => {
|
|
21188
|
+
popupCurTimeRef.current = new Date();
|
|
21189
|
+
};
|
|
21190
|
+
initTime();
|
|
21191
|
+
window.addEventListener('pageshow', initTime);
|
|
21192
|
+
return () => {
|
|
21193
|
+
window.removeEventListener('pageshow', initTime);
|
|
21194
|
+
};
|
|
21195
|
+
}, []);
|
|
21196
|
+
// ==================== 监听弹窗关闭事件 ====================
|
|
21197
|
+
// 通过轮询检测弹窗是否关闭(因为弹窗关闭时会清空 popupDetailData)
|
|
21198
|
+
React.useEffect(() => {
|
|
21199
|
+
let checkInterval = null;
|
|
21200
|
+
let wasPopupOpen = false;
|
|
21201
|
+
const checkPopupStatus = () => {
|
|
21202
|
+
// 检查是否有弹窗打开
|
|
21203
|
+
const isPopupOpen = typeof window !== 'undefined' &&
|
|
21204
|
+
window.popup &&
|
|
21205
|
+
window.popup.id !== '';
|
|
21206
|
+
// 检测从打开到关闭的转换
|
|
21207
|
+
if (wasPopupOpen && !isPopupOpen && currentPopupDataRef.current) {
|
|
21208
|
+
console.log('[StructurePage] 检测到弹窗关闭');
|
|
21209
|
+
// 弹窗关闭时上报事件
|
|
21210
|
+
const { productData, viewPosition, sectionIndex } = currentPopupDataRef.current;
|
|
21211
|
+
// 获取当前 section 的 post 数据
|
|
21212
|
+
let postData = null;
|
|
21213
|
+
if (viewPosition === 'heroSection' && (data === null || data === void 0 ? void 0 : data.heroSection)) {
|
|
21214
|
+
postData = data.heroSection;
|
|
21215
|
+
}
|
|
21216
|
+
else if (viewPosition === 'carouselSection' && (data === null || data === void 0 ? void 0 : data.carouselSection) && sectionIndex !== undefined) {
|
|
21217
|
+
postData = data.carouselSection[sectionIndex];
|
|
21218
|
+
}
|
|
21219
|
+
const rec = {
|
|
21220
|
+
video: {
|
|
21221
|
+
bindProduct: productData,
|
|
21222
|
+
bindProducts: productData ? [productData] : [],
|
|
21223
|
+
itemId: (postData === null || postData === void 0 ? void 0 : postData.itemId) || '',
|
|
21224
|
+
tags: (postData === null || postData === void 0 ? void 0 : postData.tags) || null,
|
|
21225
|
+
scene: (postData === null || postData === void 0 ? void 0 : postData.scene) || null,
|
|
21226
|
+
url: (postData === null || postData === void 0 ? void 0 : postData.url) || null,
|
|
21227
|
+
imgUrls: (postData === null || postData === void 0 ? void 0 : postData.imgUrls) || null
|
|
21228
|
+
},
|
|
21229
|
+
product: null
|
|
21230
|
+
};
|
|
21231
|
+
const viewTime = new Date() - popupCurTimeRef.current;
|
|
21232
|
+
// 上报 Engagement 事件(engagement_type: 'close_popup')
|
|
21233
|
+
bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
|
|
21234
|
+
eventName: 'Engagement',
|
|
21235
|
+
product: productData ? [productData] : undefined,
|
|
21236
|
+
rec: rec,
|
|
21237
|
+
position: sectionIndex !== undefined ? sectionIndex : 0,
|
|
21238
|
+
content_id: (productData === null || productData === void 0 ? void 0 : productData.itemId) || '',
|
|
21239
|
+
engagement_type: 'close_popup',
|
|
21240
|
+
contentType: 'product',
|
|
21241
|
+
view_time: viewTime
|
|
21242
|
+
});
|
|
21243
|
+
console.log('[StructurePage] 上报弹窗关闭事件 (Engagement)', {
|
|
21244
|
+
viewTime,
|
|
21245
|
+
productId: productData === null || productData === void 0 ? void 0 : productData.itemId,
|
|
21246
|
+
engagement_type: 'close_popup'
|
|
21247
|
+
});
|
|
21248
|
+
// 清空弹窗数据引用
|
|
21249
|
+
currentPopupDataRef.current = null;
|
|
21250
|
+
}
|
|
21251
|
+
wasPopupOpen = isPopupOpen;
|
|
21252
|
+
};
|
|
21253
|
+
// 每 200ms 检查一次弹窗状态
|
|
21254
|
+
checkInterval = setInterval(checkPopupStatus, 200);
|
|
21255
|
+
return () => {
|
|
21256
|
+
if (checkInterval) {
|
|
21257
|
+
clearInterval(checkInterval);
|
|
21258
|
+
}
|
|
21259
|
+
};
|
|
21260
|
+
}, [data, bffFbReport]);
|
|
21261
|
+
// ==================== 监听 SXP_EVENT_BUS 事件(用于弹窗内的事件响应)====================
|
|
21262
|
+
// 当页面可见性变化时,如果有弹窗打开,需要相应处理
|
|
21263
|
+
React.useEffect(() => {
|
|
21264
|
+
// 弹窗打开时监听 PAGE_DID_SHOW 事件,重置计时器
|
|
21265
|
+
const onShow = () => {
|
|
21266
|
+
if (currentPopupDataRef.current) {
|
|
21267
|
+
popupCurTimeRef.current = new Date();
|
|
21268
|
+
console.log('[StructurePage] PAGE_DID_SHOW - 重置弹窗计时器');
|
|
21269
|
+
}
|
|
21270
|
+
};
|
|
21271
|
+
// 弹窗打开时监听 PAGE_DID_HIDE 事件,上报 ExitFeed
|
|
21272
|
+
const onHide = () => {
|
|
21273
|
+
if (currentPopupDataRef.current) {
|
|
21274
|
+
const { productData, viewPosition, sectionIndex } = currentPopupDataRef.current;
|
|
21275
|
+
// 获取当前 section 的 post 数据
|
|
21276
|
+
let postData = null;
|
|
21277
|
+
if (viewPosition === 'heroSection' && (data === null || data === void 0 ? void 0 : data.heroSection)) {
|
|
21278
|
+
postData = data.heroSection;
|
|
21279
|
+
}
|
|
21280
|
+
else if (viewPosition === 'carouselSection' && (data === null || data === void 0 ? void 0 : data.carouselSection) && sectionIndex !== undefined) {
|
|
21281
|
+
postData = data.carouselSection[sectionIndex];
|
|
21282
|
+
}
|
|
21283
|
+
const rec = {
|
|
21284
|
+
video: {
|
|
21285
|
+
bindProduct: productData,
|
|
21286
|
+
bindProducts: productData ? [productData] : [],
|
|
21287
|
+
itemId: (postData === null || postData === void 0 ? void 0 : postData.itemId) || '',
|
|
21288
|
+
tags: (postData === null || postData === void 0 ? void 0 : postData.tags) || null,
|
|
21289
|
+
scene: (postData === null || postData === void 0 ? void 0 : postData.scene) || null,
|
|
21290
|
+
url: (postData === null || postData === void 0 ? void 0 : postData.url) || null,
|
|
21291
|
+
imgUrls: (postData === null || postData === void 0 ? void 0 : postData.imgUrls) || null
|
|
21292
|
+
},
|
|
21293
|
+
product: null
|
|
21294
|
+
};
|
|
21295
|
+
const viewTime = new Date() - popupCurTimeRef.current;
|
|
21296
|
+
// 上报 ExitFeed 事件(页面隐藏时)
|
|
21297
|
+
bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
|
|
21298
|
+
eventName: 'ExitFeed',
|
|
21299
|
+
product: productData ? [productData] : undefined,
|
|
21300
|
+
contentType: 'product',
|
|
21301
|
+
rec: rec,
|
|
21302
|
+
position: sectionIndex !== undefined ? sectionIndex : 0,
|
|
21303
|
+
view_time: viewTime,
|
|
21304
|
+
content_id: (productData === null || productData === void 0 ? void 0 : productData.itemId) || ''
|
|
21305
|
+
});
|
|
21306
|
+
console.log('[StructurePage] PAGE_DID_HIDE - 上报 ExitFeed (弹窗内)', {
|
|
21307
|
+
viewTime,
|
|
21308
|
+
productId: productData === null || productData === void 0 ? void 0 : productData.itemId
|
|
21309
|
+
});
|
|
21310
|
+
}
|
|
21311
|
+
};
|
|
21312
|
+
SXP_EVENT_BUS.on(SXP_EVENT_TYPE.PAGE_DID_SHOW, onShow);
|
|
21313
|
+
SXP_EVENT_BUS.on(SXP_EVENT_TYPE.PAGE_DID_HIDE, onHide);
|
|
21314
|
+
return () => {
|
|
21315
|
+
SXP_EVENT_BUS.off(SXP_EVENT_TYPE.PAGE_DID_SHOW, onShow);
|
|
21316
|
+
SXP_EVENT_BUS.off(SXP_EVENT_TYPE.PAGE_DID_HIDE, onHide);
|
|
21317
|
+
};
|
|
21318
|
+
}, [data, bffFbReport]);
|
|
20962
21319
|
if (loading) {
|
|
20963
21320
|
return (React.createElement("div", { style: Object.assign(Object.assign({}, baseStyles.container), { height: containerHeight, width: containerWidth, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontSize: '16px' }) }, "Loading..."));
|
|
20964
21321
|
}
|
|
@@ -20990,7 +21347,7 @@ const StructurePage = (_a) => {
|
|
|
20990
21347
|
return '20px';
|
|
20991
21348
|
})(),
|
|
20992
21349
|
backgroundColor: '#000',
|
|
20993
|
-
textAlign: ((
|
|
21350
|
+
textAlign: ((_f = multiCTAConfig === null || multiCTAConfig === void 0 ? void 0 : multiCTAConfig.heroTopText) === null || _f === void 0 ? void 0 : _f.textAlign) || 'center',
|
|
20994
21351
|
boxSizing: 'border-box',
|
|
20995
21352
|
display: 'flex',
|
|
20996
21353
|
alignItems: 'center',
|
|
@@ -21049,7 +21406,15 @@ const StructurePage = (_a) => {
|
|
|
21049
21406
|
return textStyle;
|
|
21050
21407
|
})()) }, data.heroSection.text))),
|
|
21051
21408
|
React.createElement("div", { style: baseStyles.heroImageContainer },
|
|
21052
|
-
React.createElement(PostView, { videoRef: heroVideoRef, isVideo: !!data.heroSection.url, autoPlayTriggerRef: heroAutoPlayTrigger
|
|
21409
|
+
React.createElement(PostView, { videoRef: heroVideoRef, isVideo: !!data.heroSection.url, autoPlayTriggerRef: heroAutoPlayTrigger, onVideoPlay: () => {
|
|
21410
|
+
// 视频开始播放,隐藏暂停图标
|
|
21411
|
+
console.log('[Hero PostView] onVideoPlay 回调');
|
|
21412
|
+
setIsHeroVideoPaused(false);
|
|
21413
|
+
}, onVideoPause: () => {
|
|
21414
|
+
// 视频暂停,显示暂停图标
|
|
21415
|
+
console.log('[Hero PostView] onVideoPause 回调');
|
|
21416
|
+
setIsHeroVideoPaused(true);
|
|
21417
|
+
} }, data.heroSection.url ? (React.createElement("div", { style: { position: 'relative', width: '100%', height: '100%' }, onClick: handleHeroVideoClick },
|
|
21053
21418
|
React.createElement("video", { ref: (el) => {
|
|
21054
21419
|
if (heroVideoRef) {
|
|
21055
21420
|
heroVideoRef.current = el;
|
|
@@ -21075,7 +21440,10 @@ const StructurePage = (_a) => {
|
|
|
21075
21440
|
});
|
|
21076
21441
|
el.addEventListener('ended', (e) => {
|
|
21077
21442
|
console.log('[Hero Video] ended event triggered');
|
|
21078
|
-
handleVideoPlayOver(data.heroSection, 'heroSection', 0, e.currentTarget);
|
|
21443
|
+
handleVideoPlayOver(data.heroSection, 'heroSection', 0, e.currentTarget, true);
|
|
21444
|
+
});
|
|
21445
|
+
el.addEventListener('timeupdate', (e) => {
|
|
21446
|
+
handleVideoTimeUpdate(data.heroSection, 'heroSection', 0, e.currentTarget);
|
|
21079
21447
|
});
|
|
21080
21448
|
}
|
|
21081
21449
|
}, src: data.heroSection.url, style: baseStyles.heroVideo, muted: true, loop: true, playsInline: true, controls: false, onLoadedMetadata: () => {
|
|
@@ -21085,8 +21453,8 @@ const StructurePage = (_a) => {
|
|
|
21085
21453
|
const initTime = videoLoadTime.current[videoId] || loadTime;
|
|
21086
21454
|
videoLoadTime.current[videoId] = loadTime - initTime;
|
|
21087
21455
|
} }),
|
|
21088
|
-
isHeroVideoPaused && (React.createElement(FormatImage$1, { className: 'clc-pb-video-pause', src: videoPlayIcon, alt: 'play' })))) : ((
|
|
21089
|
-
React.createElement("div", { style: baseStyles.heroOverlay }, renderCTA('heroButton', (
|
|
21456
|
+
isHeroVideoPaused && (React.createElement(FormatImage$1, { className: 'clc-pb-video-pause', src: videoPlayIcon, alt: 'play' })))) : ((_g = data.heroSection.imgUrls) === null || _g === void 0 ? void 0 : _g[0]) ? (React.createElement("img", { src: data.heroSection.imgUrls[0], alt: 'Hero', style: baseStyles.heroImage })) : null),
|
|
21457
|
+
React.createElement("div", { style: baseStyles.heroOverlay }, renderCTA('heroButton', (_j = (_h = data.heroSection.bindProducts) === null || _h === void 0 ? void 0 : _h[0]) === null || _j === void 0 ? void 0 : _j.bindCta, (_k = data.heroSection.bindProducts) === null || _k === void 0 ? void 0 : _k[0], baseStyles.heroButton, 'heroSection', 0))))),
|
|
21090
21458
|
data.carouselSection && data.carouselSection.length > 0 && (React.createElement("div", { ref: carouselSectionRef, style: mergeStyles(baseStyles.carouselSection, 'carouselSection', { excludeBorder: true }) },
|
|
21091
21459
|
React.createElement("div", { style: baseStyles.carouselImageContainer, onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchEnd: handleTouchEnd },
|
|
21092
21460
|
React.createElement("div", { style: Object.assign(Object.assign({}, baseStyles.carouselContainer), { transform: `translateX(-${carouselIndex * 100}%)` }) }, data.carouselSection.map((item, index) => {
|
|
@@ -21141,7 +21509,10 @@ const StructurePage = (_a) => {
|
|
|
21141
21509
|
});
|
|
21142
21510
|
el.addEventListener('ended', (e) => {
|
|
21143
21511
|
console.log('[Carousel Video] ended event triggered, index:', index);
|
|
21144
|
-
handleVideoPlayOver(item, 'carouselSection', index, e.currentTarget);
|
|
21512
|
+
handleVideoPlayOver(item, 'carouselSection', index, e.currentTarget, true);
|
|
21513
|
+
});
|
|
21514
|
+
el.addEventListener('timeupdate', (e) => {
|
|
21515
|
+
handleVideoTimeUpdate(item, 'carouselSection', index, e.currentTarget);
|
|
21145
21516
|
});
|
|
21146
21517
|
}
|
|
21147
21518
|
}, src: item.url, style: baseStyles.carouselVideo, muted: true, loop: true, playsInline: true, controls: false, draggable: false, onDragStart: (e) => e.preventDefault(), onLoadedMetadata: () => {
|
|
@@ -21174,7 +21545,10 @@ const StructurePage = (_a) => {
|
|
|
21174
21545
|
});
|
|
21175
21546
|
el.addEventListener('ended', (e) => {
|
|
21176
21547
|
console.log('[Carousel Video (non-current)] ended event triggered, index:', index);
|
|
21177
|
-
handleVideoPlayOver(item, 'carouselSection', index, e.currentTarget);
|
|
21548
|
+
handleVideoPlayOver(item, 'carouselSection', index, e.currentTarget, true);
|
|
21549
|
+
});
|
|
21550
|
+
el.addEventListener('timeupdate', (e) => {
|
|
21551
|
+
handleVideoTimeUpdate(item, 'carouselSection', index, e.currentTarget);
|
|
21178
21552
|
});
|
|
21179
21553
|
}
|
|
21180
21554
|
}, src: item.url, style: baseStyles.carouselVideo, muted: true, loop: true, playsInline: true, controls: false, draggable: false, onDragStart: (e) => e.preventDefault(), onLoadedMetadata: () => {
|
|
@@ -21197,9 +21571,9 @@ const StructurePage = (_a) => {
|
|
|
21197
21571
|
padding: '10px 20px',
|
|
21198
21572
|
backgroundColor: '#000',
|
|
21199
21573
|
color: '#fff',
|
|
21200
|
-
textAlign: ((
|
|
21574
|
+
textAlign: ((_l = multiCTAConfig === null || multiCTAConfig === void 0 ? void 0 : multiCTAConfig.carouselSection) === null || _l === void 0 ? void 0 : _l.textAlign) || 'center'
|
|
21201
21575
|
} },
|
|
21202
|
-
((
|
|
21576
|
+
((_m = data.carouselSection[carouselIndex]) === null || _m === void 0 ? void 0 : _m.text) && (React.createElement("div", { style: { marginBottom: '15px' } },
|
|
21203
21577
|
React.createElement("span", { style: Object.assign({}, (() => {
|
|
21204
21578
|
const config = multiCTAConfig === null || multiCTAConfig === void 0 ? void 0 : multiCTAConfig.carouselSection;
|
|
21205
21579
|
if (!config) {
|
|
@@ -21235,8 +21609,8 @@ const StructurePage = (_a) => {
|
|
|
21235
21609
|
textStyle.margin = config.margin;
|
|
21236
21610
|
}
|
|
21237
21611
|
return textStyle;
|
|
21238
|
-
})()) }, (
|
|
21239
|
-
renderCTA('carouselButton', (
|
|
21612
|
+
})()) }, (_o = data.carouselSection[carouselIndex]) === null || _o === void 0 ? void 0 : _o.text))),
|
|
21613
|
+
renderCTA('carouselButton', (_r = (_q = (_p = data.carouselSection[carouselIndex]) === null || _p === void 0 ? void 0 : _p.bindProducts) === null || _q === void 0 ? void 0 : _q[0]) === null || _r === void 0 ? void 0 : _r.bindCta, (_t = (_s = data.carouselSection[carouselIndex]) === null || _s === void 0 ? void 0 : _s.bindProducts) === null || _t === void 0 ? void 0 : _t[0], baseStyles.carouselButton, 'carouselSection', carouselIndex)))),
|
|
21240
21614
|
data.highlightRevealSection && (React.createElement(ProductView, { onExposure: () => handleProductViewExposure(data.highlightRevealSection, 'highlightRevealSection', 0), onLeave: () => handleProductViewLeave(data.highlightRevealSection, 'highlightRevealSection', 0) },
|
|
21241
21615
|
React.createElement("div", { style: mergeStyles(baseStyles.highlightSection, 'highlightSection', { excludeBorder: true }) },
|
|
21242
21616
|
React.createElement("div", { style: baseStyles.highlightImageContainer },
|
|
@@ -21246,7 +21620,7 @@ const StructurePage = (_a) => {
|
|
|
21246
21620
|
padding: '20px',
|
|
21247
21621
|
backgroundColor: '#000',
|
|
21248
21622
|
color: '#fff',
|
|
21249
|
-
textAlign: ((
|
|
21623
|
+
textAlign: ((_u = multiCTAConfig === null || multiCTAConfig === void 0 ? void 0 : multiCTAConfig.highlightSection) === null || _u === void 0 ? void 0 : _u.textAlign) || 'center'
|
|
21250
21624
|
} },
|
|
21251
21625
|
data.highlightRevealSection.description && (React.createElement("div", { style: { marginBottom: '10px' } },
|
|
21252
21626
|
React.createElement("span", { style: Object.assign({}, (() => {
|
|
@@ -21340,7 +21714,7 @@ const StructurePage = (_a) => {
|
|
|
21340
21714
|
padding: '20px',
|
|
21341
21715
|
backgroundColor: '#000',
|
|
21342
21716
|
color: '#fff',
|
|
21343
|
-
textAlign: ((
|
|
21717
|
+
textAlign: ((_v = multiCTAConfig === null || multiCTAConfig === void 0 ? void 0 : multiCTAConfig.footerSection) === null || _v === void 0 ? void 0 : _v.textAlign) || 'center'
|
|
21344
21718
|
} },
|
|
21345
21719
|
data.footerSection.text && (React.createElement("div", { style: { marginBottom: '15px' } },
|
|
21346
21720
|
React.createElement("span", { style: Object.assign({}, (() => {
|