~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/knotless

git that lives in your Atmosphere account

Forked from chadtmiller.com/knotless

0
0
134 lines · 4.9 KB Raw History
<script lang="ts" module>
	import { wrapDots } from '#lib/dots.ts';
	import type { RepoViewDetailed } from '#lib/lexicons/dev/knotless/defs.ts';
	export type Tab = 'code' | 'pulls' | 'issues' | 'releases' | 'checks' | 'settings';
</script>

<script lang="ts">
	import { scrollRow } from '#lib/rows.ts';
	import { repoHref, urlPath } from '#lib/format.ts';
	import Avatar from '#lib/atoms/Avatar.svelte';
	import Icon from '#lib/atoms/Icon.svelte';
	import PrivateTag from '#lib/atoms/PrivateTag.svelte';
	import ArchivedTag from '#lib/atoms/ArchivedTag.svelte';
	import RepoSwitch from '#lib/molecules/RepoSwitch.svelte';
	import ForkButton from '#lib/molecules/ForkButton.svelte';
	import RepoMenu from '#lib/molecules/RepoMenu.svelte';
	import StarButton from '#lib/molecules/StarButton.svelte';
	import WatchMenu from '#lib/molecules/WatchMenu.svelte';
	import TabLink from '#lib/molecules/TabLink.svelte';
	import RepoLinks from '#lib/molecules/RepoLinks.svelte';
	import RepoSite from '#lib/molecules/RepoSite.svelte';
	import RepoPeople from '#lib/molecules/RepoPeople.svelte';
	import RepoTopics from '#lib/molecules/RepoTopics.svelte';
	import RepoFacts from './RepoFacts.svelte';

	/** What every page about a repository shows above itself: whose it is, by `authority`, what it is and what about, the links it shows, who may push to it and what it publishes, its stars, starred and watched as whoever is `in`, forking it as `me`, by handle, where the server has logins (`login`), reporting it as whoever is `in` but not its `owner`, and its tabs, with its settings for its owner or an `admin` of the organization that owns it. */
	let {
		repo,
		authority,
		tab,
		in: logged = false,
		me,
		login = false,
		owner = false,
		admin = false
	}: {
		repo: RepoViewDetailed;
		authority: string;
		tab: Tab;
		in?: boolean;
		me?: string;
		login?: boolean;
		owner?: boolean;
		admin?: boolean;
	} = $props();
	const href = (tail = '') => repoHref(authority, repo.name, tail);
	const people = $derived(repo.collaborators ?? []);
	const bare = (url: string) => url.replace(/\/$/, '');
	// The site's own address, also among its links, is shown once, as the site.
	const links = $derived(
		(repo.links ?? [])
			.map((l) => ({ url: l.url as string, title: l.title }))
			.filter((l) => !repo.site || bare(l.url) !== bare(repo.site.url as string))
	);
</script>

<div class="repohead">
	<div class="about">
		<h1>
			<Avatar name={authority} did={repo.owner.did} src={repo.owner.avatar} /><a
				href="/{urlPath(authority)}">{authority}</a
			><span class="repo-name"
				><span class="repo-path"
					><span class="mute">/</span><a href={href()}><b>{repo.name}</b></a></span
				><RepoSwitch {authority} did={repo.owner.did} name={repo.name} /></span
			>{#if repo.private}<PrivateTag />{/if}{#if repo.archivedAt}<ArchivedTag />{/if}
		</h1>
		{#if repo.description}<p>{repo.description}</p>{/if}
		{#if repo.topics?.length}<RepoTopics topics={repo.topics} />{/if}
		{#if repo.site || links.length || people.length || repo.releases}
			<div class="facts" {@attach wrapDots}>
				{#if repo.site}<RepoSite site={repo.site} private={repo.private} />{/if}
				{#if repo.site && links.length}<span class="sep" aria-hidden="true">·</span>{/if}
				{#if links.length}<RepoLinks {links} />{/if}
				{#if (repo.site || links.length) && people.length}<span class="sep" aria-hidden="true"
						>·</span
					>{/if}
				{#if people.length}<RepoPeople {people} count={repo.collaboratorCount} />{/if}
				{#if (repo.site || links.length || people.length) && repo.releases}<span
						class="sep"
						aria-hidden="true">·</span
					>{/if}
				{#if repo.releases}<RepoFacts
						owner={authority}
						name={repo.name}
						releases={repo.releases}
					/>{/if}
			</div>
		{/if}
		{#if repo.forkOf}<p class="forked">
				<Icon name="fork" /> Forked from
				<a href={repoHref(repo.forkOf.handle, repo.forkOf.name)}
					>{`${repo.forkOf.handle}/${repo.forkOf.name}`}</a
				>
			</p>{/if}
	</div>
	<div class="repo-actions">
		{#if logged && repo.viewer}<WatchMenu {repo} />{/if}
		{#if me || login}<ForkButton {repo} {me} />{/if}
		{#if repo.starCount !== undefined}<StarButton {repo} in={logged} />{/if}
		{#if logged && !owner}<RepoMenu {repo} />{/if}
	</div>
</div>
<nav class="tabs" data-sveltekit-reset="false" {@attach scrollRow(tab)}>
	<TabLink href={href()} label="Code" icon="code" current={tab === 'code'} />
	<TabLink
		href={href('/issues')}
		label="Issues"
		icon="issue"
		count={repo.openIssues}
		current={tab === 'issues'}
	/>
	<TabLink
		href={href('/pulls')}
		label="Pulls"
		icon="pull"
		count={repo.openPulls}
		current={tab === 'pulls'}
	/>
	<TabLink
		href={href('/releases')}
		label="Releases"
		icon="tag"
		count={repo.releases?.count}
		current={tab === 'releases'}
	/>
	<TabLink href={href('/checks')} label="Checks" icon="checks" current={tab === 'checks'} />
	{#if owner || admin}<TabLink
			href={href('/settings')}
			label="Settings"
			icon="gear"
			current={tab === 'settings'}
		/>{/if}
</nav>