flotilla/src/app/components/ProfileSharedSpaces.svelte
2026-06-29 15:51:18 -07:00

69 lines
2.3 KiB
Svelte

<script lang="ts">
import cx from "classnames"
import UsersGroup from "@assets/icons/users-group-rounded.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Badge from "@lib/components/Badge.svelte"
import Link from "@lib/components/Link.svelte"
import RelayIcon from "@app/components/RelayIcon.svelte"
import RelayName from "@app/components/RelayName.svelte"
import {
groupListPubkeysByUrl,
userSpaceUrls,
deriveGroupList,
getSpaceUrlsFromGroupList,
} from "@app/groups"
import {makeSpacePath} from "@app/routes"
type Props = {
pubkey: string
isSelf?: boolean
class?: string
}
const {pubkey, isSelf = false, ...props}: Props = $props()
const groupList = deriveGroupList(pubkey)
const spaceUrls = $derived(getSpaceUrlsFromGroupList($groupList))
</script>
<div class={cx("card card-sm flex flex-col gap-3 sm:gap-4", props.class)}>
<div class="flex items-center justify-between gap-2">
<div class="flex items-center gap-2">
<Icon icon={UsersGroup} size={5} />
<strong>Spaces</strong>
</div>
<Badge variant="neutral">{spaceUrls.length}</Badge>
</div>
{#if spaceUrls.length > 0}
<div class="flex flex-col gap-2 border-t border-line pt-4">
{#each spaceUrls as url (url)}
{@const count = $groupListPubkeysByUrl.get(url)?.size || 0}
{@const isMember = !isSelf && $userSpaceUrls.includes(url)}
<Link
href={makeSpacePath(url)}
class="card card-interactive flex flex-row items-center justify-between gap-3 p-3 sm:p-4">
<RelayIcon {url} size={8} />
<div class="min-w-0 flex-1">
<div class="flex items-center gap-2">
<RelayName {url} class="truncate text-sm font-medium" />
{#if isMember}
<Badge variant="primary" class="text-xs">Member</Badge>
{/if}
</div>
<p class="text-xs opacity-75">
{#if count >= 1000}
{(count / 1000).toFixed(1).replace(/\.0$/, "")}K members
{:else}
{count} {count === 1 ? "member" : "members"}
{/if}
</p>
</div>
</Link>
{/each}
</div>
{:else}
<p class="border-t border-line pt-4 text-sm opacity-75">
{isSelf ? "You aren't in any spaces yet." : "No spaces found."}
</p>
{/if}
</div>