147 lines
3.8 KiB
TypeScript
147 lines
3.8 KiB
TypeScript
import { useCallback, useMemo, useState } from 'react';
|
|
|
|
import { Media } from '@/back-api';
|
|
import { useServiceContext } from '@/service/ServiceContext';
|
|
import { MediaServiceProps } from './Media';
|
|
|
|
export type PlaylistElement = {
|
|
MediaId: number;
|
|
};
|
|
|
|
export type ActivePlaylistServiceProps = {
|
|
playMediaList: number[];
|
|
MediaOffset?: number;
|
|
MediaActive?: Media;
|
|
setNewPlaylist: (listIds: number[]) => void;
|
|
setNewPlaylistShuffle: (listIds: number[]) => void;
|
|
playInList: (id: number | undefined, listIds: number[]) => void;
|
|
play: (id: number) => void;
|
|
previous: () => void;
|
|
next: () => void;
|
|
first: () => void;
|
|
clear: () => 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 = (
|
|
Media: MediaServiceProps
|
|
): ActivePlaylistServiceProps => {
|
|
const [playMediaList, setPlayMediaList] = useState<number[]>([]);
|
|
const [MediaOffset, setMediaOffset] = useState<number | undefined>();
|
|
const MediaActive = useMemo(() => {
|
|
return Media.store.get(MediaOffset !== undefined ? playMediaList[MediaOffset] : undefined);
|
|
}, [Media.store.data, playMediaList, MediaOffset]);
|
|
|
|
const clear = useCallback(() => {
|
|
setPlayMediaList([]);
|
|
setMediaOffset(undefined);
|
|
}, [setPlayMediaList, setMediaOffset]);
|
|
|
|
const play = useCallback(
|
|
(id: number) => {
|
|
setPlayMediaList([id]);
|
|
setMediaOffset(0);
|
|
},
|
|
[setPlayMediaList, setMediaOffset]
|
|
);
|
|
const playInList = useCallback(
|
|
(id: number | undefined, listIds: number[]) => {
|
|
console.log(`Request paly in list: ${id} in ${listIds}`);
|
|
setPlayMediaList(listIds);
|
|
setMediaOffset(id);
|
|
},
|
|
[setPlayMediaList, setMediaOffset]
|
|
);
|
|
|
|
const setNewPlaylist = useCallback(
|
|
(listIds: number[]) => {
|
|
if (listIds.length == 0) {
|
|
clear();
|
|
return;
|
|
}
|
|
setPlayMediaList(listIds);
|
|
setMediaOffset(0);
|
|
},
|
|
[setPlayMediaList, setMediaOffset, clear]
|
|
);
|
|
|
|
const setNewPlaylistShuffle = useCallback(
|
|
(listIds: number[]) => {
|
|
if (listIds.length == 0) {
|
|
clear();
|
|
return;
|
|
}
|
|
const newList = localShuffle(listIds);
|
|
setPlayMediaList(newList);
|
|
setMediaOffset(0);
|
|
},
|
|
[setPlayMediaList, setMediaOffset, clear]
|
|
);
|
|
const previous = useCallback(() => {
|
|
setMediaOffset((previous) => {
|
|
if (previous === undefined) {
|
|
return previous;
|
|
}
|
|
if (previous === 0) {
|
|
return previous;
|
|
}
|
|
return previous - 1;
|
|
});
|
|
}, [setMediaOffset]);
|
|
const next = useCallback(() => {
|
|
setMediaOffset((previous) => {
|
|
if (previous === undefined || playMediaList.length === 0) {
|
|
return previous;
|
|
}
|
|
if (previous >= playMediaList.length - 1) {
|
|
return previous;
|
|
}
|
|
return previous + 1;
|
|
});
|
|
}, [playMediaList, setMediaOffset]);
|
|
const first = useCallback(() => {
|
|
setMediaOffset((previous) => {
|
|
if (previous === undefined || playMediaList.length === 0) {
|
|
return previous;
|
|
}
|
|
return 0;
|
|
});
|
|
}, [playMediaList, setMediaOffset]);
|
|
|
|
|
|
return {
|
|
playMediaList,
|
|
MediaOffset,
|
|
setNewPlaylist,
|
|
setNewPlaylistShuffle,
|
|
playInList,
|
|
play,
|
|
previous,
|
|
next,
|
|
MediaActive,
|
|
first,
|
|
clear,
|
|
};
|
|
};
|