feat: use NIP-50 relay-side search with scope selection #114
@@ -20,22 +20,15 @@
|
||||
|
||||
const {url, h}: Props = $props()
|
||||
|
||||
type SearchScope = "room" | "space"
|
||||
|
||||
const scopes: SearchScope[] = h ? ["room", "space"] : ["space"]
|
||||
|
||||
let term = $state("")
|
||||
let show = $state(false)
|
||||
|
hodlbod marked this conversation as resolved
Outdated
|
||||
let scope = $state<SearchScope>(h ? "room" : "space")
|
||||
let results = $state<TrustedEvent[]>([])
|
||||
let loading = $state(false)
|
||||
let input: HTMLInputElement | undefined = $state()
|
||||
let controller: AbortController | undefined
|
||||
|
||||
const relayStatus = $derived(
|
||||
scope === "room"
|
||||
? `Using space relay: ${url} (room filter applied).`
|
||||
: `Using space relay: ${url}.`,
|
||||
h ? `Searching this room on relay: ${url}.` : `Searching this space on relay: ${url}.`,
|
||||
)
|
||||
|
||||
const open = () => {
|
||||
@@ -58,13 +51,10 @@
|
||||
|
||||
const getRelayUrls = () => [url]
|
||||
|
||||
const getFilter = (searchTerm: string): Filter => {
|
||||
if (scope === "room" && h) {
|
||||
return {kinds: CONTENT_KINDS, "#h": [h], search: searchTerm}
|
||||
}
|
||||
|
||||
return {kinds: CONTENT_KINDS, search: searchTerm}
|
||||
}
|
||||
const getFilter = (searchTerm: string): Filter =>
|
||||
h
|
||||
? {kinds: CONTENT_KINDS, "#h": [h], search: searchTerm}
|
||||
: {kinds: CONTENT_KINDS, search: searchTerm}
|
||||
|
||||
const search = debounce(300, async (searchTerm: string) => {
|
||||
controller?.abort()
|
||||
@@ -100,11 +90,6 @@
|
||||
void search(term)
|
||||
}
|
||||
|
||||
const setScope = (value: SearchScope) => {
|
||||
scope = value
|
||||
void search(term)
|
||||
}
|
||||
|
||||
const eventsByAge = $derived(groupBy(e => getAgeSection(e.created_at), results))
|
||||
|
||||
const getAgeSection = (createdAt: number) => {
|
||||
@@ -168,25 +153,14 @@
|
||||
bind:value={term}
|
||||
class="min-w-0 grow"
|
||||
type="text"
|
||||
placeholder={scope === "room" ? "Search this room..." : "Search this space..."}
|
||||
placeholder={h ? "Search this room..." : "Search this space..."}
|
||||
oninput={onInput} />
|
||||
</label>
|
||||
<div class="flex flex-wrap gap-1">
|
||||
{#each scopes as value (value)}
|
||||
<Button
|
||||
class={value === scope ? "btn btn-neutral btn-xs" : "btn btn-ghost btn-xs"}
|
||||
onclick={() => setScope(value)}>
|
||||
{value === "room" ? "Room" : "Space"}
|
||||
</Button>
|
||||
{/each}
|
||||
</div>
|
||||
<div class="max-h-[65vh] overflow-y-auto">
|
||||
<p class="mb-2 text-xs opacity-70">{relayStatus}</p>
|
||||
{#if !term}
|
||||
<p class="text-sm opacity-70">
|
||||
{scope === "room"
|
||||
? "Search for content in this room."
|
||||
: "Search for content in this space."}
|
||||
{h ? "Search for content in this room." : "Search for content in this space."}
|
||||
</p>
|
||||
{:else if loading}
|
||||
<p class="text-sm opacity-70">Searching...</p>
|
||||
|
||||
Reference in New Issue
Block a user
Let's just stick to room/space, it probably doesn't make sense to add the everything category until we've integrated social media features (and it should probably go on the global search page).
Sure. I've removed the
everythingscope and kept the search UI limited to room and space only.