diff --git a/apps/frontend/src/ui/components/content/Markdown.tsx b/apps/frontend/src/ui/components/content/Markdown.tsx index 00d5ee6c..d9a1a9c6 100644 --- a/apps/frontend/src/ui/components/content/Markdown.tsx +++ b/apps/frontend/src/ui/components/content/Markdown.tsx @@ -20,11 +20,10 @@ function Markdown(props: MarkdownProps) { e.preventDefault(); }} onClick={(e) => { - e.stopImmediatePropagation(); - e.preventDefault(); - - // TODO: Create a custom renderer or just use something else instead of markdown-it :D if (e.target.nodeName === 'A') { + e.stopImmediatePropagation(); + e.preventDefault(); + const target = e.target as HTMLAnchorElement; if (target.href.startsWith('http')) promptOpen(target.href); diff --git a/apps/frontend/src/ui/components/content/SearchResults.tsx b/apps/frontend/src/ui/components/content/SearchResults.tsx index 243801b2..2a6b566b 100644 --- a/apps/frontend/src/ui/components/content/SearchResults.tsx +++ b/apps/frontend/src/ui/components/content/SearchResults.tsx @@ -1,5 +1,6 @@ import type { Providers, SearchResult } from '@onelauncher/client/bindings'; import { ChevronDownIcon, Download01Icon, HeartIcon } from '@untitled-theme/icons-solid'; +import type { JSX } from 'solid-js'; import { For, Match, Show, Switch, createSignal } from 'solid-js'; import Button from '../base/Button'; import useBrowser from '~ui/hooks/useBrowser'; @@ -9,7 +10,7 @@ import { abbreviateNumber } from '~utils'; interface SearchResultsContainerProps { provider: Providers; results: SearchResult[]; - header: string; + header: string | JSX.Element; category: string; collapsable?: boolean; } @@ -22,7 +23,15 @@ function SearchResultsContainer(props: SearchResultsContainerProps) { return (
-
{props.header}
+ + +
{props.header}
+
+ + + {props.header} + +
+ +

No results found

+
+ @@ -107,16 +120,29 @@ function PackageItem(props: SearchResult & { provider: Providers; row?: boolean 'w-full h-28': !props.row, }} > - {`Icon - {`Icon + + )} + when={props.icon_url} + > + {`Icon + {`Icon +
diff --git a/apps/frontend/src/ui/hooks/useBrowser.tsx b/apps/frontend/src/ui/hooks/useBrowser.tsx index 16aad61f..47b21510 100644 --- a/apps/frontend/src/ui/hooks/useBrowser.tsx +++ b/apps/frontend/src/ui/hooks/useBrowser.tsx @@ -10,6 +10,8 @@ import Modal, { createModal } from '~ui/components/overlay/Modal'; import Dropdown from '~ui/components/base/Dropdown'; import Button from '~ui/components/base/Button'; +export type ProviderSearchOptions = ProviderSearchQuery & { provider: Providers }; + interface BrowserControllerType { cluster: Accessor; setCluster: Setter; @@ -20,8 +22,8 @@ interface BrowserControllerType { displayClusterSelector: () => void; search: () => void; - searchQuery: Accessor; - setSearchQuery: Setter; + searchQuery: Accessor; + setSearchQuery: Setter; packageType: Accessor; setPackageType: Setter; @@ -43,7 +45,8 @@ export function BrowserProvider(props: ParentProps) { // Active cluster that results should be "focused" on const [cluster, setCluster] = createSignal(); - const [searchOptions, setSearchOptions] = createSignal({ + const [searchOptions, setSearchOptions] = createSignal({ + provider: 'Modrinth', query: '', limit: 20, offset: 0, @@ -123,7 +126,7 @@ export function BrowserProvider(props: ParentProps) { createEffect(on(cluster, (cluster) => { if (cluster !== undefined) setSearchOptions((prev) => { - const opts: ProviderSearchQuery = { + const opts: ProviderSearchOptions = { ...prev, game_versions: [cluster.meta.mc_version], }; diff --git a/apps/frontend/src/ui/hooks/usePagination.tsx b/apps/frontend/src/ui/hooks/usePagination.tsx index 13f3fc9c..77b22b03 100644 --- a/apps/frontend/src/ui/hooks/usePagination.tsx +++ b/apps/frontend/src/ui/hooks/usePagination.tsx @@ -86,7 +86,9 @@ function usePagination(initialOptions: PaginationOptions) { ... - + 1}> + +
+
+
Provider
+ PROVIDERS.indexOf(controller.searchQuery().provider)} + onChange={index => controller.setSearchQuery(prev => ({ + ...prev, + provider: PROVIDERS[index] || 'Modrinth', + }))} + > + + {provider => ( + + {provider} + + )} + + +
); diff --git a/apps/frontend/src/ui/pages/browser/BrowserSearch.tsx b/apps/frontend/src/ui/pages/browser/BrowserSearch.tsx index 51d59a6e..96d4aa62 100644 --- a/apps/frontend/src/ui/pages/browser/BrowserSearch.tsx +++ b/apps/frontend/src/ui/pages/browser/BrowserSearch.tsx @@ -36,22 +36,25 @@ function BrowserSearch() { return ( - + + + +
Results
+ + + )} + /> +
-
- - - - - -
- - +
+ +
+
); } diff --git a/apps/frontend/src/utils/browser.ts b/apps/frontend/src/utils/browser.ts index 3bba4a28..716ec61f 100644 --- a/apps/frontend/src/utils/browser.ts +++ b/apps/frontend/src/utils/browser.ts @@ -1,53 +1,86 @@ -import type { BrowserListView, PackageType } from '@onelauncher/client/bindings'; +import type { BrowserListView, PackageType, Providers } from '@onelauncher/client/bindings'; export const BROWSER_VIEWS: BrowserListView[] = ['grid', 'list', 'preview'] as const; -export interface BrowserSidebarCategory { - name: string; - sub: string[]; +export interface CategoryItem { + display: string; + id: string; +} + +type ModCategories = [ + 'adventure', + 'library', + 'equipment', + 'decoration', + 'food', + 'magic', + 'performance', + 'storage', + 'technology', + 'utility', + 'worldgen', +]; + +const modMapping: Record = { + Modrinth: { + adventure: { + display: 'Adventure', + id: 'adventure', + }, + library: { + display: 'Library', + id: 'library', + }, + decoration: { + display: 'Decoration', + id: 'decoration', + }, + equipment: { + display: 'Equipment', + id: 'equipment', + }, + food: { + display: 'Food', + id: 'food', + }, + magic: { + display: 'Magic', + id: 'magic', + }, + performance: { + display: 'Performance', + id: 'optimization', + }, + storage: { + display: 'Storage', + id: 'storage', + }, + technology: { + display: 'Technology', + id: 'technology', + }, + utility: { + display: 'Utility', + id: 'utility', + }, + worldgen: { + display: 'World Generation', + id: 'worldgen', + }, + }, }; export const browserCategories = { - byPackageType(packageType: PackageType): BrowserSidebarCategory[] { + byPackageType(packageType: PackageType): CategoryItem[] { switch (packageType) { case 'mod': return this.mod(); - case 'datapack': - return this.datapack(); - case 'resourcepack': - return this.resourcepack(); - case 'shaderpack': - return this.shaderpack(); } return []; }, - mod(): BrowserSidebarCategory[] { - return [ - { - name: 'Categories', - sub: [ - 'adventure', - 'magic', - 'technology', - 'utility', - 'worldgen', - 'miscellaneous', - ], - }, - ]; - }, - - datapack(): BrowserSidebarCategory[] { - return []; - }, - - resourcepack(): BrowserSidebarCategory[] { - return []; - }, - - shaderpack(): BrowserSidebarCategory[] { - return []; + mod(provider: Providers = 'Modrinth'): CategoryItem[] { + return Object.values(modMapping[provider]); }, };