feat: tag search

This commit is contained in:
Kieran 2023-11-27 22:13:04 +00:00
parent d5d0b0b224
commit 7bff5e384f
No known key found for this signature in database
GPG Key ID: DE71CEB3925BE941
5 changed files with 43 additions and 30 deletions

View File

@ -1,35 +1,27 @@
import { useNavigate, useParams } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { Categories } from "../const";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
export function Search() { export function Search(params: { term?: string; tags?: Array<string> }) {
const params = useParams();
const navigate = useNavigate(); const navigate = useNavigate();
const [term, setTerm] = useState(""); const [term, setTerm] = useState("");
const [tags, setTags] = useState<Array<string>>([]);
useEffect(() => { useEffect(() => {
setTerm(params.term ?? ""); setTerm(params.term ?? "");
}, [params.term]); setTags(params.tags ?? []);
}, [params]);
return ( return (
<div className="flex flex-col gap-1"> <div>
<div className="flex gap-3 flex-wrap">
{Categories.map((a) => (
<div className="flex gap-1" key={a.tag}>
<input type="checkbox" />
<label>{a.name}</label>
</div>
))}
</div>
<input <input
type="text" type="text"
placeholder="Search.." placeholder="Search.."
className="p-3 rounded grow" className="p-3 rounded w-full"
value={term} value={term}
onChange={(e) => setTerm(e.target.value)} onChange={(e) => setTerm(e.target.value)}
onKeyDown={(e) => { onKeyDown={(e) => {
if (e.key == "Enter") { if (e.key == "Enter") {
navigate(`/search/${encodeURIComponent(term)}`); navigate(`/search/${encodeURIComponent(term)}${tags.length > 0 ? `?tags=${tags.join(",")}` : ""}`);
} }
}} }}
/> />

View File

@ -10,7 +10,7 @@ export function TorrentList({ items }: { items: Array<TaggedNostrEvent> }) {
return ( return (
<table className="torrent-list"> <table className="torrent-list">
<thead> <thead>
<tr> <tr className="bg-slate-600">
<th>Category</th> <th>Category</th>
<th>Name</th> <th>Name</th>
<th>Uploaded</th> <th>Uploaded</th>
@ -37,12 +37,26 @@ function TorrentTableEntry({ item }: { item: TaggedNostrEvent }) {
.reduce((acc, v) => (acc += v), 0); .reduce((acc, v) => (acc += v), 0);
const npub = hexToBech32("npub", item.pubkey); const npub = hexToBech32("npub", item.pubkey);
return ( return (
<tr> <tr className="hover:bg-slate-800">
<td> <td>
{item.tags {item.tags
.filter((a) => a[0] === "t") .filter((a) => a[0] === "t")
.map((a) => a[1]) .slice(0, 3)
.join(" > ")} .map((a, i, arr) => (
<>
<Link
to={`/search/?tags=${encodeURIComponent(
arr
.slice(0, i + 1)
.map((b) => b[1])
.join(","),
)}`}
>
{a[1]}
</Link>
{arr.length !== i + 1 && " > "}
</>
))}
</td> </td>
<td> <td>
<Link to={`/e/${NostrLink.fromEvent(item).encode()}`} state={item}> <Link to={`/e/${NostrLink.fromEvent(item).encode()}`} state={item}>

View File

@ -3,9 +3,9 @@ import { LatestTorrents } from "../element/trending";
export function HomePage() { export function HomePage() {
return ( return (
<> <div className="flex flex-col gap-2">
<Search /> <Search />
<LatestTorrents /> <LatestTorrents />
</> </div>
); );
} }

View File

@ -11,10 +11,10 @@ export function ProfilePage() {
if (!link) return; if (!link) return;
return ( return (
<> <div className="flex flex-col gap-2">
<ProfileSection pubkey={link.id} /> <ProfileSection pubkey={link.id} />
<LatestTorrents author={link.id} /> <LatestTorrents author={link.id} />
</> </div>
); );
} }

View File

@ -1,5 +1,5 @@
import { NoteCollection, RequestBuilder } from "@snort/system"; import { NoteCollection, RequestBuilder } from "@snort/system";
import { useParams } from "react-router-dom"; import { useLocation, useParams } from "react-router-dom";
import { TorrentKind } from "../const"; import { TorrentKind } from "../const";
import { useRequestBuilder } from "@snort/system-react"; import { useRequestBuilder } from "@snort/system-react";
import { TorrentList } from "../element/torrent-list"; import { TorrentList } from "../element/torrent-list";
@ -7,22 +7,29 @@ import { Search } from "../element/search";
export function SearchPage() { export function SearchPage() {
const params = useParams(); const params = useParams();
const location = useLocation();
const term = params.term as string | undefined; const term = params.term as string | undefined;
const q = new URLSearchParams(location.search ?? "");
const tags = q.get("tags")?.split(",") ?? [];
const rb = new RequestBuilder(`search:${term}`); const rb = new RequestBuilder(`search:${term}+${tags.join(",")}`);
rb.withFilter() const f = rb
.withFilter()
.kinds([TorrentKind]) .kinds([TorrentKind])
.search(term) .search(term)
.limit(100) .limit(100)
.relay(["wss://relay.nostr.band", "wss://relay.noswhere.com"]); .relay(["wss://relay.nostr.band", "wss://relay.noswhere.com"]);
if (tags.length > 0) {
f.tag("t", tags);
}
const data = useRequestBuilder(NoteCollection, rb); const data = useRequestBuilder(NoteCollection, rb);
return ( return (
<> <div className="flex flex-col gap-2">
<Search /> <Search term={term} tags={tags} />
<h2>Search Results:</h2> <h2>Search Results:</h2>
<TorrentList items={data.data ?? []} /> <TorrentList items={data.data ?? []} />
</> </div>
); );
} }