Add autocomplete to Search Module

Suggestions when searching with the search bar Fixes #12
This commit is contained in:
ajnart
2022-06-06 20:02:21 +02:00
parent c50e11c75b
commit 39d66faf4e
2 changed files with 51 additions and 54 deletions

View File

@@ -1,10 +1,4 @@
import {
Kbd,
createStyles,
Text,
Popover,
TextInput,
} from '@mantine/core';
import { Kbd, createStyles, Text, Popover, Autocomplete } from '@mantine/core';
import { useDebouncedValue, useForm, useHotkeys } from '@mantine/hooks';
import { useEffect, useRef, useState } from 'react';
import {
@@ -36,13 +30,10 @@ export const SearchModule: IModule = {
export default function SearchBar(props: any) {
const { config, setConfig } = useConfig();
const [opened, setOpened] = useState(false);
const [results, setOpenedResults] = useState(false);
const [icon, setIcon] = useState(<Search />);
const queryUrl = config.settings.searchUrl ?? 'https://www.google.com/search?q=';
const textInput = useRef<HTMLInputElement>();
// Find a service with the type of 'Overseerr'
const service = config.services.find((s) => s.type === 'Overseerr');
const form = useForm({
initialValues: {
query: '',
@@ -50,19 +41,12 @@ export default function SearchBar(props: any) {
});
const [debounced, cancel] = useDebouncedValue(form.values.query, 250);
const [data, setData] = useState([]);
const [results, setResults] = useState<any[]>([]);
useEffect(() => {
if (form.values.query !== debounced || form.values.query === '') return;
setOpened(false);
setOpenedResults(true);
if (service) {
const serviceUrl = new URL(service.url);
axios
.post(`/api/modules/overseerr?query=${form.values.query}`, {
service,
})
.then((res) => setData(res.data.results ?? []));
}
.get(`/api/modules/search?q=${form.values.query}`)
.then((res) => setResults(res.data ?? []));
}, [debounced]);
useHotkeys([['ctrl+K', () => textInput.current && textInput.current.focus()]]);
const { classes, cx } = useStyles();
@@ -82,7 +66,10 @@ export default function SearchBar(props: any) {
return null;
}
// Data with label as item.name
const autocompleteData = results.map((result) => ({
label: result.phrase,
value: result.phrase,
}));
return (
<form
onChange={() => {
@@ -114,9 +101,6 @@ export default function SearchBar(props: any) {
}, 20);
})}
>
<Popover
opened={results}
target={
<Popover
opened={opened}
position="bottom"
@@ -129,8 +113,9 @@ export default function SearchBar(props: any) {
onFocusCapture={() => setOpened(true)}
onBlurCapture={() => setOpened(false)}
target={
<TextInput
<Autocomplete
variant="filled"
data={autocompleteData}
icon={icon}
ref={textInput}
rightSectionWidth={90}
@@ -143,13 +128,6 @@ export default function SearchBar(props: any) {
{...form.getInputProps('query')}
/>
}
>
<Text>
tip: Use the prefixes <b>!yt</b> and <b>!t</b> in front of your query to search on
YouTube or for a Torrent respectively.
</Text>
</Popover>
}
>
<Text>
Tip: Use the prefixes <b>!yt</b> and <b>!t</b> in front of your query to search on YouTube

View File

@@ -0,0 +1,19 @@
import axios from 'axios';
import { NextApiRequest, NextApiResponse } from 'next';
async function Get(req: NextApiRequest, res: NextApiResponse) {
const { q } = req.query;
const response = await axios.get(`https://duckduckgo.com/ac/?q=${q}`);
res.status(200).json(response.data);
}
export default async (req: NextApiRequest, res: NextApiResponse) => {
// Filter out if the reuqest is a POST or a GET
if (req.method === 'GET') {
return Get(req, res);
}
return res.status(405).json({
statusCode: 405,
message: 'Method not allowed',
});
};