pb-sxp-ui 1.0.3-alpha.1 → 1.0.3-alpha.3

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.
Files changed (74) hide show
  1. package/dist/index.cjs +2403 -825
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.css +114 -112
  4. package/dist/index.js +2404 -826
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.min.cjs +3 -3
  7. package/dist/index.min.cjs.map +1 -1
  8. package/dist/index.min.js +3 -3
  9. package/dist/index.min.js.map +1 -1
  10. package/dist/pb-ui.js +2403 -825
  11. package/dist/pb-ui.js.map +1 -1
  12. package/dist/pb-ui.min.js +3 -3
  13. package/dist/pb-ui.min.js.map +1 -1
  14. package/es/core/components/SxpPageRender/Hashtag/index.d.ts +2 -1
  15. package/es/core/components/SxpPageRender/Hashtag/index.js +2 -2
  16. package/es/core/components/SxpPageRender/Navbar.d.ts +1 -0
  17. package/es/core/components/SxpPageRender/Navbar.js +3 -2
  18. package/es/core/components/SxpPageRender/PictureGroup/Picture.js +31 -3
  19. package/es/core/components/SxpPageRender/VideoWidget/index.js +21 -30
  20. package/es/core/components/SxpPageRender/WaterFall/List.d.ts +2 -1
  21. package/es/core/components/SxpPageRender/WaterFall/List.js +24 -14
  22. package/es/core/components/SxpPageRender/WaterFall/WaterfallList.d.ts +2 -1
  23. package/es/core/components/SxpPageRender/WaterFall/WaterfallList.js +13 -11
  24. package/es/core/components/SxpPageRender/WaterFall/index.d.ts +2 -1
  25. package/es/core/components/SxpPageRender/WaterFall/index.js +4 -3
  26. package/es/core/components/SxpPageRender/WaterFall/preview.json +1242 -0
  27. package/es/core/components/SxpPageRender/index.d.ts +2 -0
  28. package/es/core/components/SxpPageRender/index.js +5 -5
  29. package/es/core/context/EditorDataProvider.d.ts +3 -1
  30. package/es/core/context/EditorDataProvider.js +5 -2
  31. package/es/core/context/SxpDataSourceProvider.d.ts +2 -0
  32. package/es/core/context/SxpDataSourceProvider.js +7 -3
  33. package/es/materials/sxp/HashTag/index.d.ts +14 -0
  34. package/es/materials/sxp/HashTag/index.js +6 -0
  35. package/es/materials/sxp/HashTag/material.d.ts +2 -0
  36. package/es/materials/sxp/HashTag/material.js +52 -0
  37. package/es/materials/sxp/HashTag/settingRender.d.ts +122 -0
  38. package/es/materials/sxp/HashTag/settingRender.js +153 -0
  39. package/es/materials/sxp/index.d.ts +1 -0
  40. package/es/materials/sxp/index.js +1 -0
  41. package/es/materials/sxp/popup/CommodityDetailDiroNew/index.js +4 -3
  42. package/es/materials/sxp/template/components/settingRender.d.ts +15 -0
  43. package/es/materials/sxp/template/components/settingRender.js +17 -0
  44. package/lib/core/components/SxpPageRender/Hashtag/index.d.ts +2 -1
  45. package/lib/core/components/SxpPageRender/Hashtag/index.js +2 -2
  46. package/lib/core/components/SxpPageRender/Navbar.d.ts +1 -0
  47. package/lib/core/components/SxpPageRender/Navbar.js +3 -2
  48. package/lib/core/components/SxpPageRender/PictureGroup/Picture.js +30 -2
  49. package/lib/core/components/SxpPageRender/VideoWidget/index.js +21 -30
  50. package/lib/core/components/SxpPageRender/WaterFall/List.d.ts +2 -1
  51. package/lib/core/components/SxpPageRender/WaterFall/List.js +23 -14
  52. package/lib/core/components/SxpPageRender/WaterFall/WaterfallList.d.ts +2 -1
  53. package/lib/core/components/SxpPageRender/WaterFall/WaterfallList.js +12 -11
  54. package/lib/core/components/SxpPageRender/WaterFall/index.d.ts +2 -1
  55. package/lib/core/components/SxpPageRender/WaterFall/index.js +4 -3
  56. package/lib/core/components/SxpPageRender/WaterFall/preview.json +1242 -0
  57. package/lib/core/components/SxpPageRender/index.d.ts +2 -0
  58. package/lib/core/components/SxpPageRender/index.js +5 -5
  59. package/lib/core/context/EditorDataProvider.d.ts +3 -1
  60. package/lib/core/context/EditorDataProvider.js +4 -1
  61. package/lib/core/context/SxpDataSourceProvider.d.ts +2 -0
  62. package/lib/core/context/SxpDataSourceProvider.js +7 -3
  63. package/lib/materials/sxp/HashTag/index.d.ts +14 -0
  64. package/lib/materials/sxp/HashTag/index.js +9 -0
  65. package/lib/materials/sxp/HashTag/material.d.ts +2 -0
  66. package/lib/materials/sxp/HashTag/material.js +56 -0
  67. package/lib/materials/sxp/HashTag/settingRender.d.ts +122 -0
  68. package/lib/materials/sxp/HashTag/settingRender.js +155 -0
  69. package/lib/materials/sxp/index.d.ts +1 -0
  70. package/lib/materials/sxp/index.js +1 -0
  71. package/lib/materials/sxp/popup/CommodityDetailDiroNew/index.js +4 -3
  72. package/lib/materials/sxp/template/components/settingRender.d.ts +15 -0
  73. package/lib/materials/sxp/template/components/settingRender.js +17 -0
  74. package/package.json +1 -1
package/dist/pb-ui.js CHANGED
@@ -421,7 +421,7 @@
421
421
  DataSourceType[DataSourceType["BFF"] = 5] = "BFF";
422
422
  })(DataSourceType || (DataSourceType = {}));
423
423
  const UTM_KEYS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_id', 'utm_content', 'cl_source'];
424
- const SxpDataSourceProvider = ({ render, dataSources, utmVal, enableReportEvent = true, maxSize, defaultSize, isPreview = false, sxpParameter, appDomain, hashTagSize, loadingImage }) => {
424
+ const SxpDataSourceProvider = ({ render, dataSources, utmVal, enableReportEvent = true, maxSize, defaultSize, isPreview = false, sxpParameter, appDomain, hashTagSize, loadingImage, isOpenHashTag = false }) => {
425
425
  const [rtcList, setRtcList] = React.useState([]);
426
426
  const [loading, setLoading] = React.useState(false);
427
427
  const [curReqInfo, setCurReqInfo] = React.useState({ rtc: '', requestId: '' });
@@ -430,10 +430,13 @@
430
430
  // 弹窗数据
431
431
  const [popupDetailData, setPopupDetailData] = React.useState();
432
432
  const [waterFallData, setWaterFallData] = React.useState();
433
- const [openHashtag, setOpenHashtag] = React.useState(false);
433
+ const [openHashtag, setOpenHashtag] = React.useState(isOpenHashTag);
434
434
  const [cacheRtcList, setCacheRtcList] = React.useState([]);
435
435
  const [cacheActiveIndex, setCacheActiveIndex] = React.useState(0);
436
436
  const [isFromHashtag, setIsFromHashtag] = React.useState(false);
437
+ React.useEffect(() => {
438
+ setOpenHashtag(isOpenHashTag);
439
+ }, [isOpenHashTag]);
437
440
  // BFF 数据源
438
441
  const bffDataSource = React.useMemo(() => {
439
442
  return dataSources === null || dataSources === void 0 ? void 0 : dataSources.find((d) => d.type === DataSourceType.BFF);
@@ -618,7 +621,8 @@
618
621
  setIsFromHashtag,
619
622
  appDomain,
620
623
  hashTagSize,
621
- loadingImage: loadingImage !== null && loadingImage !== void 0 ? loadingImage : defaultLoadingImage
624
+ loadingImage: loadingImage !== null && loadingImage !== void 0 ? loadingImage : defaultLoadingImage,
625
+ isOpenHashTag
622
626
  } }, render({ rtcList, mutateLike: bffMutateLike, mutateUnlike: bffMutateUnlike, submitForm: bffSubmitForm })));
623
627
  };
624
628
  var SxpDataSourceProvider$1 = React.memo(SxpDataSourceProvider);
@@ -882,7 +886,7 @@
882
886
  * @FilePath: \pb-sxp-ui\src\materials\sxp\popup\AppointForm\settingRender.tsx
883
887
  *
884
888
  */
885
- var settingRender$4 = [
889
+ var settingRender$5 = [
886
890
  {
887
891
  type: 'Text',
888
892
  label: '组件名称',
@@ -1071,7 +1075,7 @@
1071
1075
  category: 'popup',
1072
1076
  type: 'AppointForm',
1073
1077
  related: {
1074
- settingRender: settingRender$4,
1078
+ settingRender: settingRender$5,
1075
1079
  bindableProps: [],
1076
1080
  interactionRender: interactionRender$8
1077
1081
  },
@@ -1113,7 +1117,7 @@
1113
1117
  * @FilePath: \pb-sxp-ui\src\materials\sxp\popup\CommodityDetailDiroNew\settingRender.tsx
1114
1118
  *
1115
1119
  */
1116
- var settingRender$3 = [
1120
+ var settingRender$4 = [
1117
1121
  {
1118
1122
  title: '商品图片',
1119
1123
  child: [
@@ -8400,7 +8404,7 @@
8400
8404
  category: 'popup',
8401
8405
  type: 'CommodityDetail',
8402
8406
  related: {
8403
- settingRender: settingRender$3
8407
+ settingRender: settingRender$4
8404
8408
  },
8405
8409
  defaulSetting: {
8406
8410
  props: {
@@ -8462,7 +8466,7 @@
8462
8466
  * @FilePath: \pb-sxp-ui\src\materials\sxp\popup\Prompt\settingRender.tsx
8463
8467
  *
8464
8468
  */
8465
- var settingRender$2 = [
8469
+ var settingRender$3 = [
8466
8470
  {
8467
8471
  type: 'Media',
8468
8472
  label: '图标',
@@ -8537,7 +8541,7 @@
8537
8541
  category: 'popup',
8538
8542
  type: 'Prompt',
8539
8543
  related: {
8540
- settingRender: settingRender$2,
8544
+ settingRender: settingRender$3,
8541
8545
  bindableProps: [],
8542
8546
  interactionRender: interactionRender$7
8543
8547
  },
@@ -8562,7 +8566,7 @@
8562
8566
  * @FilePath: \pb-sxp-ui\src\materials\sxp\popup\CommodityDetailDiroNew\settingRender.tsx
8563
8567
  *
8564
8568
  */
8565
- var settingRender$1 = [
8569
+ var settingRender$2 = [
8566
8570
  {
8567
8571
  title: '商品图片',
8568
8572
  child: [
@@ -8824,11 +8828,12 @@ Made in Italy` })));
8824
8828
  }), src: (_j = sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image) !== null && _j !== void 0 ? _j : bottom_image, alt: '' }))),
8825
8829
  React.createElement("div", { className: 'pb-commondityDiroNew-content' },
8826
8830
  React.createElement("div", { className: 'pb-commondityDiroNew-content-top' },
8827
- React.createElement("div", { className: 'pb-commondityDiroNew-content-top-title', style: commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.title }, (_k = product === null || product === void 0 ? void 0 : product.title) !== null && _k !== void 0 ? _k : 'Large Dior Toujours Bag'),
8828
- React.createElement("div", { className: '' },
8831
+ React.createElement("div", null,
8832
+ React.createElement("div", { className: 'pb-commondityDiroNew-content-top-title', style: commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.title }, (_k = product === null || product === void 0 ? void 0 : product.title) !== null && _k !== void 0 ? _k : 'Large Dior Toujours Bag'),
8833
+ React.createElement("div", { className: 'pb-commondityDiroNew-content-collection', hidden: !!product && (!(product === null || product === void 0 ? void 0 : product.collection) || (product === null || product === void 0 ? void 0 : product.collection) === ''), style: commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.collection }, (product === null || product === void 0 ? void 0 : product.collection) || 'Black Macrocannage Calfskin')),
8834
+ React.createElement("div", null,
8829
8835
  React.createElement("div", { className: 'pb-commondityDiroNew-content-top-price', hidden: !!product && !(product === null || product === void 0 ? void 0 : product.price), style: commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.price }, priceText),
8830
8836
  React.createElement("div", { className: 'pb-commondityDiroNew-content-top-price', hidden: !!product && !(product === null || product === void 0 ? void 0 : product.taxInfo), style: commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.taxInfo }, (_l = product === null || product === void 0 ? void 0 : product.taxInfo) !== null && _l !== void 0 ? _l : '税费'))),
8831
- React.createElement("div", { className: 'pb-commondityDiroNew-content-collection', hidden: !!product && (!(product === null || product === void 0 ? void 0 : product.collection) || (product === null || product === void 0 ? void 0 : product.collection) === ''), style: commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.collection }, (product === null || product === void 0 ? void 0 : product.collection) || 'Black Macrocannage Calfskin'),
8832
8837
  (!product || (product === null || product === void 0 ? void 0 : product.link)) && (React.createElement("button", { onClick: handleLink, className: 'pb-commondityDiroNew-btn', style: buttonStyle }, (_m = cta === null || cta === void 0 ? void 0 : cta.enTitle) !== null && _m !== void 0 ? _m : 'Shop now')),
8833
8838
  productInfoText({ isPost }))),
8834
8839
  React.createElement(Modal$1, { visible: showModal, onClose: () => setShowModal(false) }, productInfoText({ isPost: false }))));
@@ -8849,7 +8854,7 @@ Made in Italy` })));
8849
8854
  category: 'popup',
8850
8855
  type: 'CommodityDetailDiroNew',
8851
8856
  related: {
8852
- settingRender: settingRender$1
8857
+ settingRender: settingRender$2
8853
8858
  },
8854
8859
  defaulSetting: {
8855
8860
  props: {
@@ -8905,11 +8910,11 @@ Made in Italy` })));
8905
8910
  * @Author: binruan@chatlabs.com
8906
8911
  * @Date: 2024-03-26 16:50:25
8907
8912
  * @LastEditors: binruan@chatlabs.com
8908
- * @LastEditTime: 2024-03-29 17:03:07
8913
+ * @LastEditTime: 2024-04-03 15:51:15
8909
8914
  * @FilePath: \pb-sxp-ui\src\materials\sxp\template\components\settingRender.tsx
8910
8915
  *
8911
8916
  */
8912
- var settingRender = [
8917
+ var settingRender$1 = [
8913
8918
  {
8914
8919
  title: '主题样式',
8915
8920
  child: [
@@ -9069,6 +9074,23 @@ Made in Italy` })));
9069
9074
  }
9070
9075
  ]
9071
9076
  },
9077
+ {
9078
+ type: 'Group',
9079
+ label: '圆角',
9080
+ child: [
9081
+ {
9082
+ type: 'Slider',
9083
+ name: ['props', 'ctaTempStyles', 'ctaTitle', 'borderRadius'],
9084
+ max: 100
9085
+ },
9086
+ {
9087
+ type: 'Number',
9088
+ name: ['props', 'ctaTempStyles', 'ctaTitle', 'borderRadius'],
9089
+ addonAfter: 'px',
9090
+ max: 100
9091
+ }
9092
+ ]
9093
+ },
9072
9094
  {
9073
9095
  type: 'Color',
9074
9096
  label: '背景色',
@@ -9217,7 +9239,7 @@ Made in Italy` })));
9217
9239
  related: {
9218
9240
  interactionRender: interactionRender$6,
9219
9241
  bindableProps: [],
9220
- settingRender
9242
+ settingRender: settingRender$1
9221
9243
  },
9222
9244
  defaulSetting: {
9223
9245
  props: {
@@ -9295,7 +9317,7 @@ Made in Italy` })));
9295
9317
  type: 'Appoint',
9296
9318
  related: {
9297
9319
  interactionRender: interactionRender$5,
9298
- settingRender: settingRender === null || settingRender === void 0 ? void 0 : settingRender.filter((i) => i.type !== 'commodityTitle'),
9320
+ settingRender: settingRender$1 === null || settingRender$1 === void 0 ? void 0 : settingRender$1.filter((i) => i.type !== 'commodityTitle'),
9299
9321
  bindableProps: []
9300
9322
  },
9301
9323
  defaulSetting: {
@@ -9371,7 +9393,7 @@ Made in Italy` })));
9371
9393
  category: 'template',
9372
9394
  type: 'Link',
9373
9395
  related: {
9374
- settingRender: settingRender === null || settingRender === void 0 ? void 0 : settingRender.filter((i) => i.type !== 'commodityTitle'),
9396
+ settingRender: settingRender$1 === null || settingRender$1 === void 0 ? void 0 : settingRender$1.filter((i) => i.type !== 'commodityTitle'),
9375
9397
  bindableProps: []
9376
9398
  },
9377
9399
  defaulSetting: {
@@ -9456,7 +9478,7 @@ Made in Italy` })));
9456
9478
  type: 'CommodityDiro',
9457
9479
  related: {
9458
9480
  interactionRender: interactionRender$4,
9459
- settingRender,
9481
+ settingRender: settingRender$1,
9460
9482
  bindableProps: []
9461
9483
  },
9462
9484
  defaulSetting: {
@@ -9548,7 +9570,7 @@ Made in Italy` })));
9548
9570
  related: {
9549
9571
  interactionRender: interactionRender$3,
9550
9572
  bindableProps: [],
9551
- settingRender
9573
+ settingRender: settingRender$1
9552
9574
  },
9553
9575
  defaulSetting: {
9554
9576
  props: {
@@ -9680,7 +9702,7 @@ Made in Italy` })));
9680
9702
  related: {
9681
9703
  interactionRender: interactionRender$2,
9682
9704
  bindableProps: [],
9683
- settingRender
9705
+ settingRender: settingRender$1
9684
9706
  },
9685
9707
  defaulSetting: {
9686
9708
  props: {
@@ -9782,7 +9804,7 @@ Made in Italy` })));
9782
9804
  type: 'MultiCommodity',
9783
9805
  related: {
9784
9806
  interactionRender: interactionRender$1,
9785
- settingRender,
9807
+ settingRender: settingRender$1,
9786
9808
  bindableProps: []
9787
9809
  },
9788
9810
  defaulSetting: {
@@ -9886,7 +9908,7 @@ Made in Italy` })));
9886
9908
  related: {
9887
9909
  interactionRender,
9888
9910
  bindableProps: [],
9889
- settingRender
9911
+ settingRender: settingRender$1
9890
9912
  },
