mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
[feature-107] sorting works for download playlist modal
This commit is contained in:
+17
-5
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
+24
-11
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user