react-udux-player
Version:
A customizable music player for React applications
224 lines (223 loc) • 5.82 kB
TypeScript
import type React from "react";
import type { RefObject } from "react";
export type DominantColors = Array<string>;
export interface Track {
id: string;
title: string;
artist: string;
album?: string;
duration?: number;
coverUrl?: string;
streamUrl: string;
isLiked?: boolean;
artistId?: string;
albumId?: string;
playlistId?: string;
coverArtDominantColors?: string[];
}
export type RepeatMode = "off" | "all" | "one";
export interface PlayerState {
queue: Track[];
currentTrackIndex: number | null;
isPlaying: boolean;
volume: number;
isMuted: boolean;
previousVolume: number;
shuffle: boolean;
repeat: RepeatMode;
playbackHistory: number[];
duration: number;
currentTime: number;
isBuffering: boolean;
previousTrackIndex: number | null;
isMinimized: boolean;
isFullScreen: boolean;
isNowPlayingView: boolean;
context: string | null;
isHidePlayer: boolean;
}
export type PlayerAction = {
type: "SET_QUEUE";
payload: Track[];
} | {
type: "TOGGLE_PLAY";
} | {
type: "MINIMIZE_PLAYER";
} | {
type: "TOGGLE_FULL_SCREEN";
} | {
type: "TOGGLE_HIDE_PLAYER";
payload: boolean;
} | {
type: "PLAY";
} | {
type: "PAUSE";
} | {
type: "NEXT_TRACK";
} | {
type: "PREVIOUS_TRACK";
} | {
type: "SEEK";
payload: number;
} | {
type: "SEEK_START";
} | {
type: "SEEK_END";
} | {
type: "SET_VOLUME";
payload: number;
} | {
type: "TOGGLE_MUTE";
} | {
type: "TOGGLE_SHUFFLE";
} | {
type: "TOGGLE_REPEAT";
} | {
type: "TOGGLE_NOW_PLAYING_VIEW";
} | {
type: "SET_NOW_PLAYING_VIEW";
payload: boolean;
} | {
type: "SET_DURATION";
payload: number;
} | {
type: "UPDATE_TIME";
payload: number;
} | {
type: "TRACK_ENDED";
} | {
type: "SET_CURRENT_TRACK";
payload: {
track: Track;
index?: number;
context?: string;
};
} | {
type: "ADD_TO_QUEUE";
payload: Track;
} | {
type: "UPDATE_TRACK_IN_QUEUE";
payload: {
id: string;
track: Track;
};
} | {
type: "UPDATE_TRACK_DURATION";
payload: {
id: string;
duration: number;
};
} | {
type: "ENDED";
} | {
type: "SET_PREVIOUS_TRACK_INDEX";
payload: number | null;
};
export interface Theme {
colors: {
primary: string;
background: string;
text: string;
textSecondary: string;
progressBar: string;
progressBarFilled: string;
controlBackground?: string;
playerBorder?: string;
};
sizes: {
playerHeight: string;
progressBarHeight: string;
controlButtonSize: string;
volumeSliderWidth?: string;
coverArtSize?: string;
};
borderRadius: string;
fontFamily?: string;
}
export declare const defaultTheme: Theme;
export interface CustomComponents {
PlayButton?: React.ComponentType<{
isPlaying: boolean;
onClick: () => void;
isBuffering: boolean;
}>;
NextButton?: React.ComponentType<{
onClick: () => void;
disabled: boolean;
}>;
PreviousButton?: React.ComponentType<{
onClick: () => void;
disabled: boolean;
}>;
ShuffleButton?: React.ComponentType<{
active: boolean;
onClick: () => void;
disabled: boolean;
}>;
RepeatButton?: React.ComponentType<{
mode: RepeatMode;
onClick: () => void;
disabled: boolean;
}>;
VolumeControl?: React.ComponentType<{
volume?: number;
isMuted?: boolean;
onVolumeChange?: (volume: number) => void;
onMuteToggle?: () => void;
}>;
ProgressBar?: React.ComponentType<{
currentTime: number;
duration: number;
onSeek: (time: number) => void;
isBuffering: boolean;
}>;
TrackInfo?: React.ComponentType<{
track: Track | null;
}>;
NowPlayingView?: React.ComponentType<{}>;
PlayerContainer?: React.ComponentType<{
children: React.ReactNode;
}>;
}
export interface PlayerCallbacks {
onTrackChange?: (track: Track | null) => void;
onPlaybackStateChange?: (isPlaying: boolean) => void;
onError?: (error: Error) => void;
onTimeUpdate?: (time: number) => void;
onQueueChange?: (queue: Track[]) => void;
onVolumeChange?: (volume: number, isMuted: boolean) => void;
onShuffleChange?: (shuffleEnabled: boolean) => void;
onRepeatChange?: (repeatMode: RepeatMode) => void;
onSeek?: (time: number) => void;
onEnded?: () => void;
onLike?: (track: Track | null, isLiked: boolean) => void;
onAddToPlaylist?: (track: Track | null) => void;
onFullscreenChange?: (isFullscreen: boolean) => void;
onViewChange?: (track: Track | null, isNowPlayingView: boolean) => void;
onMinimize?: () => void;
}
export interface PlayerContextType extends PlayerState {
dispatch: React.Dispatch<PlayerAction>;
playerRef: RefObject<HTMLVideoElement | null>;
tracksToPreload: number[];
theme: Theme;
components: CustomComponents;
callbacks?: Partial<PlayerCallbacks>;
togglePlay: () => void;
toggleHidePlayer: (payload: boolean) => void;
togglePlayNowPlayingView: () => void;
setNowPlayNowPlayingView: (payload: boolean) => void;
nextTrack: () => void;
previousTrack: () => void;
seek: (time: number) => void;
setVolume: (volume: number) => void;
toggleMute: () => void;
toggleShuffle: () => void;
toggleRepeat: () => void;
setQueue: (tracks: Track[]) => void;
setCurrentTrack?: (track: Track) => void;
playTrack?: (track: Track, context?: string) => void;
addToQueue?: (track: Track) => void;
minimizePlayer?: () => void;
currentTrack: Track | null;
}