9891
9913
  defaulSetting: {
9892
9914
  props: {
@@ -9928,898 +9950,2451 @@ Made in Italy` })));
9928
9950
 
9929
9951
  /*
9930
9952
  * @Author: binruan@chatlabs.com
9931
- * @Date: 2023-07-25 14:56:49
9953
+ * @Date: 2024-04-07 14:07:12
9932
9954
  * @LastEditors: binruan@chatlabs.com
9933
- * @LastEditTime: 2024-03-20 13:46:06
9934
- * @FilePath: \pb-sxp-ui\src\materials\index.ts
9955
+ * @LastEditTime: 2024-04-07 14:54:11
9956
+ * @FilePath: \pb-sxp-ui\src\materials\sxp\HashTag\settingRender.tsx
9935
9957
  *
9936
9958
  */
9937
-
9938
- var _materials_ = /*#__PURE__*/Object.freeze({
9939
- __proto__: null,
9940
- Appoint: Appoint,
9941
- AppointForm: AppointForm,
9942
- Commodity: Commodity,
9943
- CommodityDetail: CommodityDetail,
9944
- CommodityDetailDiroNew: CommodityDetailDiroNew,
9945
- CommodityDiro: CommodityDiro,
9946
- CommodityDiroNew: CommodityDiroNew,
9947
- Link: Link,
9948
- MultiCommodity: MultiCommodity,
9949
- MultiCommodityDiro: MultiCommodityDiro,
9950
- MultiCommodityDiroNew: MultiCommodityDiroNew,
9951
- Prompt: Prompt
9952
- });
9953
-
9954
- const defaultUnLikeIconPath = '/pb_static/f71266d2c64446c5ae6a5a7f5489cc0a.png';
9955
- const defaultLikeIconPath = '/pb_static/f07900fe3f0f4ae188ea1611d4801a44.png';
9956
- const LikeButton = (_a) => {
9957
- var { active, activeIcon, unActicveIcon, recData } = _a, props = __rest(_a, ["active", "activeIcon", "unActicveIcon", "recData"]);
9958
- const { mutateLike, mutateUnlike, bffEventReport } = useSxpDataSource();
9959
- const [state, setState] = React.useState(active);
9960
- const likeIcon = useIconLink(defaultLikeIconPath);
9961
- const unlikeIcon = useIconLink(defaultUnLikeIconPath);
9962
- const handleClick = lodash.debounce(() => __awaiter(void 0, void 0, void 0, function* () {
9963
- var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
9964
- if (state) {
9965
- // 先设置状态
9966
- setState(false);
9967
- const result = (_d = (yield (mutateUnlike === null || mutateUnlike === void 0 ? void 0 : mutateUnlike({ videoItemId: (_c = (_b = recData.video) === null || _b === void 0 ? void 0 : _b.itemId) !== null && _c !== void 0 ? _c : '' })))) !== null && _d !== void 0 ? _d : false;
9968
- bffEventReport === null || bffEventReport === void 0 ? void 0 : bffEventReport({
9969
- eventInfo: {
9970
- eventSubject: 'favoriteContentCanceled',
9971
- eventDescription: 'This content was unfavorite by the user',
9972
- contentId: (_f = (_e = recData.video) === null || _e === void 0 ? void 0 : _e.itemId) !== null && _f !== void 0 ? _f : '',
9973
- contentName: (_h = (_g = recData.video) === null || _g === void 0 ? void 0 : _g.title) !== null && _h !== void 0 ? _h : '',
9974
- contentTags: JSON.stringify((_k = (_j = recData.video) === null || _j === void 0 ? void 0 : _j.tags) !== null && _k !== void 0 ? _k : []),
9975
- position: recData.position,
9976
- contentFormat: ((_l = recData.video) === null || _l === void 0 ? void 0 : _l.url) ? 'video' : 'image',
9977
- traceInfo: (_m = recData.video) === null || _m === void 0 ? void 0 : _m.traceInfo
9978
- }
9979
- });
9980
- // 如果接口调用失败,则回滚状态
9981
- if (!result) {
9982
- setState(true);
9959
+ var settingRender = [
9960
+ {
9961
+ title: '卡片样式',
9962
+ child: [
9963
+ {
9964
+ type: 'Number',
9965
+ label: '文本行数',
9966
+ name: ['props', 'lineClamp']
9967
+ },
9968
+ {
9969
+ type: 'Number',
9970
+ label: '上下边距',
9971
+ name: ['props', 'space'],
9972
+ addonAfter: 'px'
9983
9973
  }
9984
- }
9985
- else {
9986
- setState(true);
9987
- const result = (_o = (yield (mutateLike === null || mutateLike === void 0 ? void 0 : mutateLike({ content: JSON.stringify(recData) })))) !== null && _o !== void 0 ? _o : false;
9988
- bffEventReport === null || bffEventReport === void 0 ? void 0 : bffEventReport({
9989
- eventInfo: {
9990
- eventSubject: 'favoriteContent',
9991
- eventDescription: 'This content was favorite by the user',
9992
- contentId: (_q = (_p = recData.video) === null || _p === void 0 ? void 0 : _p.itemId) !== null && _q !== void 0 ? _q : '',
9993
- contentName: (_s = (_r = recData.video) === null || _r === void 0 ? void 0 : _r.title) !== null && _s !== void 0 ? _s : '',
9994
- contentTags: JSON.stringify((_u = (_t = recData.video) === null || _t === void 0 ? void 0 : _t.tags) !== null && _u !== void 0 ? _u : []),
9995
- position: recData.position,
9996
- contentFormat: ((_v = recData.video) === null || _v === void 0 ? void 0 : _v.url) ? 'video' : 'image',
9997
- traceInfo: (_w = recData.video) === null || _w === void 0 ? void 0 : _w.traceInfo
9998
- }
9999
- });
10000
- if (!result) {
10001
- setState(false);
9974
+ ]
9975
+ },
9976
+ {
9977
+ title: '文本设置',
9978
+ child: [
9979
+ {
9980
+ name: ['props', 'textStyles'],
9981
+ type: 'SelectLinkage',
9982
+ child: [
9983
+ {
9984
+ label: '字段',
9985
+ type: 'Select',
9986
+ options: [
9987
+ {
9988
+ label: 'hashtag标题',
9989
+ value: 'hashTagTitle'
9990
+ },
9991
+ {
9992
+ label: 'hashtag描述',
9993
+ value: 'hashTagDesc'
9994
+ },
9995
+ {
9996
+ label: '标题',
9997
+ value: 'title'
9998
+ },
9999
+ {
10000
+ label: '价格',
10001
+ value: 'price'
10002
+ }
10003
+ ],
10004
+ name: ['props', 'textStyles', 'field'],
10005
+ initialValue: 'title'
10006
+ },
10007
+ {
10008
+ type: 'Group',
10009
+ label: '标题字体',
10010
+ child: [
10011
+ {
10012
+ type: 'Color',
10013
+ name: ['color']
10014
+ },
10015
+ {
10016
+ type: 'Select',
10017
+ options: [{ label: '黑体', value: '黑体' }],
10018
+ name: ['fontFamily']
10019
+ },
10020
+ {
10021
+ type: 'Number',
10022
+ addonAfter: 'px',
10023
+ name: ['fontSize']
10024
+ }
10025
+ ]
10026
+ },
10027
+ {
10028
+ label: '标题样式',
10029
+ type: 'TextStyle'
10030
+ },
10031
+ {
10032
+ label: '标题对齐',
10033
+ type: 'TextAlign'
10034
+ }
10035
+ ]
10002
10036
  }
10003
- }
10004
- }), 200);
10005
- return (React.createElement("button", Object.assign({}, props, { onClick: handleClick }),
10006
- React.createElement("img", { style: { width: '100%', height: '100%', objectFit: 'contain' }, src: state ? activeIcon || likeIcon : unActicveIcon || unlikeIcon, alt: 'icon' })));
10037
+ ]
10038
+ },
10039
+ {
10040
+ title: '按钮样式',
10041
+ child: [
10042
+ {
10043
+ type: 'Color',
10044
+ label: '背景色',
10045
+ name: ['props', 'buttonStyle', 'backgroundColor'],
10046
+ initialValue: '#000'
10047
+ },
10048
+ {
10049
+ type: 'Group',
10050
+ label: '尺寸',
10051
+ child: [
10052
+ {
10053
+ type: 'Number',
10054
+ name: ['props', 'buttonStyle', 'height'],
10055
+ addonAfter: 'H'
10056
+ }
10057
+ ]
10058
+ },
10059
+ {
10060
+ type: 'Group',
10061
+ label: '圆角',
10062
+ child: [
10063
+ {
10064
+ type: 'Slider',
10065
+ name: ['props', 'buttonStyle', 'borderRadius'],
10066
+ max: 100
10067
+ },
10068
+ {
10069
+ type: 'Number',
10070
+ name: ['props', 'buttonStyle', 'borderRadius'],
10071
+ addonAfter: 'px',
10072
+ max: 100
10073
+ }
10074
+ ]
10075
+ },
10076
+ {
10077
+ type: 'TextMargin',
10078
+ name: ['props', 'buttonStyle']
10079
+ },
10080
+ {
10081
+ type: 'Group',
10082
+ label: '字体',
10083
+ child: [
10084
+ {
10085
+ type: 'Color',
10086
+ name: ['props', 'buttonStyle', 'color'],
10087
+ initialValue: '#fff'
10088
+ },
10089
+ {
10090
+ type: 'Select',
10091
+ name: ['props', 'buttonStyle', 'fontFamily'],
10092
+ options: [{ label: '黑体', value: '黑体' }]
10093
+ },
10094
+ {
10095
+ type: 'Number',
10096
+ name: ['props', 'buttonStyle', 'fontSize'],
10097
+ addonAfter: 'px'
10098
+ }
10099
+ ]
10100
+ },
10101
+ {
10102
+ type: 'TextStyle',
10103
+ name: ['props', 'buttonStyle']
10104
+ },
10105
+ {
10106
+ type: 'TextAlign',
10107
+ name: ['props', 'buttonStyle']
10108
+ }
10109
+ ]
10110
+ }
10111
+ ];
10112
+
10113
+ /*
10114
+ * @Author: binruan@chatlabs.com
10115
+ * @Date: 2023-12-26 16:11:34
10116
+ * @LastEditors: binruan@chatlabs.com
10117
+ * @LastEditTime: 2024-04-08 11:53:47
10118
+ * @FilePath: \pb-sxp-ui\src\core\components\SxpPageRender\Navbar.tsx
10119
+ *
10120
+ */
10121
+ const Navbar = ({ icon, styles, textStyle, onClose }) => {
10122
+ var _a;
10123
+ const { waterFallData, setOpenHashtag } = useSxpDataSource();
10124
+ return (React.createElement("div", { className: 'clc-sxp-nav', style: styles },
10125
+ React.createElement("img", { className: 'clc-sxp-nav-left', src: icon, alt: '', onClick: onClose }),
10126
+ React.createElement("div", { className: 'clc-sxp-nav-title', style: textStyle }, `#${(_a = waterFallData === null || waterFallData === void 0 ? void 0 : waterFallData.hashTag) !== null && _a !== void 0 ? _a : '标题'}`)));
10007
10127
  };
10008
- var LikeButton$1 = React.memo(LikeButton);
10128
+ var Navbar$1 = React.memo(Navbar);
10009
10129
 
10010
- const SXP_EVENT_BUS = new EventEmitter();
10011
- var SXP_EVENT_TYPE;
10012
- (function (SXP_EVENT_TYPE) {
10013
- SXP_EVENT_TYPE["PAGE_DID_SHOW"] = "pageDidShow";
10014
- SXP_EVENT_TYPE["PAGE_DID_HIDE"] = "pageDidHide";
10015
- })(SXP_EVENT_TYPE || (SXP_EVENT_TYPE = {}));
10130
+ var productUserId = null;
10131
+ var requestId = "3d989325-e7d6-4a74-8a97-98febdf5b567";
10132
+ var channel = null;
10133
+ var rtc = null;
10134
+ var tag = {
10135
+ info: "The dior toujours bag is distinguished by a casual and practical design. Fully embroidered with black textured tweed, it is accented by a blend of threads displaying the cannage motif.",
10136
+ link: "www.baidu.com",
10137
+ linkTitle: null,
10138
+ linkType: "WEB"
10139
+ };
10140
+ var recList = [
10141
+ {
10142
+ position: "0",
10143
+ isCollected: null,
10144
+ video: {
10145
+ itemId: "VIDEOY2BMu1710323630175",
10146
+ title: "A symbol of excellence, the Dior Toujours bag is reinterpreted in an unprecedented version. For the Dior spring-summer 2024 ready-to-wear collection, this exceptional accessory, dreamed up by Maria Grazia Chiuri, is dressed in irresistible crinkled leather featuring the iconic macrocannage motif. A new emblem of the virtuoso, perpetually reinvented savoir-faire of the Dior Ateliers.",
10147
+ tags: [
10148
+ "Dior Toujours Bag",
10149
+ "Casual",
10150
+ "Leather Strap",
10151
+ "Handbags"
10152
+ ],
10153
+ weight: null,
10154
+ traceInfo: "VECTOReVssi1704360966770:VIDEO:VIDEOY2BMu1710323630175:default:3::branch:Handbags:0",
10155
+ bindCta: null,
10156
+ bindProduct: {
10157
+ itemId: "M2821SNIOM900",
10158
+ title: "Medium Dior Toujours Bag Black Macrocannage Crinkled Leather",
10159
+ tags: [
10160
+ "Medium",
10161
+ "Black",
10162
+ "Women",
10163
+ "Handbags",
10164
+ "Bucket Bag"
10165
+ ],
10166
+ weight: null,
10167
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:M2821SNIOM900:default:3::branch:Handbags:0",
10168
+ bindCta: {
10169
+ itemId: "CTAzgoPn1709005149328",
10170
+ title: "立即购买",
10171
+ tags: [
10172
+ ],
10173
+ weight: null,
10174
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:0",
10175
+ enTitle: "Shop now",
10176
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
10177
+ link: null,
10178
+ linkTitle: null,
10179
+ linkType: null,
10180
+ menuCategoryId: "65966478d19caa37afe3603f"
10181
+ },
10182
+ homePage: [
10183
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsy6AN0OWw3rj8Luw3RTSP9n2kDLq1710497237677.jpg",
10184
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fszTc3uEUrtppdN9QVVU2XBnaaaBY1710497237986.jpg",
10185
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsKbBMTRa0tTTX661wu7DzLw9OP0r1710497237980.jpg",
10186
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsOYHlYCwgzalxzmIJcsZmIsJ2L3g1710497237145.jpg",
10187
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsKJqNVm1ZBlrgZ8XLC0YAaO6ws2F1710497237650.jpg",
10188
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsm2VoVancBQ20nDHceESUPNLyrUy1710497238312.jpg",
10189
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fs2B5YYmv8OztP3d9rlM2a9KmYswl1710497237339.jpg"
10190
+ ],
10191
+ collection: "Eté 2024",
10192
+ link: "https://www.dior.com/en_us/fashion/products/M1296ZRIW_M828-medium-dior-book-tote-ecru-and-blue-dior-oblique-embroidery-36-x-27.5-x-16.5-cm",
10193
+ linkTitle: null,
10194
+ linkType: "WEB",
10195
+ info: "The dior toujours bag is distinguished by a casual and practical design. Crafted in black crinkled calfskin with macrocannage topstitching, it showcases a spacious interior compartment with a matching pouch to organize the essentials. Its leather strap closure keeps items secure while the d of the cd lock closure twists to adjust the sides and enhance the bag's silhouette.",
10196
+ price: 4400,
10197
+ currency: "USD-$"
10198
+ },
10199
+ bindProducts: [
10200
+ ],
10201
+ cover: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fswbY3wT0hCmrYkrqDzFKnHb3NMux1710323481052.png",
10202
+ url: "https://dior-sxp-cdn.chatlabs.net/prod/sound/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fs3Ifqv7fk2Tn9nPtwOTO2YjxAuRO1710323470472.mp4",
10203
+ imgUrls: null,
10204
+ hashTags: [
10205
+ "Dior Toujours Bag",
10206
+ "Casual",
10207
+ "Leather Strap",
10208
+ "Handbags"
10209
+ ]
10210
+ },
10211
+ product: null,
10212
+ cta: null
10213
+ },
10214
+ {
10215
+ position: "1",
10216
+ isCollected: null,
10217
+ video: {
10218
+ itemId: "VIDEO6JCOb1710323364018",
10219
+ title: "Maria grazia chiuri's hallmark dior book tote offers an original take on elegance. Unveiled at the cruise 2024 fashion show, the refined style showcases the iconic blue dior oblique embroidery and calfskin. Designed to keep all the daily essentials organized, the interior is equipped with a zipped pocket and patch pockets.",
10220
+ tags: [
10221
+ "Handbags",
10222
+ "Manufacturing Craftsmanship",
10223
+ "Dior Book Tote"
10224
+ ],
10225
+ weight: null,
10226
+ traceInfo: "VECTOReVssi1704360966770:VIDEO:VIDEO6JCOb1710323364018:default:3::branch:Handbags:1",
10227
+ bindCta: null,
10228
+ bindProduct: {
10229
+ itemId: "M1296ZRIWM828",
10230
+ title: "Medium Dior Book Tote",
10231
+ tags: [
10232
+ "Maria Grazia Chiuri",
10233
+ "Hand",
10234
+ "Shoulder",
10235
+ "Handbags",
10236
+ "Blue",
10237
+ "Women"
10238
+ ],
10239
+ weight: null,
10240
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:M1296ZRIWM828:default:3::branch:Handbags:1",
10241
+ bindCta: {
10242
+ itemId: "CTAzgoPn1709005149328",
10243
+ title: "立即购买",
10244
+ tags: [
10245
+ ],
10246
+ weight: null,
10247
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:1",
10248
+ enTitle: "Shop now",
10249
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
10250
+ link: null,
10251
+ linkTitle: null,
10252
+ linkType: null,
10253
+ menuCategoryId: "65966478d19caa37afe3603f"
10254
+ },
10255
+ homePage: [
10256
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240306/fs69g46K9wPCwi5VRAP2QAgRHM0Pc1709696901624.jpg",
10257
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240306/fsAIliGV0ZJP8MNa8DECYtwsK4ker1709696900761.jpg",
10258
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240306/fsMJ4JfZ0Vhzq6H71NdIPg6YozbIz1709696897845.jpg",
10259
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240306/fsWXI06zGOmACXn9wD3EegRLkB7dg1709696911033.jpg"
10260
+ ],
10261
+ collection: "Eté 2024",
10262
+ link: "https://www.dior.com/en_us/fashion/products/M1296ZRIW_M828-medium-dior-book-tote-ecru-and-blue-dior-oblique-embroidery-36-x-27.5-x-16.5-cm",
10263
+ linkTitle: null,
10264
+ linkType: "WEB",
10265
+ info: "Introduced by Maria Grazia Chiuri, Creative Director of Christian Dior, the Dior Book Tote has become a staple of the Dior aesthetic. Designed to hold all the daily essentials, the style is fully embroidered with the ecru and blue Dior Oblique motif. Adorned with the Christian Dior Paris signature on the front, the medium tote exemplifies the House's signature savoir-faire and may be carried by hand or worn over the shoulder.",
10266
+ price: 3350,
10267
+ currency: "USD-$"
10268
+ },
10269
+ bindProducts: [
10270
+ ],
10271
+ cover: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fsAHlkdbqYj5F84o2faRzU1E3AvG11710323339209.png",
10272
+ url: "https://dior-sxp-cdn.chatlabs.net/prod/sound/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fs7KIGk2IB0MsoDL1ANWB1Mb2hqu41710323314146.mp4",
10273
+ imgUrls: null,
10274
+ hashTags: [
10275
+ "Handbags",
10276
+ "Dior Book Tote"
10277
+ ]
10278
+ },
10279
+ product: null,
10280
+ cta: null
10281
+ },
10282
+ {
10283
+ position: "2",
10284
+ isCollected: null,
10285
+ video: null,
10286
+ product: {
10287
+ itemId: "M2820OTKVM911",
10288
+ title: "Large Dior Toujours Bag Black Cannage Tweed",
10289
+ tags: [
10290
+ "Black",
10291
+ "Women",
10292
+ "Handbags",
10293
+ "Bucket Bag",
10294
+ "Dior Toujours Bag"
10295
+ ],
10296
+ weight: null,
10297
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:M2820OTKVM911:default:3::branch:Handbags:2",
10298
+ bindCta: {
10299
+ itemId: "CTAzgoPn1709005149328",
10300
+ title: "立即购买",
10301
+ tags: [
10302
+ ],
10303
+ weight: null,
10304
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:2",
10305
+ enTitle: "Shop now",
10306
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
10307
+ link: null,
10308
+ linkTitle: null,
10309
+ linkType: null,
10310
+ menuCategoryId: "65966478d19caa37afe3603f"
10311
+ },
10312
+ homePage: [
10313
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240312/fsJTjyFchOFEJSTRYxXvL2XPU1dP61710238469418.jpg",
10314
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240319/fstdFA1dFT55QjtQPU2qHNENo5peF1710836061716.jpg",
10315
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240319/fs9xf8AlIApbHezVL3BsxjUGIrN231710836061181.jpg",
10316
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240312/fs9iZ20MjLAPkXmFKvD8HzhLaBJ671710238470272.jpg",
10317
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240312/fsSSodev3wicDfE1DYNWPQVeRjErt1710238464035.jpg",
10318
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240312/fs3YAOuN6Pd9NFvH1Rdooj6eLI18S1710238465296.jpg",
10319
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240312/fsBwIEp6OzI49isvHgiKD0cPSFtrD1710238459007.jpg"
10320
+ ],
10321
+ collection: "Eté 2024",
10322
+ link: "https://www.dior.com/en_us/fashion/products/M2820OTKV_M911-large-dior-toujours-bag",
10323
+ linkTitle: null,
10324
+ linkType: "WEB",
10325
+ info: "The dior toujours bag is distinguished by a casual and practical design. Fully embroidered with black textured tweed, it is accented by a blend of threads displaying the cannage motif. It showcases a spacious interior compartment with a matching pouch to organize the essentials, while a leather strap closure keeps items secure and the d of the cd lock closure twists to adjust the sides and enhance the bag's silhouette.",
10326
+ price: 4200,
10327
+ currency: "USD-$"
10328
+ },
10329
+ cta: null
10330
+ },
10331
+ {
10332
+ position: "3",
10333
+ isCollected: null,
10334
+ video: {
10335
+ itemId: "VIDEOOL1qU1709616182569",
10336
+ title: "Maria grazia chiuri brings a fresh update to the iconic saddle bag. Crafted in black grained calfskin, the legendary design features a saddle flap with a d stirrup clasp on a magnetic strap, as well as an antique gold-finish metal cd signature on either side of the strap. Equipped with a thin, adjustable and removable shoulder strap, the saddle bag may be carried by hand, worn over the shoulder or crossbody.. Saddle bag with strap Black grained calfskin",
10337
+ tags: [
10338
+ "Maria Grazia Chiuri",
10339
+ "Saddle Bags",
10340
+ "Removable Shoulder Strap",
10341
+ "Shoulder",
10342
+ "Crossbody",
10343
+ "Cross-body & Shoulder Bags",
10344
+ "Handbags"
10345
+ ],
10346
+ weight: null,
10347
+ traceInfo: "VECTOReVssi1704360966770:VIDEO:VIDEOOL1qU1709616182569:default:3::branch:Handbags:3",
10348
+ bindCta: null,
10349
+ bindProduct: {
10350
+ itemId: "M0455CBAAM900",
10351
+ title: "Saddle Bag with Strap",
10352
+ tags: [
10353
+ "Saddle Bags",
10354
+ "Handbags",
10355
+ "Maria Grazia Chiuri"
10356
+ ],
10357
+ weight: null,
10358
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:M0455CBAAM900:default:3::branch:Handbags:3",
10359
+ bindCta: {
10360
+ itemId: "CTAzgoPn1709005149328",
10361
+ title: "立即购买",
10362
+ tags: [
10363
+ ],
10364
+ weight: null,
10365
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:3",
10366
+ enTitle: "Shop now",
10367
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
10368
+ link: null,
10369
+ linkTitle: null,
10370
+ linkType: null,
10371
+ menuCategoryId: "65966478d19caa37afe3603f"
10372
+ },
10373
+ homePage: [
10374
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240301/fsiwfgnCrVBGcGPh6gaFsvbYBIpxX1709285334896.png",
10375
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240301/fsXpilTgUS4u4oFWr0hUew8DQITi11709285353202.png",
10376
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240301/fsWxJm6YIeRYmDtDoB5WtYMjRX8bm1709285366208.png",
10377
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240301/fsj69PxKh1SAZ6p0902FbBT0vg2at1709285373714.png",
10378
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240301/fs78nKueByU2cNulReOw8gJ1ZsieF1709285412981.png",
10379
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240301/fsmAEriTIohZAUMUE6gUCWvXwbbRE1709285429332.png"
10380
+ ],
10381
+ collection: "Eté 2024",
10382
+ link: "https://www.dior.com/en_us/fashion/products/M0455CBAA_M900-saddle-bag-with-strap-black-grained-calfskin?objectID=M0455CBAA_M900&query=M0455CBAAM900&queryID=c171c63e69d6d109953e2de631718496",
10383
+ linkTitle: null,
10384
+ linkType: "WEB",
10385
+ info: "Maria Grazia Chiuri brings a fresh update to the iconic Saddle bag. Crafted in black grained calfskin, the legendary design features a Saddle flap with a D stirrup clasp on a magnetic strap, as well as an antique gold-finish metal CD signature on either side of the strap. Equipped with a thin, adjustable and removable shoulder strap, the Saddle bag may be carried by hand, worn over the shoulder or crossbody.",
10386
+ price: 4400,
10387
+ currency: "USD-$"
10388
+ },
10389
+ bindProducts: [
10390
+ ],
10391
+ cover: null,
10392
+ url: null,
10393
+ imgUrls: [
10394
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240314/fsvbBN3IRfwctVIhdqgq3doWmhbb21710399187965.jpg"
10395
+ ],
10396
+ hashTags: [
10397
+ "Maria Grazia Chiuri",
10398
+ "Saddle Bags",
10399
+ "Handbags"
10400
+ ]
10401
+ },
10402
+ product: null,
10403
+ cta: null
10404
+ },
10405
+ {
10406
+ position: "4",
10407
+ isCollected: null,
10408
+ video: null,
10409
+ product: {
10410
+ itemId: "S5909CTZQM928",
10411
+ title: "Saddle Shoulder Pouch Blue Dior Oblique Jacquard ",
10412
+ tags: [
10413
+ "Saddle Bags",
10414
+ "Handbags",
10415
+ "Small-Leather-Goods",
10416
+ "Small",
10417
+ "Mini Bags"
10418
+ ],
10419
+ weight: null,
10420
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:S5909CTZQM928:default:3::branch:Handbags:4",
10421
+ bindCta: {
10422
+ itemId: "CTAzgoPn1709005149328",
10423
+ title: "立即购买",
10424
+ tags: [
10425
+ ],
10426
+ weight: null,
10427
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:4",
10428
+ enTitle: "Shop now",
10429
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
10430
+ link: null,
10431
+ linkTitle: null,
10432
+ linkType: null,
10433
+ menuCategoryId: "65966478d19caa37afe3603f"
10434
+ },
10435
+ homePage: [
10436
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fs34CpwKJOyjEDgoHypoLYakF8oR31710316280669.png",
10437
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fsLOSOEf9pmz7wKnFaifWNw3TZ7Gy1710316287874.png",
10438
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fsWHmVcrzHKKj6EfhfnQkxYIOt20a1710316295683.png",
10439
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fslyBNMyQwjpjY4EKzyrqzTMlOGRQ1710316313161.png"
10440
+ ],
10441
+ collection: "Eté 2024",
10442
+ link: "https://www.dior.com/en_us/fashion/products/S5909CTZQ",
10443
+ linkTitle: null,
10444
+ linkType: "WEB",
10445
+ info: null,
10446
+ price: 4900,
10447
+ currency: "USD-$"
10448
+ },
10449
+ cta: null
10450
+ },
10451
+ {
10452
+ position: "5",
10453
+ isCollected: null,
10454
+ video: {
10455
+ itemId: "VIDEOrZguC1710324513737",
10456
+ title: "Introduced by Maria Grazia Chiuri, Creative Director of Christian Dior, the Dior Book Tote has become a staple of the Dior aesthetic. Designed to hold all the daily essentials, the style is fully embroidered with the ecru and blue Dior Oblique motif. Adorned with the Christian Dior Paris signature on the front, the medium tote exemplifies the House's signature savoir-faire and may be carried by hand or worn over the shoulder.",
10457
+ tags: [
10458
+ "Handbags",
10459
+ "Dior Book Tote"
10460
+ ],
10461
+ weight: null,
10462
+ traceInfo: "VECTOReVssi1704360966770:VIDEO:VIDEOrZguC1710324513737:default:3::branch:Handbags:5",
10463
+ bindCta: null,
10464
+ bindProduct: {
10465
+ itemId: "M1296ZRIWM828",
10466
+ title: "Medium Dior Book Tote",
10467
+ tags: [
10468
+ "Maria Grazia Chiuri",
10469
+ "Hand",
10470
+ "Shoulder",
10471
+ "Handbags",
10472
+ "Blue",
10473
+ "Women"
10474
+ ],
10475
+ weight: null,
10476
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:M1296ZRIWM828:default:3::branch:Handbags:5",
10477
+ bindCta: {
10478
+ itemId: "CTAzgoPn1709005149328",
10479
+ title: "立即购买",
10480
+ tags: [
10481
+ ],
10482
+ weight: null,
10483
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:5",
10484
+ enTitle: "Shop now",
10485
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
10486
+ link: null,
10487
+ linkTitle: null,
10488
+ linkType: null,
10489
+ menuCategoryId: "65966478d19caa37afe3603f"
10490
+ },
10491
+ homePage: [
10492
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240306/fs69g46K9wPCwi5VRAP2QAgRHM0Pc1709696901624.jpg",
10493
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240306/fsAIliGV0ZJP8MNa8DECYtwsK4ker1709696900761.jpg",
10494
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240306/fsMJ4JfZ0Vhzq6H71NdIPg6YozbIz1709696897845.jpg",
10495
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240306/fsWXI06zGOmACXn9wD3EegRLkB7dg1709696911033.jpg"
10496
+ ],
10497
+ collection: "Eté 2024",
10498
+ link: "https://www.dior.com/en_us/fashion/products/M1296ZRIW_M828-medium-dior-book-tote-ecru-and-blue-dior-oblique-embroidery-36-x-27.5-x-16.5-cm",
10499
+ linkTitle: null,
10500
+ linkType: "WEB",
10501
+ info: "Introduced by Maria Grazia Chiuri, Creative Director of Christian Dior, the Dior Book Tote has become a staple of the Dior aesthetic. Designed to hold all the daily essentials, the style is fully embroidered with the ecru and blue Dior Oblique motif. Adorned with the Christian Dior Paris signature on the front, the medium tote exemplifies the House's signature savoir-faire and may be carried by hand or worn over the shoulder.",
10502
+ price: 3350,
10503
+ currency: "USD-$"
10504
+ },
10505
+ bindProducts: [
10506
+ ],
10507
+ cover: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fstXNWStczbY8HbIKEqMwfCkv5CI51710324494939.png",
10508
+ url: "https://dior-sxp-cdn.chatlabs.net/prod/sound/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fsOqu34FxaJTdascLcj6DHoYIIAs01710324439851.mp4",
10509
+ imgUrls: null,
10510
+ hashTags: [
10511
+ "Handbags",
10512
+ "Dior Book Tote"
10513
+ ]
10514
+ },
10515
+ product: null,
10516
+ cta: null
10517
+ },
10518
+ {
10519
+ position: "6",
10520
+ isCollected: null,
10521
+ video: null,
10522
+ product: {
10523
+ itemId: "M1296ZRIWM828",
10524
+ title: "Medium Dior Book Tote",
10525
+ tags: [
10526
+ "Maria Grazia Chiuri",
10527
+ "Hand",
10528
+ "Shoulder",
10529
+ "Handbags",
10530
+ "Blue",
10531
+ "Women"
10532
+ ],
10533
+ weight: null,
10534
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:M1296ZRIWM828:default:3::branch:Handbags:6",
10535
+ bindCta: {
10536
+ itemId: "CTAzgoPn1709005149328",
10537
+ title: "立即购买",
10538
+ tags: [
10539
+ ],
10540
+ weight: null,
10541
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:6",
10542
+ enTitle: "Shop now",
10543
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
10544
+ link: null,
10545
+ linkTitle: null,
10546
+ linkType: null,
10547
+ menuCategoryId: "65966478d19caa37afe3603f"
10548
+ },
10549
+ homePage: [
10550
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240306/fs69g46K9wPCwi5VRAP2QAgRHM0Pc1709696901624.jpg",
10551
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240306/fsAIliGV0ZJP8MNa8DECYtwsK4ker1709696900761.jpg",
10552
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240306/fsMJ4JfZ0Vhzq6H71NdIPg6YozbIz1709696897845.jpg",
10553
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240306/fsWXI06zGOmACXn9wD3EegRLkB7dg1709696911033.jpg"
10554
+ ],
10555
+ collection: "Eté 2024",
10556
+ link: "https://www.dior.com/en_us/fashion/products/M1296ZRIW_M828-medium-dior-book-tote-ecru-and-blue-dior-oblique-embroidery-36-x-27.5-x-16.5-cm",
10557
+ linkTitle: null,
10558
+ linkType: "WEB",
10559
+ info: "Introduced by Maria Grazia Chiuri, Creative Director of Christian Dior, the Dior Book Tote has become a staple of the Dior aesthetic. Designed to hold all the daily essentials, the style is fully embroidered with the ecru and blue Dior Oblique motif. Adorned with the Christian Dior Paris signature on the front, the medium tote exemplifies the House's signature savoir-faire and may be carried by hand or worn over the shoulder.",
10560
+ price: 3350,
10561
+ currency: "USD-$"
10562
+ },
10563
+ cta: null
10564
+ },
10565
+ {
10566
+ position: "7",
10567
+ isCollected: null,
10568
+ video: {
10569
+ itemId: "VIDEOEtr621710300614047",
10570
+ title: "Unveiled at the spring-summer 2023 fashion show, the dior toujours bag is distinguished by a casual and practical design. Crafted in black calfskin with macrocannage topstitching, it showcases a spacious interior compartment with a matching pouch to organize essentials. Its leather strap closure keeps items secure while the d of the cd lock closure twists to adjust the sides and enhance the bag's silhouette. T",
10571
+ tags: [
10572
+ "Handbags",
10573
+ "Leather Strap",
10574
+ "Spring-Summer 2024 Fashion Show",
10575
+ "Backstage",
10576
+ "Dior Toujours Bag"
10577
+ ],
10578
+ weight: null,
10579
+ traceInfo: "VECTOReVssi1704360966770:VIDEO:VIDEOEtr621710300614047:default:3::branch:Handbags:7",
10580
+ bindCta: null,
10581
+ bindProduct: null,
10582
+ bindProducts: [
10583
+ ],
10584
+ cover: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fshkOldZwfsSqTgvxHJzNBwS66ySc1710300910103.jpg",
10585
+ url: null,
10586
+ imgUrls: [
10587
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240314/fsryDXTtPWXjYFWoSUEBUi48RHZCh1710398617300.jpg"
10588
+ ],
10589
+ hashTags: [
10590
+ "Backstage",
10591
+ "Handbags",
10592
+ "Spring-Summer 2024 Fashion Show",
10593
+ "Dior Toujours Bag"
10594
+ ]
10595
+ },
10596
+ product: null,
10597
+ cta: null
10598
+ },
10599
+ {
10600
+ position: "8",
10601
+ isCollected: null,
10602
+ video: {
10603
+ itemId: "VIDEOO8Zjt1709616802987",
10604
+ title: "Introduced by Maria Grazia Chiuri, Creative Director of Christian Dior, the Dior Book Tote has become a staple of the Dior aesthetic. Designed to hold all the daily essentials, the style is fully embroidered with the ecru and blue Dior Oblique motif. Adorned with the Christian Dior Paris signature on the front, the medium tote exemplifies the House's signature savoir-faire and may be carried by hand or worn over the shoulder.",
10605
+ tags: [
10606
+ "Blue",
10607
+ "Medium",
10608
+ "Shoulder",
10609
+ "Hand",
10610
+ "Handbags",
10611
+ "Dior Book Tote"
10612
+ ],
10613
+ weight: null,
10614
+ traceInfo: "VECTOReVssi1704360966770:VIDEO:VIDEOO8Zjt1709616802987:default:3::branch:Handbags:8",
10615
+ bindCta: null,
10616
+ bindProduct: {
10617
+ itemId: "M1296ZRIWM828",
10618
+ title: "Medium Dior Book Tote",
10619
+ tags: [
10620
+ "Maria Grazia Chiuri",
10621
+ "Hand",
10622
+ "Shoulder",
10623
+ "Handbags",
10624
+ "Blue",
10625
+ "Women"
10626
+ ],
10627
+ weight: null,
10628
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:M1296ZRIWM828:default:3::branch:Handbags:8",
10629
+ bindCta: {
10630
+ itemId: "CTAzgoPn1709005149328",
10631
+ title: "立即购买",
10632
+ tags: [
10633
+ ],
10634
+ weight: null,
10635
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:8",
10636
+ enTitle: "Shop now",
10637
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
10638
+ link: null,
10639
+ linkTitle: null,
10640
+ linkType: null,
10641
+ menuCategoryId: "65966478d19caa37afe3603f"
10642
+ },
10643
+ homePage: [
10644
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240306/fs69g46K9wPCwi5VRAP2QAgRHM0Pc1709696901624.jpg",
10645
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240306/fsAIliGV0ZJP8MNa8DECYtwsK4ker1709696900761.jpg",
10646
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240306/fsMJ4JfZ0Vhzq6H71NdIPg6YozbIz1709696897845.jpg",
10647
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240306/fsWXI06zGOmACXn9wD3EegRLkB7dg1709696911033.jpg"
10648
+ ],
10649
+ collection: "Eté 2024",
10650
+ link: "https://www.dior.com/en_us/fashion/products/M1296ZRIW_M828-medium-dior-book-tote-ecru-and-blue-dior-oblique-embroidery-36-x-27.5-x-16.5-cm",
10651
+ linkTitle: null,
10652
+ linkType: "WEB",
10653
+ info: "Introduced by Maria Grazia Chiuri, Creative Director of Christian Dior, the Dior Book Tote has become a staple of the Dior aesthetic. Designed to hold all the daily essentials, the style is fully embroidered with the ecru and blue Dior Oblique motif. Adorned with the Christian Dior Paris signature on the front, the medium tote exemplifies the House's signature savoir-faire and may be carried by hand or worn over the shoulder.",
10654
+ price: 3350,
10655
+ currency: "USD-$"
10656
+ },
10657
+ bindProducts: [
10658
+ ],
10659
+ cover: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240305/fsmS72zfInwmblYTnuYzRuZKAOlhr1709616742898.jpg",
10660
+ url: null,
10661
+ imgUrls: [
10662
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240314/fsU2gDw28XFd1nOAqlUjb1r1h6mpT1710400349981.jpg"
10663
+ ],
10664
+ hashTags: [
10665
+ "Dior Book Tote",
10666
+ "Handbags"
10667
+ ]
10668
+ },
10669
+ product: null,
10670
+ cta: null
10671
+ },
10672
+ {
10673
+ position: "9",
10674
+ isCollected: null,
10675
+ video: null,
10676
+ product: {
10677
+ itemId: "M2821SNIOM900",
10678
+ title: "Medium Dior Toujours Bag Black Macrocannage Crinkled Leather",
10679
+ tags: [
10680
+ "Medium",
10681
+ "Black",
10682
+ "Women",
10683
+ "Handbags",
10684
+ "Bucket Bag"
10685
+ ],
10686
+ weight: null,
10687
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:M2821SNIOM900:default:3::branch:Handbags:9",
10688
+ bindCta: {
10689
+ itemId: "CTAzgoPn1709005149328",
10690
+ title: "立即购买",
10691
+ tags: [
10692
+ ],
10693
+ weight: null,
10694
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:9",
10695
+ enTitle: "Shop now",
10696
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
10697
+ link: null,
10698
+ linkTitle: null,
10699
+ linkType: null,
10700
+ menuCategoryId: "65966478d19caa37afe3603f"
10701
+ },
10702
+ homePage: [
10703
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsy6AN0OWw3rj8Luw3RTSP9n2kDLq1710497237677.jpg",
10704
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fszTc3uEUrtppdN9QVVU2XBnaaaBY1710497237986.jpg",
10705
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsKbBMTRa0tTTX661wu7DzLw9OP0r1710497237980.jpg",
10706
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsOYHlYCwgzalxzmIJcsZmIsJ2L3g1710497237145.jpg",
10707
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsKJqNVm1ZBlrgZ8XLC0YAaO6ws2F1710497237650.jpg",
10708
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsm2VoVancBQ20nDHceESUPNLyrUy1710497238312.jpg",
10709
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fs2B5YYmv8OztP3d9rlM2a9KmYswl1710497237339.jpg"
10710
+ ],
10711
+ collection: "Eté 2024",
10712
+ link: "https://www.dior.com/en_us/fashion/products/M1296ZRIW_M828-medium-dior-book-tote-ecru-and-blue-dior-oblique-embroidery-36-x-27.5-x-16.5-cm",
10713
+ linkTitle: null,
10714
+ linkType: "WEB",
10715
+ info: "The dior toujours bag is distinguished by a casual and practical design. Crafted in black crinkled calfskin with macrocannage topstitching, it showcases a spacious interior compartment with a matching pouch to organize the essentials. Its leather strap closure keeps items secure while the d of the cd lock closure twists to adjust the sides and enhance the bag's silhouette.",
10716
+ price: 4400,
10717
+ currency: "USD-$"
10718
+ },
10719
+ cta: null
10720
+ },
10721
+ {
10722
+ position: "10",
10723
+ isCollected: null,
10724
+ video: {
10725
+ itemId: "VIDEOesZlV1710323980494",
10726
+ title: "The lady dior bag embodies dior's vision of elegance and beauty. Sleek and refined, the timeless style demonstrates the house's exceptional savoir-faire. The black patent-to-matte gradient lambskin style is embellished with iconic cannage topstitching, while the ultra-matte metal d.i.o.r. Charms lend a modern touch. Featuring a thin, removable leather shoulder strap, the medium lady dior bag can be carried by hand or worn crossbody.",
10727
+ tags: [
10728
+ "Lady Dior",
10729
+ "Removable Shoulder Strap",
10730
+ "Medium",
10731
+ "Handbags",
10732
+ "Crossbody"
10733
+ ],
10734
+ weight: null,
10735
+ traceInfo: "VECTOReVssi1704360966770:VIDEO:VIDEOesZlV1710323980494:default:3::branch:Handbags:10",
10736
+ bindCta: null,
10737
+ bindProduct: {
10738
+ itemId: "M0565SDBRM900",
10739
+ title: "Medium Lady Dior Bag",
10740
+ tags: [
10741
+ "Women",
10742
+ "Black",
10743
+ "Handbags",
10744
+ "Hand",
10745
+ "Lady Dior",
10746
+ "Crossbody"
10747
+ ],
10748
+ weight: null,
10749
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:M0565SDBRM900:default:3::branch:Handbags:10",
10750
+ bindCta: {
10751
+ itemId: "CTAzgoPn1709005149328",
10752
+ title: "立即购买",
10753
+ tags: [
10754
+ ],
10755
+ weight: null,
10756
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:10",
10757
+ enTitle: "Shop now",
10758
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
10759
+ link: null,
10760
+ linkTitle: null,
10761
+ linkType: null,
10762
+ menuCategoryId: "65966478d19caa37afe3603f"
10763
+ },
10764
+ homePage: [
10765
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsnyiCm9oirbXLqmqY7231O8O2Yhb1710498970982.jpg",
10766
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fskwIRRKCtuw9cb9btuubt2D5bXfB1710498970676.jpg",
10767
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsqXFTCyhxspeYCD3uo4UiuN5vQ7w1710498970671.jpg",
10768
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fs8rDRSKJmWUNI42MjrMWVlI0D9Fz1710498970729.jpg",
10769
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsca9Cjqo3WMJVU0OL0OjQo8xOoMx1710498972076.jpg",
10770
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsjl1bxi56X0QrKwfvl8YocBVJ2N81710498971352.jpg"
10771
+ ],
10772
+ collection: null,
10773
+ link: "https://www.dior.com/en_us/fashion/products/M0565SDBR_M900-medium-lady-dior-bag-black-patent-to-matte-gradient-cannage-lambskin?objectID=M0565SDBR_M900&query=M0565SDBRM900&queryID=14cc52b35774a9a42e78fd9ba199860e",
10774
+ linkTitle: null,
10775
+ linkType: "WEB",
10776
+ info: "The Lady Dior bag embodies Dior's vision of elegance and beauty. Sleek and refined, the timeless style demonstrates the House's exceptional savoir-faire. The black patent-to-matte gradient lambskin style is embellished with iconic Cannage topstitching, while the ultra-matte metal D.I.O.R. charms lend a modern touch. Featuring a thin, removable leather shoulder strap, the medium Lady Dior bag can be carried by hand or worn crossbody.",
10777
+ price: 7100,
10778
+ currency: "USD-$"
10779
+ },
10780
+ bindProducts: [
10781
+ ],
10782
+ cover: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fsiwMQ88zO5Xdnl939krMyBMbz7Js1710323763013.png",
10783
+ url: "https://dior-sxp-cdn.chatlabs.net/prod/sound/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fsxyS8nr7nn0LMe7EqOt3ETXqLu7d1710323753073.mp4",
10784
+ imgUrls: null,
10785
+ hashTags: [
10786
+ "Lady Dior",
10787
+ "Handbags"
10788
+ ]
10789
+ },
10790
+ product: null,
10791
+ cta: null
10792
+ },
10793
+ {
10794
+ position: "11",
10795
+ isCollected: null,
10796
+ video: {
10797
+ itemId: "VIDEOdvsXq1710324342942",
10798
+ title: "New for summer 2024, the lady d-sire my abcdior bag draws inspiration from the signature elegance of the lady dior design. Reimagined with a casual style for an urban look, the lightweight black grained bull leather feels soft to the touch yet offers excellent durability. The medium bag is embellished with pale gold-finish metal d.i.o.r. Charms that highlight the silhouette.",
10799
+ tags: [
10800
+ "Summer 2024",
10801
+ "Lady Dior",
10802
+ "Casual",
10803
+ "Lightweight",
10804
+ "Medium",
10805
+ "Handbags"
10806
+ ],
10807
+ weight: null,
10808
+ traceInfo: "VECTOReVssi1704360966770:VIDEO:VIDEOdvsXq1710324342942:default:3::branch:Handbags:11",
10809
+ bindCta: null,
10810
+ bindProduct: {
10811
+ itemId: "M1151OTRLM900",
10812
+ title: "Medium Lady D-Sire My ABCDior Bag",
10813
+ tags: [
10814
+ "Handbags",
10815
+ "Summer 2024",
10816
+ "Lady Dior",
10817
+ "Black",
10818
+ "Medium",
10819
+ "Women",
10820
+ "Lady D-Sire"
10821
+ ],
10822
+ weight: null,
10823
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:M1151OTRLM900:default:3::branch:Handbags:11",
10824
+ bindCta: {
10825
+ itemId: "CTAzgoPn1709005149328",
10826
+ title: "立即购买",
10827
+ tags: [
10828
+ ],
10829
+ weight: null,
10830
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:11",
10831
+ enTitle: "Shop now",
10832
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
10833
+ link: null,
10834
+ linkTitle: null,
10835
+ linkType: null,
10836
+ menuCategoryId: "65966478d19caa37afe3603f"
10837
+ },
10838
+ homePage: [
10839
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsBvqPYhaE9Ct1JzBd4gm8g9YOiAZ1710499102900.jpg",
10840
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fs6sf9nB7WpJuLNIZT3c8O8Fmf3Gu1710499102936.jpg",
10841
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsSxYBxyVx2yRrUgEaYmarWhlUbk41710499102531.jpg",
10842
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsyhykK1B7W9613MAfipfIuE1foim1710499102345.jpg",
10843
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fs6FXJdaXib8lP0NPloe1XQGpoiKc1710499103268.jpg",
10844
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsCRx7T4ejNvgKNensH6LT4dPt6251710499103615.jpg"
10845
+ ],
10846
+ collection: null,
10847
+ link: "https://www.dior.com/en_us/fashion/products/M1151OTRL_M900-medium-lady-d-sire-my-abcdior-bag-black-bull-leather?objectID=M1151OTRL_M900&query=M1151OTRLM900&queryID=e82938220687c425c75277a7c526b932",
10848
+ linkTitle: null,
10849
+ linkType: "WEB",
10850
+ info: "New for Summer 2024, the Lady D-Sire My ABCDior bag draws inspiration from the signature elegance of the Lady Dior design. Reimagined with a casual style for an urban look, the lightweight black grained bull leather feels soft to the touch yet offers excellent durability. The medium bag is embellished with pale gold-finish metal D.I.O.R. charms that highlight the silhouette. Showcasing a shoulder strap that can be personalized by adding symbolic badges, the unique bag can be carried by hand or w",
10851
+ price: 6100,
10852
+ currency: "USD-$"
10853
+ },
10854
+ bindProducts: [
10855
+ ],
10856
+ cover: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fsOsdUSXr57U5Twhhkv17th3yHqBJ1710324292456.png",
10857
+ url: "https://dior-sxp-cdn.chatlabs.net/prod/sound/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fsZyr3slVtlsParX6D0DqsM0QEx8d1710324283147.mp4",
10858
+ imgUrls: null,
10859
+ hashTags: [
10860
+ "Summer 2024",
10861
+ "Lady Dior",
10862
+ "Handbags"
10863
+ ]
10864
+ },
10865
+ product: null,
10866
+ cta: null
10867
+ },
10868
+ {
10869
+ position: "12",
10870
+ isCollected: null,
10871
+ video: {
10872
+ itemId: "VIDEOy76Fr1710324746846",
10873
+ title: "Maria grazia chiuri brings a fresh update to the iconic saddle bag. Crafted in black grained calfskin, the legendary design features a saddle flap with a d stirrup clasp on a magnetic strap, as well as an antique gold-finish metal cd signature on either side of the strap. Equipped with a thin, adjustable and removable shoulder strap, the saddle bag may be carried by hand, worn over the shoulder or crossbody.. Saddle bag with strap Black grained calfskin",
10874
+ tags: [
10875
+ "Maria Grazia Chiuri",
10876
+ "Saddle Bags",
10877
+ "Removable Shoulder Strap",
10878
+ "Hand",
10879
+ "Shoulder",
10880
+ "Crossbody",
10881
+ "Handbags"
10882
+ ],
10883
+ weight: null,
10884
+ traceInfo: "VECTOReVssi1704360966770:VIDEO:VIDEOy76Fr1710324746846:default:3::branch:Handbags:12",
10885
+ bindCta: null,
10886
+ bindProduct: {
10887
+ itemId: "M0455CBAAM900",
10888
+ title: "Saddle Bag with Strap",
10889
+ tags: [
10890
+ "Saddle Bags",
10891
+ "Handbags",
10892
+ "Maria Grazia Chiuri"
10893
+ ],
10894
+ weight: null,
10895
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:M0455CBAAM900:default:3::branch:Handbags:12",
10896
+ bindCta: {
10897
+ itemId: "CTAzgoPn1709005149328",
10898
+ title: "立即购买",
10899
+ tags: [
10900
+ ],
10901
+ weight: null,
10902
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:12",
10903
+ enTitle: "Shop now",
10904
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
10905
+ link: null,
10906
+ linkTitle: null,
10907
+ linkType: null,
10908
+ menuCategoryId: "65966478d19caa37afe3603f"
10909
+ },
10910
+ homePage: [
10911
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240301/fsiwfgnCrVBGcGPh6gaFsvbYBIpxX1709285334896.png",
10912
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240301/fsXpilTgUS4u4oFWr0hUew8DQITi11709285353202.png",
10913
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240301/fsWxJm6YIeRYmDtDoB5WtYMjRX8bm1709285366208.png",
10914
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240301/fsj69PxKh1SAZ6p0902FbBT0vg2at1709285373714.png",
10915
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240301/fs78nKueByU2cNulReOw8gJ1ZsieF1709285412981.png",
10916
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240301/fsmAEriTIohZAUMUE6gUCWvXwbbRE1709285429332.png"
10917
+ ],
10918
+ collection: "Eté 2024",
10919
+ link: "https://www.dior.com/en_us/fashion/products/M0455CBAA_M900-saddle-bag-with-strap-black-grained-calfskin?objectID=M0455CBAA_M900&query=M0455CBAAM900&queryID=c171c63e69d6d109953e2de631718496",
10920
+ linkTitle: null,
10921
+ linkType: "WEB",
10922
+ info: "Maria Grazia Chiuri brings a fresh update to the iconic Saddle bag. Crafted in black grained calfskin, the legendary design features a Saddle flap with a D stirrup clasp on a magnetic strap, as well as an antique gold-finish metal CD signature on either side of the strap. Equipped with a thin, adjustable and removable shoulder strap, the Saddle bag may be carried by hand, worn over the shoulder or crossbody.",
10923
+ price: 4400,
10924
+ currency: "USD-$"
10925
+ },
10926
+ bindProducts: [
10927
+ ],
10928
+ cover: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fsqwogfFahvNml7vmATxwfKLcNlh91710324602536.png",
10929
+ url: "https://dior-sxp-cdn.chatlabs.net/prod/sound/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fsVRd4z4V8UScNc7Wc96xv4xDVByb1710324589932.mp4",
10930
+ imgUrls: null,
10931
+ hashTags: [
10932
+ "Maria Grazia Chiuri",
10933
+ "Saddle Bags",
10934
+ "Handbags"
10935
+ ]
10936
+ },
10937
+ product: null,
10938
+ cta: null
10939
+ },
10940
+ {
10941
+ position: "13",
10942
+ isCollected: null,
10943
+ video: {
10944
+ itemId: "VIDEOvqhF71709609258469",
10945
+ title: "The lady dior bag embodies dior's vision of elegance and beauty. Sleek and refined, the timeless style demonstrates the house's exceptional savoir-faire. The black patent-to-matte gradient lambskin style is embellished with iconic cannage topstitching, while the ultra-matte metal d.i.o.r. Charms lend a modern touch. Featuring a thin, removable leather shoulder strap, the medium lady dior bag can be carried by hand or worn crossbody.",
10946
+ tags: [
10947
+ "Thin",
10948
+ "Removable Shoulder Strap",
10949
+ "Medium",
10950
+ "Lady Dior",
10951
+ "Crossbody",
10952
+ "Handbags",
10953
+ "Cross-body & Shoulder Bags"
10954
+ ],
10955
+ weight: null,
10956
+ traceInfo: "VECTOReVssi1704360966770:VIDEO:VIDEOvqhF71709609258469:default:3::branch:Handbags:13",
10957
+ bindCta: null,
10958
+ bindProduct: {
10959
+ itemId: "M0565SDBRM900",
10960
+ title: "Medium Lady Dior Bag",
10961
+ tags: [
10962
+ "Women",
10963
+ "Black",
10964
+ "Handbags",
10965
+ "Hand",
10966
+ "Lady Dior",
10967
+ "Crossbody"
10968
+ ],
10969
+ weight: null,
10970
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:M0565SDBRM900:default:3::branch:Handbags:13",
10971
+ bindCta: {
10972
+ itemId: "CTAzgoPn1709005149328",
10973
+ title: "立即购买",
10974
+ tags: [
10975
+ ],
10976
+ weight: null,
10977
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:13",
10978
+ enTitle: "Shop now",
10979
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
10980
+ link: null,
10981
+ linkTitle: null,
10982
+ linkType: null,
10983
+ menuCategoryId: "65966478d19caa37afe3603f"
10984
+ },
10985
+ homePage: [
10986
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsnyiCm9oirbXLqmqY7231O8O2Yhb1710498970982.jpg",
10987
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fskwIRRKCtuw9cb9btuubt2D5bXfB1710498970676.jpg",
10988
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsqXFTCyhxspeYCD3uo4UiuN5vQ7w1710498970671.jpg",
10989
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fs8rDRSKJmWUNI42MjrMWVlI0D9Fz1710498970729.jpg",
10990
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsca9Cjqo3WMJVU0OL0OjQo8xOoMx1710498972076.jpg",
10991
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsjl1bxi56X0QrKwfvl8YocBVJ2N81710498971352.jpg"
10992
+ ],
10993
+ collection: null,
10994
+ link: "https://www.dior.com/en_us/fashion/products/M0565SDBR_M900-medium-lady-dior-bag-black-patent-to-matte-gradient-cannage-lambskin?objectID=M0565SDBR_M900&query=M0565SDBRM900&queryID=14cc52b35774a9a42e78fd9ba199860e",
10995
+ linkTitle: null,
10996
+ linkType: "WEB",
10997
+ info: "The Lady Dior bag embodies Dior's vision of elegance and beauty. Sleek and refined, the timeless style demonstrates the House's exceptional savoir-faire. The black patent-to-matte gradient lambskin style is embellished with iconic Cannage topstitching, while the ultra-matte metal D.I.O.R. charms lend a modern touch. Featuring a thin, removable leather shoulder strap, the medium Lady Dior bag can be carried by hand or worn crossbody.",
10998
+ price: 7100,
10999
+ currency: "USD-$"
11000
+ },
11001
+ bindProducts: [
11002
+ ],
11003
+ cover: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240305/fsHmNyOcNdgB9Y8aIFYWCHlEZVl4x1709608981919.jpg",
11004
+ url: null,
11005
+ imgUrls: [
11006
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240314/fslhMX6mwCM4i5XFY6dpcMZdPocYv1710398865153.jpg",
11007
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240314/fsJQCe9rZmsEjuIUpdck9Hs2gpNU81710398856427.jpg",
11008
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240314/fsnHUJufSHptF88bNsyUGmSSKYH4A1710398855734.jpg"
11009
+ ],
11010
+ hashTags: [
11011
+ "Lady Dior",
11012
+ "Handbags"
11013
+ ]
11014
+ },
11015
+ product: null,
11016
+ cta: null
11017
+ },
11018
+ {
11019
+ position: "14",
11020
+ isCollected: null,
11021
+ video: null,
11022
+ product: {
11023
+ itemId: "M0455CBAAM900",
11024
+ title: "Saddle Bag with Strap",
11025
+ tags: [
11026
+ "Saddle Bags",
11027
+ "Handbags",
11028
+ "Maria Grazia Chiuri"
11029
+ ],
11030
+ weight: null,
11031
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:M0455CBAAM900:default:3::branch:Handbags:14",
11032
+ bindCta: {
11033
+ itemId: "CTAzgoPn1709005149328",
11034
+ title: "立即购买",
11035
+ tags: [
11036
+ ],
11037
+ weight: null,
11038
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:14",
11039
+ enTitle: "Shop now",
11040
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
11041
+ link: null,
11042
+ linkTitle: null,
11043
+ linkType: null,
11044
+ menuCategoryId: "65966478d19caa37afe3603f"
11045
+ },
11046
+ homePage: [
11047
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240301/fsiwfgnCrVBGcGPh6gaFsvbYBIpxX1709285334896.png",
11048
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240301/fsXpilTgUS4u4oFWr0hUew8DQITi11709285353202.png",
11049
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240301/fsWxJm6YIeRYmDtDoB5WtYMjRX8bm1709285366208.png",
11050
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240301/fsj69PxKh1SAZ6p0902FbBT0vg2at1709285373714.png",
11051
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240301/fs78nKueByU2cNulReOw8gJ1ZsieF1709285412981.png",
11052
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240301/fsmAEriTIohZAUMUE6gUCWvXwbbRE1709285429332.png"
11053
+ ],
11054
+ collection: "Eté 2024",
11055
+ link: "https://www.dior.com/en_us/fashion/products/M0455CBAA_M900-saddle-bag-with-strap-black-grained-calfskin?objectID=M0455CBAA_M900&query=M0455CBAAM900&queryID=c171c63e69d6d109953e2de631718496",
11056
+ linkTitle: null,
11057
+ linkType: "WEB",
11058
+ info: "Maria Grazia Chiuri brings a fresh update to the iconic Saddle bag. Crafted in black grained calfskin, the legendary design features a Saddle flap with a D stirrup clasp on a magnetic strap, as well as an antique gold-finish metal CD signature on either side of the strap. Equipped with a thin, adjustable and removable shoulder strap, the Saddle bag may be carried by hand, worn over the shoulder or crossbody.",
11059
+ price: 4400,
11060
+ currency: "USD-$"
11061
+ },
11062
+ cta: null
11063
+ },
11064
+ {
11065
+ position: "15",
11066
+ isCollected: null,
11067
+ video: {
11068
+ itemId: "VIDEO693hq1709628690318",
11069
+ title: "New for the summer 2024 season, the dior caro top handle camera bag is a sophisticated and practical design. Crafted in black calfskin, the small model is elevated by the originality of the macrocannage stitching's quilted effect. The bag features a zip closure and an antique gold-tone metal cd signature.",
11070
+ tags: [
11071
+ "Ready-To-Wear",
11072
+ "Handbags",
11073
+ "Signature Hardware Design",
11074
+ "Monogram/Logo Print",
11075
+ "Calfskin Leather",
11076
+ "Summer 2024",
11077
+ "Black"
11078
+ ],
11079
+ weight: null,
11080
+ traceInfo: "VECTOReVssi1704360966770:VIDEO:VIDEO693hq1709628690318:default:3::branch:Handbags:15",
11081
+ bindCta: null,
11082
+ bindProduct: {
11083
+ itemId: "M3352UBHMM900",
11084
+ title: "Small Dior Caro Top Handle Camera Bag Black Macrocannage Calfskin ",
11085
+ tags: [
11086
+ "Summer 2024",
11087
+ "Black",
11088
+ "Women",
11089
+ "Handbags",
11090
+ "Dior Caro"
11091
+ ],
11092
+ weight: null,
11093
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:M3352UBHMM900:default:3::branch:Handbags:15",
11094
+ bindCta: {
11095
+ itemId: "CTAzgoPn1709005149328",
11096
+ title: "立即购买",
11097
+ tags: [
11098
+ ],
11099
+ weight: null,
11100
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:15",
11101
+ enTitle: "Shop now",
11102
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
11103
+ link: null,
11104
+ linkTitle: null,
11105
+ linkType: null,
11106
+ menuCategoryId: "65966478d19caa37afe3603f"
11107
+ },
11108
+ homePage: [
11109
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsx3wufMP9P6ovvCrXL58eVVA61gI1710499528917.jpg",
11110
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fs82a414vXXhbgMXsw3Zm8TWyDMvI1710499528543.jpg",
11111
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsJaZoFhur3jfMEciQdk5GMV8O2un1710499528346.jpg",
11112
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fstO8CRKfBzpJUmAMyCDHDo23ji9N1710499528346.jpg",
11113
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsagaUiox7KECRhbPn6MScg3s4Nwd1710499528602.jpg",
11114
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsBsyFADiYBLWHaAIQfNRsgweVOWj1710499529947.jpg",
11115
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsqJEwfvOLpXQ6nQt76o92XdLwzs11710499529939.jpg"
11116
+ ],
11117
+ collection: "Eté 2024",
11118
+ link: "https://www.dior.com/en_us/fashion/products/M3352UBHM_M900",
11119
+ linkTitle: null,
11120
+ linkType: "WEB",
11121
+ info: "New for the Summer 2024 season, the Dior Caro Top Handle Camera bag is a sophisticated and practical design. Crafted in black calfskin, the small model is elevated by the originality of the Macrocannage stitching's quilted effect. The bag features a zip closure and an antique gold-tone metal CD signature. ",
11122
+ price: 3350,
11123
+ currency: "USD-$"
11124
+ },
11125
+ bindProducts: [
11126
+ ],
11127
+ cover: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240305/fsZhMDVzP6kuh9Qt86c11whAMglMU1709628656988.jpg",
11128
+ url: null,
11129
+ imgUrls: [
11130
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240314/fsWrEKA6oRWUmOY14D1POTJjgiks51710401973577.jpg"
11131
+ ],
11132
+ hashTags: [
11133
+ "Ready-To-Wear"
11134
+ ]
11135
+ },
11136
+ product: null,
11137
+ cta: null
11138
+ },
11139
+ {
11140
+ position: "16",
11141
+ isCollected: null,
11142
+ video: {
11143
+ itemId: "VIDEO2rUuG1709617832960",
11144
+ title: "The dior toujours bag is distinguished by a casual and practical design. Crafted in black crinkled calfskin with macrocannage topstitching, it showcases a spacious interior compartment with a matching pouch to organize the essentials. Its leather strap closure keeps items secure while the d of the cd lock closure twists to adjust the sides and enhance the bag's silhouette.",
11145
+ tags: [
11146
+ "Dior Toujours Bag",
11147
+ "Casual",
11148
+ "Leather Strap",
11149
+ "Handbags"
11150
+ ],
11151
+ weight: null,
11152
+ traceInfo: "VECTOReVssi1704360966770:VIDEO:VIDEO2rUuG1709617832960:default:3::branch:Handbags:16",
11153
+ bindCta: null,
11154
+ bindProduct: {
11155
+ itemId: "M2821SNIOM900",
11156
+ title: "Medium Dior Toujours Bag Black Macrocannage Crinkled Leather",
11157
+ tags: [
11158
+ "Medium",
11159
+ "Black",
11160
+ "Women",
11161
+ "Handbags",
11162
+ "Bucket Bag"
11163
+ ],
11164
+ weight: null,
11165
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:M2821SNIOM900:default:3::branch:Handbags:16",
11166
+ bindCta: {
11167
+ itemId: "CTAzgoPn1709005149328",
11168
+ title: "立即购买",
11169
+ tags: [
11170
+ ],
11171
+ weight: null,
11172
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:16",
11173
+ enTitle: "Shop now",
11174
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
11175
+ link: null,
11176
+ linkTitle: null,
11177
+ linkType: null,
11178
+ menuCategoryId: "65966478d19caa37afe3603f"
11179
+ },
11180
+ homePage: [
11181
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsy6AN0OWw3rj8Luw3RTSP9n2kDLq1710497237677.jpg",
11182
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fszTc3uEUrtppdN9QVVU2XBnaaaBY1710497237986.jpg",
11183
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsKbBMTRa0tTTX661wu7DzLw9OP0r1710497237980.jpg",
11184
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsOYHlYCwgzalxzmIJcsZmIsJ2L3g1710497237145.jpg",
11185
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsKJqNVm1ZBlrgZ8XLC0YAaO6ws2F1710497237650.jpg",
11186
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsm2VoVancBQ20nDHceESUPNLyrUy1710497238312.jpg",
11187
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fs2B5YYmv8OztP3d9rlM2a9KmYswl1710497237339.jpg"
11188
+ ],
11189
+ collection: "Eté 2024",
11190
+ link: "https://www.dior.com/en_us/fashion/products/M1296ZRIW_M828-medium-dior-book-tote-ecru-and-blue-dior-oblique-embroidery-36-x-27.5-x-16.5-cm",
11191
+ linkTitle: null,
11192
+ linkType: "WEB",
11193
+ info: "The dior toujours bag is distinguished by a casual and practical design. Crafted in black crinkled calfskin with macrocannage topstitching, it showcases a spacious interior compartment with a matching pouch to organize the essentials. Its leather strap closure keeps items secure while the d of the cd lock closure twists to adjust the sides and enhance the bag's silhouette.",
11194
+ price: 4400,
11195
+ currency: "USD-$"
11196
+ },
11197
+ bindProducts: [
11198
+ ],
11199
+ cover: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240305/fs0BUtn8TYp4l8gWsg5WD9Ht8AP7R1709617796077.jpg",
11200
+ url: null,
11201
+ imgUrls: [
11202
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240314/fsmecPfhI3OtZwJmKAXLv8scBSSdK1710399333565.jpg",
11203
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240314/fsfsWBLxbC36B7Pm7Ae1uL98EmoaH1710399333017.jpg"
11204
+ ],
11205
+ hashTags: [
11206
+ "Handbags",
11207
+ "Dior Toujours Bag"
11208
+ ]
11209
+ },
11210
+ product: null,
11211
+ cta: null
11212
+ },
11213
+ {
11214
+ position: "17",
11215
+ isCollected: null,
11216
+ video: {
11217
+ itemId: "VIDEOGZGZI1709629679782",
11218
+ title: "The Lady Dior bag embodies Dior's vision of elegance and beauty. Sleek and refined, the timeless white and navy blue calfskin style offers a new take on the iconic House motif with this season's signature Toile de Jouy Soleil, layering suns and crescent moons into a floral design representing the four seasons. A",
11219
+ tags: [
11220
+ "Handbags"
11221
+ ],
11222
+ weight: null,
11223
+ traceInfo: "VECTOReVssi1704360966770:VIDEO:VIDEOGZGZI1709629679782:default:3::branch:Handbags:17",
11224
+ bindCta: null,
11225
+ bindProduct: {
11226
+ itemId: "M0565OZEDM928",
11227
+ title: "Medium Lady Dior Bag",
11228
+ tags: [
11229
+ "Lady Dior",
11230
+ "Medium",
11231
+ "Handbags",
11232
+ "Crossbody"
11233
+ ],
11234
+ weight: null,
11235
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:M0565OZEDM928:default:3::branch:Handbags:17",
11236
+ bindCta: {
11237
+ itemId: "CTAzgoPn1709005149328",
11238
+ title: "立即购买",
11239
+ tags: [
11240
+ ],
11241
+ weight: null,
11242
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:17",
11243
+ enTitle: "Shop now",
11244
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
11245
+ link: null,
11246
+ linkTitle: null,
11247
+ linkType: null,
11248
+ menuCategoryId: "65966478d19caa37afe3603f"
11249
+ },
11250
+ homePage: [
11251
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsbVwOx4grEmqCNmvOnKpIS0vTPPc1710499656033.jpg",
11252
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240319/fsJrpY9R8uGenvzM7NnzI4lPMCF8g1710836215790.jpg",
11253
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240319/fsYQG9gipUNt6UbzFPXTwLTNgj5BF1710836214937.jpg",
11254
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240319/fsqPEXjWl7l3wPAxJIZbnnhZPXDCw1710836216838.jpg",
11255
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsNHlPmAsNYPsGDJ5w0G213wJkwFf1710499654946.jpg",
11256
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fs8dAObnEoAYe1V6pwJOGTs4vCBJO1710499655963.jpg",
11257
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsJpaBPC8OxQ4aYwxsMcqZpGtPWnq1710499655730.jpg"
11258
+ ],
11259
+ collection: "Eté 2024",
11260
+ link: "https://www.dior.com/en_us/fashion/products/M0565OZED_M928",
11261
+ linkTitle: null,
11262
+ linkType: "WEB",
11263
+ info: "The Lady Dior bag embodies Dior's vision of elegance and beauty. Sleek and refined, the timeless white and navy blue calfskin style offers a new take on the iconic House motif with this season's signature Toile de Jouy Soleil, layering suns and crescent moons into a floral design representing the four seasons. Accented by pale gold-finish metal D.I.O.R. charms illuminating the silhouette and featuring a thin, removable leather shoulder strap, the medium Lady Dior bag can be carried by hand or wo",
11264
+ price: 6500,
11265
+ currency: "USD-$"
11266
+ },
11267
+ bindProducts: [
11268
+ ],
11269
+ cover: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240305/fsG1IT2gcB5iabcTL89Xs9bRHISMb1709629659698.jpg",
11270
+ url: null,
11271
+ imgUrls: [
11272
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240314/fsJB1txgzSsQLBBJSTzqGI40BvLkr1710399454552.jpg"
11273
+ ],
11274
+ hashTags: [
11275
+ "Handbags"
11276
+ ]
11277
+ },
11278
+ product: null,
11279
+ cta: null
11280
+ },
11281
+ {
11282
+ position: "18",
11283
+ isCollected: null,
11284
+ video: {
11285
+ itemId: "VIDEOC2IMa1710324169054",
11286
+ title: "The lady dior bag embodies dior's vision of elegance and beauty. Sleek and refined, the timeless style demonstrates the house's exceptional savoir-faire. The black patent-to-matte gradient lambskin style is embellished with iconic cannage topstitching, while the ultra-matte metal d.i.o.r. Charms lend a modern touch. Featuring a thin, removable leather shoulder strap, the medium lady dior bag can be carried by hand or worn crossbody.",
11287
+ tags: [
11288
+ "Lady Dior",
11289
+ "Removable Shoulder Strap",
11290
+ "Medium",
11291
+ "Handbags",
11292
+ "Crossbody"
11293
+ ],
11294
+ weight: null,
11295
+ traceInfo: "VECTOReVssi1704360966770:VIDEO:VIDEOC2IMa1710324169054:default:3::branch:Handbags:18",
11296
+ bindCta: null,
11297
+ bindProduct: {
11298
+ itemId: "M0565SDBRM900",
11299
+ title: "Medium Lady Dior Bag",
11300
+ tags: [
11301
+ "Women",
11302
+ "Black",
11303
+ "Handbags",
11304
+ "Hand",
11305
+ "Lady Dior",
11306
+ "Crossbody"
11307
+ ],
11308
+ weight: null,
11309
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:M0565SDBRM900:default:3::branch:Handbags:18",
11310
+ bindCta: {
11311
+ itemId: "CTAzgoPn1709005149328",
11312
+ title: "立即购买",
11313
+ tags: [
11314
+ ],
11315
+ weight: null,
11316
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:18",
11317
+ enTitle: "Shop now",
11318
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
11319
+ link: null,
11320
+ linkTitle: null,
11321
+ linkType: null,
11322
+ menuCategoryId: "65966478d19caa37afe3603f"
11323
+ },
11324
+ homePage: [
11325
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsnyiCm9oirbXLqmqY7231O8O2Yhb1710498970982.jpg",
11326
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fskwIRRKCtuw9cb9btuubt2D5bXfB1710498970676.jpg",
11327
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsqXFTCyhxspeYCD3uo4UiuN5vQ7w1710498970671.jpg",
11328
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fs8rDRSKJmWUNI42MjrMWVlI0D9Fz1710498970729.jpg",
11329
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsca9Cjqo3WMJVU0OL0OjQo8xOoMx1710498972076.jpg",
11330
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsjl1bxi56X0QrKwfvl8YocBVJ2N81710498971352.jpg"
11331
+ ],
11332
+ collection: null,
11333
+ link: "https://www.dior.com/en_us/fashion/products/M0565SDBR_M900-medium-lady-dior-bag-black-patent-to-matte-gradient-cannage-lambskin?objectID=M0565SDBR_M900&query=M0565SDBRM900&queryID=14cc52b35774a9a42e78fd9ba199860e",
11334
+ linkTitle: null,
11335
+ linkType: "WEB",
11336
+ info: "The Lady Dior bag embodies Dior's vision of elegance and beauty. Sleek and refined, the timeless style demonstrates the House's exceptional savoir-faire. The black patent-to-matte gradient lambskin style is embellished with iconic Cannage topstitching, while the ultra-matte metal D.I.O.R. charms lend a modern touch. Featuring a thin, removable leather shoulder strap, the medium Lady Dior bag can be carried by hand or worn crossbody.",
11337
+ price: 7100,
11338
+ currency: "USD-$"
11339
+ },
11340
+ bindProducts: [
11341
+ ],
11342
+ cover: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fsuF6sqlC9LCBLTgxHwMRinXwB6bF1710324135846.png",
11343
+ url: "https://dior-sxp-cdn.chatlabs.net/prod/sound/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240313/fsFwNsGElWR2SXQ2tWwHkaiqMZN5H1710324095954.mp4",
11344
+ imgUrls: null,
11345
+ hashTags: [
11346
+ "Lady Dior",
11347
+ "Handbags"
11348
+ ]
11349
+ },
11350
+ product: null,
11351
+ cta: null
11352
+ },
11353
+ {
11354
+ position: "19",
11355
+ isCollected: null,
11356
+ video: null,
11357
+ product: {
11358
+ itemId: "M0565OZEDM928",
11359
+ title: "Medium Lady Dior Bag",
11360
+ tags: [
11361
+ "Lady Dior",
11362
+ "Medium",
11363
+ "Handbags",
11364
+ "Crossbody"
11365
+ ],
11366
+ weight: null,
11367
+ traceInfo: "VECTOReVssi1704360966770:PRODUCT:M0565OZEDM928:default:3::branch:Handbags:19",
11368
+ bindCta: {
11369
+ itemId: "CTAzgoPn1709005149328",
11370
+ title: "立即购买",
11371
+ tags: [
11372
+ ],
11373
+ weight: null,
11374
+ traceInfo: "VECTOReVssi1704360966770:CTA:CTAzgoPn1709005149328:default:3::branch:Handbags:19",
11375
+ enTitle: "Shop now",
11376
+ icon: "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240227/fsIkhOh3SihCkTDQ3oI41kwCsjq6A1709005134510.png",
11377
+ link: null,
11378
+ linkTitle: null,
11379
+ linkType: null,
11380
+ menuCategoryId: "65966478d19caa37afe3603f"
11381
+ },
11382
+ homePage: [
11383
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsbVwOx4grEmqCNmvOnKpIS0vTPPc1710499656033.jpg",
11384
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240319/fsJrpY9R8uGenvzM7NnzI4lPMCF8g1710836215790.jpg",
11385
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240319/fsYQG9gipUNt6UbzFPXTwLTNgj5BF1710836214937.jpg",
11386
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240319/fsqPEXjWl7l3wPAxJIZbnnhZPXDCw1710836216838.jpg",
11387
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsNHlPmAsNYPsGDJ5w0G213wJkwFf1710499654946.jpg",
11388
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fs8dAObnEoAYe1V6pwJOGTs4vCBJO1710499655963.jpg",
11389
+ "https://dior-sxp-cdn.chatlabs.net/prod/img/edc1a0de-330e-40e4-bdf3-17d57d57c19b/sxp-portal/20240315/fsJpaBPC8OxQ4aYwxsMcqZpGtPWnq1710499655730.jpg"
11390
+ ],
11391
+ collection: "Eté 2024",
11392
+ link: "https://www.dior.com/en_us/fashion/products/M0565OZED_M928",
11393
+ linkTitle: null,
11394
+ linkType: "WEB",
11395
+ info: "The Lady Dior bag embodies Dior's vision of elegance and beauty. Sleek and refined, the timeless white and navy blue calfskin style offers a new take on the iconic House motif with this season's signature Toile de Jouy Soleil, layering suns and crescent moons into a floral design representing the four seasons. Accented by pale gold-finish metal D.I.O.R. charms illuminating the silhouette and featuring a thin, removable leather shoulder strap, the medium Lady Dior bag can be carried by hand or wo",
11396
+ price: 6500,
11397
+ currency: "USD-$"
11398
+ },
11399
+ cta: null
11400
+ }
11401
+ ];
11402
+ var hashTag = "Handbags";
11403
+ var previewData = {
11404
+ productUserId: productUserId,
11405
+ requestId: requestId,
11406
+ channel: channel,
11407
+ rtc: rtc,
11408
+ tag: tag,
11409
+ recList: recList,
11410
+ hashTag: hashTag
11411
+ };
10016
11412
 
10017
- const VideoWidget = ({ rec, index, height, data, muted, activeIndex }) => {
10018
- const [isPauseVideo, setIsPauseVideo] = React.useState(false);
10019
- const videoRef = React.useRef(null);
10020
- const { bffEventReport, sxpParameter, waterFallData, openHashtag } = useSxpDataSource();
10021
- const videoStartTime = React.useRef(0);
10022
- const [isLoad, setIsLoad] = React.useState(false);
10023
- const { isActive } = useSwiperSlide();
10024
- React.useEffect(() => {
10025
- if (!videoRef.current)
10026
- return;
10027
- videoRef.current.muted = muted;
10028
- }, [muted]);
10029
- const handleVideoStart = React.useCallback(() => {
10030
- var _a, _b;
10031
- if (!(videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) || ((_a = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _a === void 0 ? void 0 : _a.readyState) < 2)
10032
- return;
10033
- (_b = videoRef.current) === null || _b === void 0 ? void 0 : _b.play();
10034
- }, []);
10035
- const PAUSE_ICON = useIconLink('/pb_static/06f28a2025c74c1cb49be6767316d827.png');
10036
- const handlePlaying = React.useCallback(() => {
10037
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
10038
- setIsPauseVideo(false);
10039
- const item = data[index];
10040
- if (item && isLoad && ((_a = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _a === void 0 ? void 0 : _a.duration)) {
10041
- videoStartTime.current = ((_b = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _b === void 0 ? void 0 : _b.currentTime) || 0;
10042
- const videoDuration = ((_d = (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.duration) !== null && _d !== void 0 ? _d : 0).toFixed(2);
10043
- const videoCurrentTime = ((_f = (_e = videoRef.current) === null || _e === void 0 ? void 0 : _e.currentTime) !== null && _f !== void 0 ? _f : 0).toFixed(2);
10044
- const playType = '1';
10045
- bffEventReport === null || bffEventReport === void 0 ? void 0 : bffEventReport({
10046
- eventInfo: {
10047
- eventSubject: 'playVideo',
10048
- eventDescription: 'User played the video',
10049
- contentId: (_h = (_g = item.video) === null || _g === void 0 ? void 0 : _g.itemId) !== null && _h !== void 0 ? _h : '',
10050
- contentName: (_k = (_j = item.video) === null || _j === void 0 ? void 0 : _j.title) !== null && _k !== void 0 ? _k : '',
10051
- playType,
10052
- startTime: videoCurrentTime,
10053
- videoDuration,
10054
- contentTags: JSON.stringify((_m = (_l = item.video) === null || _l === void 0 ? void 0 : _l.tags) !== null && _m !== void 0 ? _m : []),
10055
- position: item.position,
10056
- contentFormat: 'video',
10057
- traceInfo: (_o = item.video) === null || _o === void 0 ? void 0 : _o.traceInfo
10058
- }
10059
- });
10060
- }
10061
- if (!isLoad) {
10062
- setIsLoad(true);
11413
+ const WaterfallFlowItem = (props) => {
11414
+ const { rec, index, list, reportTagsView, textStyles, space } = props;
11415
+ const { swiperRef, setRtcList, setOpenHashtag, bffEventReport, sxpParameter } = useSxpDataSource();
11416
+ const [showVideo, setShowVideo] = React.useState(false);
11417
+ const imgDom = React.useRef(null);
11418
+ const videoDom = React.useRef(null);
11419
+ const canvasRef = React.useRef(null);
11420
+ const [firstFrameSrc, setFirstFrameSrc] = React.useState('');
11421
+ const src = React.useMemo(() => {
11422
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
11423
+ if ((_a = rec === null || rec === void 0 ? void 0 : rec.video) === null || _a === void 0 ? void 0 : _a.cover) {
11424
+ return (_b = rec === null || rec === void 0 ? void 0 : rec.video) === null || _b === void 0 ? void 0 : _b.cover;
10063
11425
  }
10064
- }, [bffEventReport, data, index, isLoad]);
10065
- const handleLoadedMetadata = React.useCallback(() => {
10066
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
10067
- const item = data[index];
10068
- if (item && !isLoad && ((_a = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _a === void 0 ? void 0 : _a.duration)) {
10069
- videoStartTime.current = ((_b = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _b === void 0 ? void 0 : _b.currentTime) || 0;
10070
- const videoDuration = ((_d = (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.duration) !== null && _d !== void 0 ? _d : 0).toFixed(2);
10071
- const videoCurrentTime = ((_f = (_e = videoRef.current) === null || _e === void 0 ? void 0 : _e.currentTime) !== null && _f !== void 0 ? _f : 0).toFixed(2);
10072
- const playType = '0';
10073
- bffEventReport === null || bffEventReport === void 0 ? void 0 : bffEventReport({
10074
- eventInfo: {
10075
- eventSubject: 'playVideo',
10076
- eventDescription: 'User played the video',
10077
- contentId: (_h = (_g = item.video) === null || _g === void 0 ? void 0 : _g.itemId) !== null && _h !== void 0 ? _h : '',
10078
- contentName: (_k = (_j = item.video) === null || _j === void 0 ? void 0 : _j.title) !== null && _k !== void 0 ? _k : '',
10079
- playType,
10080
- startTime: videoCurrentTime,
10081
- videoDuration,
10082
- contentTags: JSON.stringify((_m = (_l = item.video) === null || _l === void 0 ? void 0 : _l.tags) !== null && _m !== void 0 ? _m : []),
10083
- position: item.position,
10084
- contentFormat: 'video',
10085
- traceInfo: (_o = item.video) === null || _o === void 0 ? void 0 : _o.traceInfo
10086
- }
10087
- });
11426
+ else if ((_c = rec === null || rec === void 0 ? void 0 : rec.video) === null || _c === void 0 ? void 0 : _c.url) {
11427
+ setShowVideo(true);
11428
+ return (_d = rec === null || rec === void 0 ? void 0 : rec.video) === null || _d === void 0 ? void 0 : _d.url;
10088
11429
  }
10089
- setTimeout(() => {
10090
- var _a, _b;
10091
- if (!(videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) || ((_a = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _a === void 0 ? void 0 : _a.readyState) < 2)
10092
- return;
10093
- (_b = videoRef.current) === null || _b === void 0 ? void 0 : _b.play();
10094
- }, 0);
10095
- }, [index, bffEventReport, data, isLoad]);
10096
- const handleClickVideo = React.useCallback((type) => () => {
10097
- var _a, _b, _c, _d, _e, _f;
10098
- if (!(videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) || ((_a = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _a === void 0 ? void 0 : _a.readyState) < 2)
10099
- return;
10100
- if (!isLoad)
10101
- return;
10102
- const isPause = (_b = videoRef.current) === null || _b === void 0 ? void 0 : _b.paused;
10103
- switch (type) {
10104
- case 'start':
10105
- if (!isPause)
10106
- return;
10107
- (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.play();
10108
- setIsPauseVideo(false);
10109
- break;
10110
- case 'pause':
10111
- if (isPause)
10112
- return;
10113
- (_d = videoRef.current) === null || _d === void 0 ? void 0 : _d.pause();
10114
- setIsPauseVideo(true);
10115
- break;
10116
- default:
10117
- if (isPause) {
10118
- (_e = videoRef.current) === null || _e === void 0 ? void 0 : _e.play();
10119
- }
10120
- else {
10121
- (_f = videoRef.current) === null || _f === void 0 ? void 0 : _f.pause();
10122
- }
10123
- setIsPauseVideo(!isPause);
10124
- break;
11430
+ else if ((_f = (_e = rec === null || rec === void 0 ? void 0 : rec.video) === null || _e === void 0 ? void 0 : _e.imgUrls) === null || _f === void 0 ? void 0 : _f.length) {
11431
+ return (_h = (_g = rec === null || rec === void 0 ? void 0 : rec.video) === null || _g === void 0 ? void 0 : _g.imgUrls) === null || _h === void 0 ? void 0 : _h[0];
10125
11432
  }
10126
- }, [data, index, isLoad]);
10127
- const onPause = React.useCallback(() => {
10128
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
10129
- const item = data[index];
10130
- const videoDuration = ((_b = (_a = videoRef.current) === null || _a === void 0 ? void 0 : _a.duration) !== null && _b !== void 0 ? _b : 0).toFixed(2);
10131
- const videoCurrentTime = ((_d = (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.currentTime) !== null && _d !== void 0 ? _d : 0).toFixed(2);
10132
- if ((_e = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _e === void 0 ? void 0 : _e.duration) {
10133
- const playDuration = (((_f = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _f === void 0 ? void 0 : _f.currentTime) - videoStartTime.current).toFixed(2);
10134
- bffEventReport === null || bffEventReport === void 0 ? void 0 : bffEventReport({
10135
- eventInfo: {
10136
- eventSubject: 'playOverVideo',
10137
- eventDescription: 'User finished playing the video',
10138
- contentId: (_h = (_g = item.video) === null || _g === void 0 ? void 0 : _g.itemId) !== null && _h !== void 0 ? _h : '',
10139
- contentName: (_k = (_j = item.video) === null || _j === void 0 ? void 0 : _j.title) !== null && _k !== void 0 ? _k : '',
10140
- endTime: videoCurrentTime,
10141
- videoDuration,
10142
- playDuration,
10143
- contentTags: JSON.stringify((_m = (_l = item.video) === null || _l === void 0 ? void 0 : _l.tags) !== null && _m !== void 0 ? _m : []),
10144
- position: item.position,
10145
- contentFormat: 'video',
10146
- traceInfo: (_o = item.video) === null || _o === void 0 ? void 0 : _o.traceInfo
10147
- }
10148
- });
11433
+ else if ((_k = (_j = rec === null || rec === void 0 ? void 0 : rec.product) === null || _j === void 0 ? void 0 : _j.homePage) === null || _k === void 0 ? void 0 : _k.length) {
11434
+ return (_m = (_l = rec === null || rec === void 0 ? void 0 : rec.product) === null || _l === void 0 ? void 0 : _l.homePage) === null || _m === void 0 ? void 0 : _m[0];
10149
11435
  }
10150
- }, [data, index, bffEventReport]);
10151
- React.useEffect(() => {
10152
- var _a, _b, _c, _d, _e, _f;
10153
- if (data.length <= 0)
10154
- return;
10155
- if (!videoRef.current)
10156
- return;
10157
- const isPause = (_a = videoRef.current) === null || _a === void 0 ? void 0 : _a.paused;
10158
- setIsPauseVideo(false);
10159
- if (!isActive) {
10160
- if (!isPause && ((_b = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _b === void 0 ? void 0 : _b.readyState) >= 2)
10161
- (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.pause();
10162
- return;
11436
+ else {
11437
+ return (sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image) || '';
10163
11438
  }
10164
- if (!videoRef.current.src) {
10165
- const videoSrc = rec.video.url;
10166
- // if (videoSrc.includes('.m3u8')) {
10167
- // if (Hls.isSupported()) {
10168
- // const hls = new Hls();
10169
- // hls.loadSource(videoSrc);
10170
- // hls.attachMedia(videoRef.current);
10171
- // } else if (videoRef.current.canPlayType('application/vnd.apple.mpegurl')) {
10172
- // videoRef.current.src = videoSrc;
10173
- // } else {
10174
- // videoRef.current.src = videoSrc;
10175
- // }
10176
- // } else {
10177
- // videoRef.current.src = videoSrc;
10178
- // }
10179
- videoRef.current.src = videoSrc;
10180
- videoRef.current.setAttribute('x5-playsinline', 'true');
10181
- videoRef.current.setAttribute('webkit-playsinline', 'true');
11439
+ }, [rec, sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image]);
11440
+ const title = React.useMemo(() => {
11441
+ var _a, _b;
11442
+ return ((_a = rec === null || rec === void 0 ? void 0 : rec.product) === null || _a === void 0 ? void 0 : _a.title) || ((_b = rec === null || rec === void 0 ? void 0 : rec.video) === null || _b === void 0 ? void 0 : _b.title) || null;
11443
+ }, [rec]);
11444
+ const priceText = React.useMemo(() => {
11445
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
11446
+ if (((_a = rec === null || rec === void 0 ? void 0 : rec.product) === null || _a === void 0 ? void 0 : _a.currency) && ((_b = rec === null || rec === void 0 ? void 0 : rec.product) === null || _b === void 0 ? void 0 : _b.price)) {
11447
+ return `${(_f = (_e = (_d = (_c = rec === null || rec === void 0 ? void 0 : rec.product) === null || _c === void 0 ? void 0 : _c.currency) === null || _d === void 0 ? void 0 : _d.split('-')[1]) === null || _e === void 0 ? void 0 : _e.toUpperCase()) !== null && _f !== void 0 ? _f : ''}${(_j = (_h = (_g = rec === null || rec === void 0 ? void 0 : rec.product) === null || _g === void 0 ? void 0 : _g.price) === null || _h === void 0 ? void 0 : _h.toLocaleString('zh', {
11448
+ minimumFractionDigits: 0
11449
+ })) !== null && _j !== void 0 ? _j : ''}`;
10182
11450
  }
10183
11451
  else {
10184
- if (((_d = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _d === void 0 ? void 0 : _d.readyState) < 2)
10185
- return;
10186
- videoRef.current.play();
11452
+ return null;
10187
11453
  }
10188
- (_e = videoRef.current) === null || _e === void 0 ? void 0 : _e.addEventListener('canplay', handleLoadedMetadata);
10189
- (_f = videoRef.current) === null || _f === void 0 ? void 0 : _f.addEventListener('playing', handlePlaying);
11454
+ }, [rec]);
11455
+ // useEffect(() => {
11456
+ // if (imgDom.current === null || src === '') {
11457
+ // return;
11458
+ // }
11459
+ // const img = new Image();
11460
+ // if (showVideo && firstFrameSrc) {
11461
+ // img.src = firstFrameSrc;
11462
+ // } else {
11463
+ // img.src = src;
11464
+ // }
11465
+ // // img.onload = () => {
11466
+ // // setIsLoading(true);
11467
+ // // };
11468
+ // imgDom.current.src = img.src;
11469
+ // }, [src, showVideo, firstFrameSrc]);
11470
+ React.useEffect(() => {
11471
+ const observer = new IntersectionObserver((entries) => {
11472
+ entries.forEach((entry) => {
11473
+ if (entry.isIntersecting) {
11474
+ if (imgDom.current === null || src === '') {
11475
+ return;
11476
+ }
11477
+ if (showVideo && firstFrameSrc) {
11478
+ imgDom.current.src = firstFrameSrc;
11479
+ }
11480
+ else {
11481
+ imgDom.current.src = src;
11482
+ }
11483
+ observer.unobserve(imgDom.current);
11484
+ }
11485
+ });
11486
+ });
11487
+ observer.observe(imgDom.current);
10190
11488
  return () => {
10191
- var _a, _b;
10192
- (_a = videoRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('canplay', handleLoadedMetadata);
10193
- (_b = videoRef.current) === null || _b === void 0 ? void 0 : _b.removeEventListener('playing', handlePlaying);
11489
+ observer.disconnect();
10194
11490
  };
10195
- }, [data, handleLoadedMetadata, handlePlaying, isActive, isLoad, rec.video]);
10196
- /*
10197
- 打开/关闭hashtag暂停/播放视频
10198
- */
11491
+ }, [src, showVideo, firstFrameSrc]);
11492
+ const calculateHeightForWidth = (videoWidth, videoHeight, targetWidth) => {
11493
+ const aspectRatio = videoWidth / videoHeight;
11494
+ const targetHeight = targetWidth / aspectRatio;
11495
+ return targetHeight;
11496
+ };
10199
11497
  React.useEffect(() => {
10200
- var _a, _b, _c, _d;
10201
- if (!(videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) || ((_a = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _a === void 0 ? void 0 : _a.readyState) < 2)
10202
- return;
10203
- const isPause = (_b = videoRef.current) === null || _b === void 0 ? void 0 : _b.paused;
10204
- if (!isActive)
11498
+ const video = videoDom === null || videoDom === void 0 ? void 0 : videoDom.current;
11499
+ if (video === null || src === '' || !showVideo) {
10205
11500
  return;
10206
- if (!isPause && openHashtag) {
10207
- (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.pause();
10208
11501
  }
10209
- else if (!openHashtag) {
10210
- (_d = videoRef.current) === null || _d === void 0 ? void 0 : _d.play();
10211
- }
10212
- }, [openHashtag, isActive]);
10213
- React.useEffect(() => {
10214
- if (!isActive)
10215
- return;
10216
- const onShow = handleClickVideo('start');
10217
- const onHide = handleClickVideo('pause');
10218
- SXP_EVENT_BUS.on(SXP_EVENT_TYPE.PAGE_DID_SHOW, onShow);
10219
- SXP_EVENT_BUS.on(SXP_EVENT_TYPE.PAGE_DID_HIDE, onHide);
10220
- return () => {
10221
- SXP_EVENT_BUS.off(SXP_EVENT_TYPE.PAGE_DID_SHOW, onShow);
10222
- SXP_EVENT_BUS.off(SXP_EVENT_TYPE.PAGE_DID_HIDE, onHide);
11502
+ video.src = src;
11503
+ video.currentTime = 1;
11504
+ video.crossOrigin = 'anonymous';
11505
+ video.onloadeddata = () => {
11506
+ const canvas = canvasRef === null || canvasRef === void 0 ? void 0 : canvasRef.current;
11507
+ if (!canvas)
11508
+ return;
11509
+ const ctx = canvas.getContext('2d');
11510
+ const targetWidth = (window === null || window === void 0 ? void 0 : window.innerWidth) / 2;
11511
+ const targetHeight = calculateHeightForWidth(video.videoWidth, video.videoHeight, targetWidth);
11512
+ canvas.height = targetHeight;
11513
+ canvas.width = targetWidth;
11514
+ ctx === null || ctx === void 0 ? void 0 : ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
11515
+ setFirstFrameSrc(canvas.toDataURL());
11516
+ video.remove();
11517
+ canvas.remove();
10223
11518
  };
10224
- }, [handleClickVideo, isActive]);
10225
- const renderPoster = React.useMemo(() => {
10226
- if (!(sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image)) {
10227
- return null;
11519
+ }, [src, showVideo]);
11520
+ const handleClickToDetail = () => {
11521
+ reportTagsView();
11522
+ setRtcList === null || setRtcList === void 0 ? void 0 : setRtcList(list);
11523
+ setTimeout(() => {
11524
+ var _a;
11525
+ (_a = swiperRef === null || swiperRef === void 0 ? void 0 : swiperRef.current) === null || _a === void 0 ? void 0 : _a.swiper.slideTo(index, 0, false);
11526
+ setOpenHashtag === null || setOpenHashtag === void 0 ? void 0 : setOpenHashtag(false);
11527
+ }, 0);
11528
+ };
11529
+ return (React.createElement("div", { className: 'list-content-listItem', key: index, onClick: handleClickToDetail, style: { marginBottom: space } },
11530
+ React.createElement("div", { className: 'list-content-listItem-picture' },
11531
+ showVideo && (React.createElement("div", { style: { display: 'none' } },
11532
+ React.createElement("video", { ref: videoDom, crossOrigin: 'anonymous', className: 'list-content-listItem-picture-img' }),
11533
+ React.createElement("canvas", { ref: canvasRef }))),
11534
+ React.createElement("img", { className: 'list-content-listItem-picture-img', loading: 'lazy', ref: imgDom })),
11535
+ React.createElement("div", { className: 'list-content-listItem-info' },
11536
+ React.createElement("div", { className: `${'list-content-listItem-info-title'} ${priceText ? 'list-content-listItem-info-nowrap' : ''}`, style: textStyles === null || textStyles === void 0 ? void 0 : textStyles.title }, title && title),
11537
+ React.createElement("div", { className: 'list-content-listItem-info-price', style: textStyles === null || textStyles === void 0 ? void 0 : textStyles.price, hidden: !priceText }, priceText))));
11538
+ };
11539
+ function WaterfallList(_a) {
11540
+ var _b, _c, _d, _e, _f, _g, _h;
11541
+ var { reportTagsView } = _a, props = __rest(_a, ["reportTagsView"]);
11542
+ const { waterFallData, getRecommendVideos, hashTagSize, loadingImage, isOpenHashTag } = useSxpDataSource();
11543
+ const [list, setList] = React.useState();
11544
+ const [data, setData] = React.useState();
11545
+ const [isLoadingData, setIsLoadingData] = React.useState(false);
11546
+ const containerRef = React.useRef(null);
11547
+ const [isLoadMore, setIsLoadMore] = React.useState(false);
11548
+ React.useCallback(() => {
11549
+ if (isLoadMore)
11550
+ return;
11551
+ setIsLoadMore(true);
11552
+ waterFallData &&
11553
+ (getRecommendVideos === null || getRecommendVideos === void 0 ? void 0 : getRecommendVideos({
11554
+ hashTag: waterFallData === null || waterFallData === void 0 ? void 0 : waterFallData.hashTag,
11555
+ 'itemFilter.itemId': waterFallData === null || waterFallData === void 0 ? void 0 : waterFallData.itemId,
11556
+ 'itemFilter.itemType': waterFallData === null || waterFallData === void 0 ? void 0 : waterFallData.itemType
11557
+ }).then((res) => {
11558
+ var _a;
11559
+ setList(list === null || list === void 0 ? void 0 : list.concat((_a = res === null || res === void 0 ? void 0 : res.recList) !== null && _a !== void 0 ? _a : []));
11560
+ setIsLoadMore(false);
11561
+ }));
11562
+ }, [waterFallData, getRecommendVideos, list, isLoadMore]);
11563
+ React.useEffect(() => {
11564
+ var _a, _b;
11565
+ setIsLoadingData(true);
11566
+ waterFallData &&
11567
+ (getRecommendVideos === null || getRecommendVideos === void 0 ? void 0 : getRecommendVideos({
11568
+ hashTag: waterFallData === null || waterFallData === void 0 ? void 0 : waterFallData.hashTag,
11569
+ 'itemFilter.itemId': waterFallData === null || waterFallData === void 0 ? void 0 : waterFallData.itemId,
11570
+ 'itemFilter.itemType': waterFallData === null || waterFallData === void 0 ? void 0 : waterFallData.itemType,
11571
+ defaultSize: hashTagSize
11572
+ }).then((res) => {
11573
+ var _a, _b;
11574
+ setData(res);
11575
+ setList((_b = (_a = res === null || res === void 0 ? void 0 : res.recList) === null || _a === void 0 ? void 0 : _a.filter((item) => (item === null || item === void 0 ? void 0 : item.video) !== null || (item === null || item === void 0 ? void 0 : item.product) !== null)) !== null && _b !== void 0 ? _b : []);
11576
+ setIsLoadingData(false);
11577
+ }));
11578
+ if (isOpenHashTag) {
11579
+ const res = previewData;
11580
+ setData(res);
11581
+ setList((_b = (_a = res === null || res === void 0 ? void 0 : res.recList) === null || _a === void 0 ? void 0 : _a.filter((item) => (item === null || item === void 0 ? void 0 : item.video) !== null || (item === null || item === void 0 ? void 0 : item.product) !== null)) !== null && _b !== void 0 ? _b : []);
11582
+ setIsLoadingData(false);
10228
11583
  }
10229
- return (React.createElement("img", { hidden: isLoad, style: { position: 'absolute', left: 0, top: 0, width: '100%', height: '100%', objectFit: 'cover' }, src: sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image }));
10230
- }, [isLoad, sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image]);
11584
+ }, [waterFallData, getRecommendVideos, hashTagSize, isOpenHashTag]);
11585
+ // useEffect(() => {
11586
+ // const container = containerRef?.current;
11587
+ // if (!container) return;
11588
+ // const handleScroll = () => {
11589
+ // const top = (container as any)?.scrollTop;
11590
+ // const clientHeight = (container as any)?.clientHeight;
11591
+ // const scrollHeight = (container as any)?.scrollHeight;
11592
+ // if (scrollHeight <= top + clientHeight && !isLoadingData) {
11593
+ // loadMoreData();
11594
+ // }
11595
+ // };
11596
+ // container?.addEventListener('scroll', handleScroll);
11597
+ // return () => {
11598
+ // container?.removeEventListener('scroll', handleScroll); // 在组件卸载时移除事件监听器
11599
+ // };
11600
+ // }, [isLoadingData, containerRef, loadMoreData]);
11601
+ const handleClickLink = () => {
11602
+ var _a, _b;
11603
+ if ((_a = data === null || data === void 0 ? void 0 : data.tag) === null || _a === void 0 ? void 0 : _a.link) {
11604
+ reportTagsView();
11605
+ window.location.href = (_b = data === null || data === void 0 ? void 0 : data.tag) === null || _b === void 0 ? void 0 : _b.link;
11606
+ }
11607
+ };
11608
+ return (React.createElement(React.Fragment, null, isLoadingData ? (React.createElement("div", { style: { height: '100%', width: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center' } },
11609
+ React.createElement("img", { width: 64, height: 64, src: loadingImage, alt: 'loading...', style: { objectFit: 'contain' } }))) : (React.createElement("div", { className: 'list' },
11610
+ React.createElement("div", { className: 'list-scroll', ref: containerRef, style: {
11611
+ bottom: ((_b = data === null || data === void 0 ? void 0 : data.tag) === null || _b === void 0 ? void 0 : _b.link) ? '100px' : 0
11612
+ } },
11613
+ React.createElement("div", { className: 'list-info', style: (_c = props === null || props === void 0 ? void 0 : props.textStyles) === null || _c === void 0 ? void 0 : _c.hashTagDesc }, (_d = data === null || data === void 0 ? void 0 : data.tag) === null || _d === void 0 ? void 0 : _d.info),
11614
+ React.createElement("div", { hidden: !((_e = data === null || data === void 0 ? void 0 : data.tag) === null || _e === void 0 ? void 0 : _e.link), className: 'list-collection', onClick: handleClickLink, style: { marginBottom: props === null || props === void 0 ? void 0 : props.space } }, ((_f = data === null || data === void 0 ? void 0 : data.tag) === null || _f === void 0 ? void 0 : _f.linkTitle) || 'Shop the collection'),
11615
+ React.createElement("div", { className: 'list-content' }, list === null || list === void 0 ? void 0 : list.map((item, ind) => {
11616
+ return (React.createElement(WaterfallFlowItem, Object.assign({ key: ind, index: ind, rec: item, list: list, reportTagsView: reportTagsView }, props)));
11617
+ })),
11618
+ React.createElement("div", { hidden: !isLoadMore, style: { textAlign: 'center' } }, "loading...")),
11619
+ React.createElement("div", { className: 'list-bottom', hidden: !((_g = data === null || data === void 0 ? void 0 : data.tag) === null || _g === void 0 ? void 0 : _g.link) },
11620
+ React.createElement("button", { className: 'list-bottom-btn', style: props === null || props === void 0 ? void 0 : props.buttonStyle, onClick: handleClickLink }, ((_h = data === null || data === void 0 ? void 0 : data.tag) === null || _h === void 0 ? void 0 : _h.linkTitle) || 'Shop the collection'))))));
11621
+ }
11622
+
11623
+ var img$1 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAaZJREFUeF7t2jFKBEEQRuG3mSJeQTARURDMTL2EqXfwAnoKD6FHMDEzNVIw2tzQC2gFggyDrExX1V92T7wz9PumFnqbXdH5teq8nwEwJqBzgfEVKDYAW8Ae8NZq3ZUm4Aa4AnaBR+C8BUIVAIu/ngSfAs9LESoAWLgB/LzWwP7SeLtfHWAu3tZ9Adz/dwD3eOUJCIlXBQiLVwQIjVcDCI9XAkiJVwFIi1cASI3PBpjb3jbd5GyyUcraCUrEZ02ATHwGgFR8NIBcfCSAZHwUgGx8BIB0vDeAfLwnQIl4L4Ay8R4ApeJbA2wD78DOZA/e7ABzk739Xz/T8rfAIfA6WYCd3BqA7NUSwCKfgLNKCK0BjoC7rzP74yoIrQGsuxSCB0ApBC+AMgieACUQvAHkESIApBGiAGQRIgEkEaIB5BAyAKQQsgBkEDIBJBCyAdIRFABSEVQA0hCUAFIQ1ADCERQBQhFUAcIQlAFCENQBfkOwg9eXpeftFQDmEOzv8ifARy8A3wiXwAHwANwujbf7q0xAi9bZZwwAN9oiDx4TUORFuS2z+wn4BAiAaEHnKChjAAAAAElFTkSuQmCC";
11624
+
11625
+ /*
11626
+ * @Author: binruan@chatlabs.com
11627
+ * @Date: 2024-01-10 10:58:24
11628
+ * @LastEditors: binruan@chatlabs.com
11629
+ * @LastEditTime: 2024-04-07 15:18:35
11630
+ * @FilePath: \pb-sxp-ui\src\core\components\SxpPageRender\WaterFall\index.tsx
11631
+ *
11632
+ */
11633
+ const WaterFall = (props) => {
11634
+ var _a;
11635
+ const { waterFallData, setOpenHashtag, openHashtag, swiperRef, setWaterFallData, cacheRtcList, setRtcList, cacheActiveIndex, rtcList, setCacheRtcList, setIsFromHashtag, isFromHashtag, bffEventReport } = useSxpDataSource();
11636
+ React.useRef(null);
11637
+ const modalEleRef = React.useRef(null);
11638
+ const [viewTime, setViewTime] = React.useState();
10231
11639
  React.useEffect(() => {
10232
- const handleBeforeUnload = () => {
11640
+ const parentNode = document.getElementById('sxp-render');
11641
+ const node = document.getElementById('water-fall');
11642
+ if (node) {
11643
+ modalEleRef.current = node;
11644
+ }
11645
+ else {
11646
+ modalEleRef.current = document.createElement('div');
11647
+ modalEleRef.current.setAttribute('id', 'water-fall');
11648
+ parentNode === null || parentNode === void 0 ? void 0 : parentNode.appendChild(modalEleRef.current);
11649
+ }
11650
+ }, []);
11651
+ const handleClose = () => {
11652
+ const isEq = lodash.isEqual(rtcList, cacheRtcList);
11653
+ if (!isEq && cacheRtcList && (cacheRtcList === null || cacheRtcList === void 0 ? void 0 : cacheRtcList.length)) {
11654
+ setRtcList === null || setRtcList === void 0 ? void 0 : setRtcList(cacheRtcList);
11655
+ }
11656
+ reportTagsView();
11657
+ setWaterFallData === null || setWaterFallData === void 0 ? void 0 : setWaterFallData(undefined);
11658
+ setIsFromHashtag === null || setIsFromHashtag === void 0 ? void 0 : setIsFromHashtag(false);
11659
+ setTimeout(() => {
10233
11660
  var _a, _b;
10234
- if (activeIndex === index && ((_a = rec === null || rec === void 0 ? void 0 : rec.video) === null || _a === void 0 ? void 0 : _a.url) && ((_b = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _b === void 0 ? void 0 : _b.src) && !isPauseVideo) {
10235
- handleClickVideo('pause')();
11661
+ if (!isEq) {
11662
+ (_b = (_a = swiperRef === null || swiperRef === void 0 ? void 0 : swiperRef.current) === null || _a === void 0 ? void 0 : _a.swiper) === null || _b === void 0 ? void 0 : _b.slideTo(cacheActiveIndex, 0, false);
11663
+ }
11664
+ setOpenHashtag === null || setOpenHashtag === void 0 ? void 0 : setOpenHashtag(false);
11665
+ }, 0);
11666
+ };
11667
+ const [recData, setRecData] = React.useState();
11668
+ React.useEffect(() => {
11669
+ if (waterFallData) {
11670
+ setRecData(waterFallData);
11671
+ }
11672
+ }, [waterFallData]);
11673
+ const reportTagsView = React.useCallback(() => {
11674
+ var _a, _b, _c, _d, _e, _f;
11675
+ const rec = recData === null || recData === void 0 ? void 0 : recData.rec;
11676
+ if (!rec)
11677
+ return;
11678
+ let fromKName = '';
11679
+ if (isFromHashtag) {
11680
+ fromKName = 'hashTagPage';
11681
+ }
11682
+ else if ((_a = rec === null || rec === void 0 ? void 0 : rec.video) === null || _a === void 0 ? void 0 : _a.url) {
11683
+ fromKName = 'videoPage';
11684
+ }
11685
+ else if ((_c = (_b = rec === null || rec === void 0 ? void 0 : rec.video) === null || _b === void 0 ? void 0 : _b.imgUrls) === null || _c === void 0 ? void 0 : _c.length) {
11686
+ fromKName = 'imagePage';
11687
+ }
11688
+ bffEventReport === null || bffEventReport === void 0 ? void 0 : bffEventReport({
11689
+ eventInfo: {
11690
+ relatedContentId: (_d = rec === null || rec === void 0 ? void 0 : rec.video) === null || _d === void 0 ? void 0 : _d.itemId,
11691
+ position: rec === null || rec === void 0 ? void 0 : rec.position,
11692
+ contentTags: JSON.stringify((_e = rec === null || rec === void 0 ? void 0 : rec.video) === null || _e === void 0 ? void 0 : _e.tags),
11693
+ traceInfo: JSON.stringify((_f = rec === null || rec === void 0 ? void 0 : rec.video) === null || _f === void 0 ? void 0 : _f.traceInfo),
11694
+ hashTags: JSON.stringify([recData === null || recData === void 0 ? void 0 : recData.hashTag]),
11695
+ fromKName,
11696
+ fromKPage: location === null || location === void 0 ? void 0 : location.href,
11697
+ timeOnSite: Math.floor((new Date() - viewTime) / 1000) + '',
11698
+ eventSubject: 'clickTagsViewContents',
11699
+ eventDescription: 'User click tags view contents'
10236
11700
  }
11701
+ });
11702
+ }, [recData, bffEventReport, viewTime, isFromHashtag]);
11703
+ React.useEffect(() => {
11704
+ if (openHashtag) {
11705
+ setViewTime(new Date());
11706
+ }
11707
+ }, [openHashtag]);
11708
+ React.useEffect(() => {
11709
+ const initTime = () => {
11710
+ setViewTime(new Date());
10237
11711
  };
10238
- window.addEventListener('beforeunload', handleBeforeUnload);
11712
+ window.addEventListener('pageshow', initTime);
10239
11713
  return () => {
10240
- window.removeEventListener('beforeunload', handleBeforeUnload);
11714
+ window.removeEventListener('pageshow', initTime);
10241
11715
  };
10242
- }, [activeIndex, index, rec, videoRef, handleClickVideo, isPauseVideo]);
10243
- if (!rec.video) {
11716
+ }, []);
11717
+ if (!modalEleRef.current)
10244
11718
  return null;
10245
- }
10246
- return (React.createElement("div", { className: 'video-container', key: rec.video.itemId, onClick: handleClickVideo(), style: {
10247
- position: 'relative',
10248
- width: '100%',
10249
- height
11719
+ return ReactDOM__namespace.createPortal(React.createElement("div", { className: 'waterfall', style: {
11720
+ display: openHashtag ? 'block' : 'none'
10250
11721
  } },
10251
- React.createElement("video", { id: `pb-video-${index}`, className: 'clc-pb-video', ref: videoRef, poster: sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image, muted: true, controls: false, playsInline: true, preload: 'auto', onPause: onPause, onEnded: handleVideoStart }),
10252
- renderPoster,
10253
- React.createElement("img", { hidden: !isPauseVideo, className: 'clc-pb-video-pause', src: PAUSE_ICON })));
11722
+ React.createElement(Navbar$1, { icon: img$1, styles: { top: '32px' }, textStyle: (_a = props === null || props === void 0 ? void 0 : props.textStyles) === null || _a === void 0 ? void 0 : _a.hashTagTitle, onClose: handleClose }),
11723
+ React.createElement(WaterfallList, Object.assign({ reportTagsView: reportTagsView }, props))), modalEleRef.current);
10254
11724
  };
10255
- var VideoWidget$1 = React.memo(VideoWidget);
11725
+ var WaterFall$1 = React.memo(WaterFall);
10256
11726
 
10257
11727
  /*
10258
11728
  * @Author: binruan@chatlabs.com
10259
- * @Date: 2023-12-27 19:02:59
11729
+ * @Date: 2024-01-15 19:03:09
10260
11730
  * @LastEditors: binruan@chatlabs.com
10261
- * @LastEditTime: 2024-01-24 10:30:13
10262
- * @FilePath: \pb-sxp-ui\src\core\components\SxpPageRender\ToggleButton\index.tsx
11731
+ * @LastEditTime: 2024-04-07 15:42:10
11732
+ * @FilePath: \pb-sxp-ui\src\materials\sxp\HashTag\index.tsx
10263
11733
  *
10264
11734
  */
10265
- const ToggleButton = ({ defaultValue, activeIcon, unactiveIcon, onChange, style }) => {
10266
- const [isTrue, setIsTure] = React.useState(defaultValue);
10267
- const handleClick = (e) => {
10268
- e.stopPropagation();
10269
- const result = !isTrue;
10270
- setIsTure(result);
10271
- onChange === null || onChange === void 0 ? void 0 : onChange(result);
10272
- };
10273
- return (React.createElement("button", { style: style, className: 'pb-toggle-button', onClick: handleClick },
10274
- React.createElement("img", { className: 'pb-toggle-button-icon', src: isTrue ? activeIcon : unactiveIcon })));
11735
+ const HashTag$1 = (props) => {
11736
+ return React.createElement(WaterFall$1, Object.assign({}, props));
10275
11737
  };
10276
- var ToggleButton$1 = React.memo(ToggleButton);
11738
+ var HashTagComponent = React.memo(HashTag$1);
10277
11739
 
10278
11740
  /*
10279
11741
  * @Author: binruan@chatlabs.com
10280
- * @Date: 2024-01-15 19:03:09
11742
+ * @Date: 2023-07-28 18:29:57
10281
11743
  * @LastEditors: binruan@chatlabs.com
10282
- * @LastEditTime: 2024-03-13 10:53:56
10283
- * @FilePath: \pb-sxp-ui\src\core\components\SxpPageRender\FingerSwipeTip\index.tsx
11744
+ * @LastEditTime: 2024-04-07 16:22:28
11745
+ * @FilePath: \pb-sxp-ui\src\materials\sxp\HashTag\material.tsx
10284
11746
  *
10285
11747
  */
10286
- const FingerSwipeTip = ({ imageUrl }) => {
10287
- const [show, setShow] = React.useState(true);
10288
- useEditor();
10289
- React.useEffect(() => {
10290
- setTimeout(() => {
10291
- setShow(false);
10292
- }, 2000);
10293
- }, []);
10294
- const FINGER_SWIPE_ICON = useIconLink('/pb_static/finger-swipe-tip.29dc3a48a3c746c906ea..png');
10295
- const animationCls = React.useMemo(() => {
10296
- return show ? 'pb-fadeIn' : 'pb-fadeOut';
10297
- }, [show]);
10298
- return (React.createElement("div", { hidden: !show, className: `pb-finger-wrap ${animationCls}` },
10299
- React.createElement("img", { src: imageUrl || FINGER_SWIPE_ICON })));
10300
- };
10301
-
10302
- const Picture = (props) => {
10303
- const { src, height, width } = props;
10304
- const imgDom = React.useRef(null);
10305
- const { sxpParameter } = useSxpDataSource();
10306
- return (React.createElement("div", { style: {
10307
- overflow: 'hidden',
10308
- height,
10309
- width: '100%',
10310
- position: 'relative'
10311
- } },
10312
- React.createElement("img", { ref: imgDom, loading: 'lazy', src: src !== null && src !== void 0 ? src : sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image, style: {
10313
- height: '100%',
10314
- width: '100%',
10315
- objectFit: 'cover'
10316
- } })));
10317
- };
10318
-
10319
- /*
10320
- * @Author: lewinlu@chatlabs.com
10321
- * @Date: 2024-01-03 14:39:09
10322
- * @LastEditors: binruan@chatlabs.com
10323
- * @LastEditTime: 2024-03-25 15:08:11
10324
- * @FilePath: \pb-sxp-ui\src\core\components\SxpPageRender\PictureGroup\index.tsx
10325
- */
10326
- const PictureGroup = ({ imgUrls, width, height, rec, index, onReportViewImageEnd, onViewImageStartEvent }) => {
10327
- const { isActive } = useSwiperSlide();
10328
- const { sxpParameter, openHashtag } = useSxpDataSource();
10329
- const [isLoad, setIsLoad] = React.useState(false);
10330
- React.useEffect(() => {
10331
- if (isLoad && isActive) {
10332
- if (openHashtag) {
10333
- onReportViewImageEnd(rec);
10334
- }
10335
- else {
10336
- onViewImageStartEvent(index);
11748
+ const HashTag = createMaterial(HashTagComponent, {
11749
+ displayName: '',
11750
+ icon: '',
11751
+ category: 'base',
11752
+ type: 'HashTag',
11753
+ related: {
11754
+ settingRender,
11755
+ bindableProps: []
11756
+ },
11757
+ defaulSetting: {
11758
+ props: {
11759
+ lineClamp: 1,
11760
+ space: 40,
11761
+ textStyles: {
11762
+ hashTagTitle: {
11763
+ fontSize: 16,
11764
+ color: '#000'
11765
+ },
11766
+ hashTagDesc: {
11767
+ fontSize: 12,
11768
+ textAlign: 'center',
11769
+ color: '#000'
11770
+ },
11771
+ title: {
11772
+ fontSize: 12,
11773
+ color: '#000'
11774
+ },
11775
+ price: {
11776
+ fontSize: 12,
11777
+ fontWeight: 'bold',
11778
+ color: '#000'
11779
+ }
11780
+ },
11781
+ buttonStyle: {
11782
+ backgroundColor: '#000',
11783
+ fontSize: 12,
11784
+ height: 52,
11785
+ fontWeight: 'bold',
11786
+ textAlign: 'center',
11787
+ color: '#fff',
11788
+ borderRadius: 25
10337
11789
  }
10338
11790
  }
10339
- else {
10340
- setIsLoad(true);
10341
- }
10342
- }, [rec, isActive, onReportViewImageEnd, openHashtag, index, onViewImageStartEvent, isLoad]);
10343
- if (!isActive) {
10344
- return React.createElement("img", { src: sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image, style: { width, height, objectFit: 'cover' } });
10345
- }
10346
- return (React.createElement(Swiper, { defaultValue: 0, direction: 'horizontal', modules: [Pagination, Autoplay], pagination: { clickable: true, bulletActiveClass: 'swipe-item-active-bullet' }, height: height, loop: true, autoplay: { delay: 3000 } }, imgUrls === null || imgUrls === void 0 ? void 0 : imgUrls.map((url) => {
10347
- return (React.createElement(SwiperSlide, { key: url },
10348
- React.createElement(Picture, { src: url, width: width, height: height })));
10349
- })));
10350
- };
10351
- var PictureGroup$1 = React.memo(PictureGroup);
11791
+ },
11792
+ w: 100,
11793
+ h: 40,
11794
+ sort: 2
11795
+ });
10352
11796
 
10353
11797
  /*
10354
11798
  * @Author: binruan@chatlabs.com
10355
- * @Date: 2024-01-15 19:03:09
11799
+ * @Date: 2023-07-25 14:56:49
10356
11800
  * @LastEditors: binruan@chatlabs.com
10357
- * @LastEditTime: 2024-03-25 10:42:07
10358
- * @FilePath: \pb-sxp-ui\src\core\components\SxpPageRender\Hashtag\index.tsx
11801
+ * @LastEditTime: 2024-03-20 13:46:06
11802
+ * @FilePath: \pb-sxp-ui\src\materials\index.ts
10359
11803
  *
10360
11804
  */
10361
- const Hashtag = ({ tags, itemId, itemType, index, rec }) => {
10362
- const [isShowMore, setIsShowMore] = React.useState(false);
10363
- const { setWaterFallData, setOpenHashtag, setCacheActiveIndex, waterFallData, setIsFromHashtag } = useSxpDataSource();
10364
- const handleClickTag = (data) => {
10365
- if (!waterFallData) {
10366
- setCacheActiveIndex === null || setCacheActiveIndex === void 0 ? void 0 : setCacheActiveIndex(index);
10367
- }
10368
- else {
10369
- setIsFromHashtag === null || setIsFromHashtag === void 0 ? void 0 : setIsFromHashtag(true);
10370
- }
10371
- if (itemType) {
10372
- setWaterFallData === null || setWaterFallData === void 0 ? void 0 : setWaterFallData({
10373
- hashTag: data,
10374
- itemId,
10375
- itemType,
10376
- rec
11805
+
11806
+ var _materials_ = /*#__PURE__*/Object.freeze({
11807
+ __proto__: null,
11808
+ Appoint: Appoint,
11809
+ AppointForm: AppointForm,
11810
+ Commodity: Commodity,
11811
+ CommodityDetail: CommodityDetail,
11812
+ CommodityDetailDiroNew: CommodityDetailDiroNew,
11813
+ CommodityDiro: CommodityDiro,
11814
+ CommodityDiroNew: CommodityDiroNew,
11815
+ HashTag: HashTag,
11816
+ Link: Link,
11817
+ MultiCommodity: MultiCommodity,
11818
+ MultiCommodityDiro: MultiCommodityDiro,
11819
+ MultiCommodityDiroNew: MultiCommodityDiroNew,
11820
+ Prompt: Prompt
11821
+ });
11822
+
11823
+ const defaultUnLikeIconPath = '/pb_static/f71266d2c64446c5ae6a5a7f5489cc0a.png';
11824
+ const defaultLikeIconPath = '/pb_static/f07900fe3f0f4ae188ea1611d4801a44.png';
11825
+ const LikeButton = (_a) => {
11826
+ var { active, activeIcon, unActicveIcon, recData } = _a, props = __rest(_a, ["active", "activeIcon", "unActicveIcon", "recData"]);
11827
+ const { mutateLike, mutateUnlike, bffEventReport } = useSxpDataSource();
11828
+ const [state, setState] = React.useState(active);
11829
+ const likeIcon = useIconLink(defaultLikeIconPath);
11830
+ const unlikeIcon = useIconLink(defaultUnLikeIconPath);
11831
+ const handleClick = lodash.debounce(() => __awaiter(void 0, void 0, void 0, function* () {
11832
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
11833
+ if (state) {
11834
+ // 先设置状态
11835
+ setState(false);
11836
+ const result = (_d = (yield (mutateUnlike === null || mutateUnlike === void 0 ? void 0 : mutateUnlike({ videoItemId: (_c = (_b = recData.video) === null || _b === void 0 ? void 0 : _b.itemId) !== null && _c !== void 0 ? _c : '' })))) !== null && _d !== void 0 ? _d : false;
11837
+ bffEventReport === null || bffEventReport === void 0 ? void 0 : bffEventReport({
11838
+ eventInfo: {
11839
+ eventSubject: 'favoriteContentCanceled',
11840
+ eventDescription: 'This content was unfavorite by the user',
11841
+ contentId: (_f = (_e = recData.video) === null || _e === void 0 ? void 0 : _e.itemId) !== null && _f !== void 0 ? _f : '',
11842
+ contentName: (_h = (_g = recData.video) === null || _g === void 0 ? void 0 : _g.title) !== null && _h !== void 0 ? _h : '',
11843
+ contentTags: JSON.stringify((_k = (_j = recData.video) === null || _j === void 0 ? void 0 : _j.tags) !== null && _k !== void 0 ? _k : []),
11844
+ position: recData.position,
11845
+ contentFormat: ((_l = recData.video) === null || _l === void 0 ? void 0 : _l.url) ? 'video' : 'image',
11846
+ traceInfo: (_m = recData.video) === null || _m === void 0 ? void 0 : _m.traceInfo
11847
+ }
10377
11848
  });
11849
+ // 如果接口调用失败,则回滚状态
11850
+ if (!result) {
11851
+ setState(true);
11852
+ }
10378
11853
  }
10379
11854
  else {
10380
- setWaterFallData === null || setWaterFallData === void 0 ? void 0 : setWaterFallData({
10381
- hashTag: data,
10382
- rec
11855
+ setState(true);
11856
+ const result = (_o = (yield (mutateLike === null || mutateLike === void 0 ? void 0 : mutateLike({ content: JSON.stringify(recData) })))) !== null && _o !== void 0 ? _o : false;
11857
+ bffEventReport === null || bffEventReport === void 0 ? void 0 : bffEventReport({
11858
+ eventInfo: {
11859
+ eventSubject: 'favoriteContent',
11860
+ eventDescription: 'This content was favorite by the user',
11861
+ contentId: (_q = (_p = recData.video) === null || _p === void 0 ? void 0 : _p.itemId) !== null && _q !== void 0 ? _q : '',
11862
+ contentName: (_s = (_r = recData.video) === null || _r === void 0 ? void 0 : _r.title) !== null && _s !== void 0 ? _s : '',
11863
+ contentTags: JSON.stringify((_u = (_t = recData.video) === null || _t === void 0 ? void 0 : _t.tags) !== null && _u !== void 0 ? _u : []),
11864
+ position: recData.position,
11865
+ contentFormat: ((_v = recData.video) === null || _v === void 0 ? void 0 : _v.url) ? 'video' : 'image',
11866
+ traceInfo: (_w = recData.video) === null || _w === void 0 ? void 0 : _w.traceInfo
11867
+ }
10383
11868
  });
11869
+ if (!result) {
11870
+ setState(false);
11871
+ }
10384
11872
  }
10385
- setOpenHashtag === null || setOpenHashtag === void 0 ? void 0 : setOpenHashtag(true);
10386
- };
10387
- React.useMemo(() => {
10388
- if (tags.length <= 6) {
10389
- return null;
10390
- }
10391
- return (React.createElement("span", { style: { textDecoration: 'underline', cursor: 'pointer', color: '#fff' }, onClick: () => setIsShowMore(!isShowMore) }, isShowMore ? 'show less' : 'show more'));
10392
- }, [isShowMore, tags]);
10393
- return (React.createElement("div", { className: 'clc-sxp-bottom-hashtag' },
10394
- React.createElement(Scroll$1, null, tags === null || tags === void 0 ? void 0 : tags.map((item, index) => (React.createElement(SwiperSlide, { key: index, hidden: !isShowMore ? index >= 6 : false, className: 'clc-sxp-bottom-hashtag-item', onClick: () => handleClickTag(item) }, `#${item}`))))));
10395
- };
10396
- var Hashtag$1 = React.memo(Hashtag);
10397
-
10398
- /*
10399
- * @Author: binruan@chatlabs.com
10400
- * @Date: 2023-12-26 16:11:34
10401
- * @LastEditors: binruan@chatlabs.com
10402
- * @LastEditTime: 2024-03-04 17:35:19
10403
- * @FilePath: \pb-sxp-ui\src\core\components\SxpPageRender\Navbar.tsx
10404
- *
10405
- */
10406
- const Navbar = ({ icon, styles, onClose }) => {
10407
- const { waterFallData, setOpenHashtag } = useSxpDataSource();
10408
- return (React.createElement("div", { className: 'clc-sxp-nav', style: styles },
10409
- React.createElement("img", { className: 'clc-sxp-nav-left', src: icon, alt: '', onClick: onClose }),
10410
- React.createElement("div", { className: 'clc-sxp-nav-title' }, `#${waterFallData === null || waterFallData === void 0 ? void 0 : waterFallData.hashTag}`)));
11873
+ }), 200);
11874
+ return (React.createElement("button", Object.assign({}, props, { onClick: handleClick }),
11875
+ React.createElement("img", { style: { width: '100%', height: '100%', objectFit: 'contain' }, src: state ? activeIcon || likeIcon : unActicveIcon || unlikeIcon, alt: 'icon' })));
10411
11876
  };
10412
- var Navbar$1 = React.memo(Navbar);
10413
-
10414
- var img$1 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAbtJREFUeF7t2DFKxFAQxvHv6xTxCoKNiAuCna2X2NY7eAE9hYdwj2BjZ2ulYLW9pQcYDWyxBIK7ZN7MNyapk/D+v8zC20dM/OLE+zEDzBMwcYH5J1BpAMzsAMAJyU+vdZeZADN7AHAH4BjAC8kbD4QSAJv4+17wFcm3sQjyAGbWhXdff/takzwdG989Lw0wEN+te0ly9a8BIuJlJyAqXhIgMl4OIDpeCiAjXgYgK14CIDM+HSA7PhVgYHvrusnZZaOUshNUiU+ZAKX4cAC1+FAAxfgwANX4EADl+OYA6vFNASrENwOoEt8EoFK8O0C1eFcAMzsE8AXgqLcHdzvA3GVvv+89bv8FzOwcwEdvASuSy30XFXm/G0C3aDN7BXBdCcEb4ALAE4BFFQRXgM0UlEJwB6iG0ASgEkIzgCoITQEqIDQHUEcIAVBGCANQRQgFUEQIB1BDSAFQQkgDUEFIBVBASAfIRpAAyESQAchCkALIQJADiEaQBIhEkAWIQpAG+ANh8Xvk/j72CF0eYABhDeCS5PckALYQbgGcAXgm+Tg2vnu+xAR4hA69YwZoqVvh3fMEVPhKLdc4+Qn4AXwYBFBN2dYpAAAAAElFTkSuQmCC";
11877
+ var LikeButton$1 = React.memo(LikeButton);
10415
11878
 
10416
- function withBindDataSource(Component) {
10417
- // 处理函数事件中的数据源
10418
- return React.memo(function (props) {
10419
- const { $store } = useDataSource();
10420
- const handleDataSourceByEvent = (value) => {
10421
- let res = value;
10422
- const dataArr = value.match(/{{.*?}}/g);
10423
- if (dataArr === null || dataArr === void 0 ? void 0 : dataArr.length) {
10424
- dataArr.forEach((item) => {
10425
- item.replace(/{{\s*([\w.]+)\s*}}/g, (match, p) => {
10426
- if (p) {
10427
- const v = lodash.get($store, p);
10428
- res = res.replace(item, v);
10429
- return v;
10430
- }
10431
- });
10432
- });
10433
- }
10434
- return res;
10435
- };
10436
- const clonedProps = React.useMemo(() => {
10437
- var _a, _b, _c;
10438
- const { bindDatas } = props, cloneProps = __rest(props, ["bindDatas"]);
10439
- (_a = bindDatas === null || bindDatas === void 0 ? void 0 : bindDatas.forEach) === null || _a === void 0 ? void 0 : _a.call(bindDatas, (d) => {
10440
- if ((d === null || d === void 0 ? void 0 : d.propKey) && (d === null || d === void 0 ? void 0 : d.dataPath)) {
10441
- const { propKey, dataPath } = d;
10442
- dataPath.replace(/{{\s*([\w.]+)\s*}}/g, (match, p) => {
10443
- var _a, _b;
10444
- if (p) {
10445
- const v = (_b = (_a = lodash.get($store, p)) !== null && _a !== void 0 ? _a : props[propKey]) !== null && _b !== void 0 ? _b : '';
10446
- cloneProps[propKey] = v;
10447
- return v;
10448
- }
10449
- });
10450
- }
10451
- });
10452
- if (cloneProps) {
10453
- cloneProps.eventMap = {};
10454
- const eventObj = lodash.cloneDeep(cloneProps.event) || {};
10455
- for (const key in eventObj) {
10456
- if (Object.prototype.hasOwnProperty.call(eventObj, key)) {
10457
- try {
10458
- eventObj[key].value = handleDataSourceByEvent(eventObj[key].value);
10459
- cloneProps.eventMap[key] = new Function(eventObj[key].value);
10460
- }
10461
- catch (error) { }
10462
- }
10463
- }
10464
- }
10465
- if ((_c = (_b = cloneProps === null || cloneProps === void 0 ? void 0 : cloneProps.event) === null || _b === void 0 ? void 0 : _b.onClick) === null || _c === void 0 ? void 0 : _c.linkType) {
10466
- cloneProps.style.cursor = 'pointer';
10467
- }
10468
- return cloneProps;
10469
- }, [$store, props]);
10470
- return React.createElement(Component, Object.assign({}, clonedProps, clonedProps.eventMap));
10471
- });
10472
- }
11879
+ const SXP_EVENT_BUS = new EventEmitter();
11880
+ var SXP_EVENT_TYPE;
11881
+ (function (SXP_EVENT_TYPE) {
11882
+ SXP_EVENT_TYPE["PAGE_DID_SHOW"] = "pageDidShow";
11883
+ SXP_EVENT_TYPE["PAGE_DID_HIDE"] = "pageDidHide";
11884
+ })(SXP_EVENT_TYPE || (SXP_EVENT_TYPE = {}));
10473
11885
 
10474
- /*
10475
- * @Author: binruan@chatlabs.com
10476
- * @Date: 2023-12-26 16:11:34
10477
- * @LastEditors: binruan@chatlabs.com
10478
- * @LastEditTime: 2024-03-04 14:25:27
10479
- * @FilePath: \pb-sxp-ui\src\core\components\SxpPageRender\RenderCard.tsx
10480
- *
10481
- */
10482
- const RenderCard = ({ rec, index, tempMap, resolver }) => {
10483
- const { schema } = useEditor();
10484
- const renderComp = React.useMemo(() => {
10485
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2;
10486
- if (!(rec === null || rec === void 0 ? void 0 : rec.video))
10487
- return null;
10488
- let cta = null;
10489
- if ((_b = (_a = rec === null || rec === void 0 ? void 0 : rec.video) === null || _a === void 0 ? void 0 : _a.bindProducts) === null || _b === void 0 ? void 0 : _b.length) {
10490
- cta = '多商品CTA';
10491
- }
10492
- else if ((_c = rec === null || rec === void 0 ? void 0 : rec.video) === null || _c === void 0 ? void 0 : _c.bindProduct) {
10493
- cta = '商品CTA';
10494
- }
10495
- else {
10496
- cta = (_e = (_d = rec === null || rec === void 0 ? void 0 : rec.video) === null || _d === void 0 ? void 0 : _d.bindCta) === null || _e === void 0 ? void 0 : _e.itemId;
10497
- }
10498
- const value = tempMap === null || tempMap === void 0 ? void 0 : tempMap[cta];
10499
- if ((((_f = value === null || value === void 0 ? void 0 : value.item) === null || _f === void 0 ? void 0 : _f.type) === 'CommodityDiro' && !((_g = rec === null || rec === void 0 ? void 0 : rec.video) === null || _g === void 0 ? void 0 : _g.bindProduct)) ||
10500
- (((_h = value === null || value === void 0 ? void 0 : value.item) === null || _h === void 0 ? void 0 : _h.type) === 'Commodity' && !((_j = rec === null || rec === void 0 ? void 0 : rec.video) === null || _j === void 0 ? void 0 : _j.bindProduct)) ||
10501
- (((_k = value === null || value === void 0 ? void 0 : value.item) === null || _k === void 0 ? void 0 : _k.type) === 'CommodityDiroNew' && !((_l = rec === null || rec === void 0 ? void 0 : rec.video) === null || _l === void 0 ? void 0 : _l.bindProduct)) ||
10502
- (((_m = value === null || value === void 0 ? void 0 : value.item) === null || _m === void 0 ? void 0 : _m.type) === 'MultiCommodity' && !((_p = (_o = rec === null || rec === void 0 ? void 0 : rec.video) === null || _o === void 0 ? void 0 : _o.bindProducts) === null || _p === void 0 ? void 0 : _p.length)) ||
10503
- (((_q = value === null || value === void 0 ? void 0 : value.item) === null || _q === void 0 ? void 0 : _q.type) === 'MultiCommodityDiro' && !((_s = (_r = rec === null || rec === void 0 ? void 0 : rec.video) === null || _r === void 0 ? void 0 : _r.bindProducts) === null || _s === void 0 ? void 0 : _s.length)) ||
10504
- (((_t = value === null || value === void 0 ? void 0 : value.item) === null || _t === void 0 ? void 0 : _t.type) === 'MultiCommodityDiroNew' && !((_v = (_u = rec === null || rec === void 0 ? void 0 : rec.video) === null || _u === void 0 ? void 0 : _u.bindProducts) === null || _v === void 0 ? void 0 : _v.length))) {
10505
- return null;
11886
+ const VideoWidget = ({ rec, index, height, data, muted, activeIndex }) => {
11887
+ const [isPauseVideo, setIsPauseVideo] = React.useState(false);
11888
+ const videoRef = React.useRef(null);
11889
+ const { bffEventReport, sxpParameter, waterFallData, openHashtag } = useSxpDataSource();
11890
+ const videoStartTime = React.useRef(0);
11891
+ const [isLoad, setIsLoad] = React.useState(false);
11892
+ const { isActive } = useSwiperSlide();
11893
+ React.useEffect(() => {
11894
+ if (!videoRef.current)
11895
+ return;
11896
+ videoRef.current.muted = muted;
11897
+ }, [muted]);
11898
+ const handleVideoStart = React.useCallback(() => {
11899
+ var _a;
11900
+ (_a = videoRef.current) === null || _a === void 0 ? void 0 : _a.play();
11901
+ }, []);
11902
+ const PAUSE_ICON = useIconLink('/pb_static/06f28a2025c74c1cb49be6767316d827.png');
11903
+ const handlePlaying = React.useCallback(() => {
11904
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
11905
+ setIsPauseVideo(false);
11906
+ const item = data[index];
11907
+ if (item && isLoad && ((_a = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _a === void 0 ? void 0 : _a.duration)) {
11908
+ videoStartTime.current = ((_b = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _b === void 0 ? void 0 : _b.currentTime) || 0;
11909
+ const videoDuration = ((_d = (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.duration) !== null && _d !== void 0 ? _d : 0).toFixed(2);
11910
+ const videoCurrentTime = ((_f = (_e = videoRef.current) === null || _e === void 0 ? void 0 : _e.currentTime) !== null && _f !== void 0 ? _f : 0).toFixed(2);
11911
+ const playType = '1';
11912
+ bffEventReport === null || bffEventReport === void 0 ? void 0 : bffEventReport({
11913
+ eventInfo: {
11914
+ eventSubject: 'playVideo',
11915
+ eventDescription: 'User played the video',
11916
+ contentId: (_h = (_g = item.video) === null || _g === void 0 ? void 0 : _g.itemId) !== null && _h !== void 0 ? _h : '',
11917
+ contentName: (_k = (_j = item.video) === null || _j === void 0 ? void 0 : _j.title) !== null && _k !== void 0 ? _k : '',
11918
+ playType,
11919
+ startTime: videoCurrentTime,
11920
+ videoDuration,
11921
+ contentTags: JSON.stringify((_m = (_l = item.video) === null || _l === void 0 ? void 0 : _l.tags) !== null && _m !== void 0 ? _m : []),
11922
+ position: item.position,
11923
+ contentFormat: 'video',
11924
+ traceInfo: (_o = item.video) === null || _o === void 0 ? void 0 : _o.traceInfo
11925
+ }
11926
+ });
10506
11927
  }
10507
- if (value && resolver) {
10508
- const Component = withBindDataSource(resolver[(_w = value === null || value === void 0 ? void 0 : value.item) === null || _w === void 0 ? void 0 : _w.type]);
10509
- return (React.createElement(Component, Object.assign({ style: Object.assign(Object.assign({}, (_x = value === null || value === void 0 ? void 0 : value.item) === null || _x === void 0 ? void 0 : _x.style), { zIndex: 50, marginLeft: '20px' }), textStyle: (_y = value === null || value === void 0 ? void 0 : value.item) === null || _y === void 0 ? void 0 : _y.textStyle, bindDatas: (_0 = (_z = value === null || value === void 0 ? void 0 : value.item) === null || _z === void 0 ? void 0 : _z.bindDatas) !== null && _0 !== void 0 ? _0 : [] }, (_1 = value === null || value === void 0 ? void 0 : value.item) === null || _1 === void 0 ? void 0 : _1.props, { event: ((_2 = value === null || value === void 0 ? void 0 : value.item) === null || _2 === void 0 ? void 0 : _2.event) || {}, schema: schema, id: value === null || value === void 0 ? void 0 : value.id, key: value === null || value === void 0 ? void 0 : value.id, recData: rec })));
11928
+ if (!isLoad) {
11929
+ setIsLoad(true);
10510
11930
  }
10511
- else {
10512
- return null;
11931
+ }, [bffEventReport, data, index, isLoad]);
11932
+ const handleLoadedMetadata = React.useCallback(() => {
11933
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
11934
+ const item = data[index];
11935
+ if (item && !isLoad && ((_a = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _a === void 0 ? void 0 : _a.duration)) {
11936
+ videoStartTime.current = ((_b = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _b === void 0 ? void 0 : _b.currentTime) || 0;
11937
+ const videoDuration = ((_d = (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.duration) !== null && _d !== void 0 ? _d : 0).toFixed(2);
11938
+ const videoCurrentTime = ((_f = (_e = videoRef.current) === null || _e === void 0 ? void 0 : _e.currentTime) !== null && _f !== void 0 ? _f : 0).toFixed(2);
11939
+ const playType = '0';
11940
+ bffEventReport === null || bffEventReport === void 0 ? void 0 : bffEventReport({
11941
+ eventInfo: {
11942
+ eventSubject: 'playVideo',
11943
+ eventDescription: 'User played the video',
11944
+ contentId: (_h = (_g = item.video) === null || _g === void 0 ? void 0 : _g.itemId) !== null && _h !== void 0 ? _h : '',
11945
+ contentName: (_k = (_j = item.video) === null || _j === void 0 ? void 0 : _j.title) !== null && _k !== void 0 ? _k : '',
11946
+ playType,
11947
+ startTime: videoCurrentTime,
11948
+ videoDuration,
11949
+ contentTags: JSON.stringify((_m = (_l = item.video) === null || _l === void 0 ? void 0 : _l.tags) !== null && _m !== void 0 ? _m : []),
11950
+ position: item.position,
11951
+ contentFormat: 'video',
11952
+ traceInfo: (_o = item.video) === null || _o === void 0 ? void 0 : _o.traceInfo
11953
+ }
11954
+ });
10513
11955
  }
10514
- }, [rec, resolver, tempMap, schema]);
10515
- return React.createElement(React.Fragment, null, renderComp);
10516
- };
10517
- var RenderCard$1 = React.memo(RenderCard);
10518
-
10519
- const WaterfallFlowItem = (props) => {
10520
- const { rec, index, list, reportTagsView } = props;
10521
- const { swiperRef, setRtcList, setOpenHashtag, bffEventReport, sxpParameter } = useSxpDataSource();
10522
- const [showVideo, setShowVideo] = React.useState(false);
10523
- const imgDom = React.useRef(null);
10524
- const videoDom = React.useRef(null);
10525
- const canvasRef = React.useRef(null);
10526
- const [firstFrameSrc, setFirstFrameSrc] = React.useState('');
10527
- const src = React.useMemo(() => {
10528
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
10529
- if ((_a = rec === null || rec === void 0 ? void 0 : rec.video) === null || _a === void 0 ? void 0 : _a.cover) {
10530
- return (_b = rec === null || rec === void 0 ? void 0 : rec.video) === null || _b === void 0 ? void 0 : _b.cover;
11956
+ setTimeout(() => {
11957
+ var _a;
11958
+ (_a = videoRef.current) === null || _a === void 0 ? void 0 : _a.play();
11959
+ }, 0);
11960
+ }, [index, bffEventReport, data, isLoad]);
11961
+ const handleClickVideo = React.useCallback((type) => () => {
11962
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
11963
+ if (!isLoad)
11964
+ return;
11965
+ data[index];
11966
+ ((_b = (_a = videoRef.current) === null || _a === void 0 ? void 0 : _a.duration) !== null && _b !== void 0 ? _b : 0).toFixed(2);
11967
+ ((_d = (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.currentTime) !== null && _d !== void 0 ? _d : 0).toFixed(2);
11968
+ const isPause = (_e = videoRef.current) === null || _e === void 0 ? void 0 : _e.paused;
11969
+ switch (type) {
11970
+ case 'start':
11971
+ if (!isPause)
11972
+ return;
11973
+ (_f = videoRef.current) === null || _f === void 0 ? void 0 : _f.play();
11974
+ setIsPauseVideo(false);
11975
+ break;
11976
+ case 'pause':
11977
+ if (isPause)
11978
+ return;
11979
+ (_g = videoRef.current) === null || _g === void 0 ? void 0 : _g.pause();
11980
+ setIsPauseVideo(true);
11981
+ break;
11982
+ default:
11983
+ if (isPause) {
11984
+ (_h = videoRef.current) === null || _h === void 0 ? void 0 : _h.play();
11985
+ }
11986
+ else {
11987
+ (_j = videoRef.current) === null || _j === void 0 ? void 0 : _j.pause();
11988
+ }
11989
+ setIsPauseVideo(!isPause);
11990
+ break;
10531
11991
  }
10532
- else if ((_c = rec === null || rec === void 0 ? void 0 : rec.video) === null || _c === void 0 ? void 0 : _c.url) {
10533
- setShowVideo(true);
10534
- return (_d = rec === null || rec === void 0 ? void 0 : rec.video) === null || _d === void 0 ? void 0 : _d.url;
11992
+ }, [data, index, isLoad]);
11993
+ const onPause = React.useCallback(() => {
11994
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
11995
+ const item = data[index];
11996
+ const videoDuration = ((_b = (_a = videoRef.current) === null || _a === void 0 ? void 0 : _a.duration) !== null && _b !== void 0 ? _b : 0).toFixed(2);
11997
+ const videoCurrentTime = ((_d = (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.currentTime) !== null && _d !== void 0 ? _d : 0).toFixed(2);
11998
+ if ((_e = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _e === void 0 ? void 0 : _e.duration) {
11999
+ const playDuration = (((_f = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _f === void 0 ? void 0 : _f.currentTime) - videoStartTime.current).toFixed(2);
12000
+ bffEventReport === null || bffEventReport === void 0 ? void 0 : bffEventReport({
12001
+ eventInfo: {
12002
+ eventSubject: 'playOverVideo',
12003
+ eventDescription: 'User finished playing the video',
12004
+ contentId: (_h = (_g = item.video) === null || _g === void 0 ? void 0 : _g.itemId) !== null && _h !== void 0 ? _h : '',
12005
+ contentName: (_k = (_j = item.video) === null || _j === void 0 ? void 0 : _j.title) !== null && _k !== void 0 ? _k : '',
12006
+ endTime: videoCurrentTime,
12007
+ videoDuration,
12008
+ playDuration,
12009
+ contentTags: JSON.stringify((_m = (_l = item.video) === null || _l === void 0 ? void 0 : _l.tags) !== null && _m !== void 0 ? _m : []),
12010
+ position: item.position,
12011
+ contentFormat: 'video',
12012
+ traceInfo: (_o = item.video) === null || _o === void 0 ? void 0 : _o.traceInfo
12013
+ }
12014
+ });
10535
12015
  }
10536
- else if ((_f = (_e = rec === null || rec === void 0 ? void 0 : rec.video) === null || _e === void 0 ? void 0 : _e.imgUrls) === null || _f === void 0 ? void 0 : _f.length) {
10537
- return (_h = (_g = rec === null || rec === void 0 ? void 0 : rec.video) === null || _g === void 0 ? void 0 : _g.imgUrls) === null || _h === void 0 ? void 0 : _h[0];
12016
+ }, [data, index, bffEventReport]);
12017
+ React.useEffect(() => {
12018
+ var _a, _b, _c;
12019
+ if (data.length <= 0)
12020
+ return;
12021
+ if (!videoRef.current)
12022
+ return;
12023
+ setIsPauseVideo(false);
12024
+ if (!isActive) {
12025
+ (_a = videoRef.current) === null || _a === void 0 ? void 0 : _a.pause();
12026
+ return;
10538
12027
  }
10539
- else if ((_k = (_j = rec === null || rec === void 0 ? void 0 : rec.product) === null || _j === void 0 ? void 0 : _j.homePage) === null || _k === void 0 ? void 0 : _k.length) {
10540
- return (_m = (_l = rec === null || rec === void 0 ? void 0 : rec.product) === null || _l === void 0 ? void 0 : _l.homePage) === null || _m === void 0 ? void 0 : _m[0];
12028
+ if (!videoRef.current.src) {
12029
+ const videoSrc = rec.video.url;
12030
+ // if (videoSrc.includes('.m3u8')) {
12031
+ // if (Hls.isSupported()) {
12032
+ // const hls = new Hls();
12033
+ // hls.loadSource(videoSrc);
12034
+ // hls.attachMedia(videoRef.current);
12035
+ // } else if (videoRef.current.canPlayType('application/vnd.apple.mpegurl')) {
12036
+ // videoRef.current.src = videoSrc;
12037
+ // } else {
12038
+ // videoRef.current.src = videoSrc;
12039
+ // }
12040
+ // } else {
12041
+ // videoRef.current.src = videoSrc;
12042
+ // }
12043
+ videoRef.current.src = videoSrc;
12044
+ videoRef.current.setAttribute('x5-playsinline', 'true');
12045
+ videoRef.current.setAttribute('webkit-playsinline', 'true');
10541
12046
  }
10542
12047
  else {
10543
- return (sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image) || '';
12048
+ videoRef.current.play();
10544
12049
  }
10545
- }, [rec, sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image]);
10546
- const title = React.useMemo(() => {
10547
- var _a, _b;
10548
- return ((_a = rec === null || rec === void 0 ? void 0 : rec.product) === null || _a === void 0 ? void 0 : _a.title) || ((_b = rec === null || rec === void 0 ? void 0 : rec.video) === null || _b === void 0 ? void 0 : _b.title) || null;
10549
- }, [rec]);
10550
- const priceText = React.useMemo(() => {
10551
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
10552
- if (((_a = rec === null || rec === void 0 ? void 0 : rec.product) === null || _a === void 0 ? void 0 : _a.currency) && ((_b = rec === null || rec === void 0 ? void 0 : rec.product) === null || _b === void 0 ? void 0 : _b.price)) {
10553
- return `${(_f = (_e = (_d = (_c = rec === null || rec === void 0 ? void 0 : rec.product) === null || _c === void 0 ? void 0 : _c.currency) === null || _d === void 0 ? void 0 : _d.split('-')[1]) === null || _e === void 0 ? void 0 : _e.toUpperCase()) !== null && _f !== void 0 ? _f : ''}${(_j = (_h = (_g = rec === null || rec === void 0 ? void 0 : rec.product) === null || _g === void 0 ? void 0 : _g.price) === null || _h === void 0 ? void 0 : _h.toLocaleString('zh', {
10554
- minimumFractionDigits: 0
10555
- })) !== null && _j !== void 0 ? _j : ''}`;
12050
+ (_b = videoRef.current) === null || _b === void 0 ? void 0 : _b.addEventListener('canplay', handleLoadedMetadata);
12051
+ (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.addEventListener('playing', handlePlaying);
12052
+ return () => {
12053
+ var _a, _b;
12054
+ (_a = videoRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('canplay', handleLoadedMetadata);
12055
+ (_b = videoRef.current) === null || _b === void 0 ? void 0 : _b.removeEventListener('playing', handlePlaying);
12056
+ };
12057
+ }, [data, handleLoadedMetadata, handlePlaying, isActive, isLoad, rec.video]);
12058
+ /*
12059
+ 打开/关闭hashtag暂停/播放视频
12060
+ */
12061
+ React.useEffect(() => {
12062
+ var _a, _b, _c;
12063
+ const isPause = (_a = videoRef.current) === null || _a === void 0 ? void 0 : _a.paused;
12064
+ if (!isActive)
12065
+ return;
12066
+ if (!isPause && openHashtag) {
12067
+ (_b = videoRef.current) === null || _b === void 0 ? void 0 : _b.pause();
10556
12068
  }
10557
- else {
12069
+ else if (!openHashtag) {
12070
+ (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.play();
12071
+ }
12072
+ }, [openHashtag, isActive]);
12073
+ React.useEffect(() => {
12074
+ if (!isActive)
12075
+ return;
12076
+ const onShow = handleClickVideo('start');
12077
+ const onHide = handleClickVideo('pause');
12078
+ SXP_EVENT_BUS.on(SXP_EVENT_TYPE.PAGE_DID_SHOW, onShow);
12079
+ SXP_EVENT_BUS.on(SXP_EVENT_TYPE.PAGE_DID_HIDE, onHide);
12080
+ return () => {
12081
+ SXP_EVENT_BUS.off(SXP_EVENT_TYPE.PAGE_DID_SHOW, onShow);
12082
+ SXP_EVENT_BUS.off(SXP_EVENT_TYPE.PAGE_DID_HIDE, onHide);
12083
+ };
12084
+ }, [handleClickVideo, isActive]);
12085
+ const renderPoster = React.useMemo(() => {
12086
+ if (!(sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image)) {
10558
12087
  return null;
10559
12088
  }
10560
- }, [rec]);
10561
- // useEffect(() => {
10562
- // if (imgDom.current === null || src === '') {
10563
- // return;
10564
- // }
10565
- // const img = new Image();
10566
- // if (showVideo && firstFrameSrc) {
10567
- // img.src = firstFrameSrc;
10568
- // } else {
10569
- // img.src = src;
10570
- // }
10571
- // // img.onload = () => {
10572
- // // setIsLoading(true);
10573
- // // };
10574
- // imgDom.current.src = img.src;
10575
- // }, [src, showVideo, firstFrameSrc]);
12089
+ return (React.createElement("img", { hidden: isLoad, style: { position: 'absolute', left: 0, top: 0, width: '100%', height: '100%', objectFit: 'cover' }, src: sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image }));
12090
+ }, [isLoad, sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image]);
10576
12091
  React.useEffect(() => {
10577
- const observer = new IntersectionObserver((entries) => {
10578
- entries.forEach((entry) => {
10579
- if (entry.isIntersecting) {
10580
- if (imgDom.current === null || src === '') {
10581
- return;
10582
- }
10583
- if (showVideo && firstFrameSrc) {
10584
- imgDom.current.src = firstFrameSrc;
10585
- }
10586
- else {
10587
- imgDom.current.src = src;
10588
- }
10589
- observer.unobserve(imgDom.current);
10590
- }
10591
- });
10592
- });
10593
- observer.observe(imgDom.current);
12092
+ const handleBeforeUnload = () => {
12093
+ var _a, _b;
12094
+ if (activeIndex === index && ((_a = rec === null || rec === void 0 ? void 0 : rec.video) === null || _a === void 0 ? void 0 : _a.url) && ((_b = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _b === void 0 ? void 0 : _b.src) && !isPauseVideo) {
12095
+ handleClickVideo('pause')();
12096
+ }
12097
+ };
12098
+ window.addEventListener('beforeunload', handleBeforeUnload);
10594
12099
  return () => {
10595
- observer.disconnect();
12100
+ window.removeEventListener('beforeunload', handleBeforeUnload);
10596
12101
  };
10597
- }, [src, showVideo, firstFrameSrc]);
10598
- const calculateHeightForWidth = (videoWidth, videoHeight, targetWidth) => {
10599
- const aspectRatio = videoWidth / videoHeight;
10600
- const targetHeight = targetWidth / aspectRatio;
10601
- return targetHeight;
12102
+ }, [activeIndex, index, rec, videoRef, handleClickVideo, isPauseVideo]);
12103
+ if (!rec.video) {
12104
+ return null;
12105
+ }
12106
+ return (React.createElement("div", { className: 'video-container', key: rec.video.itemId, onClick: handleClickVideo(), style: {
12107
+ position: 'relative',
12108
+ width: '100%',
12109
+ height
12110
+ } },
12111
+ React.createElement("video", { id: `pb-video-${index}`, className: 'clc-pb-video', ref: videoRef, poster: sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image, muted: true, controls: false, playsInline: true, preload: 'auto', onPause: onPause, onEnded: handleVideoStart }),
12112
+ renderPoster,
12113
+ React.createElement("img", { hidden: !isPauseVideo, className: 'clc-pb-video-pause', src: PAUSE_ICON })));
12114
+ };
12115
+ var VideoWidget$1 = React.memo(VideoWidget);
12116
+
12117
+ /*
12118
+ * @Author: binruan@chatlabs.com
12119
+ * @Date: 2023-12-27 19:02:59
12120
+ * @LastEditors: binruan@chatlabs.com
12121
+ * @LastEditTime: 2024-01-24 10:30:13
12122
+ * @FilePath: \pb-sxp-ui\src\core\components\SxpPageRender\ToggleButton\index.tsx
12123
+ *
12124
+ */
12125
+ const ToggleButton = ({ defaultValue, activeIcon, unactiveIcon, onChange, style }) => {
12126
+ const [isTrue, setIsTure] = React.useState(defaultValue);
12127
+ const handleClick = (e) => {
12128
+ e.stopPropagation();
12129
+ const result = !isTrue;
12130
+ setIsTure(result);
12131
+ onChange === null || onChange === void 0 ? void 0 : onChange(result);
10602
12132
  };
12133
+ return (React.createElement("button", { style: style, className: 'pb-toggle-button', onClick: handleClick },
12134
+ React.createElement("img", { className: 'pb-toggle-button-icon', src: isTrue ? activeIcon : unactiveIcon })));
12135
+ };
12136
+ var ToggleButton$1 = React.memo(ToggleButton);
12137
+
12138
+ /*
12139
+ * @Author: binruan@chatlabs.com
12140
+ * @Date: 2024-01-15 19:03:09
12141
+ * @LastEditors: binruan@chatlabs.com
12142
+ * @LastEditTime: 2024-03-13 10:53:56
12143
+ * @FilePath: \pb-sxp-ui\src\core\components\SxpPageRender\FingerSwipeTip\index.tsx
12144
+ *
12145
+ */
12146
+ const FingerSwipeTip = ({ imageUrl }) => {
12147
+ const [show, setShow] = React.useState(true);
12148
+ useEditor();
10603
12149
  React.useEffect(() => {
10604
- const video = videoDom === null || videoDom === void 0 ? void 0 : videoDom.current;
10605
- if (video === null || src === '' || !showVideo) {
10606
- return;
10607
- }
10608
- video.src = src;
10609
- video.currentTime = 1;
10610
- video.crossOrigin = 'anonymous';
10611
- video.onloadeddata = () => {
10612
- const canvas = canvasRef === null || canvasRef === void 0 ? void 0 : canvasRef.current;
10613
- if (!canvas)
10614
- return;
10615
- const ctx = canvas.getContext('2d');
10616
- const targetWidth = (window === null || window === void 0 ? void 0 : window.innerWidth) / 2;
10617
- const targetHeight = calculateHeightForWidth(video.videoWidth, video.videoHeight, targetWidth);
10618
- canvas.height = targetHeight;
10619
- canvas.width = targetWidth;
10620
- ctx === null || ctx === void 0 ? void 0 : ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
10621
- setFirstFrameSrc(canvas.toDataURL());
10622
- video.remove();
10623
- canvas.remove();
10624
- };
10625
- }, [src, showVideo]);
10626
- const handleClickToDetail = () => {
10627
- reportTagsView();
10628
- setRtcList === null || setRtcList === void 0 ? void 0 : setRtcList(list);
10629
12150
  setTimeout(() => {
10630
- var _a;
10631
- (_a = swiperRef === null || swiperRef === void 0 ? void 0 : swiperRef.current) === null || _a === void 0 ? void 0 : _a.swiper.slideTo(index, 0, false);
10632
- setOpenHashtag === null || setOpenHashtag === void 0 ? void 0 : setOpenHashtag(false);
10633
- }, 0);
10634
- };
10635
- return (React.createElement("div", { className: 'list-content-listItem', key: index, onClick: handleClickToDetail },
10636
- React.createElement("div", { className: 'list-content-listItem-picture' },
10637
- showVideo && (React.createElement("div", { style: { display: 'none' } },
10638
- React.createElement("video", { ref: videoDom, crossOrigin: 'anonymous', className: 'list-content-listItem-picture-img' }),
10639
- React.createElement("canvas", { ref: canvasRef }))),
10640
- React.createElement("img", { className: 'list-content-listItem-picture-img', loading: 'lazy', ref: imgDom })),
10641
- React.createElement("div", { className: 'list-content-listItem-info' },
10642
- React.createElement("div", { className: `${'list-content-listItem-info-title'} ${priceText ? 'list-content-listItem-info-nowrap' : ''}` }, title && title),
10643
- React.createElement("div", { className: 'list-content-listItem-info-price', hidden: !priceText }, priceText))));
12151
+ setShow(false);
12152
+ }, 2000);
12153
+ }, []);
12154
+ const FINGER_SWIPE_ICON = useIconLink('/pb_static/finger-swipe-tip.29dc3a48a3c746c906ea..png');
12155
+ const animationCls = React.useMemo(() => {
12156
+ return show ? 'pb-fadeIn' : 'pb-fadeOut';
12157
+ }, [show]);
12158
+ return (React.createElement("div", { hidden: !show, className: `pb-finger-wrap ${animationCls}` },
12159
+ React.createElement("img", { src: imageUrl || FINGER_SWIPE_ICON })));
10644
12160
  };
10645
- function WaterfallList({ reportTagsView }) {
10646
- var _a, _b, _c, _d, _e, _f;
10647
- const { waterFallData, getRecommendVideos, hashTagSize, loadingImage } = useSxpDataSource();
10648
- const [list, setList] = React.useState();
10649
- const [data, setData] = React.useState();
10650
- const [isLoadingData, setIsLoadingData] = React.useState(false);
10651
- const containerRef = React.useRef(null);
10652
- const [isLoadMore, setIsLoadMore] = React.useState(false);
10653
- React.useCallback(() => {
10654
- if (isLoadMore)
10655
- return;
10656
- setIsLoadMore(true);
10657
- waterFallData &&
10658
- (getRecommendVideos === null || getRecommendVideos === void 0 ? void 0 : getRecommendVideos({
10659
- hashTag: waterFallData === null || waterFallData === void 0 ? void 0 : waterFallData.hashTag,
10660
- 'itemFilter.itemId': waterFallData === null || waterFallData === void 0 ? void 0 : waterFallData.itemId,
10661
- 'itemFilter.itemType': waterFallData === null || waterFallData === void 0 ? void 0 : waterFallData.itemType
10662
- }).then((res) => {
10663
- var _a;
10664
- setList(list === null || list === void 0 ? void 0 : list.concat((_a = res === null || res === void 0 ? void 0 : res.recList) !== null && _a !== void 0 ? _a : []));
10665
- setIsLoadMore(false);
10666
- }));
10667
- }, [waterFallData, getRecommendVideos, list, isLoadMore]);
12161
+
12162
+ /*
12163
+ * @Author: binruan@chatlabs.com
12164
+ * @Date: 2024-03-20 10:27:31
12165
+ * @LastEditors: binruan@chatlabs.com
12166
+ * @LastEditTime: 2024-04-08 18:44:58
12167
+ * @FilePath: \pb-sxp-ui\src\core\components\SxpPageRender\PictureGroup\Picture.tsx
12168
+ *
12169
+ */
12170
+ const Picture = (props) => {
12171
+ const { src, height, width } = props;
12172
+ const [blur, setBlur] = React.useState(false);
12173
+ const imgDom = React.useRef(null);
12174
+ const { sxpParameter } = useSxpDataSource();
10668
12175
  React.useEffect(() => {
10669
- setIsLoadingData(true);
10670
- waterFallData &&
10671
- (getRecommendVideos === null || getRecommendVideos === void 0 ? void 0 : getRecommendVideos({
10672
- hashTag: waterFallData === null || waterFallData === void 0 ? void 0 : waterFallData.hashTag,
10673
- 'itemFilter.itemId': waterFallData === null || waterFallData === void 0 ? void 0 : waterFallData.itemId,
10674
- 'itemFilter.itemType': waterFallData === null || waterFallData === void 0 ? void 0 : waterFallData.itemType,
10675
- defaultSize: hashTagSize
10676
- }).then((res) => {
10677
- var _a, _b;
10678
- setData(res);
10679
- setList((_b = (_a = res === null || res === void 0 ? void 0 : res.recList) === null || _a === void 0 ? void 0 : _a.filter((item) => (item === null || item === void 0 ? void 0 : item.video) !== null || (item === null || item === void 0 ? void 0 : item.product) !== null)) !== null && _b !== void 0 ? _b : []);
10680
- setIsLoadingData(false);
10681
- }));
10682
- }, [waterFallData, getRecommendVideos, hashTagSize]);
10683
- // useEffect(() => {
10684
- // const container = containerRef?.current;
10685
- // if (!container) return;
10686
- // const handleScroll = () => {
10687
- // const top = (container as any)?.scrollTop;
10688
- // const clientHeight = (container as any)?.clientHeight;
10689
- // const scrollHeight = (container as any)?.scrollHeight;
10690
- // if (scrollHeight <= top + clientHeight && !isLoadingData) {
10691
- // loadMoreData();
10692
- // }
10693
- // };
10694
- // container?.addEventListener('scroll', handleScroll);
10695
- // return () => {
10696
- // container?.removeEventListener('scroll', handleScroll); // 在组件卸载时移除事件监听器
10697
- // };
10698
- // }, [isLoadingData, containerRef, loadMoreData]);
10699
- const handleClickLink = () => {
10700
- var _a, _b;
10701
- if ((_a = data === null || data === void 0 ? void 0 : data.tag) === null || _a === void 0 ? void 0 : _a.link) {
10702
- reportTagsView();
10703
- window.location.href = (_b = data === null || data === void 0 ? void 0 : data.tag) === null || _b === void 0 ? void 0 : _b.link;
12176
+ if (imgDom.current === null || src === '') {
12177
+ return;
10704
12178
  }
10705
- };
10706
- return (React.createElement(React.Fragment, null, isLoadingData ? (React.createElement("div", { style: { height: '100%', width: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center' } },
10707
- React.createElement("img", { width: 64, height: 64, src: loadingImage, alt: 'loading...', style: { objectFit: 'contain' } }))) : (React.createElement("div", { className: 'list' },
10708
- React.createElement("div", { className: 'list-scroll', ref: containerRef, style: {
10709
- bottom: ((_a = data === null || data === void 0 ? void 0 : data.tag) === null || _a === void 0 ? void 0 : _a.link) ? '100px' : 0
10710
- } },
10711
- React.createElement("div", { className: 'list-info' }, (_b = data === null || data === void 0 ? void 0 : data.tag) === null || _b === void 0 ? void 0 : _b.info),
10712
- React.createElement("div", { hidden: !((_c = data === null || data === void 0 ? void 0 : data.tag) === null || _c === void 0 ? void 0 : _c.link), className: 'list-collection', onClick: handleClickLink }, ((_d = data === null || data === void 0 ? void 0 : data.tag) === null || _d === void 0 ? void 0 : _d.linkTitle) || 'Shop the collection'),
10713
- React.createElement("div", { className: 'list-content' }, list === null || list === void 0 ? void 0 : list.map((item, ind) => {
10714
- return (React.createElement(WaterfallFlowItem, { key: ind, index: ind, rec: item, list: list, reportTagsView: reportTagsView }));
10715
- })),
10716
- React.createElement("div", { hidden: !isLoadMore, style: { textAlign: 'center' } }, "loading...")),
10717
- React.createElement("div", { className: 'list-bottom', hidden: !((_e = data === null || data === void 0 ? void 0 : data.tag) === null || _e === void 0 ? void 0 : _e.link) },
10718
- React.createElement("button", { className: 'list-bottom-btn', onClick: handleClickLink }, ((_f = data === null || data === void 0 ? void 0 : data.tag) === null || _f === void 0 ? void 0 : _f.linkTitle) || 'Shop the collection'))))));
10719
- }
12179
+ const img = new Image();
12180
+ img.src = src;
12181
+ img.onload = () => {
12182
+ const aspectRatio = img.height / img.width;
12183
+ const targetAspectRatio = 16 / 9;
12184
+ const tolerance = 0.05; // 允许的宽高比误差范围
12185
+ if (Math.abs(aspectRatio - targetAspectRatio) > tolerance) {
12186
+ setBlur(true);
12187
+ }
12188
+ };
12189
+ imgDom.current.src = src;
12190
+ }, [src]);
12191
+ return (React.createElement("div", { style: {
12192
+ overflow: 'hidden',
12193
+ height,
12194
+ width: '100%',
12195
+ position: 'relative'
12196
+ } },
12197
+ React.createElement("img", { ref: imgDom, loading: 'lazy', src: src !== null && src !== void 0 ? src : sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image, style: {
12198
+ height: '100%',
12199
+ width: '100%',
12200
+ objectFit: 'cover',
12201
+ filter: blur ? 'blur(10px)' : 'none',
12202
+ transform: blur ? 'scale(1.2)' : 'none'
12203
+ } }),
12204
+ blur && (React.createElement("img", { ref: imgDom, src: src, loading: 'lazy', style: {
12205
+ width: '100%',
12206
+ objectFit: 'contain',
12207
+ position: 'absolute',
12208
+ top: '50%',
12209
+ transform: 'translateY(-50%)',
12210
+ left: 0,
12211
+ right: 0
12212
+ } }))));
12213
+ };
10720
12214
 
10721
- var img = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAaZJREFUeF7t2jFKBEEQRuG3mSJeQTARURDMTL2EqXfwAnoKD6FHMDEzNVIw2tzQC2gFggyDrExX1V92T7wz9PumFnqbXdH5teq8nwEwJqBzgfEVKDYAW8Ae8NZq3ZUm4Aa4AnaBR+C8BUIVAIu/ngSfAs9LESoAWLgB/LzWwP7SeLtfHWAu3tZ9Adz/dwD3eOUJCIlXBQiLVwQIjVcDCI9XAkiJVwFIi1cASI3PBpjb3jbd5GyyUcraCUrEZ02ATHwGgFR8NIBcfCSAZHwUgGx8BIB0vDeAfLwnQIl4L4Ay8R4ApeJbA2wD78DOZA/e7ABzk739Xz/T8rfAIfA6WYCd3BqA7NUSwCKfgLNKCK0BjoC7rzP74yoIrQGsuxSCB0ApBC+AMgieACUQvAHkESIApBGiAGQRIgEkEaIB5BAyAKQQsgBkEDIBJBCyAdIRFABSEVQA0hCUAFIQ1ADCERQBQhFUAcIQlAFCENQBfkOwg9eXpeftFQDmEOzv8ifARy8A3wiXwAHwANwujbf7q0xAi9bZZwwAN9oiDx4TUORFuS2z+wn4BAiAaEHnKChjAAAAAElFTkSuQmCC";
12215
+ /*
12216
+ * @Author: lewinlu@chatlabs.com
12217
+ * @Date: 2024-01-03 14:39:09
12218
+ * @LastEditors: binruan@chatlabs.com
12219
+ * @LastEditTime: 2024-03-25 15:08:11
12220
+ * @FilePath: \pb-sxp-ui\src\core\components\SxpPageRender\PictureGroup\index.tsx
12221
+ */
12222
+ const PictureGroup = ({ imgUrls, width, height, rec, index, onReportViewImageEnd, onViewImageStartEvent }) => {
12223
+ const { isActive } = useSwiperSlide();
12224
+ const { sxpParameter, openHashtag } = useSxpDataSource();
12225
+ const [isLoad, setIsLoad] = React.useState(false);
12226
+ React.useEffect(() => {
12227
+ if (isLoad && isActive) {
12228
+ if (openHashtag) {
12229
+ onReportViewImageEnd(rec);
12230
+ }
12231
+ else {
12232
+ onViewImageStartEvent(index);
12233
+ }
12234
+ }
12235
+ else {
12236
+ setIsLoad(true);
12237
+ }
12238
+ }, [rec, isActive, onReportViewImageEnd, openHashtag, index, onViewImageStartEvent, isLoad]);
12239
+ if (!isActive) {
12240
+ return React.createElement("img", { src: sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image, style: { width, height, objectFit: 'cover' } });
12241
+ }
12242
+ return (React.createElement(Swiper, { defaultValue: 0, direction: 'horizontal', modules: [Pagination, Autoplay], pagination: { clickable: true, bulletActiveClass: 'swipe-item-active-bullet' }, height: height, loop: true, autoplay: { delay: 3000 } }, imgUrls === null || imgUrls === void 0 ? void 0 : imgUrls.map((url) => {
12243
+ return (React.createElement(SwiperSlide, { key: url },
12244
+ React.createElement(Picture, { src: url, width: width, height: height })));
12245
+ })));
12246
+ };
12247
+ var PictureGroup$1 = React.memo(PictureGroup);
10722
12248
 
10723
12249
  /*
10724
12250
  * @Author: binruan@chatlabs.com
10725
- * @Date: 2024-01-10 10:58:24
12251
+ * @Date: 2024-01-15 19:03:09
10726
12252
  * @LastEditors: binruan@chatlabs.com
10727
- * @LastEditTime: 2024-03-12 14:53:22
10728
- * @FilePath: \pb-sxp-ui\src\core\components\SxpPageRender\WaterFall\index.tsx
12253
+ * @LastEditTime: 2024-04-03 14:51:17
12254
+ * @FilePath: \pb-sxp-ui\src\core\components\SxpPageRender\Hashtag\index.tsx
10729
12255
  *
10730
12256
  */
10731
- const WaterFall = () => {
10732
- const { waterFallData, setOpenHashtag, openHashtag, swiperRef, setWaterFallData, cacheRtcList, setRtcList, cacheActiveIndex, rtcList, setCacheRtcList, setIsFromHashtag, isFromHashtag, bffEventReport } = useSxpDataSource();
10733
- React.useRef(null);
10734
- const modalEleRef = React.useRef(null);
10735
- const [viewTime, setViewTime] = React.useState();
10736
- React.useEffect(() => {
10737
- const parentNode = document.getElementById('sxp-render');
10738
- const node = document.getElementById('water-fall');
10739
- if (node) {
10740
- modalEleRef.current = node;
12257
+ const Hashtag = ({ tags, itemId, itemType, index, rec, hashTagStyle }) => {
12258
+ const [isShowMore, setIsShowMore] = React.useState(false);
12259
+ const { setWaterFallData, setOpenHashtag, setCacheActiveIndex, waterFallData, setIsFromHashtag } = useSxpDataSource();
12260
+ const handleClickTag = (data) => {
12261
+ if (!waterFallData) {
12262
+ setCacheActiveIndex === null || setCacheActiveIndex === void 0 ? void 0 : setCacheActiveIndex(index);
10741
12263
  }
10742
12264
  else {
10743
- modalEleRef.current = document.createElement('div');
10744
- modalEleRef.current.setAttribute('id', 'water-fall');
10745
- parentNode === null || parentNode === void 0 ? void 0 : parentNode.appendChild(modalEleRef.current);
12265
+ setIsFromHashtag === null || setIsFromHashtag === void 0 ? void 0 : setIsFromHashtag(true);
10746
12266
  }
10747
- }, []);
10748
- const handleClose = () => {
10749
- const isEq = lodash.isEqual(rtcList, cacheRtcList);
10750
- if (!isEq && cacheRtcList && (cacheRtcList === null || cacheRtcList === void 0 ? void 0 : cacheRtcList.length)) {
10751
- setRtcList === null || setRtcList === void 0 ? void 0 : setRtcList(cacheRtcList);
12267
+ if (itemType) {
12268
+ setWaterFallData === null || setWaterFallData === void 0 ? void 0 : setWaterFallData({
12269
+ hashTag: data,
12270
+ itemId,
12271
+ itemType,
12272
+ rec
12273
+ });
10752
12274
  }
10753
- reportTagsView();
10754
- setWaterFallData === null || setWaterFallData === void 0 ? void 0 : setWaterFallData(undefined);
10755
- setIsFromHashtag === null || setIsFromHashtag === void 0 ? void 0 : setIsFromHashtag(false);
10756
- setTimeout(() => {
10757
- var _a, _b;
10758
- if (!isEq) {
10759
- (_b = (_a = swiperRef === null || swiperRef === void 0 ? void 0 : swiperRef.current) === null || _a === void 0 ? void 0 : _a.swiper) === null || _b === void 0 ? void 0 : _b.slideTo(cacheActiveIndex, 0, false);
10760
- }
10761
- setOpenHashtag === null || setOpenHashtag === void 0 ? void 0 : setOpenHashtag(false);
10762
- }, 0);
12275
+ else {
12276
+ setWaterFallData === null || setWaterFallData === void 0 ? void 0 : setWaterFallData({
12277
+ hashTag: data,
12278
+ rec
12279
+ });
12280
+ }
12281
+ setOpenHashtag === null || setOpenHashtag === void 0 ? void 0 : setOpenHashtag(true);
10763
12282
  };
10764
- const [recData, setRecData] = React.useState();
10765
- React.useEffect(() => {
10766
- if (waterFallData) {
10767
- setRecData(waterFallData);
12283
+ React.useMemo(() => {
12284
+ if (tags.length <= 6) {
12285
+ return null;
10768
12286
  }
10769
- }, [waterFallData]);
10770
- const reportTagsView = React.useCallback(() => {
10771
- var _a, _b, _c, _d, _e, _f;
10772
- const rec = recData === null || recData === void 0 ? void 0 : recData.rec;
10773
- if (!rec)
10774
- return;
10775
- let fromKName = '';
10776
- if (isFromHashtag) {
10777
- fromKName = 'hashTagPage';
12287
+ return (React.createElement("span", { style: { textDecoration: 'underline', cursor: 'pointer', color: '#fff' }, onClick: () => setIsShowMore(!isShowMore) }, isShowMore ? 'show less' : 'show more'));
12288
+ }, [isShowMore, tags]);
12289
+ return (React.createElement("div", { className: 'clc-sxp-bottom-hashtag' },
12290
+ React.createElement(Scroll$1, null, tags === null || tags === void 0 ? void 0 : tags.map((item, index) => (React.createElement(SwiperSlide, { key: index, hidden: !isShowMore ? index >= 6 : false, className: 'clc-sxp-bottom-hashtag-item', style: hashTagStyle, onClick: () => handleClickTag(item) }, `#${item}`))))));
12291
+ };
12292
+ var Hashtag$1 = React.memo(Hashtag);
12293
+
12294
+ var img = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAbtJREFUeF7t2DFKxFAQxvHv6xTxCoKNiAuCna2X2NY7eAE9hYdwj2BjZ2ulYLW9pQcYDWyxBIK7ZN7MNyapk/D+v8zC20dM/OLE+zEDzBMwcYH5J1BpAMzsAMAJyU+vdZeZADN7AHAH4BjAC8kbD4QSAJv4+17wFcm3sQjyAGbWhXdff/takzwdG989Lw0wEN+te0ly9a8BIuJlJyAqXhIgMl4OIDpeCiAjXgYgK14CIDM+HSA7PhVgYHvrusnZZaOUshNUiU+ZAKX4cAC1+FAAxfgwANX4EADl+OYA6vFNASrENwOoEt8EoFK8O0C1eFcAMzsE8AXgqLcHdzvA3GVvv+89bv8FzOwcwEdvASuSy30XFXm/G0C3aDN7BXBdCcEb4ALAE4BFFQRXgM0UlEJwB6iG0ASgEkIzgCoITQEqIDQHUEcIAVBGCANQRQgFUEQIB1BDSAFQQkgDUEFIBVBASAfIRpAAyESQAchCkALIQJADiEaQBIhEkAWIQpAG+ANh8Xvk/j72CF0eYABhDeCS5PckALYQbgGcAXgm+Tg2vnu+xAR4hA69YwZoqVvh3fMEVPhKLdc4+Qn4AXwYBFBN2dYpAAAAAElFTkSuQmCC";
12295
+
12296
+ function withBindDataSource(Component) {
12297
+ // 处理函数事件中的数据源
12298
+ return React.memo(function (props) {
12299
+ const { $store } = useDataSource();
12300
+ const handleDataSourceByEvent = (value) => {
12301
+ let res = value;
12302
+ const dataArr = value.match(/{{.*?}}/g);
12303
+ if (dataArr === null || dataArr === void 0 ? void 0 : dataArr.length) {
12304
+ dataArr.forEach((item) => {
12305
+ item.replace(/{{\s*([\w.]+)\s*}}/g, (match, p) => {
12306
+ if (p) {
12307
+ const v = lodash.get($store, p);
12308
+ res = res.replace(item, v);
12309
+ return v;
12310
+ }
12311
+ });
12312
+ });
12313
+ }
12314
+ return res;
12315
+ };
12316
+ const clonedProps = React.useMemo(() => {
12317
+ var _a, _b, _c;
12318
+ const { bindDatas } = props, cloneProps = __rest(props, ["bindDatas"]);
12319
+ (_a = bindDatas === null || bindDatas === void 0 ? void 0 : bindDatas.forEach) === null || _a === void 0 ? void 0 : _a.call(bindDatas, (d) => {
12320
+ if ((d === null || d === void 0 ? void 0 : d.propKey) && (d === null || d === void 0 ? void 0 : d.dataPath)) {
12321
+ const { propKey, dataPath } = d;
12322
+ dataPath.replace(/{{\s*([\w.]+)\s*}}/g, (match, p) => {
12323
+ var _a, _b;
12324
+ if (p) {
12325
+ const v = (_b = (_a = lodash.get($store, p)) !== null && _a !== void 0 ? _a : props[propKey]) !== null && _b !== void 0 ? _b : '';
12326
+ cloneProps[propKey] = v;
12327
+ return v;
12328
+ }
12329
+ });
12330
+ }
12331
+ });
12332
+ if (cloneProps) {
12333
+ cloneProps.eventMap = {};
12334
+ const eventObj = lodash.cloneDeep(cloneProps.event) || {};
12335
+ for (const key in eventObj) {
12336
+ if (Object.prototype.hasOwnProperty.call(eventObj, key)) {
12337
+ try {
12338
+ eventObj[key].value = handleDataSourceByEvent(eventObj[key].value);
12339
+ cloneProps.eventMap[key] = new Function(eventObj[key].value);
12340
+ }
12341
+ catch (error) { }
12342
+ }
12343
+ }
12344
+ }
12345
+ if ((_c = (_b = cloneProps === null || cloneProps === void 0 ? void 0 : cloneProps.event) === null || _b === void 0 ? void 0 : _b.onClick) === null || _c === void 0 ? void 0 : _c.linkType) {
12346
+ cloneProps.style.cursor = 'pointer';
12347
+ }
12348
+ return cloneProps;
12349
+ }, [$store, props]);
12350
+ return React.createElement(Component, Object.assign({}, clonedProps, clonedProps.eventMap));
12351
+ });
12352
+ }
12353
+
12354
+ /*
12355
+ * @Author: binruan@chatlabs.com
12356
+ * @Date: 2023-12-26 16:11:34
12357
+ * @LastEditors: binruan@chatlabs.com
12358
+ * @LastEditTime: 2024-03-04 14:25:27
12359
+ * @FilePath: \pb-sxp-ui\src\core\components\SxpPageRender\RenderCard.tsx
12360
+ *
12361
+ */
12362
+ const RenderCard = ({ rec, index, tempMap, resolver }) => {
12363
+ const { schema } = useEditor();
12364
+ const renderComp = React.useMemo(() => {
12365
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2;
12366
+ if (!(rec === null || rec === void 0 ? void 0 : rec.video))
12367
+ return null;
12368
+ let cta = null;
12369
+ if ((_b = (_a = rec === null || rec === void 0 ? void 0 : rec.video) === null || _a === void 0 ? void 0 : _a.bindProducts) === null || _b === void 0 ? void 0 : _b.length) {
12370
+ cta = '多商品CTA';
10778
12371
  }
10779
- else if ((_a = rec === null || rec === void 0 ? void 0 : rec.video) === null || _a === void 0 ? void 0 : _a.url) {
10780
- fromKName = 'videoPage';
12372
+ else if ((_c = rec === null || rec === void 0 ? void 0 : rec.video) === null || _c === void 0 ? void 0 : _c.bindProduct) {
12373
+ cta = '商品CTA';
10781
12374
  }
10782
- else if ((_c = (_b = rec === null || rec === void 0 ? void 0 : rec.video) === null || _b === void 0 ? void 0 : _b.imgUrls) === null || _c === void 0 ? void 0 : _c.length) {
10783
- fromKName = 'imagePage';
12375
+ else {
12376
+ cta = (_e = (_d = rec === null || rec === void 0 ? void 0 : rec.video) === null || _d === void 0 ? void 0 : _d.bindCta) === null || _e === void 0 ? void 0 : _e.itemId;
10784
12377
  }
10785
- bffEventReport === null || bffEventReport === void 0 ? void 0 : bffEventReport({
10786
- eventInfo: {
10787
- relatedContentId: (_d = rec === null || rec === void 0 ? void 0 : rec.video) === null || _d === void 0 ? void 0 : _d.itemId,
10788
- position: rec === null || rec === void 0 ? void 0 : rec.position,
10789
- contentTags: JSON.stringify((_e = rec === null || rec === void 0 ? void 0 : rec.video) === null || _e === void 0 ? void 0 : _e.tags),
10790
- traceInfo: JSON.stringify((_f = rec === null || rec === void 0 ? void 0 : rec.video) === null || _f === void 0 ? void 0 : _f.traceInfo),
10791
- hashTags: JSON.stringify([recData === null || recData === void 0 ? void 0 : recData.hashTag]),
10792
- fromKName,
10793
- fromKPage: location === null || location === void 0 ? void 0 : location.href,
10794
- timeOnSite: Math.floor((new Date() - viewTime) / 1000) + '',
10795
- eventSubject: 'clickTagsViewContents',
10796
- eventDescription: 'User click tags view contents'
10797
- }
10798
- });
10799
- }, [recData, bffEventReport, viewTime, isFromHashtag]);
10800
- React.useEffect(() => {
10801
- if (openHashtag) {
10802
- setViewTime(new Date());
12378
+ const value = tempMap === null || tempMap === void 0 ? void 0 : tempMap[cta];
12379
+ if ((((_f = value === null || value === void 0 ? void 0 : value.item) === null || _f === void 0 ? void 0 : _f.type) === 'CommodityDiro' && !((_g = rec === null || rec === void 0 ? void 0 : rec.video) === null || _g === void 0 ? void 0 : _g.bindProduct)) ||
12380
+ (((_h = value === null || value === void 0 ? void 0 : value.item) === null || _h === void 0 ? void 0 : _h.type) === 'Commodity' && !((_j = rec === null || rec === void 0 ? void 0 : rec.video) === null || _j === void 0 ? void 0 : _j.bindProduct)) ||
12381
+ (((_k = value === null || value === void 0 ? void 0 : value.item) === null || _k === void 0 ? void 0 : _k.type) === 'CommodityDiroNew' && !((_l = rec === null || rec === void 0 ? void 0 : rec.video) === null || _l === void 0 ? void 0 : _l.bindProduct)) ||
12382
+ (((_m = value === null || value === void 0 ? void 0 : value.item) === null || _m === void 0 ? void 0 : _m.type) === 'MultiCommodity' && !((_p = (_o = rec === null || rec === void 0 ? void 0 : rec.video) === null || _o === void 0 ? void 0 : _o.bindProducts) === null || _p === void 0 ? void 0 : _p.length)) ||
12383
+ (((_q = value === null || value === void 0 ? void 0 : value.item) === null || _q === void 0 ? void 0 : _q.type) === 'MultiCommodityDiro' && !((_s = (_r = rec === null || rec === void 0 ? void 0 : rec.video) === null || _r === void 0 ? void 0 : _r.bindProducts) === null || _s === void 0 ? void 0 : _s.length)) ||
12384
+ (((_t = value === null || value === void 0 ? void 0 : value.item) === null || _t === void 0 ? void 0 : _t.type) === 'MultiCommodityDiroNew' && !((_v = (_u = rec === null || rec === void 0 ? void 0 : rec.video) === null || _u === void 0 ? void 0 : _u.bindProducts) === null || _v === void 0 ? void 0 : _v.length))) {
12385
+ return null;
10803
12386
  }
10804
- }, [openHashtag]);
10805
- React.useEffect(() => {
10806
- const initTime = () => {
10807
- setViewTime(new Date());
10808
- };
10809
- window.addEventListener('pageshow', initTime);
10810
- return () => {
10811
- window.removeEventListener('pageshow', initTime);
10812
- };
10813
- }, []);
10814
- if (!modalEleRef.current)
10815
- return null;
10816
- return ReactDOM__namespace.createPortal(React.createElement("div", { className: 'waterfall', style: {
10817
- display: openHashtag ? 'block' : 'none'
10818
- } },
10819
- React.createElement(Navbar$1, { icon: img, styles: { top: '32px' }, onClose: handleClose }),
10820
- React.createElement(WaterfallList, { reportTagsView: reportTagsView })), modalEleRef.current);
12387
+ if (value && resolver) {
12388
+ const Component = withBindDataSource(resolver[(_w = value === null || value === void 0 ? void 0 : value.item) === null || _w === void 0 ? void 0 : _w.type]);
12389
+ return (React.createElement(Component, Object.assign({ style: Object.assign(Object.assign({}, (_x = value === null || value === void 0 ? void 0 : value.item) === null || _x === void 0 ? void 0 : _x.style), { zIndex: 50, marginLeft: '20px' }), textStyle: (_y = value === null || value === void 0 ? void 0 : value.item) === null || _y === void 0 ? void 0 : _y.textStyle, bindDatas: (_0 = (_z = value === null || value === void 0 ? void 0 : value.item) === null || _z === void 0 ? void 0 : _z.bindDatas) !== null && _0 !== void 0 ? _0 : [] }, (_1 = value === null || value === void 0 ? void 0 : value.item) === null || _1 === void 0 ? void 0 : _1.props, { event: ((_2 = value === null || value === void 0 ? void 0 : value.item) === null || _2 === void 0 ? void 0 : _2.event) || {}, schema: schema, id: value === null || value === void 0 ? void 0 : value.id, key: value === null || value === void 0 ? void 0 : value.id, recData: rec })));
12390
+ }
12391
+ else {
12392
+ return null;
12393
+ }
12394
+ }, [rec, resolver, tempMap, schema]);
12395
+ return React.createElement(React.Fragment, null, renderComp);
10821
12396
  };
10822
- var WaterFall$1 = React.memo(WaterFall);
12397
+ var RenderCard$1 = React.memo(RenderCard);
10823
12398
 
10824
12399
  const Nudge = ({ nudge }) => {
10825
12400
  return (React.createElement("div", { hidden: !(nudge === null || nudge === void 0 ? void 0 : nudge.isOpen), className: 'clc-sxp-bottom-nudge', style: {
@@ -10837,12 +12412,12 @@ Made in Italy` })));
10837
12412
  * @Author: binruan@chatlabs.com
10838
12413
  * @Date: 2024-01-15 19:03:09
10839
12414
  * @LastEditors: binruan@chatlabs.com
10840
- * @LastEditTime: 2024-04-02 10:42:58
12415
+ * @LastEditTime: 2024-04-07 17:06:06
10841
12416
  * @FilePath: \pb-sxp-ui\src\core\components\SxpPageRender\index.tsx
10842
12417
  *
10843
12418
  */
10844
- const SxpPageRender = ({ globalConfig, descStyle, containerHeight = window.innerHeight, containerWidth = window.innerWidth, tempMap, resolver, data = [], ctaType, tipText, nudge, _schema }) => {
10845
- var _a, _b, _c, _d;
12419
+ const SxpPageRender = ({ globalConfig, descStyle, containerHeight = window.innerHeight, containerWidth = window.innerWidth, tempMap, resolver, data = [], ctaType, tipText, nudge, _schema, hashTagStyle }) => {
12420
+ var _a, _b, _c, _d, _e, _f, _g;
10846
12421
  const { schema } = useEditor();
10847
12422
  const [activeIndex, setActiveIndex] = React.useState(0);
10848
12423
  const viewImageStartTime = React.useRef(0);
@@ -11022,10 +12597,10 @@ Made in Italy` })));
11022
12597
  React.createElement(RenderCard$1, { rec: rec, index: index, tempMap: tempMap, resolver: resolver })),
11023
12598
  React.createElement("div", { className: 'clc-sxp-bottom-text' },
11024
12599
  React.createElement(ExpandableText$1, { isPost: true, foldText: tipText === null || tipText === void 0 ? void 0 : tipText.foldText, unfoldText: tipText === null || tipText === void 0 ? void 0 : tipText.unfoldText, text: (_c = (_b = rec.video) === null || _b === void 0 ? void 0 : _b.title) !== null && _c !== void 0 ? _c : '', style: descStyle })),
11025
- React.createElement(Hashtag$1, { index: activeIndex, tags: (_e = (_d = rec === null || rec === void 0 ? void 0 : rec.video) === null || _d === void 0 ? void 0 : _d.hashTags) !== null && _e !== void 0 ? _e : [], itemId: (_f = rec === null || rec === void 0 ? void 0 : rec.video) === null || _f === void 0 ? void 0 : _f.itemId, itemType: ((_g = rec.video) === null || _g === void 0 ? void 0 : _g.url) ? 'VIDEO' : null, rec: rec }))));
12600
+ React.createElement(Hashtag$1, { index: activeIndex, tags: (_e = (_d = rec === null || rec === void 0 ? void 0 : rec.video) === null || _d === void 0 ? void 0 : _d.hashTags) !== null && _e !== void 0 ? _e : [], itemId: (_f = rec === null || rec === void 0 ? void 0 : rec.video) === null || _f === void 0 ? void 0 : _f.itemId, itemType: ((_g = rec.video) === null || _g === void 0 ? void 0 : _g.url) ? 'VIDEO' : null, rec: rec, hashTagStyle: hashTagStyle }))));
11026
12601
  }
11027
12602
  return null;
11028
- }, [descStyle, activeIndex, tempMap, resolver, tipText, nudge]);
12603
+ }, [descStyle, activeIndex, tempMap, resolver, tipText, nudge, hashTagStyle]);
11029
12604
  const renderLikeButton = React.useCallback((rec) => {
11030
12605
  var _a, _b;
11031
12606
  if (!(globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.isShowLike))
@@ -11164,7 +12739,7 @@ Made in Italy` })));
11164
12739
  const mutedIcon = useIconLink('/pb_static/5beaaa5ce7f3477b99db3838619cc471.png');
11165
12740
  const unmutedIcon = useIconLink('/pb_static/fea8668a8a894e4aa3a86bcc775e895e.png');
11166
12741
  return (React.createElement("div", { id: 'sxp-render', className: 'clc-sxp-container' },
11167
- waterFallData && (React.createElement(Navbar$1, { icon: img$1, styles: { background: 'rgba(0,0,0,.3)', color: '#fff' }, onClose: () => {
12742
+ waterFallData && (React.createElement(Navbar$1, { icon: img, styles: { background: 'rgba(0,0,0,.3)', color: '#fff' }, onClose: () => {
11168
12743
  setOpenHashtag === null || setOpenHashtag === void 0 ? void 0 : setOpenHashtag(true);
11169
12744
  } })),
11170
12745
  renderLogo,
@@ -11208,7 +12783,7 @@ Made in Italy` })));
11208
12783
  zIndex: 999
11209
12784
  }, defaultValue: isMuted, activeIcon: (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.unMuteIcon) ? globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.unMuteIcon : mutedIcon, unactiveIcon: (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.muteIcon) ? globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.muteIcon : unmutedIcon, onChange: setIsMuted }),
11210
12785
  renderView),
11211
- React.createElement(WaterFall$1, null)));
12786
+ React.createElement(WaterFall$1, Object.assign({}, (_g = (_f = (_e = globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.hashTag) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.item) === null || _g === void 0 ? void 0 : _g.props))));
11212
12787
  };
11213
12788
 
11214
12789
  /*
@@ -11315,13 +12890,14 @@ Made in Italy` })));
11315
12890
  * @Author: binruan@chatlabs.com
11316
12891
  * @Date: 2023-12-26 10:38:53
11317
12892
  * @LastEditors: binruan@chatlabs.com
11318
- * @LastEditTime: 2024-03-14 15:13:36
12893
+ * @LastEditTime: 2024-04-08 10:53:29
11319
12894
  * @FilePath: \pb-sxp-ui\src\core\context\EditorDataProvider.tsx
11320
12895
  *
11321
12896
  */
11322
12897
  const EditorDataContext = React.createContext({});
11323
12898
  const EditorDataProvider = ({ children, data }) => {
11324
12899
  var _a, _b, _c, _d, _e, _f;
12900
+ const [openHashtag, setOpenHashtag] = React.useState(false);
11325
12901
  return (React.createElement(EditorDataContext.Provider, { value: {
11326
12902
  sxpPrameter: {
11327
12903
  bottomImage: (_a = data === null || data === void 0 ? void 0 : data.sxp_parameter) === null || _a === void 0 ? void 0 : _a.bottom_image,
@@ -11331,7 +12907,9 @@ Made in Italy` })));
11331
12907
  hashTagSize: (_e = data === null || data === void 0 ? void 0 : data.sxp_parameter) === null || _e === void 0 ? void 0 : _e.hash_tag_size,
11332
12908
  loadingImage: (_f = data === null || data === void 0 ? void 0 : data.sxp_parameter) === null || _f === void 0 ? void 0 : _f.loading_image
11333
12909
  },
11334
- appDomain: data === null || data === void 0 ? void 0 : data.appDomain
12910
+ appDomain: data === null || data === void 0 ? void 0 : data.appDomain,
12911
+ openHashtag,
12912
+ setOpenHashtag
11335
12913
  } }, children));
11336
12914
  };
11337
12915
  function useEditorDataProvider() {