OneLauncher-Cracked/apps/frontend/src/ui/pages/browser/BrowserMain.tsx
2024-08-03 08:39:12 +02:00

138 lines
3.4 KiB
TypeScript

import { A } from '@solidjs/router';
import { Download01Icon, FileCode01Icon, FilterLinesIcon, SearchMdIcon } from '@untitled-theme/icons-solid';
import { For, createSignal, onMount } from 'solid-js';
import type { ManagedPackage } from '~bindings';
import { bridge } from '~imports';
import Button from '~ui/components/base/Button';
import Dropdown from '~ui/components/base/Dropdown';
import TextField from '~ui/components/base/TextField';
import ModCard, { Provider } from '~ui/components/content/ModCard';
import { tryResult } from '~ui/hooks/useCommand';
import { createSortable } from '~utils';
interface CardProps {
id: string;
name: string;
date_added: number;
date_updated: number;
provider: Provider;
};
interface BrowserFilters {
provider: Provider[]; // TODO: Change with Provider types from Rust
}
function BrowserMain() {
const [_filters, _setFilters] = createSignal<BrowserFilters>({
provider: [Provider.Curseforge],
});
const [modRowData, setModRowData] = createSignal<ModsRowProps[]>([]);
onMount(() => {
Promise.all([
tryResult(bridge.commands.randomMods),
tryResult(bridge.commands.getMod, 'oneconfig'),
tryResult(bridge.commands.getMod, 'chatting'),
tryResult(bridge.commands.getMod, 'patcher'),
]).then((pkgs) => {
const list: ModsRowProps[] = [
{
header: 'Polyfrost',
category: 'polyfrost',
packages: [
pkgs[1],
pkgs[2],
pkgs[3],
],
},
{
header: 'Random Mods',
category: 'random',
packages: pkgs[0],
},
];
setModRowData(list);
});
});
const sortable = createSortable<CardProps>([], {
'A-Z': (a, b) => a.name.localeCompare(b.name),
'Z-A': (a, b) => b.name.localeCompare(a.name),
'Last Updated': (a, b) => a.date_updated - b.date_updated,
'New': (a, b) => b.date_added - a.date_added,
});
return (
<div class="flex flex-col flex-1 h-full gap-2 relative">
<div class="flex flex-row justify-between sticky top-0 z-10 bg-primary">
<div class="flex flex-row gap-2 h-8">
<TextField
iconLeft={<SearchMdIcon />}
placeholder="Search for content"
/>
<Dropdown.Minimal
onChange={sortable.setKey}
icon={<FilterLinesIcon />}
>
<For each={Object.keys(sortable.sortables)}>
{sortable => (
<Dropdown.Row>{sortable}</Dropdown.Row>
)}
</For>
</Dropdown.Minimal>
</div>
<div class="flex flex-row gap-2 justify-end">
<Button
iconLeft={<Download01Icon />}
children="From URL"
/>
<Button
iconLeft={<FileCode01Icon />}
children="From File"
buttonStyle="secondary"
/>
</div>
</div>
<div class="flex flex-col gap-4 py-2">
<For each={modRowData()}>
{row => (
<ModsRow {...row} />
)}
</For>
</div>
</div>
);
}
interface ModsRowProps {
header: string;
category: string;
packages: ManagedPackage[];
};
function ModsRow(props: ModsRowProps) {
return (
<div class="flex flex-col flex-1 gap-3">
<div class="flex flex-row flex-1 justify-between">
<h4>{props.header}</h4>
<A class="text-fg-secondary hover:text-fg-secondary-hover active:text-fg-secondary-pressed" href={`category?category=${props.category}`}>See all</A>
</div>
<div class="flex flex-row gap-2 max-w-full flex-wrap">
<For each={props.packages}>
{mod => <ModCard {...mod} />}
</For>
</div>
</div>
);
}
export default BrowserMain;