Monorepo for Tangled
tangled.org
1<script lang="ts">
2 import { resolve } from "$app/paths";
3 import Avatar from "$lib/components/ui/Avatar.svelte";
4 import Users from "$icon/users";
5 import FollowButton from "./FollowButton.svelte";
6 import type { FollowChange, PersonData } from "./types";
7 import { createOptimisticCount } from "$lib/optimistic.svelte";
8
9 let { person }: { person: PersonData } = $props();
10
11 const followerCount = createOptimisticCount({
12 key: () => person.did,
13 loaded: () => person.followers
14 });
15
16 const followed = (change: FollowChange) => followerCount.adjust(change.delta);
17</script>
18
19<div class="flex flex-col gap-4 md:flex-row md:items-center">
20 <div class="flex h-24 w-24 shrink-0 items-center justify-center">
21 <Avatar src={person.avatar} handle={person.handle} size="size-24" class="p-2" />
22 </div>
23
24 <div class="flex min-w-0 flex-1 flex-col gap-2 md:flex-row md:items-center md:justify-between">
25 <div class="flex min-h-0 flex-1 flex-col justify-around">
26 <a
27 href={resolve(`/${person.handle}` as "/")}
28 class="max-w-full overflow-hidden text-ellipsis whitespace-nowrap font-bold text-foreground-default hover:underline"
29 >
30 {person.handle}
31 </a>
32 {#if person.description}
33 <p class="break-words pb-2 text-sm text-foreground-muted md:pb-2">{person.description}</p>
34 {/if}
35 <div
36 class="my-2 flex max-w-full items-center gap-2 overflow-hidden text-ellipsis whitespace-nowrap text-sm text-foreground-subtle"
37 >
38 <Users class="size-4 shrink-0" />
39 <span
40 ><a
41 href={resolve(`/${person.handle}?tab=followers` as "/")}
42 class="hover:text-foreground-default hover:underline">{followerCount.value} followers</a
43 ></span
44 >
45 <span class="select-none after:content-['·']"></span>
46 <span
47 ><a
48 href={resolve(`/${person.handle}?tab=following` as "/")}
49 class="hover:text-foreground-default hover:underline">{person.following} following</a
50 ></span
51 >
52 </div>
53 </div>
54
55 {#if !person.isSelf}
56 <div class="order-last w-full md:order-none md:w-auto md:max-w-32">
57 <FollowButton
58 profileDid={person.did}
59 initialRkey={person.viewerFollowRkey}
60 size="md"
61 onCommit={followed}
62 />
63 </div>
64 {/if}
65 </div>
66</div>