karideo/front/src/service/ActivePlaylist.ts

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,
};
};