@xhub-reels/sdk 0.1.22 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1447,7 +1447,7 @@ function useHls(options) {
1447
1447
  setIsReady(false);
1448
1448
  canPlayFiredRef.current = false;
1449
1449
  currentSrcRef.current = src;
1450
- const handleCanPlay2 = () => {
1450
+ const handleCanPlay = () => {
1451
1451
  canPlayFiredRef.current = true;
1452
1452
  setIsReady(true);
1453
1453
  };
@@ -1457,10 +1457,10 @@ function useHls(options) {
1457
1457
  setIsReady(true);
1458
1458
  }
1459
1459
  };
1460
- video.addEventListener("canplay", handleCanPlay2, { once: true });
1460
+ video.addEventListener("canplay", handleCanPlay, { once: true });
1461
1461
  video.addEventListener("loadeddata", handleLoadedData, { once: true });
1462
1462
  return () => {
1463
- video.removeEventListener("canplay", handleCanPlay2);
1463
+ video.removeEventListener("canplay", handleCanPlay);
1464
1464
  video.removeEventListener("loadeddata", handleLoadedData);
1465
1465
  };
1466
1466
  }
@@ -1470,13 +1470,21 @@ function useHls(options) {
1470
1470
  }
1471
1471
  if (hlsRef.current && currentSrcRef.current === src) {
1472
1472
  if (!canPlayFiredRef.current) {
1473
- const handleCanPlay2 = () => {
1473
+ if (video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA) {
1474
+ canPlayFiredRef.current = true;
1475
+ setIsReady(true);
1476
+ return void 0;
1477
+ }
1478
+ const handleReady2 = () => {
1479
+ if (canPlayFiredRef.current) return;
1474
1480
  canPlayFiredRef.current = true;
1475
1481
  setIsReady(true);
1476
1482
  };
1477
- video.addEventListener("canplay", handleCanPlay2, { once: true });
1483
+ video.addEventListener("loadeddata", handleReady2, { once: true });
1484
+ video.addEventListener("canplay", handleReady2, { once: true });
1478
1485
  return () => {
1479
- video.removeEventListener("canplay", handleCanPlay2);
1486
+ video.removeEventListener("loadeddata", handleReady2);
1487
+ video.removeEventListener("canplay", handleReady2);
1480
1488
  };
1481
1489
  }
1482
1490
  return void 0;
@@ -1513,15 +1521,18 @@ function useHls(options) {
1513
1521
  const mapped = mapHlsError(data);
1514
1522
  onErrorRef.current?.(mapped.code, mapped.message);
1515
1523
  });
1516
- const handleCanPlay = () => {
1524
+ const handleReady = () => {
1525
+ if (canPlayFiredRef.current) return;
1517
1526
  canPlayFiredRef.current = true;
1518
1527
  setIsReady(true);
1519
1528
  };
1520
- video.addEventListener("canplay", handleCanPlay, { once: true });
1529
+ video.addEventListener("loadeddata", handleReady, { once: true });
1530
+ video.addEventListener("canplay", handleReady, { once: true });
1521
1531
  hls.attachMedia(video);
1522
1532
  hls.loadSource(src);
1523
1533
  return () => {
1524
- video.removeEventListener("canplay", handleCanPlay);
1534
+ video.removeEventListener("loadeddata", handleReady);
1535
+ video.removeEventListener("canplay", handleReady);
1525
1536
  if (hlsRef.current === hls) {
1526
1537
  hls.destroy();
1527
1538
  hlsRef.current = null;
@@ -1892,11 +1903,18 @@ function VideoSlotInner({
1892
1903
  };
1893
1904
  if (isActive && !isManuallyPaused) {
1894
1905
  wasActiveRef.current = true;
1895
- if (video.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA) {
1906
+ if (video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA) {
1896
1907
  attemptPlay();
1897
1908
  } else {
1898
- onReady = attemptPlay;
1899
- video.addEventListener("canplay", onReady, { once: true });
1909
+ let consumed = false;
1910
+ const handler = () => {
1911
+ if (consumed) return;
1912
+ consumed = true;
1913
+ attemptPlay();
1914
+ };
1915
+ onReady = handler;
1916
+ video.addEventListener("loadeddata", handler, { once: true });
1917
+ video.addEventListener("canplay", handler, { once: true });
1900
1918
  }
1901
1919
  } else if (isActive && isManuallyPaused) {
1902
1920
  wasActiveRef.current = true;
@@ -1912,7 +1930,10 @@ function VideoSlotInner({
1912
1930
  }
1913
1931
  return () => {
1914
1932
  cancelled = true;
1915
- if (onReady) video.removeEventListener("canplay", onReady);
1933
+ if (onReady) {
1934
+ video.removeEventListener("loadeddata", onReady);
1935
+ video.removeEventListener("canplay", onReady);
1936
+ }
1916
1937
  };
1917
1938
  }, [isActive, isMuted, hasPlayedAhead, isManuallyPaused, onAutoplayBlocked]);
1918
1939
  react.useEffect(() => {
@@ -2052,7 +2073,7 @@ function VideoSlotInner({
2052
2073
  inset: 0,
2053
2074
  backgroundImage: `url(${item.poster})`,
2054
2075
  backgroundSize: "cover",
2055
- backgroundPosition: "center center",
2076
+ backgroundPosition: "center",
2056
2077
  opacity: showPosterOverlay ? 1 : 0,
2057
2078
  transition: "opacity 0.15s ease",
2058
2079
  pointerEvents: "none"
@@ -2919,12 +2940,16 @@ function transformVideoItem(raw) {
2919
2940
  const stats = transformStats(obj);
2920
2941
  const interaction = transformInteraction(obj);
2921
2942
  let poster;
2922
- let duration = 0;
2923
- const mediaArr = obj["media"];
2924
- if (Array.isArray(mediaArr) && mediaArr.length > 0) {
2925
- const first = mediaArr[0];
2926
- poster = toStr(first["poster"], "") || void 0;
2927
- duration = toNum(first["duration"], 0);
2943
+ const thumbnailObj = obj["thumbnail"];
2944
+ if (thumbnailObj && thumbnailObj["url"]) {
2945
+ poster = toStr(thumbnailObj["url"], "") || void 0;
2946
+ }
2947
+ if (!poster) {
2948
+ const mediaArr2 = obj["media"];
2949
+ if (Array.isArray(mediaArr2) && mediaArr2.length > 0) {
2950
+ const first = mediaArr2[0];
2951
+ poster = toStr(first["poster"], "") || void 0;
2952
+ }
2928
2953
  }
2929
2954
  if (!poster) {
2930
2955
  poster = toStr(
@@ -2932,11 +2957,11 @@ function transformVideoItem(raw) {
2932
2957
  void 0
2933
2958
  ) || void 0;
2934
2959
  }
2935
- if (!poster) {
2936
- const thumbnailObj = obj["thumbnail"];
2937
- if (thumbnailObj && thumbnailObj["url"]) {
2938
- poster = toStr(thumbnailObj["url"], "") || void 0;
2939
- }
2960
+ let duration = 0;
2961
+ const mediaArr = obj["media"];
2962
+ if (Array.isArray(mediaArr) && mediaArr.length > 0) {
2963
+ const first = mediaArr[0];
2964
+ duration = toNum(first["duration"], 0);
2940
2965
  }
2941
2966
  if (duration === 0) {
2942
2967
  duration = toNum(tryFields(obj, "duration", "duration_seconds", "length", "video_duration"), 0);
package/dist/index.js CHANGED
@@ -1441,7 +1441,7 @@ function useHls(options) {
1441
1441
  setIsReady(false);
1442
1442
  canPlayFiredRef.current = false;
1443
1443
  currentSrcRef.current = src;
1444
- const handleCanPlay2 = () => {
1444
+ const handleCanPlay = () => {
1445
1445
  canPlayFiredRef.current = true;
1446
1446
  setIsReady(true);
1447
1447
  };
@@ -1451,10 +1451,10 @@ function useHls(options) {
1451
1451
  setIsReady(true);
1452
1452
  }
1453
1453
  };
1454
- video.addEventListener("canplay", handleCanPlay2, { once: true });
1454
+ video.addEventListener("canplay", handleCanPlay, { once: true });
1455
1455
  video.addEventListener("loadeddata", handleLoadedData, { once: true });
1456
1456
  return () => {
1457
- video.removeEventListener("canplay", handleCanPlay2);
1457
+ video.removeEventListener("canplay", handleCanPlay);
1458
1458
  video.removeEventListener("loadeddata", handleLoadedData);
1459
1459
  };
1460
1460
  }
@@ -1464,13 +1464,21 @@ function useHls(options) {
1464
1464
  }
1465
1465
  if (hlsRef.current && currentSrcRef.current === src) {
1466
1466
  if (!canPlayFiredRef.current) {
1467
- const handleCanPlay2 = () => {
1467
+ if (video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA) {
1468
+ canPlayFiredRef.current = true;
1469
+ setIsReady(true);
1470
+ return void 0;
1471
+ }
1472
+ const handleReady2 = () => {
1473
+ if (canPlayFiredRef.current) return;
1468
1474
  canPlayFiredRef.current = true;
1469
1475
  setIsReady(true);
1470
1476
  };
1471
- video.addEventListener("canplay", handleCanPlay2, { once: true });
1477
+ video.addEventListener("loadeddata", handleReady2, { once: true });
1478
+ video.addEventListener("canplay", handleReady2, { once: true });
1472
1479
  return () => {
1473
- video.removeEventListener("canplay", handleCanPlay2);
1480
+ video.removeEventListener("loadeddata", handleReady2);
1481
+ video.removeEventListener("canplay", handleReady2);
1474
1482
  };
1475
1483
  }
1476
1484
  return void 0;
@@ -1507,15 +1515,18 @@ function useHls(options) {
1507
1515
  const mapped = mapHlsError(data);
1508
1516
  onErrorRef.current?.(mapped.code, mapped.message);
1509
1517
  });
1510
- const handleCanPlay = () => {
1518
+ const handleReady = () => {
1519
+ if (canPlayFiredRef.current) return;
1511
1520
  canPlayFiredRef.current = true;
1512
1521
  setIsReady(true);
1513
1522
  };
1514
- video.addEventListener("canplay", handleCanPlay, { once: true });
1523
+ video.addEventListener("loadeddata", handleReady, { once: true });
1524
+ video.addEventListener("canplay", handleReady, { once: true });
1515
1525
  hls.attachMedia(video);
1516
1526
  hls.loadSource(src);
1517
1527
  return () => {
1518
- video.removeEventListener("canplay", handleCanPlay);
1528
+ video.removeEventListener("loadeddata", handleReady);
1529
+ video.removeEventListener("canplay", handleReady);
1519
1530
  if (hlsRef.current === hls) {
1520
1531
  hls.destroy();
1521
1532
  hlsRef.current = null;
@@ -1886,11 +1897,18 @@ function VideoSlotInner({
1886
1897
  };
1887
1898
  if (isActive && !isManuallyPaused) {
1888
1899
  wasActiveRef.current = true;
1889
- if (video.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA) {
1900
+ if (video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA) {
1890
1901
  attemptPlay();
1891
1902
  } else {
1892
- onReady = attemptPlay;
1893
- video.addEventListener("canplay", onReady, { once: true });
1903
+ let consumed = false;
1904
+ const handler = () => {
1905
+ if (consumed) return;
1906
+ consumed = true;
1907
+ attemptPlay();
1908
+ };
1909
+ onReady = handler;
1910
+ video.addEventListener("loadeddata", handler, { once: true });
1911
+ video.addEventListener("canplay", handler, { once: true });
1894
1912
  }
1895
1913
  } else if (isActive && isManuallyPaused) {
1896
1914
  wasActiveRef.current = true;
@@ -1906,7 +1924,10 @@ function VideoSlotInner({
1906
1924
  }
1907
1925
  return () => {
1908
1926
  cancelled = true;
1909
- if (onReady) video.removeEventListener("canplay", onReady);
1927
+ if (onReady) {
1928
+ video.removeEventListener("loadeddata", onReady);
1929
+ video.removeEventListener("canplay", onReady);
1930
+ }
1910
1931
  };
1911
1932
  }, [isActive, isMuted, hasPlayedAhead, isManuallyPaused, onAutoplayBlocked]);
1912
1933
  useEffect(() => {
@@ -2046,7 +2067,7 @@ function VideoSlotInner({
2046
2067
  inset: 0,
2047
2068
  backgroundImage: `url(${item.poster})`,
2048
2069
  backgroundSize: "cover",
2049
- backgroundPosition: "center center",
2070
+ backgroundPosition: "center",
2050
2071
  opacity: showPosterOverlay ? 1 : 0,
2051
2072
  transition: "opacity 0.15s ease",
2052
2073
  pointerEvents: "none"
@@ -2913,12 +2934,16 @@ function transformVideoItem(raw) {
2913
2934
  const stats = transformStats(obj);
2914
2935
  const interaction = transformInteraction(obj);
2915
2936
  let poster;
2916
- let duration = 0;
2917
- const mediaArr = obj["media"];
2918
- if (Array.isArray(mediaArr) && mediaArr.length > 0) {
2919
- const first = mediaArr[0];
2920
- poster = toStr(first["poster"], "") || void 0;
2921
- duration = toNum(first["duration"], 0);
2937
+ const thumbnailObj = obj["thumbnail"];
2938
+ if (thumbnailObj && thumbnailObj["url"]) {
2939
+ poster = toStr(thumbnailObj["url"], "") || void 0;
2940
+ }
2941
+ if (!poster) {
2942
+ const mediaArr2 = obj["media"];
2943
+ if (Array.isArray(mediaArr2) && mediaArr2.length > 0) {
2944
+ const first = mediaArr2[0];
2945
+ poster = toStr(first["poster"], "") || void 0;
2946
+ }
2922
2947
  }
2923
2948
  if (!poster) {
2924
2949
  poster = toStr(
@@ -2926,11 +2951,11 @@ function transformVideoItem(raw) {
2926
2951
  void 0
2927
2952
  ) || void 0;
2928
2953
  }
2929
- if (!poster) {
2930
- const thumbnailObj = obj["thumbnail"];
2931
- if (thumbnailObj && thumbnailObj["url"]) {
2932
- poster = toStr(thumbnailObj["url"], "") || void 0;
2933
- }
2954
+ let duration = 0;
2955
+ const mediaArr = obj["media"];
2956
+ if (Array.isArray(mediaArr) && mediaArr.length > 0) {
2957
+ const first = mediaArr[0];
2958
+ duration = toNum(first["duration"], 0);
2934
2959
  }
2935
2960
  if (duration === 0) {
2936
2961
  duration = toNum(tryFields(obj, "duration", "duration_seconds", "length", "video_duration"), 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xhub-reels/sdk",
3
- "version": "0.1.22",
3
+ "version": "0.2.5",
4
4
  "description": "High-performance Short Video / Reels SDK for React — optimized for Flutter WebView",
5
5
  "license": "MIT",
6
6
  "type": "module",