fix: browser category selector
This commit is contained in:
parent
2593b293de
commit
089fbd3e26
3 changed files with 53 additions and 14 deletions
|
|
@ -1,17 +1,16 @@
|
|||
import type { ClusterModel } from '@/bindings.gen';
|
||||
import type { ClusterModel, Provider, SearchQuery } from '@/bindings.gen';
|
||||
import { bindings } from '@/main';
|
||||
import { PROVIDERS } from '@/utils';
|
||||
import { useCommand } from '@onelauncher/common';
|
||||
import { createContext, useContext, useMemo, useState } from 'react';
|
||||
|
||||
type Provider = typeof PROVIDERS[number];
|
||||
|
||||
export interface BrowserControllerType {
|
||||
cluster: ClusterModel | undefined;
|
||||
setCluster: (cluster: ClusterModel | undefined) => void;
|
||||
provider: Provider;
|
||||
setProvider: (provider: Provider) => void;
|
||||
|
||||
query: SearchQuery;
|
||||
setQuery: (query: SearchQuery) => void;
|
||||
search: () => void;
|
||||
}
|
||||
|
||||
|
|
@ -28,14 +27,23 @@ export function BrowserProvider(props: any) {
|
|||
const { children } = props;
|
||||
const [cluster, setCluster] = useState<ClusterModel | undefined>(undefined);
|
||||
const [provider, setProvider] = useState<Provider>(PROVIDERS[0]);
|
||||
const [query, setQuery] = useState<SearchQuery>({
|
||||
filters: null,
|
||||
query: null,
|
||||
limit: 18 as unknown as bigint,
|
||||
offset: null,
|
||||
sort: null,
|
||||
});
|
||||
|
||||
const context = useMemo<BrowserControllerType>(() => ({
|
||||
cluster,
|
||||
setCluster,
|
||||
provider,
|
||||
setProvider,
|
||||
query,
|
||||
setQuery,
|
||||
search: () => {},
|
||||
}), [cluster, provider]);
|
||||
}), [cluster, provider, query]);
|
||||
|
||||
return (
|
||||
<BrowserContext.Provider value={context}>
|
||||
|
|
@ -43,3 +51,7 @@ export function BrowserProvider(props: any) {
|
|||
</BrowserContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useBrowserSearch(provider: Provider, query: SearchQuery) {
|
||||
return useCommand('searchPackages', () => bindings.core.searchPackages(provider, query));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import OneConfigLogo from '@/assets/logos/oneconfig.svg';
|
||||
import { useBrowserContext } from '@/hooks/useBrowser';
|
||||
import { useBrowserContext, useBrowserSearch } from '@/hooks/useBrowser';
|
||||
import { Button, Show } from '@onelauncher/common/components';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
import { createFileRoute, useSearch } from '@tanstack/react-router';
|
||||
import { ChevronRightIcon } from '@untitled-theme/icons-react';
|
||||
import { BrowserLayout } from './route';
|
||||
|
||||
|
|
@ -20,6 +20,8 @@ function RouteComponent() {
|
|||
}
|
||||
|
||||
function Featured() {
|
||||
const context = useBrowserContext();
|
||||
const search = useBrowserSearch(context.provider, context.query);
|
||||
return (
|
||||
<Show when>
|
||||
<div className="flex flex-col gap-y-1">
|
||||
|
|
@ -48,6 +50,12 @@ function Featured() {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{search.status}
|
||||
{search.isSuccess && (
|
||||
<>
|
||||
{search.data.items.map(item => <p key={item.id}>{item.name}</p>)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Show>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
import type { Filters } from '@/bindings.gen';
|
||||
import ProviderIcon from '@/components/content/ProviderIcon';
|
||||
import { BrowserProvider, useBrowserContext } from '@/hooks/useBrowser';
|
||||
import { useClusters } from '@/hooks/useCluster';
|
||||
import { PROVIDERS } from '@/utils';
|
||||
import { browserCategories } from '@/utils/browser';
|
||||
import { Button, Dropdown, Show, TextField } from '@onelauncher/common/components';
|
||||
import { Dropdown, Show, TextField } from '@onelauncher/common/components';
|
||||
import { createFileRoute, Outlet } from '@tanstack/react-router';
|
||||
import { SearchMdIcon } from '@untitled-theme/icons-react';
|
||||
import { memo } from 'react';
|
||||
|
||||
export const Route = createFileRoute('/app/browser')({
|
||||
component: RouteComponent,
|
||||
|
|
@ -70,9 +72,9 @@ function BrowserSidebar() {
|
|||
</div>
|
||||
<div className="flex flex-col gap-y-1">
|
||||
<h6 className="my-1">Provider</h6>
|
||||
<Dropdown>
|
||||
<Dropdown onSelectionChange={id => context.setProvider(id as typeof context.provider)} selectedKey={context.provider}>
|
||||
{PROVIDERS.map(provider => (
|
||||
<Dropdown.Item key={provider}>
|
||||
<Dropdown.Item id={provider} key={provider}>
|
||||
<div className="flex flex-row">
|
||||
<ProviderIcon className="size-4 mr-2 self-center" provider={provider} />
|
||||
{provider}
|
||||
|
|
@ -86,8 +88,23 @@ function BrowserSidebar() {
|
|||
);
|
||||
}
|
||||
|
||||
const defaultFilters:Filters = {
|
||||
categories: null,
|
||||
game_versions: null,
|
||||
loaders: null,
|
||||
package_types: null
|
||||
}
|
||||
|
||||
function BrowserCategories() {
|
||||
const categories = browserCategories.byPackageType('mod', 'Modrinth');
|
||||
const context = useBrowserContext();
|
||||
const categories = browserCategories.byPackageType('mod', context.provider);
|
||||
|
||||
function switchCategory(category:string){
|
||||
if(context.query.filters?.categories?.includes(category))
|
||||
context.setQuery({...context.query, filters: {...defaultFilters, ...context.query.filters, categories: (context.query.filters?.categories ?? []).filter(cat=>cat!==category)}})
|
||||
else
|
||||
context.setQuery({...context.query, filters: {...defaultFilters, ...context.query.filters, categories: [...(context.query.filters?.categories ?? []), category]}})
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="top-0 grid grid-cols-[1fr_auto] h-fit min-w-50 gap-y-6">
|
||||
|
|
@ -95,11 +112,13 @@ function BrowserCategories() {
|
|||
<div className="flex flex-col gap-y-6">
|
||||
<Show when>
|
||||
<div className="flex flex-col gap-y-2">
|
||||
<h6 className="my-1">Categories</h6>
|
||||
<h6 className="my-1 uppercase">Categories</h6>
|
||||
{categories.map(category => (
|
||||
<p
|
||||
className="text-md capitalize opacity-100 hover:opacity-90 text-fg-primary hover:text-fg-primary-hover"
|
||||
aria-selected={context.query.filters?.categories?.includes(category.id)}
|
||||
className="text-md capitalize opacity-60 hover:opacity-90 text-fg-primary hover:text-fg-primary-hover aria-selected:opacity-100"
|
||||
key={category.id}
|
||||
onClick={()=>switchCategory(category.id)}
|
||||
>
|
||||
{category.display}
|
||||
</p>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue