first commit
Some checks failed
Build / run (push) Has been cancelled

This commit is contained in:
maher
2025-10-29 11:42:25 +01:00
commit 703f50a09d
4595 changed files with 385164 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
import {usePlayerStore} from '@common/player/hooks/use-player-store';
import {useTrans} from '@common/i18n/use-trans';
import {message} from '@common/i18n/message';
import {usePlayerActions} from '@common/player/hooks/use-player-actions';
import {IconButton} from '@common/ui/buttons/icon-button';
import {ButtonProps} from '@common/ui/buttons/button';
import {ReactElement} from 'react';
import {SvgIconProps} from '@common/icons/svg-icon';
import {MediaSeekForward15Icon} from '@common/icons/media/media-seek-forward15';
interface Props {
color?: ButtonProps['color'];
size?: ButtonProps['size'];
iconSize?: ButtonProps['size'];
className?: string;
seconds?: number | string;
children?: ReactElement<SvgIconProps>;
}
export function SeekButton({
size = 'md',
iconSize,
color,
className,
seconds = '+15',
children,
}: Props) {
const {trans} = useTrans();
const player = usePlayerActions();
const playerReady = usePlayerStore(s => s.providerReady);
return (
<IconButton
disabled={!playerReady}
aria-label={trans(message('Next'))}
size={size}
color={color}
iconSize={iconSize}
className={className}
onClick={() => {
player.seek(seconds);
}}
>
{children || <MediaSeekForward15Icon />}
</IconButton>
);
}

View File

@@ -0,0 +1,63 @@
import {Slider} from '@common/ui/forms/slider/slider';
import {UseSliderProps} from '@common/ui/forms/slider/use-slider';
import {usePlayerActions} from '@common/player/hooks/use-player-actions';
import {usePlayerStore} from '@common/player/hooks/use-player-store';
import {useCurrentTime} from '@common/player/hooks/use-current-time';
import {useRef} from 'react';
interface Props {
trackColor?: UseSliderProps['trackColor'];
fillColor?: UseSliderProps['fillColor'];
className?: string;
onPointerMove?: UseSliderProps['onPointerMove'];
}
export function Seekbar({
trackColor,
fillColor,
className,
onPointerMove,
}: Props) {
const {pause, seek, setIsSeeking, play, getState} = usePlayerActions();
const duration = usePlayerStore(s => s.mediaDuration);
const playerReady = usePlayerStore(s => s.providerReady);
const pauseWhileSeeking = usePlayerStore(s => s.pauseWhileSeeking);
const currentTime = useCurrentTime();
const wasPlayingBeforeDragging = useRef(false);
return (
<Slider
fillColor={fillColor}
trackColor={trackColor}
thumbSize="w-14 h-14"
showThumbOnHoverOnly
className={className}
width="w-auto"
isDisabled={!playerReady}
value={currentTime}
minValue={0}
maxValue={duration}
onPointerMove={onPointerMove}
onPointerDown={() => {
setIsSeeking(true);
if (pauseWhileSeeking) {
wasPlayingBeforeDragging.current =
getState().isPlaying || getState().isBuffering;
pause();
}
}}
onChange={value => {
getState().emit('progress', {currentTime: value});
seek(value);
}}
onChangeEnd={() => {
setIsSeeking(false);
if (pauseWhileSeeking && wasPlayingBeforeDragging.current) {
play();
wasPlayingBeforeDragging.current = false;
}
}}
/>
);
}