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