import { useCallback, useMemo, useState } from 'react'; import { ObjectId, Track } from '@/back-api'; import { useServiceContext } from '@/service/ServiceContext'; import { TrackServiceProps } from './Track'; export type PlaylistElement = { trackId: ObjectId; }; export type ActivePlaylistServiceProps = { playTrackList: ObjectId[]; trackOffset?: number; trackActive?: Track; setNewPlaylist: (listIds: ObjectId[]) => void; setNewPlaylistShuffle: (listIds: ObjectId[]) => void; playInList: (id: number | undefined, listIds: ObjectId[]) => void; play: (id: ObjectId) => void; previous: () => void; next: () => void; first: () => void; }; export const useActivePlaylistService = (): ActivePlaylistServiceProps => { const { activePlaylist } = useServiceContext(); return activePlaylist; }; export function localShuffle(array: T[]): T[] { let currentIndex = array.length, randomIndex; // While there remain elements to shuffle. while (currentIndex != 0) { // Pick a remaining element. randomIndex = Math.floor(Math.random() * currentIndex); currentIndex--; // And swap it with the current element. [array[currentIndex], array[randomIndex]] = [ array[randomIndex], array[currentIndex], ]; } return array; } export const useActivePlaylistServiceWrapped = ( track: TrackServiceProps ): ActivePlaylistServiceProps => { const [playTrackList, setPlayTrackList] = useState([]); const [trackOffset, setTrackOffset] = useState(); const trackActive = useMemo(() => { return track.store.get( trackOffset !== undefined ? playTrackList[trackOffset] : undefined ); }, [track.store.data, playTrackList, trackOffset]); const clear = useCallback(() => { setPlayTrackList([]); setTrackOffset(undefined); }, [setPlayTrackList, setTrackOffset]); const play = useCallback( (id: ObjectId) => { setPlayTrackList([id]); setTrackOffset(0); }, [setPlayTrackList, setTrackOffset] ); const playInList = useCallback( (id: number | undefined, listIds: ObjectId[]) => { console.log(`Request play in list: ${id} in ${listIds?.length}`); setPlayTrackList(listIds); setTrackOffset(id); }, [setPlayTrackList, setTrackOffset] ); const setNewPlaylist = useCallback( (listIds: ObjectId[]) => { if (listIds.length == 0) { clear(); return; } setPlayTrackList(listIds); setTrackOffset(0); }, [setPlayTrackList, setTrackOffset, clear] ); const setNewPlaylistShuffle = useCallback( (listIds: ObjectId[]) => { if (listIds.length == 0) { clear(); return; } const newList = localShuffle(listIds); setPlayTrackList(newList); setTrackOffset(0); }, [setPlayTrackList, setTrackOffset, clear] ); const previous = useCallback(() => { setTrackOffset((previous) => { if (previous === undefined) { return previous; } if (previous === 0) { return previous; } return previous - 1; }); }, [setTrackOffset]); const next = useCallback(() => { setTrackOffset((previous) => { if (previous === undefined || playTrackList.length === 0) { return previous; } if (previous >= playTrackList.length - 1) { return previous; } return previous + 1; }); }, [playTrackList, setTrackOffset]); const first = useCallback(() => { setTrackOffset((previous) => { if (previous === undefined || playTrackList.length === 0) { return previous; } return 0; }); }, [playTrackList, setTrackOffset]); return { playTrackList, trackOffset, setNewPlaylist, setNewPlaylistShuffle, playInList, play, previous, next, trackActive, first, }; };