Coves frontend - a photon fork
at main 81 lines 2.4 kB view raw
1<script lang="ts"> 2 // @ts-nocheck TODO(coves-migration): Needs Coves user search API 3 import { getClient } from '$lib/api/client.svelte' 4 import type { ListingType, Person } from '$lib/api/types' 5 import Avatar from '$lib/ui/generic/Avatar.svelte' 6 import { MenuButton, Search } from 'mono-svelte' 7 import { createEventDispatcher } from 'svelte' 8 import { Icon, XCircle } from 'svelte-hero-icons/dist' 9 import { fly } from 'svelte/transition' 10 11 interface Props { 12 q?: string 13 instance?: string | undefined 14 listing_type?: ListingType 15 showWhenEmpty?: boolean 16 /** @deprecated No longer functional - will filter users when Coves API provides DID */ 17 hideOwnUser?: boolean 18 placeholder?: string 19 onselect?: (e?: Person) => void 20 } 21 22 let { 23 q = $bindable(''), 24 instance = undefined, 25 listing_type = 'Subscribed', 26 showWhenEmpty = false, 27 // eslint-disable-next-line @typescript-eslint/no-unused-vars 28 hideOwnUser = false, 29 ...rest 30 }: Props = $props() 31 32 const dispatcher = createEventDispatcher<{ select: Person | undefined }>() 33</script> 34 35<Search 36 search={async (q) => { 37 const users = ( 38 await getClient(instance).search({ 39 q: q || ' ', 40 type_: 'Users', 41 limit: 20, 42 listing_type: listing_type, 43 sort: 'TopAll', 44 }) 45 ).users.map((c) => c.person) 46 47 // TODO: Filter out own user when DID comparison is available 48 return users 49 }} 50 extractName={(c) => `${c.name}@${new URL(c.actor_id).hostname}`} 51 bind:query={q} 52 {...rest} 53> 54 {#snippet noresults()} 55 <div class="w-full h-full"> 56 {#if showWhenEmpty} 57 <MenuButton onclick={() => dispatcher('select', undefined)}> 58 <Icon src={XCircle} size="16" mini /> 59 <div class="flex flex-col text-left"> 60 <span>None</span> 61 </div> 62 </MenuButton> 63 {:else} 64 <span class="mx-auto my-auto">No results.</span> 65 {/if} 66 </div> 67 {/snippet} 68 {#snippet children({ item, select })} 69 <div in:fly|global={{ y: -4, opacity: 0 }}> 70 <MenuButton onclick={() => select(item)}> 71 <Avatar url={item.avatar} alt={item.name} width={24} /> 72 <div class="flex flex-col text-left"> 73 <span>{item.name}</span> 74 <span class="text-xs opacity-80"> 75 {new URL(item.actor_id).hostname} 76 </span> 77 </div> 78 </MenuButton> 79 </div> 80 {/snippet} 81</Search>