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

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