karusic/front/src/service/ActivePlaylist.ts
2025-05-01 23:10:05 +02:00

147 lines
3.8 KiB
TypeScript

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<T>(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<ObjectId[]>([]);
const [trackOffset, setTrackOffset] = useState<number | undefined>();
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,
};
};