appview-less bluesky client
1<script lang="ts">
2 import { generateColorForDid } from '$lib/accounts';
3 import { resolveDidDoc } from '$lib/at/client.svelte';
4 import { handles, router } from '$lib/state.svelte';
5 import { map } from '$lib/result';
6 import type { Did } from '@atcute/lexicons';
7 import Icon from '@iconify/svelte';
8
9 interface Props {
10 style: string;
11 did: Did;
12 onRemove: () => void;
13 }
14
15 let { style, did, onRemove }: Props = $props();
16
17 const handle = $derived(handles.get(did));
18 const color = $derived(generateColorForDid(did));
19
20 $effect(() => {
21 if (!handles.has(did)) {
22 resolveDidDoc(did).then((r) => {
23 if (r.ok) handles.set(did, r.value.handle);
24 else handles.set(did, 'handle.invalid');
25 });
26 }
27 });
28
29 const goToProfile = () => router.navigate(`/profile/${did}`);
30</script>
31
32<div {style} class="box-border w-full py-0.5">
33 <!-- svelte-ignore a11y_click_events_have_key_events -->
34 <!-- svelte-ignore a11y_no_static_element_interactions -->
35 <div
36 class="group flex cursor-pointer items-center gap-2 rounded-sm bg-(--nucleus-fg)/5 px-2 py-1.5 transition-colors hover:bg-(--post-color)/15"
37 style={`--post-color: ${color};`}
38 >
39 <span
40 onclick={goToProfile}
41 class="semibold flex-1 truncate text-sm transition-colors group-hover:text-(--post-color)"
42 style="color: {color}"
43 >
44 {handle ? `@${handle}` : did}
45 </span>
46 <button
47 onclick={onRemove}
48 class="text-sm text-red-400 opacity-0 transition-opacity group-hover:opacity-100 hover:text-red-500"
49 >
50 <Icon icon="heroicons:x-mark-16-solid" width="24" />
51 </button>
52 </div>
53</div>