<script lang="ts">
import InlineMarkdown from "#lib/components/ui/InlineMarkdown.svelte";
import { resolve } from "$app/paths";
import GitFork from "$icon/git-fork";
import Globe from "$icon/globe";
import Button from "#lib/components/ui/Button.svelte";
import ButtonGroup from "#lib/components/ui/ButtonGroup.svelte";
import OwnerTitle from "#lib/components/repo/OwnerTitle.svelte";
import KnotUpgradeTag from "#lib/components/repo/KnotUpgradeTag.svelte";
import TopicList from "#lib/components/repo/TopicList.svelte";
import Pending from "#lib/components/ui/Pending.svelte";
import Bones from "#lib/components/ui/Bones.svelte";
import bonesLoadingprimitivesCount from "#lib/bones/bones-loadingprimitives--count.bones.json";
import StarButton from "#lib/components/repo/StarButton.svelte";
import type { KnotInfo, RepoCounts, RepoInfo, RepoSource } from "#lib/components/repo/types.ts";
import SubscribeButton from "#lib/components/repo/SubscribeButton.svelte";
import { formatCount } from "#lib/format.ts";
import { safeHref } from "#lib/safeHref.ts";
interface Props {
repo: RepoInfo;
counts: RepoCounts | Promise<RepoCounts>;
viewerStarRkey?: string | null | Promise<string | null>;
viewerSubscriptionRkey?: string | null | Promise<string | null>;
source?: RepoSource | null | Promise<RepoSource | null>;
knotInfo?: KnotInfo | Promise<KnotInfo>;
}
let { repo, counts, viewerStarRkey, viewerSubscriptionRkey, source, knotInfo }: Props =
$props();
const base = $derived(`/${repo.ownerHandle}/${repo.name}`);
const website = $derived(safeHref(repo.website));
const trimScheme = (url: string) => url.replace(/^https?:\/\//, "").replace(/\/$/, "");
const topics = $derived([...new Set(repo.topics ?? [])]);
</script>
{#snippet repoActions(className: string, itemClass: string | undefined)}
<div class={className}>
<StarButton
subject={{
kind: "repo",
did: repo.repoDid ?? "",
ownerHandle: repo.ownerHandle,
name: repo.name
}}
initialCount={counts}
initialRkey={viewerStarRkey}
class={itemClass ?? "flex-1"}
/>
<ButtonGroup class={itemClass ?? "flex-1"}>
<Button
href={resolve(`${base}/fork` as "/")}
variant="default"
icon={GitFork}
disabled={!repo.git}
title={repo.git ? undefined : "This repository doesn't support git"}
class="flex-1 px-md!"
>
Fork
</Button>
<Button href={resolve(`${base}/forks` as "/")} variant="ghost" title="Forked by">
{#if typeof counts === "object" && counts !== null && "then" in counts}
<Pending>
{#snippet skeleton()}
<Bones
capture={bonesLoadingprimitivesCount}
class="inline-block w-8 align-middle"
/>
{/snippet}
{formatCount((await counts).forks)}
</Pending>
{:else}
{formatCount(counts.forks)}
{/if}
</Button>
</ButtonGroup>
<SubscribeButton
repoDid={repo.repoDid ?? ""}
initialRkey={viewerSubscriptionRkey}
class={itemClass}
/>
</div>
{/snippet}
<section class="mb-xs px-md py-xs">
<div class="mb-xs flex flex-col items-start justify-between gap-md sm:flex-row sm:items-center">
<div class="flex w-full min-w-0 flex-col gap-xs sm:flex-1">
<OwnerTitle
ownerDid={repo.ownerDid}
ownerHandle={repo.ownerHandle}
name={repo.name}
href={resolve(`/${repo.ownerHandle}/${repo.name}` as "/")}
>
{#await knotInfo then info}
{#if info?.needsUpgrade}
<KnotUpgradeTag reason={info.needsUpgrade} knot={repo.knot} />
{/if}
{/await}
</OwnerTitle>
</div>
{@render repoActions("hidden shrink-0 items-start gap-xs sm:flex", undefined)}
</div>
<div class="flex flex-col gap-xs">
<div class="flex flex-wrap items-center gap-x-md gap-y-2xs text-foreground-muted">
{#if repo.description}
<span data-testid="repoDescription" class="wrap-anywhere"
><InlineMarkdown text={repo.description} /></span
>
{/if}
<Pending>
{@const resolvedSource = await (source ?? repo.source)}
{#if resolvedSource}
<span class="flex items-center gap-2xs">
<GitFork class="size-3.5 shrink-0" aria-hidden="true" />
<span data-testid="forkedFromPrefix">forked from</span>
<a
href={resolve(
`/${resolvedSource.ownerHandle}/${resolvedSource.name}` as "/"
)}
class="min-w-0 wrap-anywhere underline"
>
{resolvedSource.ownerHandle}/{resolvedSource.name}
</a>
</span>
{/if}
</Pending>
{#if website}
<span class="flex items-center gap-2xs">
<Globe class="size-3.5 shrink-0" aria-hidden="true" />
<a
href={website}
rel="external ugc nofollow noopener noreferrer"
class="min-w-0 wrap-anywhere">{trimScheme(website)}</a
>
</span>
{/if}
</div>
<TopicList {topics} />
</div>
{@render repoActions("mt-xs flex gap-xs sm:hidden", "flex-auto")}
</section>