mirror of
https://github.com/Jellify-Music/App.git
synced 2026-05-03 00:59:48 -05:00
Adding the crudest search functionality
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import Client from "../../../api/client";
|
||||
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { getItemsApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import { isEmpty, trim } from "lodash";
|
||||
|
||||
/**
|
||||
* Performs a search for items against the Jellyfin server, trimming whitespace
|
||||
* around the search term for the best possible results.
|
||||
* @param searchString The search term to look up against
|
||||
* @returns A promise of a BaseItemDto array, be it empty or not
|
||||
*/
|
||||
export async function search(searchString: string | undefined) : Promise<BaseItemDto[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
if (isEmpty(searchString))
|
||||
resolve([]);
|
||||
|
||||
getItemsApi(Client.api!)
|
||||
.getItems({
|
||||
searchTerm: trim(searchString),
|
||||
recursive: true,
|
||||
includeItemTypes: [
|
||||
'Audio',
|
||||
'MusicAlbum',
|
||||
'MusicArtist',
|
||||
'Playlist'
|
||||
]
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.data.Items)
|
||||
resolve(response.data.Items)
|
||||
else
|
||||
resolve([]);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error)
|
||||
});
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import Client from "../../../api/client";
|
||||
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { getSuggestionsApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
|
||||
export async function fetchSearchSuggestions() : Promise<BaseItemDto[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
getSuggestionsApi(Client.api!)
|
||||
.getSuggestions({
|
||||
userId: Client.user!.id,
|
||||
type: [
|
||||
'MusicArtist',
|
||||
'MusicAlbum',
|
||||
'Audio',
|
||||
'Playlist'
|
||||
]
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.data.Items)
|
||||
resolve(response.data.Items)
|
||||
else
|
||||
resolve([]);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export async function fetchSuggestedArtists() : Promise<BaseItemDto[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
getSuggestionsApi(Client.api!)
|
||||
.getSuggestions({
|
||||
userId: Client.user!.id,
|
||||
type: [
|
||||
'MusicArtist'
|
||||
]
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.data.Items)
|
||||
resolve(response.data.Items)
|
||||
else
|
||||
resolve([]);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export async function fetchSuggestedAlbums() : Promise<BaseItemDto[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
getSuggestionsApi(Client.api!)
|
||||
.getSuggestions({
|
||||
userId: Client.user!.id,
|
||||
type: [
|
||||
'MusicAlbum'
|
||||
]
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.data.Items)
|
||||
resolve(response.data.Items)
|
||||
else
|
||||
resolve([]);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export async function fetchSuggestedTracks() : Promise<BaseItemDto[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
getSuggestionsApi(Client.api!)
|
||||
.getSuggestions({
|
||||
userId: Client.user!.id,
|
||||
type: [
|
||||
'Audio'
|
||||
]
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.data.Items)
|
||||
resolve(response.data.Items)
|
||||
else
|
||||
resolve([]);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { QueryKeys } from "../../enums/query-keys";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { search } from "./functions/search";
|
||||
|
||||
export const useSearch = (searchString: string | undefined) => useQuery({
|
||||
queryKey: [QueryKeys.Search, searchString],
|
||||
queryFn: () => search(searchString)
|
||||
})
|
||||
@@ -0,0 +1,8 @@
|
||||
import { QueryKeys } from "../../enums/query-keys";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { fetchSearchSuggestions } from "./functions/suggestions";
|
||||
|
||||
export const useSearchSuggestions = () => useQuery({
|
||||
queryKey: [QueryKeys.SearchSuggestions],
|
||||
queryFn: () => fetchSearchSuggestions()
|
||||
})
|
||||
@@ -1,10 +1,37 @@
|
||||
import React from "react";
|
||||
import { View } from "tamagui";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
import Input from "../Global/helpers/input";
|
||||
import { debounce } from "lodash";
|
||||
import { useSearch } from "../../api/queries/search";
|
||||
import { Text } from "../Global/helpers/text";
|
||||
|
||||
export default function Search(): React.JSX.Element {
|
||||
|
||||
const [searchString, setSearchString] = useState<string | undefined>(undefined);
|
||||
|
||||
const { data: items, refetch } = useSearch(searchString)
|
||||
|
||||
useEffect(() => {
|
||||
debounce(() => {
|
||||
refetch()
|
||||
}, 500)
|
||||
}, [
|
||||
searchString
|
||||
])
|
||||
|
||||
return (
|
||||
<View>
|
||||
|
||||
</View>
|
||||
<SafeAreaView edges={["top", "right", "left"]}>
|
||||
<Input
|
||||
placeholder="The Seeker"
|
||||
onChangeText={(value) => setSearchString(value)}
|
||||
value={searchString}
|
||||
/>
|
||||
|
||||
{ items?.map(item => {
|
||||
return (
|
||||
<Text>{ item.Name ?? "" }</Text>
|
||||
)
|
||||
})}
|
||||
</SafeAreaView>
|
||||
)
|
||||
}
|
||||
@@ -36,4 +36,6 @@ export enum QueryKeys {
|
||||
UserData = "UserData",
|
||||
UpdatePlayerOptions = "UpdatePlayerOptions",
|
||||
Item = "Item",
|
||||
Search = "Search",
|
||||
SearchSuggestions = "SearchSuggestions",
|
||||
}
|
||||
Reference in New Issue
Block a user