[feature-107] sorting works for download playlist modal

This commit is contained in:
MathieuG-P
2024-05-19 20:07:03 +02:00
parent c02ac39184
commit 7f726537ff
2 changed files with 41 additions and 16 deletions
@@ -4,6 +4,7 @@ import { BsmDropdownButton } from "renderer/components/shared/bsm-dropdown-butto
import { BsmSelect, BsmSelectOption } from "renderer/components/shared/bsm-select.component";
import { cn } from "renderer/helpers/css-class.helpers";
import { useConstant } from "renderer/hooks/use-constant.hook";
import { useOnUpdate } from "renderer/hooks/use-on-update.hook";
import { PlaylistSearchParams, BsvSearchOrder } from "shared/models/maps/beat-saver.model";
type Props = {
@@ -20,23 +21,34 @@ export function DownloadPlaylistModalHeader({ className, value, onSubmit }: Prop
const [order, setOrder] = useState<BsvSearchOrder>(value?.sortOrder || BsvSearchOrder.Latest);
const sortOptions: BsmSelectOption<BsvSearchOrder>[] = useConstant(() => {
return Object.values(BsvSearchOrder).map(sort => ({ text: `beat-saver.maps-sorts.${sort}`, value: sort }));
return Object.values(BsvSearchOrder).reduce((acc, value) => {
if(value === BsvSearchOrder.Rating){ return acc; }
acc.push({ text: `beat-saver.maps-sorts.${value}`, value: value });
return acc;
}, []);
});
const submit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
useOnUpdate(() => {
submit();
}, [order]);
const handleOrderChange = (value: BsvSearchOrder) => {
setOrder(() => value);
};
const submit = () => {
if(!onSubmit){ return; }
onSubmit({ q: query, sortOrder: order });
};
return (
<form className={cn('flex flex-row gap-2', className)} onSubmit={submit}>
<form className={cn('flex flex-row gap-2', className)} onSubmit={e => {e.preventDefault(); submit();}}>
<BsmDropdownButton buttonClassName="flex items-center justify-center h-full rounded-full px-2 py-1 !bg-light-main-color-1 dark:!bg-main-color-1" icon="filter" text="pages.version-viewer.maps.search-bar.filters-btn" withBar={false}>
<span>Filter Panel</span>
</BsmDropdownButton>
<input className="h-full theme-color-1 rounded-full px-2 grow pb-0.5" type="text" placeholder="Rechercher une playlist" value={query} onChange={e => setQuery(e.target.value)} />
<BsmButton type="submit" className="shrink-0 rounded-full py-1 px-3 !theme-color-1 flex justify-center items-center capitalize" icon="search" text="modals.download-maps.search-btn" withBar={false} />
<BsmSelect className="theme-color-1 rounded-full px-1 pb-0.5 text-center cursor-pointer" options={sortOptions} selected={order} onChange={setOrder}/>
<BsmSelect className="theme-color-1 rounded-full px-1 pb-0.5 text-center cursor-pointer" options={sortOptions} selected={order} onChange={handleOrderChange}/>
</form>
)
}
@@ -15,6 +15,8 @@ import { PlaylistItemComponentPropsMapper } from "shared/mappers/playlist/playli
import { motion } from "framer-motion"
import { PlaylistDownloaderService } from "renderer/services/playlist-downloader.service"
// TODO : Translate
export const DownloadPlaylistModal: ModalComponent<void, {version: BSVersion, ownedPlaylists$: Observable<LocalBPListsDetails[]>, ownedMaps$: Observable<BsmLocalMap[]>}> = (
{ resolver, options: { data: { version, ownedPlaylists$, ownedMaps$ }} }
) => {
@@ -41,7 +43,8 @@ export const DownloadPlaylistModal: ModalComponent<void, {version: BSVersion, ow
}, [searchParams])
const handleNewSearch = (value: Omit<PlaylistSearchParams, "page">) => {
setSearchParams({ ...value, page: 0});
setPlaylists(() => []);
setSearchParams(() => ({ ...value, page: 0}));
};
const loadMorePlaylists = () => {
@@ -51,16 +54,26 @@ export const DownloadPlaylistModal: ModalComponent<void, {version: BSVersion, ow
return (
<div className="max-w-[95vw] w-[970px] h-[85vh] flex flex-col gap-3">
<DownloadPlaylistModalHeader className="h-9 w-full" value={searchParams} onSubmit={handleNewSearch}/>
<ul className="p-2 size-full flex flex-row flex-wrap justify-start content-start gap-3 grow overflow-y-scroll overflow-x-hidden z-10">
{playlists.map(playlist => (
<PlaylistItem
key={playlist.playlistId}
{...PlaylistItemComponentPropsMapper.fromBsvPlaylist(playlist)}
onClickSync={() => lastValueFrom(playlistDownloader.downloadPlaylist({ downloadSource: playlist.downloadURL, ignoreSongsHashs: ownedMaps.map(map => map.hash), version }))}
/>
))}
<motion.span className="w-full h-8" onViewportEnter={loadMorePlaylists}/>
</ul>
{(() => {
if(loading && playlists.length === 0){
return <div className="flex justify-center items-center h-full w-full">Loading...</div>
}
else if(playlists.length === 0){
return <div className="flex justify-center items-center h-full w-full">No playlists found</div>
}
return (
<ul className="p-2 size-full flex flex-row flex-wrap justify-start content-start gap-3 grow overflow-y-scroll overflow-x-hidden z-10">
{playlists.map(playlist => (
<PlaylistItem
key={playlist.playlistId}
{...PlaylistItemComponentPropsMapper.fromBsvPlaylist(playlist)}
onClickSync={() => lastValueFrom(playlistDownloader.downloadPlaylist({ downloadSource: playlist.downloadURL, ignoreSongsHashs: ownedMaps.map(map => map.hash), version }))}
/>
))}
<motion.span className="block w-full h-8" onViewportEnter={loadMorePlaylists}/>
</ul>
)
})()}
</div>
)
}