@xhub-short/sdk 1.0.0-beta.24 → 1.0.0-beta.26
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.d.ts +135 -154
- package/dist/index.js +47 -54
- package/package.json +8 -8
package/dist/index.d.ts
CHANGED
|
@@ -1365,27 +1365,6 @@ interface VideoSlotWiredProps extends VideoSlotProps {
|
|
|
1365
1365
|
reportedButtonText?: string;
|
|
1366
1366
|
/** Custom styles */
|
|
1367
1367
|
style?: React.CSSProperties;
|
|
1368
|
-
/**
|
|
1369
|
-
* Disable long-press speed boost gesture.
|
|
1370
|
-
* When true, holding won't trigger 2x speed.
|
|
1371
|
-
* @default false
|
|
1372
|
-
*/
|
|
1373
|
-
disableSpeedBoost?: boolean;
|
|
1374
|
-
/**
|
|
1375
|
-
* Speed multiplier for speed boost.
|
|
1376
|
-
* @default 2
|
|
1377
|
-
*/
|
|
1378
|
-
speedBoostSpeed?: number;
|
|
1379
|
-
/**
|
|
1380
|
-
* Hold delay in ms before speed boost activates.
|
|
1381
|
-
* @default 2000
|
|
1382
|
-
*/
|
|
1383
|
-
speedBoostHoldDelay?: number;
|
|
1384
|
-
/**
|
|
1385
|
-
* Pull-down distance in px to trigger speed lock.
|
|
1386
|
-
* @default 50
|
|
1387
|
-
*/
|
|
1388
|
-
speedBoostPullDownThreshold?: number;
|
|
1389
1368
|
}
|
|
1390
1369
|
/**
|
|
1391
1370
|
* SDK Player Error - Preserves error metadata from PlayerEngine
|
|
@@ -1435,7 +1414,7 @@ declare class SDKPlayerError extends Error {
|
|
|
1435
1414
|
* Host app must trigger these manually or wait for future IntersectionObserver
|
|
1436
1415
|
* implementation in VideoSlotHeadless.
|
|
1437
1416
|
*/
|
|
1438
|
-
declare function VideoSlot({ video, index, resourceState: resourceStateOverride, playerState: playerStateOverride, playerControls: playerControlsOverride, className, children, onVisible, onHidden, onTap, onDoubleTap, onLongPress, disableTap, renderError, renderLoading, reportedTitle, reportedMessage, reportedButtonText, style,
|
|
1417
|
+
declare function VideoSlot({ video, index, resourceState: resourceStateOverride, playerState: playerStateOverride, playerControls: playerControlsOverride, className, children, onVisible, onHidden, onTap, onDoubleTap, onLongPress, disableTap, renderError, renderLoading, reportedTitle, reportedMessage, reportedButtonText, style, }: VideoSlotWiredProps): React.ReactElement;
|
|
1439
1418
|
declare namespace VideoSlot {
|
|
1440
1419
|
var displayName: string;
|
|
1441
1420
|
}
|
|
@@ -1735,18 +1714,134 @@ interface DefaultVideoSlotProps {
|
|
|
1735
1714
|
enableZoom?: boolean;
|
|
1736
1715
|
zoomMaxScale?: number;
|
|
1737
1716
|
zoomSnapBackAnimation?: 'none' | 'ease' | 'spring';
|
|
1738
|
-
/** Disable speed boost (default: false) */
|
|
1739
|
-
disableSpeedBoost?: boolean;
|
|
1740
|
-
/** Speed multiplier for speed boost (default: 2) */
|
|
1741
|
-
speedBoostSpeed?: number;
|
|
1742
|
-
/** Hold delay in ms before speed boost activates (default: 2000) */
|
|
1743
|
-
speedBoostHoldDelay?: number;
|
|
1744
|
-
/** Pull-down distance in px to trigger speed lock (default: 50) */
|
|
1745
|
-
speedBoostPullDownThreshold?: number;
|
|
1746
1717
|
className?: string;
|
|
1747
1718
|
}
|
|
1748
1719
|
declare const DefaultVideoSlot: react.NamedExoticComponent<DefaultVideoSlotProps>;
|
|
1749
1720
|
|
|
1721
|
+
/**
|
|
1722
|
+
* Snap-back animation type
|
|
1723
|
+
* - 'none': Instant snap (no animation)
|
|
1724
|
+
* - 'ease': Smooth ease-out transition
|
|
1725
|
+
* - 'spring': Spring-like bounce effect
|
|
1726
|
+
*/
|
|
1727
|
+
type SnapBackAnimation = 'none' | 'ease' | 'spring';
|
|
1728
|
+
/**
|
|
1729
|
+
* Configuration for useZoomGesture
|
|
1730
|
+
*/
|
|
1731
|
+
interface UseZoomGestureConfig {
|
|
1732
|
+
/** Minimum scale factor (default: 1) */
|
|
1733
|
+
minScale?: number;
|
|
1734
|
+
/** Maximum scale factor (default: 5) */
|
|
1735
|
+
maxScale?: number;
|
|
1736
|
+
/** Whether to lock vertical swipe during zoom (default: true) */
|
|
1737
|
+
lockVerticalSwipe?: boolean;
|
|
1738
|
+
/**
|
|
1739
|
+
* Snap-back animation type (default: 'ease')
|
|
1740
|
+
* - 'none': Instant snap, onZoomEnd called immediately
|
|
1741
|
+
* - 'ease': Smooth ease-out, onZoomEnd called after duration
|
|
1742
|
+
* - 'spring': Spring bounce effect, onZoomEnd called after duration
|
|
1743
|
+
*/
|
|
1744
|
+
snapBackAnimation?: SnapBackAnimation;
|
|
1745
|
+
/** Snap-back animation duration in ms (default: 200) */
|
|
1746
|
+
snapBackDuration?: number;
|
|
1747
|
+
/** Callback when zoom starts (scale > 1) */
|
|
1748
|
+
onZoomStart?: () => void;
|
|
1749
|
+
/** Callback when zoom ends (after snap-back animation completes) */
|
|
1750
|
+
onZoomEnd?: (finalScale: number) => void;
|
|
1751
|
+
/** Callback on scale change during gesture */
|
|
1752
|
+
onZoomChange?: (scale: number) => void;
|
|
1753
|
+
/** Whether zoom is enabled (default: true) */
|
|
1754
|
+
enabled?: boolean;
|
|
1755
|
+
}
|
|
1756
|
+
/**
|
|
1757
|
+
* Touch event handlers
|
|
1758
|
+
*/
|
|
1759
|
+
interface ZoomGestureHandlers {
|
|
1760
|
+
onTouchStart: (e: react__default.TouchEvent) => void;
|
|
1761
|
+
onTouchMove: (e: react__default.TouchEvent) => void;
|
|
1762
|
+
onTouchEnd: (e: react__default.TouchEvent) => void;
|
|
1763
|
+
}
|
|
1764
|
+
/**
|
|
1765
|
+
* Return type for useZoomGesture
|
|
1766
|
+
*/
|
|
1767
|
+
interface UseZoomGestureReturn {
|
|
1768
|
+
/** Current scale factor (1 = normal) */
|
|
1769
|
+
scale: number;
|
|
1770
|
+
/** Current X translation in pixels */
|
|
1771
|
+
translateX: number;
|
|
1772
|
+
/** Current Y translation in pixels */
|
|
1773
|
+
translateY: number;
|
|
1774
|
+
/** Whether actively zooming (2+ fingers) */
|
|
1775
|
+
isZooming: boolean;
|
|
1776
|
+
/** Whether currently panning while zoomed */
|
|
1777
|
+
isPanning: boolean;
|
|
1778
|
+
/** Whether snap-back animation is playing */
|
|
1779
|
+
isAnimating: boolean;
|
|
1780
|
+
/** Whether vertical swipe is locked */
|
|
1781
|
+
isSwipeLocked: boolean;
|
|
1782
|
+
/** Touch event handlers to spread on container */
|
|
1783
|
+
handlers: ZoomGestureHandlers;
|
|
1784
|
+
/** Manually reset to default state */
|
|
1785
|
+
reset: () => void;
|
|
1786
|
+
/** CSS transform string for convenience */
|
|
1787
|
+
transform: string;
|
|
1788
|
+
/** CSS transform-origin string */
|
|
1789
|
+
transformOrigin: string;
|
|
1790
|
+
/**
|
|
1791
|
+
* CSS styles for container element.
|
|
1792
|
+
* Includes `touchAction: 'none'` for proper gesture handling on mobile.
|
|
1793
|
+
* Always spread this on your container for best compatibility.
|
|
1794
|
+
*/
|
|
1795
|
+
containerStyle: react__default.CSSProperties;
|
|
1796
|
+
/**
|
|
1797
|
+
* CSS transition string for snap-back animation.
|
|
1798
|
+
* Apply this to the transform property for smooth animations.
|
|
1799
|
+
*/
|
|
1800
|
+
transitionStyle: react__default.CSSProperties;
|
|
1801
|
+
}
|
|
1802
|
+
/**
|
|
1803
|
+
* useZoomGesture - Pinch-to-zoom gesture handler
|
|
1804
|
+
*
|
|
1805
|
+
* Handles pinch gestures for video zoom with pan support.
|
|
1806
|
+
* Always snaps back to scale=1 on release (Instagram Reels behavior).
|
|
1807
|
+
*
|
|
1808
|
+
* @example
|
|
1809
|
+
* ```tsx
|
|
1810
|
+
* function VideoPlayer({ video }: { video: VideoItem }) {
|
|
1811
|
+
* const {
|
|
1812
|
+
* transform,
|
|
1813
|
+
* transformOrigin,
|
|
1814
|
+
* containerStyle,
|
|
1815
|
+
* handlers,
|
|
1816
|
+
* isZooming,
|
|
1817
|
+
* } = useZoomGesture({
|
|
1818
|
+
* onZoomStart: () => enterCleanMode('zoom'),
|
|
1819
|
+
* onZoomEnd: () => exitCleanMode(),
|
|
1820
|
+
* snapBackAnimation: 'ease', // smooth snap-back
|
|
1821
|
+
* });
|
|
1822
|
+
*
|
|
1823
|
+
* return (
|
|
1824
|
+
* <div
|
|
1825
|
+
* style={{
|
|
1826
|
+
* ...containerStyle, // includes touchAction: 'none' for proper gesture handling
|
|
1827
|
+
* transform,
|
|
1828
|
+
* transformOrigin,
|
|
1829
|
+
* }}
|
|
1830
|
+
* {...handlers}
|
|
1831
|
+
* >
|
|
1832
|
+
* <video src={video.url} />
|
|
1833
|
+
* </div>
|
|
1834
|
+
* );
|
|
1835
|
+
* }
|
|
1836
|
+
* ```
|
|
1837
|
+
*
|
|
1838
|
+
* @remarks
|
|
1839
|
+
* **Important:** Always spread `containerStyle` on your container element.
|
|
1840
|
+
* This sets `touchAction: 'none'` which is required for `preventDefault()` to work
|
|
1841
|
+
* on mobile browsers (Chrome 56+, Safari) where touch events are passive by default.
|
|
1842
|
+
*/
|
|
1843
|
+
declare function useZoomGesture(config?: UseZoomGestureConfig): UseZoomGestureReturn;
|
|
1844
|
+
|
|
1750
1845
|
/**
|
|
1751
1846
|
* Minimum requirements for content used in SlotComposer
|
|
1752
1847
|
*/
|
|
@@ -1778,6 +1873,14 @@ interface ComposerState {
|
|
|
1778
1873
|
isMenuOpen: boolean;
|
|
1779
1874
|
/** Whether report sheet is open */
|
|
1780
1875
|
isReportSheetOpen: boolean;
|
|
1876
|
+
/** Zoom transform property */
|
|
1877
|
+
zoomTransform: string;
|
|
1878
|
+
/** Zoom transform origin */
|
|
1879
|
+
zoomTransformOrigin: string;
|
|
1880
|
+
/** Zoom container style (includes touchAction: 'none') */
|
|
1881
|
+
zoomContainerStyle: React.CSSProperties;
|
|
1882
|
+
/** Zoom snap-back transition style */
|
|
1883
|
+
zoomTransitionStyle: React.CSSProperties;
|
|
1781
1884
|
}
|
|
1782
1885
|
/**
|
|
1783
1886
|
* Handlers provided by SlotComposer
|
|
@@ -1801,6 +1904,8 @@ interface ComposerHandlers {
|
|
|
1801
1904
|
setCommentSheetOpen: (open: boolean) => void;
|
|
1802
1905
|
setMenuOpen: (open: boolean) => void;
|
|
1803
1906
|
setReportSheetOpen: (open: boolean) => void;
|
|
1907
|
+
/** Pinch-to-zoom touch event handlers */
|
|
1908
|
+
zoomHandlers: ReturnType<typeof useZoomGesture>['handlers'];
|
|
1804
1909
|
}
|
|
1805
1910
|
/**
|
|
1806
1911
|
* Pre-configured wired components
|
|
@@ -3754,130 +3859,6 @@ interface UseAdvancedControlsConfig {
|
|
|
3754
3859
|
*/
|
|
3755
3860
|
declare function useAdvancedControls(config?: UseAdvancedControlsConfig): UseAdvancedControlsReturn;
|
|
3756
3861
|
|
|
3757
|
-
/**
|
|
3758
|
-
* Snap-back animation type
|
|
3759
|
-
* - 'none': Instant snap (no animation)
|
|
3760
|
-
* - 'ease': Smooth ease-out transition
|
|
3761
|
-
* - 'spring': Spring-like bounce effect
|
|
3762
|
-
*/
|
|
3763
|
-
type SnapBackAnimation = 'none' | 'ease' | 'spring';
|
|
3764
|
-
/**
|
|
3765
|
-
* Configuration for useZoomGesture
|
|
3766
|
-
*/
|
|
3767
|
-
interface UseZoomGestureConfig {
|
|
3768
|
-
/** Minimum scale factor (default: 1) */
|
|
3769
|
-
minScale?: number;
|
|
3770
|
-
/** Maximum scale factor (default: 5) */
|
|
3771
|
-
maxScale?: number;
|
|
3772
|
-
/** Whether to lock vertical swipe during zoom (default: true) */
|
|
3773
|
-
lockVerticalSwipe?: boolean;
|
|
3774
|
-
/**
|
|
3775
|
-
* Snap-back animation type (default: 'ease')
|
|
3776
|
-
* - 'none': Instant snap, onZoomEnd called immediately
|
|
3777
|
-
* - 'ease': Smooth ease-out, onZoomEnd called after duration
|
|
3778
|
-
* - 'spring': Spring bounce effect, onZoomEnd called after duration
|
|
3779
|
-
*/
|
|
3780
|
-
snapBackAnimation?: SnapBackAnimation;
|
|
3781
|
-
/** Snap-back animation duration in ms (default: 200) */
|
|
3782
|
-
snapBackDuration?: number;
|
|
3783
|
-
/** Callback when zoom starts (scale > 1) */
|
|
3784
|
-
onZoomStart?: () => void;
|
|
3785
|
-
/** Callback when zoom ends (after snap-back animation completes) */
|
|
3786
|
-
onZoomEnd?: (finalScale: number) => void;
|
|
3787
|
-
/** Callback on scale change during gesture */
|
|
3788
|
-
onZoomChange?: (scale: number) => void;
|
|
3789
|
-
/** Whether zoom is enabled (default: true) */
|
|
3790
|
-
enabled?: boolean;
|
|
3791
|
-
}
|
|
3792
|
-
/**
|
|
3793
|
-
* Touch event handlers
|
|
3794
|
-
*/
|
|
3795
|
-
interface ZoomGestureHandlers {
|
|
3796
|
-
onTouchStart: (e: react__default.TouchEvent) => void;
|
|
3797
|
-
onTouchMove: (e: react__default.TouchEvent) => void;
|
|
3798
|
-
onTouchEnd: (e: react__default.TouchEvent) => void;
|
|
3799
|
-
}
|
|
3800
|
-
/**
|
|
3801
|
-
* Return type for useZoomGesture
|
|
3802
|
-
*/
|
|
3803
|
-
interface UseZoomGestureReturn {
|
|
3804
|
-
/** Current scale factor (1 = normal) */
|
|
3805
|
-
scale: number;
|
|
3806
|
-
/** Current X translation in pixels */
|
|
3807
|
-
translateX: number;
|
|
3808
|
-
/** Current Y translation in pixels */
|
|
3809
|
-
translateY: number;
|
|
3810
|
-
/** Whether actively zooming (2+ fingers) */
|
|
3811
|
-
isZooming: boolean;
|
|
3812
|
-
/** Whether currently panning while zoomed */
|
|
3813
|
-
isPanning: boolean;
|
|
3814
|
-
/** Whether snap-back animation is playing */
|
|
3815
|
-
isAnimating: boolean;
|
|
3816
|
-
/** Whether vertical swipe is locked */
|
|
3817
|
-
isSwipeLocked: boolean;
|
|
3818
|
-
/** Touch event handlers to spread on container */
|
|
3819
|
-
handlers: ZoomGestureHandlers;
|
|
3820
|
-
/** Manually reset to default state */
|
|
3821
|
-
reset: () => void;
|
|
3822
|
-
/** CSS transform string for convenience */
|
|
3823
|
-
transform: string;
|
|
3824
|
-
/** CSS transform-origin string */
|
|
3825
|
-
transformOrigin: string;
|
|
3826
|
-
/**
|
|
3827
|
-
* CSS styles for container element.
|
|
3828
|
-
* Includes `touchAction: 'none'` for proper gesture handling on mobile.
|
|
3829
|
-
* Always spread this on your container for best compatibility.
|
|
3830
|
-
*/
|
|
3831
|
-
containerStyle: react__default.CSSProperties;
|
|
3832
|
-
/**
|
|
3833
|
-
* CSS transition string for snap-back animation.
|
|
3834
|
-
* Apply this to the transform property for smooth animations.
|
|
3835
|
-
*/
|
|
3836
|
-
transitionStyle: react__default.CSSProperties;
|
|
3837
|
-
}
|
|
3838
|
-
/**
|
|
3839
|
-
* useZoomGesture - Pinch-to-zoom gesture handler
|
|
3840
|
-
*
|
|
3841
|
-
* Handles pinch gestures for video zoom with pan support.
|
|
3842
|
-
* Always snaps back to scale=1 on release (Instagram Reels behavior).
|
|
3843
|
-
*
|
|
3844
|
-
* @example
|
|
3845
|
-
* ```tsx
|
|
3846
|
-
* function VideoPlayer({ video }: { video: VideoItem }) {
|
|
3847
|
-
* const {
|
|
3848
|
-
* transform,
|
|
3849
|
-
* transformOrigin,
|
|
3850
|
-
* containerStyle,
|
|
3851
|
-
* handlers,
|
|
3852
|
-
* isZooming,
|
|
3853
|
-
* } = useZoomGesture({
|
|
3854
|
-
* onZoomStart: () => enterCleanMode('zoom'),
|
|
3855
|
-
* onZoomEnd: () => exitCleanMode(),
|
|
3856
|
-
* snapBackAnimation: 'ease', // smooth snap-back
|
|
3857
|
-
* });
|
|
3858
|
-
*
|
|
3859
|
-
* return (
|
|
3860
|
-
* <div
|
|
3861
|
-
* style={{
|
|
3862
|
-
* ...containerStyle, // includes touchAction: 'none' for proper gesture handling
|
|
3863
|
-
* transform,
|
|
3864
|
-
* transformOrigin,
|
|
3865
|
-
* }}
|
|
3866
|
-
* {...handlers}
|
|
3867
|
-
* >
|
|
3868
|
-
* <video src={video.url} />
|
|
3869
|
-
* </div>
|
|
3870
|
-
* );
|
|
3871
|
-
* }
|
|
3872
|
-
* ```
|
|
3873
|
-
*
|
|
3874
|
-
* @remarks
|
|
3875
|
-
* **Important:** Always spread `containerStyle` on your container element.
|
|
3876
|
-
* This sets `touchAction: 'none'` which is required for `preventDefault()` to work
|
|
3877
|
-
* on mobile browsers (Chrome 56+, Safari) where touch events are passive by default.
|
|
3878
|
-
*/
|
|
3879
|
-
declare function useZoomGesture(config?: UseZoomGestureConfig): UseZoomGestureReturn;
|
|
3880
|
-
|
|
3881
3862
|
/**
|
|
3882
3863
|
* useReportedVideo - Hook to check/manage reported video state
|
|
3883
3864
|
*
|
package/dist/index.js
CHANGED
|
@@ -46,19 +46,17 @@ var PlaylistFeedAdapter = class {
|
|
|
46
46
|
});
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
|
-
const
|
|
50
|
-
const items = currentState.items;
|
|
49
|
+
const items = this.playlistManager.getFullItems();
|
|
51
50
|
return {
|
|
52
51
|
items,
|
|
53
52
|
nextCursor: null,
|
|
54
|
-
// Playlist sliding window
|
|
53
|
+
// Playlist is finite — sliding window manages memory, not pagination
|
|
55
54
|
hasMore: false
|
|
56
55
|
};
|
|
57
56
|
}
|
|
58
57
|
async getContentDetail(id) {
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
if (item) return item;
|
|
58
|
+
const fullItem = this.playlistManager.getFullItems().find((i) => i.id === id);
|
|
59
|
+
if (fullItem) return fullItem;
|
|
62
60
|
throw new Error(`Content not found in playlist: ${id}`);
|
|
63
61
|
}
|
|
64
62
|
/**
|
|
@@ -3742,8 +3740,8 @@ function PlaylistSheet({ headerAccessory, translations }) {
|
|
|
3742
3740
|
);
|
|
3743
3741
|
const isOpen = state.isPlaylistSheetOpen;
|
|
3744
3742
|
const onClose = useCallback(() => {
|
|
3745
|
-
|
|
3746
|
-
}, [
|
|
3743
|
+
uiStore.getState().closePlaylistSheet();
|
|
3744
|
+
}, [uiStore]);
|
|
3747
3745
|
const handleItemSelect = useCallback(
|
|
3748
3746
|
(index) => {
|
|
3749
3747
|
jumpTo(index);
|
|
@@ -4419,7 +4417,14 @@ function SlotComposer({
|
|
|
4419
4417
|
const reactiveContent = useFeedSelector(
|
|
4420
4418
|
(state) => state.itemsById.get(initialContent.id) ?? initialContent
|
|
4421
4419
|
);
|
|
4422
|
-
const {
|
|
4420
|
+
const {
|
|
4421
|
+
isZooming,
|
|
4422
|
+
transform,
|
|
4423
|
+
transformOrigin,
|
|
4424
|
+
containerStyle,
|
|
4425
|
+
transitionStyle,
|
|
4426
|
+
handlers: zoomHandlers
|
|
4427
|
+
} = useZoomGesture({
|
|
4423
4428
|
enabled: true,
|
|
4424
4429
|
maxScale: zoomMaxScale,
|
|
4425
4430
|
snapBackAnimation: zoomSnapBackAnimation,
|
|
@@ -4500,6 +4505,10 @@ function SlotComposer({
|
|
|
4500
4505
|
state: {
|
|
4501
4506
|
cleanMode,
|
|
4502
4507
|
isZoomActive: isZooming,
|
|
4508
|
+
zoomTransform: transform,
|
|
4509
|
+
zoomTransformOrigin: transformOrigin,
|
|
4510
|
+
zoomContainerStyle: containerStyle,
|
|
4511
|
+
zoomTransitionStyle: transitionStyle,
|
|
4503
4512
|
isLiked: reactiveContent.isLiked ?? false,
|
|
4504
4513
|
isBookmarked,
|
|
4505
4514
|
isCommentSheetOpen,
|
|
@@ -4516,7 +4525,8 @@ function SlotComposer({
|
|
|
4516
4525
|
handleCloseAll,
|
|
4517
4526
|
setCommentSheetOpen,
|
|
4518
4527
|
setMenuOpen,
|
|
4519
|
-
setReportSheetOpen
|
|
4528
|
+
setReportSheetOpen,
|
|
4529
|
+
zoomHandlers
|
|
4520
4530
|
},
|
|
4521
4531
|
components: {
|
|
4522
4532
|
ActionBarComponent: ({ icons, onOpenComments: onOpenC, onShare: onS }) => {
|
|
@@ -4579,6 +4589,11 @@ function SlotComposer({
|
|
|
4579
4589
|
initialContent.id,
|
|
4580
4590
|
cleanMode,
|
|
4581
4591
|
isZooming,
|
|
4592
|
+
transform,
|
|
4593
|
+
transformOrigin,
|
|
4594
|
+
containerStyle,
|
|
4595
|
+
transitionStyle,
|
|
4596
|
+
zoomHandlers,
|
|
4582
4597
|
isBookmarked,
|
|
4583
4598
|
isCommentSheetOpen,
|
|
4584
4599
|
isMenuOpen,
|
|
@@ -5236,11 +5251,7 @@ function VideoSlot({
|
|
|
5236
5251
|
reportedTitle,
|
|
5237
5252
|
reportedMessage,
|
|
5238
5253
|
reportedButtonText,
|
|
5239
|
-
style
|
|
5240
|
-
disableSpeedBoost,
|
|
5241
|
-
speedBoostSpeed,
|
|
5242
|
-
speedBoostHoldDelay,
|
|
5243
|
-
speedBoostPullDownThreshold
|
|
5254
|
+
style
|
|
5244
5255
|
}) {
|
|
5245
5256
|
const { playerEngine, uiStore } = useSDK();
|
|
5246
5257
|
const { shouldShowOverlay, dismissOverlay } = useReportedVideo(video.id);
|
|
@@ -5301,31 +5312,6 @@ function VideoSlot({
|
|
|
5301
5312
|
const setVolume = useCallback((v) => playerEngine.setVolume(v), [playerEngine]);
|
|
5302
5313
|
const toggleMute = useCallback(() => playerEngine.setMuted(!muted), [playerEngine, muted]);
|
|
5303
5314
|
const setMuted = useCallback((m) => playerEngine.setMuted(m), [playerEngine]);
|
|
5304
|
-
const speedLockedVideoIdRef = useRef(null);
|
|
5305
|
-
const preBoostSpeedRef = useRef(1);
|
|
5306
|
-
const handleSpeedBoost = useCallback(
|
|
5307
|
-
(speed) => {
|
|
5308
|
-
preBoostSpeedRef.current = playerEngine.store.getState().playbackRate;
|
|
5309
|
-
playerEngine.setPlaybackRate(speed);
|
|
5310
|
-
},
|
|
5311
|
-
[playerEngine]
|
|
5312
|
-
);
|
|
5313
|
-
const handleSpeedReset = useCallback(() => {
|
|
5314
|
-
playerEngine.setPlaybackRate(preBoostSpeedRef.current);
|
|
5315
|
-
}, [playerEngine]);
|
|
5316
|
-
const handleSpeedLock = useCallback(
|
|
5317
|
-
(speed) => {
|
|
5318
|
-
playerEngine.setPlaybackRate(speed);
|
|
5319
|
-
speedLockedVideoIdRef.current = video.id;
|
|
5320
|
-
},
|
|
5321
|
-
[playerEngine, video.id]
|
|
5322
|
-
);
|
|
5323
|
-
useEffect(() => {
|
|
5324
|
-
if (speedLockedVideoIdRef.current && speedLockedVideoIdRef.current !== video.id) {
|
|
5325
|
-
speedLockedVideoIdRef.current = null;
|
|
5326
|
-
playerEngine.setPlaybackRate(1);
|
|
5327
|
-
}
|
|
5328
|
-
}, [video.id, playerEngine]);
|
|
5329
5315
|
const baseResourceState = useMemo(
|
|
5330
5316
|
() => resourceStateOverride ?? mapToResourceState(allocation, index, focusedIndex),
|
|
5331
5317
|
[resourceStateOverride, allocation, index, focusedIndex]
|
|
@@ -5371,13 +5357,6 @@ function VideoSlot({
|
|
|
5371
5357
|
renderError,
|
|
5372
5358
|
renderLoading,
|
|
5373
5359
|
restoreFrame: pendingRestoreFrame ?? void 0,
|
|
5374
|
-
onSpeedBoost: disableSpeedBoost ? void 0 : handleSpeedBoost,
|
|
5375
|
-
onSpeedReset: disableSpeedBoost ? void 0 : handleSpeedReset,
|
|
5376
|
-
onSpeedLock: disableSpeedBoost ? void 0 : handleSpeedLock,
|
|
5377
|
-
disableSpeedBoost,
|
|
5378
|
-
speedBoostSpeed,
|
|
5379
|
-
speedBoostHoldDelay,
|
|
5380
|
-
speedBoostPullDownThreshold,
|
|
5381
5360
|
children: [
|
|
5382
5361
|
children,
|
|
5383
5362
|
shouldShowOverlay && /* @__PURE__ */ jsx(
|
|
@@ -5474,13 +5453,25 @@ function DefaultVideoSlotContent(props) {
|
|
|
5474
5453
|
renderError: renderError ?? defaultErrorRenderer,
|
|
5475
5454
|
className,
|
|
5476
5455
|
disableTap: enableZoom && isZoomActive,
|
|
5477
|
-
disableSpeedBoost: props.disableSpeedBoost,
|
|
5478
|
-
speedBoostSpeed: props.speedBoostSpeed,
|
|
5479
|
-
speedBoostHoldDelay: props.speedBoostHoldDelay,
|
|
5480
|
-
speedBoostPullDownThreshold: props.speedBoostPullDownThreshold,
|
|
5481
5456
|
onHidden: () => onContentHidden?.(video.id),
|
|
5482
5457
|
children: [
|
|
5483
|
-
|
|
5458
|
+
enableZoom ? /* @__PURE__ */ jsx(
|
|
5459
|
+
"div",
|
|
5460
|
+
{
|
|
5461
|
+
style: {
|
|
5462
|
+
...state.zoomContainerStyle,
|
|
5463
|
+
transform: state.zoomTransform,
|
|
5464
|
+
transformOrigin: state.zoomTransformOrigin,
|
|
5465
|
+
transition: state.zoomTransitionStyle.transition,
|
|
5466
|
+
position: "absolute",
|
|
5467
|
+
inset: 0,
|
|
5468
|
+
width: "100%",
|
|
5469
|
+
height: "100%"
|
|
5470
|
+
},
|
|
5471
|
+
...handlers.zoomHandlers,
|
|
5472
|
+
children: renderPlayer ? renderPlayer({ muted: false }) : /* @__PURE__ */ jsx(VideoPlayer, { muted: false })
|
|
5473
|
+
}
|
|
5474
|
+
) : renderPlayer ? renderPlayer({ muted: false }) : /* @__PURE__ */ jsx(VideoPlayer, { muted: false }),
|
|
5484
5475
|
showPoster && !isZoomActive && !cleanMode && /* @__PURE__ */ jsx(VideoSlotPoster, {}),
|
|
5485
5476
|
showPlayIndicator && !isZoomActive && /* @__PURE__ */ jsx(VideoSlotPlayIndicator, { persistWhenPaused: persistPlayIndicatorWhenPaused }),
|
|
5486
5477
|
showLikeAnimation && /* @__PURE__ */ jsx(
|
|
@@ -6552,8 +6543,8 @@ function createSDK(config) {
|
|
|
6552
6543
|
...config?.optimistic
|
|
6553
6544
|
});
|
|
6554
6545
|
const uiStore = createUIStore();
|
|
6555
|
-
const playlistManager = new PlaylistManager(playlist);
|
|
6556
|
-
const playlistCollectionManager = new PlaylistCollectionManager(playlist);
|
|
6546
|
+
const playlistManager = new PlaylistManager(playlist, {}, resourceGovernor, storage);
|
|
6547
|
+
const playlistCollectionManager = new PlaylistCollectionManager(playlist, storage);
|
|
6557
6548
|
const bootstrapSettings = async () => {
|
|
6558
6549
|
try {
|
|
6559
6550
|
const savedSpeed = await storage.get(STORAGE_KEY_SPEED);
|
|
@@ -6566,6 +6557,8 @@ function createSDK(config) {
|
|
|
6566
6557
|
uiStore.getState().setAutoScrollEnabled(!!savedAutoScroll);
|
|
6567
6558
|
logger.debug("[SDK] Restored auto-scroll from storage", { enabled: !!savedAutoScroll });
|
|
6568
6559
|
}
|
|
6560
|
+
await playlistCollectionManager.hydrateFromCache();
|
|
6561
|
+
logger.debug("[SDK] Hydrated playlist collection from cache");
|
|
6569
6562
|
} catch (error) {
|
|
6570
6563
|
logger.error("[SDK] Failed to restore settings from storage", error);
|
|
6571
6564
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xhub-short/sdk",
|
|
3
3
|
"sideEffects": false,
|
|
4
|
-
"version": "1.0.0-beta.
|
|
4
|
+
"version": "1.0.0-beta.26",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -21,13 +21,13 @@
|
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"zustand": "^5.0.0",
|
|
24
|
-
"@xhub-short/contracts": "1.0.0-beta.
|
|
25
|
-
"@xhub-short/adapters": "1.0.0-beta.
|
|
26
|
-
"@xhub-short/
|
|
27
|
-
"@xhub-short/
|
|
24
|
+
"@xhub-short/contracts": "1.0.0-beta.26",
|
|
25
|
+
"@xhub-short/adapters": "1.0.0-beta.26",
|
|
26
|
+
"@xhub-short/core": "1.0.0-beta.26",
|
|
27
|
+
"@xhub-short/ui": "1.0.0-beta.26"
|
|
28
28
|
},
|
|
29
29
|
"optionalDependencies": {
|
|
30
|
-
"@xhub-short/bridge": "0.1.0-beta.
|
|
30
|
+
"@xhub-short/bridge": "0.1.0-beta.25"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"react": "^19.0.0",
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"tsup": "^8.3.0",
|
|
44
44
|
"typescript": "^5.7.0",
|
|
45
45
|
"vitest": "^2.1.0",
|
|
46
|
-
"@xhub-short/
|
|
47
|
-
"@xhub-short/
|
|
46
|
+
"@xhub-short/vitest-config": "0.1.0-beta.13",
|
|
47
|
+
"@xhub-short/tsconfig": "0.0.1-beta.2"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "tsup",
|