@theoplayer/react-native-ui
Version:
A React Native UI for @theoplayer/react-native
103 lines • 4.14 kB
JavaScript
import React, { useContext, useState } from 'react';
import { StyleSheet, View } from 'react-native';
import { PlayerContext } from '../util/PlayerContext';
import { Slider } from '@miblanchard/react-native-slider';
import { useChaptersTrack, useDuration, useSeekable, useDebounce } from '../../hooks/barrel';
import { SingleThumbnailView } from './thumbnail/SingleThumbnailView';
import { useSliderTime } from './useSliderTime';
import { TestIDs } from '../../utils/TestIDs';
import { jsx as _jsx } from "react/jsx-runtime";
/**
* The delay in milliseconds before an actual seek is executed while scrubbing the SeekBar.
*/
const DEBOUNCE_SEEK_DELAY = 250;
const renderThumbnailView = (isScrubbing, scrubberTime, seekBarWidth) => {
return isScrubbing && scrubberTime !== undefined && /*#__PURE__*/_jsx(SingleThumbnailView, {
currentTime: scrubberTime,
seekBarWidth: seekBarWidth
});
};
export const SeekBar = props => {
const {
onScrubbing,
renderAboveThumbComponent: customRenderAboveThumbComponent
} = props;
const {
player
} = useContext(PlayerContext);
const [isScrubbing, setIsScrubbing] = useState(false);
const [scrubberTime, setScrubberTime] = useState(undefined);
const [width, setWidth] = useState(0);
const duration = useDuration();
const seekable = useSeekable();
const sliderTime = useSliderTime();
const chapters = useChaptersTrack();
const chapterMarkerTimes = chapters?.cues?.map(cue => cue.endTime).slice(0, -1) ?? [];
// Do not continuously seek while dragging the slider
const debounceSeek = useDebounce(value => {
player.currentTime = value;
}, DEBOUNCE_SEEK_DELAY);
const onSlidingStart = value => {
setIsScrubbing(true);
debounceSeek(value[0]);
};
const onSlidingValueChange = value => {
if (isScrubbing) {
if (onScrubbing) onScrubbing(value[0]);
setScrubberTime(value[0]);
debounceSeek(value[0]);
}
};
const onSlidingComplete = value => {
setScrubberTime(undefined);
if (onScrubbing) onScrubbing(undefined);
setIsScrubbing(false);
debounceSeek(value[0], true);
};
const normalizedDuration = isNaN(duration) || !isFinite(duration) ? 0 : Math.max(0, duration);
const seekableRange = {
start: seekable.length > 0 ? seekable[0].start : 0,
end: seekable.length > 0 ? seekable[seekable.length - 1].end : normalizedDuration
};
const renderAboveThumbComponent = (_index, value) => {
if (customRenderAboveThumbComponent) {
return customRenderAboveThumbComponent(isScrubbing, value, width);
}
return renderThumbnailView(isScrubbing, value, width);
};
return /*#__PURE__*/_jsx(PlayerContext.Consumer, {
children: context => /*#__PURE__*/_jsx(View, {
style: [props.style ?? {
flex: 1
}],
testID: props.testID ?? TestIDs.SEEK_BAR,
onLayout: event => {
setWidth(event.nativeEvent.layout.width);
},
children: /*#__PURE__*/_jsx(Slider, {
disabled: !(duration > 0) && seekable.length > 0 || context.adInProgress,
minimumValue: seekableRange.start,
maximumValue: seekableRange.end,
containerStyle: props.sliderContainerStyle ?? {
marginHorizontal: 8
},
minimumTrackStyle: props.sliderMinimumTrackStyle ?? {},
maximumTrackStyle: props.sliderMaximumTrackStyle ?? {},
step: 1000,
renderAboveThumbComponent: renderAboveThumbComponent,
onSlidingStart: onSlidingStart,
onValueChange: onSlidingValueChange,
onSlidingComplete: onSlidingComplete,
value: isScrubbing && scrubberTime !== undefined ? scrubberTime : sliderTime,
minimumTrackTintColor: context.style.colors.seekBarMinimum,
maximumTrackTintColor: context.style.colors.seekBarMaximum,
thumbTintColor: context.style.colors.seekBarDot,
thumbStyle: StyleSheet.flatten(props.thumbStyle),
thumbTouchSize: props.thumbTouchSize,
renderTrackMarkComponent: chapterMarkerTimes.length ? props.chapterMarkers : undefined,
trackMarks: chapterMarkerTimes
})
})
});
};
//# sourceMappingURL=SeekBar.js.map