Skip to content

Commit

Permalink
feat: Browser Search sorta works, gotta implement filtering
Browse files Browse the repository at this point in the history
  • Loading branch information
LynithDev committed Sep 4, 2024
1 parent e1c96dc commit 5012f2c
Show file tree
Hide file tree
Showing 10 changed files with 159 additions and 32 deletions.
26 changes: 15 additions & 11 deletions apps/desktop/src/api/commands/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,25 +51,29 @@ pub async fn get_provider_package_version(
Ok(provider.get_version(&version).await?)
}

#[specta::specta]
#[tauri::command]
pub async fn search_provider_packages(
provider: Providers,
#[derive(specta::Type, serde::Deserialize, serde::Serialize)]
pub struct ProviderSearchQuery {
query: Option<String>,
limit: Option<u8>,
game_versions: Option<Vec<String>>,
categories: Option<Vec<String>>,
loaders: Option<Vec<Loader>>,
package_types: Option<Vec<PackageType>>,
open_source: Option<bool>,
) -> Result<ProviderSearchResults, String> {
}

#[specta::specta]
#[tauri::command]
pub async fn search_provider_packages(provider: Providers, query: ProviderSearchQuery) -> Result<ProviderSearchResults, String> {
Ok(provider
.search(
query,
limit,
game_versions,
categories,
loaders,
open_source,
query.query,
query.limit,
query.game_versions,
query.categories,
query.loaders,
query.package_types,
query.open_source,
)
.await?)
}
Expand Down
18 changes: 14 additions & 4 deletions apps/frontend/src/ui/components/base/TextField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type TextFieldProps = {
} & JSX.InputHTMLAttributes<HTMLInputElement>;

function TextField(props: TextFieldProps) {
const [split, rest] = splitProps(props, ['iconLeft', 'iconRight', 'inputFilter', 'onValidInput', 'onValidSubmit', 'labelClass']);
const [split, rest] = splitProps(props, ['iconLeft', 'iconRight', 'inputFilter', 'onValidInput', 'onValidSubmit', 'labelClass', 'onInput', 'onChange']);
const [isValid, setIsValid] = createSignal(true);
const id = createUniqueId();

Expand All @@ -30,9 +30,19 @@ function TextField(props: TextFieldProps) {
split.onValidInput(value);
}

function onSubmit() {
function onInput(e: Event) {
validate();

// @ts-expect-error -- I do not care about the event types anymore
split.onInput?.(e);
}

function onChange(e: Event) {
if (isValid() && split.onValidSubmit)
split.onValidSubmit(ref.value);

// @ts-expect-error -- I do not care about the event types anymore
split.onChange?.(e);
}

onMount(() => {
Expand All @@ -46,8 +56,8 @@ function TextField(props: TextFieldProps) {
id={id}
type="text"
ref={ref}
onInput={validate}
onChange={onSubmit}
onInput={onInput}
onChange={onChange}
{...rest}
/>
{split.iconRight && <span class={styles.icon}>{split.iconRight}</span>}
Expand Down
30 changes: 27 additions & 3 deletions apps/frontend/src/ui/hooks/useBrowser.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useNavigate } from '@solidjs/router';
import { type Accessor, type Context, For, type ParentProps, type Setter, Show, createContext, createEffect, createSignal, onMount, untrack, useContext } from 'solid-js';
import type { Cluster, ManagedPackage, PackageType, ProviderSearchResults, Providers } from '@onelauncher/client/bindings';
import type { Cluster, ManagedPackage, PackageType, ProviderSearchQuery, ProviderSearchResults, Providers } from '@onelauncher/client/bindings';
import useCommand, { tryResult } from './useCommand';
import { useRecentCluster } from './useCluster';
import { bridge } from '~imports';
Expand All @@ -19,6 +19,10 @@ interface BrowserControllerType {
displayCategory: (category: string) => void;
displayClusterSelector: () => void;

search: () => void;
searchQuery: Accessor<ProviderSearchQuery>;
setSearchQuery: Setter<ProviderSearchQuery>;

packageType: Accessor<PackageType>;
setPackageType: Setter<PackageType>;

Expand All @@ -33,11 +37,24 @@ export function BrowserProvider(props: ParentProps) {
const [mainPageCache, setMainPageCache] = createSignal<ProviderSearchResults>();
const [featured, setFeatured] = createSignal<ManagedPackage | undefined>();

// Used for the current "Browser Mode". It'll only show packages of the selected type
const [packageType, setPackageType] = createSignal<PackageType>('mod');

// Active cluster that results should be "focused" on
const [cluster, setCluster] = createSignal<Cluster>();
const recentCluster = useRecentCluster();

const [searchOptions, setSearchOptions] = createSignal<ProviderSearchQuery>({
query: '',
limit: 20,
categories: null,
game_versions: null,
loaders: null,
package_types: ['mod'],
open_source: null,
});

const navigate = useNavigate();
const recentCluster = useRecentCluster();

const modal = createModal(props => (
<ChooseClusterModal
Expand Down Expand Up @@ -65,11 +82,18 @@ export function BrowserProvider(props: ParentProps) {
modal.show();
},

search: () => {
navigate('/browser/search');
},
searchQuery: searchOptions,
setSearchQuery: setSearchOptions,

packageType,
setPackageType,

async refreshCache() {
const res = await tryResult(() => bridge.commands.searchProviderPackages('Modrinth', null, 10, null, null, null, null));
const opts = untrack(searchOptions);
const res = await tryResult(() => bridge.commands.searchProviderPackages('Modrinth', opts));

setMainPageCache(res);

Expand Down
8 changes: 7 additions & 1 deletion apps/frontend/src/ui/pages/browser/BrowserMain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ interface FeaturedProps {
}

function Featured(props: FeaturedProps) {
const browser = useBrowser();

const open = () => {
browser.displayPackage(props.package.id, props.package.provider);
};

return (
<div class="flex flex-col gap-y-1">
<h5 class="ml-2">Featured</h5>
Expand All @@ -55,7 +61,7 @@ function Featured(props: FeaturedProps) {
buttonStyle="ghost"
iconRight={<ChevronRightIcon />}
children="View Package"
onClick={() => { }}
onClick={open}
/>
</div>
</div>
Expand Down
30 changes: 20 additions & 10 deletions apps/frontend/src/ui/pages/browser/BrowserRoot.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Route } from '@solidjs/router';
import { For, type ParentProps } from 'solid-js';
import { For, type JSX, type ParentProps } from 'solid-js';
import { SearchMdIcon, Settings01Icon } from '@untitled-theme/icons-solid';
import type { PackageType } from '@onelauncher/client/bindings';
import BrowserMain from './BrowserMain';
import BrowserCategory from './BrowserCategory';
import BrowserPackage from './BrowserPackage';
import BrowserSearch from './BrowserSearch';
import Button from '~ui/components/base/Button';
import TextField from '~ui/components/base/TextField';
import useBrowser from '~ui/hooks/useBrowser';
Expand All @@ -16,6 +17,7 @@ function BrowserRoutes() {
<Route path="/" component={BrowserMain} />
<Route path="/category" component={BrowserCategory} />
<Route path="/package" component={BrowserPackage} children={<BrowserPackage.Routes />} />
<Route path="/search" component={BrowserSearch} />
</>
);
}
Expand All @@ -27,23 +29,31 @@ function BrowserRoot(props: ParentProps) {
}

function BrowserToolbar() {
// const controller = useBrowser();
const browser = useBrowser();

const onKeyPress: JSX.EventHandlerUnion<HTMLInputElement, KeyboardEvent> = (e) => {
if (e.key === 'Enter') {
const query = e.currentTarget.value;

browser.setSearchQuery(prev => ({
...prev,
query,
}));

browser.search();
}
};

return (
<div class="w-full flex flex-row justify-between bg-page">
<div class="flex flex-row gap-2">
{/* <Button
buttonStyle="secondary"
children={controller.cluster()?.meta.name || 'None'}
iconLeft={<Settings01Icon />}
onClick={controller.displayClusterSelector}
/> */}
</div>
<div class="flex flex-row gap-2" />

<div class="flex flex-row gap-2">
<TextField
iconLeft={<SearchMdIcon />}
value={browser.searchQuery().query || ''}
placeholder="Search for content"
onKeyPress={onKeyPress}
/>
</div>
</div>
Expand Down
34 changes: 34 additions & 0 deletions apps/frontend/src/ui/pages/browser/BrowserSearch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Show, createEffect, on } from 'solid-js';
import { BrowserContent } from './BrowserRoot';
import { bridge } from '~imports';
import SearchResultsContainer from '~ui/components/content/SearchResults';
import Spinner from '~ui/components/Spinner';
import useBrowser from '~ui/hooks/useBrowser';
import useCommand from '~ui/hooks/useCommand';

function BrowserSearch() {
const browser = useBrowser();

const [results, { refetch }] = useCommand(() => bridge.commands.searchProviderPackages('Modrinth', browser.searchQuery()));

createEffect(on(() => browser.searchQuery().query, () => {
refetch();
}));

return (
<BrowserContent>
<Spinner.Suspense>
<Show when={results() !== undefined}>
<SearchResultsContainer
category="test"
header="Results"
provider="Modrinth"
results={results()!.results}
/>
</Show>
</Spinner.Suspense>
</BrowserContent>
);
}

export default BrowserSearch;
21 changes: 21 additions & 0 deletions apps/testing/examples/search_packages.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use onelauncher::{data::PackageType, package::content, Result, State};

#[tokio::main]
async fn main() -> Result<()> {
let _ = State::get().await?;

let provider = content::Providers::Modrinth;
let results = provider.search(
Some("chatting".to_string()),
Some(5),
None,
None,
None,
Some(vec![PackageType::Mod]),
None
).await?;

println!("{:#?}", results);

Ok(())
}
13 changes: 12 additions & 1 deletion packages/core/src/api/package/content/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use modrinth::{Facet, FacetOperation};
use serde::{Deserialize, Serialize};

use crate::data::{Loader, ManagedPackage, ManagedUser, ManagedVersion};
use crate::data::{Loader, ManagedPackage, ManagedUser, ManagedVersion, PackageType};
use crate::package::content::modrinth::FacetBuilder;
use crate::store::{Author, ProviderSearchResults};
use crate::Result;
Expand Down Expand Up @@ -47,6 +47,7 @@ impl Providers {
game_versions: Option<Vec<String>>,
categories: Option<Vec<String>>,
loaders: Option<Vec<Loader>>,
package_types: Option<Vec<PackageType>>,
open_source: Option<bool>,
) -> Result<ProviderSearchResults> {
match self {
Expand All @@ -70,6 +71,16 @@ impl Providers {
}
}

if let Some(package_types) = package_types {
for package_type in package_types {
builder.or(Facet(
"project_types".to_string(),
FacetOperation::Eq,
package_type.get_name().to_string(),
));
}
}

if let Some(loaders) = loaders {
for loader in loaders {
builder.or(Facet(
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/api/package/content/modrinth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ impl FacetBuilder {
if i != 0 {
builder.push(',');
}
builder.push_str(f.to_string().as_str());
builder.push_str(format!("\"{}\"", f.to_string()).as_str());
}
builder.push(']');
}
Expand Down Expand Up @@ -322,7 +322,7 @@ where
if facets.is_empty() {
"".to_string()
} else {
format!("&facets={}", facets)
format!("&facets=[{}]", facets)
}
)
.as_str(),
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/store/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ pub enum PackageType {
ResourcePack,
/// Represents a shaderpack file
ShaderPack,
/// Represents a modpack file
ModPack,
}

impl PackageType {
Expand Down Expand Up @@ -59,6 +61,7 @@ impl PackageType {
"datapacks" => Some(PackageType::DataPack),
"resourcepacks" => Some(PackageType::ResourcePack),
"shaderpacks" => Some(PackageType::ShaderPack),
"modpack" => Some(PackageType::ModPack),
_ => None,
}
}
Expand All @@ -69,6 +72,7 @@ impl PackageType {
PackageType::DataPack => "datapack",
PackageType::ResourcePack => "resourcepack",
PackageType::ShaderPack => "shaderpack",
PackageType::ModPack => "modpack",
}
}

Expand All @@ -78,6 +82,7 @@ impl PackageType {
PackageType::DataPack => "datapacks",
PackageType::ResourcePack => "resourcepacks",
PackageType::ShaderPack => "shaderpacks",
PackageType::ModPack => "modpack",
}
}

Expand Down Expand Up @@ -283,6 +288,7 @@ impl PackageManager {
PackageType::DataPack => &self.datapacks,
PackageType::ResourcePack => &self.resourcepacks,
PackageType::ShaderPack => &self.shaderpacks,
_ => unreachable!(),
}
}

Expand All @@ -293,6 +299,7 @@ impl PackageManager {
PackageType::DataPack => &mut self.datapacks,
PackageType::ResourcePack => &mut self.resourcepacks,
PackageType::ShaderPack => &mut self.shaderpacks,
_ => unreachable!(),
}
}

Expand Down

0 comments on commit 5012f2c

Please sign in to comment.