mirror of
https://github.com/artegoser/ultyt.git
synced 2024-11-22 03:56:21 +03:00
feat: suggestions
This commit is contained in:
parent
b6bd7c01af
commit
5b2300cd79
3 changed files with 57 additions and 25 deletions
|
@ -16,7 +16,7 @@ export function ChannelComponent({
|
||||||
navigate(channel.url || "");
|
navigate(channel.url || "");
|
||||||
}}
|
}}
|
||||||
shadow="none"
|
shadow="none"
|
||||||
className="md:col-span-2 xl:col-span-3 2xl:col-span-4 gap-2 p-1 md:p-4"
|
className="md:col-span-2 xl:col-span-4 2xl:col-span-5 gap-2 p-1 md:p-4"
|
||||||
>
|
>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<div className="flex flex-row flex-wrap">
|
<div className="flex flex-row flex-wrap">
|
||||||
|
@ -27,18 +27,17 @@ export function ChannelComponent({
|
||||||
{channel.verified && <CheckCircleIcon className="w-6 h-6 p-1" />}
|
{channel.verified && <CheckCircleIcon className="w-6 h-6 p-1" />}
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
<p className="pt-4 text-start">
|
|
||||||
{channel.description || "No description"}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|
||||||
|
<CardBody className="flex flex-col p-1">
|
||||||
|
<p className="text-start">{channel.description || "No description"}</p>
|
||||||
{(channel.videos || -1) >= 0 && (
|
{(channel.videos || -1) >= 0 && (
|
||||||
<CardBody className="flex gap-3 flex-row">
|
|
||||||
<p className="text-md">
|
<p className="text-md">
|
||||||
{`${shortenNumber(channel.videos || -1)} videos`}
|
{`${shortenNumber(channel.videos || -1)} videos`}
|
||||||
</p>
|
</p>
|
||||||
</CardBody>
|
|
||||||
)}
|
)}
|
||||||
|
</CardBody>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,10 +14,7 @@ export function ItemComponent({ item, channel }: ItemComponentProps) {
|
||||||
);
|
);
|
||||||
} else if (item.type === "channel") {
|
} else if (item.type === "channel") {
|
||||||
item = item as Channel;
|
item = item as Channel;
|
||||||
return [
|
return <ChannelComponent channel={item} />;
|
||||||
<ChannelComponent channel={item} />,
|
|
||||||
<div className="2xl:col-span-1 xl:col-span-1 md:col-span-2 gap-2 p-1 md:p-4" />,
|
|
||||||
];
|
|
||||||
} else {
|
} else {
|
||||||
<div className="" key={Math.random()}>
|
<div className="" key={Math.random()}>
|
||||||
Idk how to render this
|
Idk how to render this
|
||||||
|
|
|
@ -8,14 +8,20 @@ import {
|
||||||
NavbarMenu,
|
NavbarMenu,
|
||||||
NavbarMenuItem,
|
NavbarMenuItem,
|
||||||
Input,
|
Input,
|
||||||
|
Button,
|
||||||
} from "@nextui-org/react";
|
} from "@nextui-org/react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Link, useNavigate, useSearchParams } from "react-router-dom";
|
import { Link, useNavigate, useSearchParams } from "react-router-dom";
|
||||||
|
|
||||||
export function NavbarComponent() {
|
export function NavbarComponent() {
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState(undefined as string | undefined);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
|
const [suggestions, setSuggestions] = useState([] as string[]);
|
||||||
|
async function updateSuggestions(query) {
|
||||||
|
const res = await window.piped_api.suggestions(query);
|
||||||
|
setSuggestions(res);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Navbar>
|
<Navbar>
|
||||||
|
@ -30,19 +36,49 @@ export function NavbarComponent() {
|
||||||
|
|
||||||
<NavbarContent className="sm:flex gap-4" justify="start">
|
<NavbarContent className="sm:flex gap-4" justify="start">
|
||||||
<NavbarItem>
|
<NavbarItem>
|
||||||
|
<div className="relative block">
|
||||||
<Input
|
<Input
|
||||||
isClearable
|
isClearable
|
||||||
radius="lg"
|
radius="lg"
|
||||||
placeholder="Type to search..."
|
placeholder="Type to search..."
|
||||||
startContent={<MagnifyingGlassIcon className="h-6 w-6" />}
|
startContent={<MagnifyingGlassIcon className="h-6 w-6" />}
|
||||||
onChange={(e) => setSearch(e.target.value)}
|
onChange={(e) => {
|
||||||
onKeyDown={(e) => {
|
updateSuggestions(e.target.value);
|
||||||
|
setSearch(e.target.value);
|
||||||
|
}}
|
||||||
|
onKeyDown={async (e) => {
|
||||||
if (e.key === "Enter") {
|
if (e.key === "Enter") {
|
||||||
navigate(`/search?q=${search}`);
|
await setSuggestions([]);
|
||||||
|
await navigate(`/search?q=${search}`);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
defaultValue={searchParams.get("q") || ""}
|
onClear={() => {
|
||||||
|
setSuggestions([]);
|
||||||
|
setSearch("");
|
||||||
|
}}
|
||||||
|
value={
|
||||||
|
(search !== undefined ? search : searchParams.get("q")) || ""
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
|
<div
|
||||||
|
className="absolute right-1/2 md:right-1 mt-1 flex flex-col justify-center backdrop-blur-3xl rounded-xl p-2 bg-gray-50 dark:bg-transparent"
|
||||||
|
style={{
|
||||||
|
backfaceVisibility: "hidden",
|
||||||
|
transform: "translateZ(0)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{suggestions.length > 0 &&
|
||||||
|
suggestions.map((suggestion) => (
|
||||||
|
<Button
|
||||||
|
key={suggestion}
|
||||||
|
onClick={() => navigate(`/search?q=${suggestion}`)}
|
||||||
|
className="m-1"
|
||||||
|
>
|
||||||
|
{suggestion}
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</NavbarItem>
|
</NavbarItem>
|
||||||
</NavbarContent>
|
</NavbarContent>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue