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

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