UNPKG

@zezosoft/zezo-ott-react-native-video-player

Version:

Production-ready React Native OTT video player library for Android & iOS. Features: playlists, seasons, auto-next playback, subtitles (SRT/VTT), custom theming, analytics tracking, fullscreen mode, gesture controls, ads player (pre-roll/mid-roll/post-roll

124 lines (123 loc) 3.78 kB
"use strict"; /* eslint-disable react-hooks/exhaustive-deps */ import React, { useEffect, useMemo, useCallback } from 'react'; import { View, StyleSheet } from 'react-native'; import { Slider } from 'react-native-awesome-slider'; import { useSharedValue, withTiming } from 'react-native-reanimated'; import { moderateScale } from 'react-native-size-matters'; import { useVideoPlayerConfig } from "../context/index.js"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; const ProgressBar = /*#__PURE__*/React.memo(({ duration, currentTime, bufferedTime, onSeek, showThumb = true, disabled = false, adMarkers = [], height }) => { const { colors, metrics } = useVideoPlayerConfig(); const sliderHeight = height ?? metrics.sliderHeight; const thumbSize = useMemo(() => { return sliderHeight * 3; }, [sliderHeight]); const progress = useSharedValue(currentTime); const cache = useSharedValue(bufferedTime); const min = useSharedValue(0); const max = useSharedValue(duration); useEffect(() => { progress.value = withTiming(currentTime, { duration: 160 }); }, [currentTime]); useEffect(() => { cache.value = withTiming(bufferedTime, { duration: 180 }); }, [bufferedTime]); useEffect(() => { max.value = duration; }, [duration]); const adPositions = useMemo(() => { if (duration <= 0) return []; return adMarkers.map(t => t / duration * 100); }, [adMarkers, duration]); const handleSeek = useCallback(value => { if (!disabled) onSeek?.(value); }, [onSeek, disabled]); return /*#__PURE__*/_jsxs(View, { style: [styles.container, { height: thumbSize }], children: [/*#__PURE__*/_jsx(Slider, { progress: progress, minimumValue: min, maximumValue: max, cache: cache, disable: disabled, onValueChange: handleSeek, containerStyle: [styles.sliderContainer, { borderRadius: sliderHeight / 2, height: sliderHeight }], renderThumb: showThumb ? () => /*#__PURE__*/_jsx(View, { style: { backgroundColor: colors.primary, width: thumbSize, height: thumbSize, borderRadius: thumbSize / 2 } }) : () => null, renderBubble: () => null, thumbWidth: showThumb ? thumbSize : 0, theme: { minimumTrackTintColor: colors.primary, maximumTrackTintColor: colors.secondary, cacheTrackTintColor: colors.buffer, disableMinTrackTintColor: colors.primary, bubbleBackgroundColor: colors.white } }), adPositions.length > 0 && /*#__PURE__*/_jsx(View, { style: styles.adMarkersContainer, pointerEvents: "none", children: adPositions.map((pos, index) => /*#__PURE__*/_jsx(View, { style: [styles.adMarker, { left: `${pos}%`, backgroundColor: colors.primary, width: sliderHeight }] }, `ad-${index}`)) })] }); }, (p, n) => p.currentTime === n.currentTime && p.bufferedTime === n.bufferedTime && p.duration === n.duration && p.disabled === n.disabled && p.showThumb === n.showThumb && p.height === n.height && JSON.stringify(p.adMarkers) === JSON.stringify(n.adMarkers)); export default ProgressBar; const styles = StyleSheet.create({ container: { position: 'relative', width: '100%', overflow: 'hidden', justifyContent: 'center' }, sliderContainer: { overflow: 'hidden' }, adMarkersContainer: { position: 'absolute', width: '100%', height: '100%', justifyContent: 'center' }, adMarker: { position: 'absolute', aspectRatio: 1, top: '50%', transform: [{ translateY: -moderateScale(2.5) }] } }); //# sourceMappingURL=ProgressBar.js.map