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

johnandersen777.bsky.social/knotless

git that lives in your Atmosphere account

Forked from chadtmiller.com/knotless

0
0
141 lines · 5.0 KB Raw History
<script lang="ts">
	import { monthly } from '#lib/activity.ts';
	import { urlPath } from '#lib/format.ts';
	import More from '#lib/atoms/More.svelte';
	import ActivityRollup from '#lib/organisms/ActivityRollup.svelte';
	import ActivityStrip from '#lib/organisms/ActivityStrip.svelte';
	import Feed from '#lib/organisms/Feed.svelte';
	import ProfileRepos from '#lib/organisms/ProfileRepos.svelte';
	import RepoCards from '#lib/organisms/RepoCards.svelte';
	import RepoList from '#lib/organisms/RepoList.svelte';
	import ActorList from '#lib/organisms/ActorList.svelte';
	import OrgMembers from '#lib/organisms/OrgMembers.svelte';
	import ProfilePage from '#lib/templates/ProfilePage.svelte';
	import { Pages } from '#lib/pages.svelte.ts';
	import Empty from '#lib/molecules/Empty.svelte';
	let { data } = $props();
	/** Months the overview sums up. */
	const MONTHS = 3;
	/** Repositories shared with the account the overview shows, to it. */
	const SHARED = 4;
	const p = $derived(data.profile);
	const handle = $derived(p.handle ?? p.did);
	const base = $derived(`/${urlPath(handle)}`);
	// Those pushed to last first, then those made last.
	const recent = $derived.by(() => {
		const pushed = new Map((data.activity?.repos ?? []).map((r) => [r.name, r.pushedAt]));
		const last = (r: (typeof data.repos)[number]) => pushed.get(r.name) ?? r.createdAt;
		return [...data.repos].sort((a, b) => last(b).localeCompare(last(a))).slice(0, 4);
	});
	// The overview's last few months of it, as counts.
	const months = $derived(
		data.activity ? monthly(data.activity.days, data.activity.repos).slice(0, MONTHS) : []
	);
	const feed = new Pages(
		() => data,
		(d) => ({ items: d.feed?.events ?? [], cursor: d.feed?.cursor })
	);
	// The account itself, who may begin to invite.
	const me = $derived(data.viewer?.actor?.did);
	const follows = new Pages(
		() => data,
		(d) => ({ items: d.follows?.actors ?? [], cursor: d.follows?.cursor }),
		(a) => a.did
	);
</script>

<!-- How to make one is said to the account itself, who can push. -->
{#snippet none()}{#if me === p.did}<Empty
			title="No public repositories yet"
			cmd="git push knotless://{handle}/project main"
			>Push a branch to a new name to start one.</Empty
		>{:else}<Empty title="No public repositories yet" />{/if}{/snippet}

<ProfilePage profile={p} {base} tab={data.tab} repos={data.repos.length}>
	{#if data.tab === 'repos'}
		<ProfileRepos
			repos={data.repos}
			shared={data.shared}
			pushes={data.activity?.repos ?? null}
			today={data.today}
			{base}
			{...data.filter}
			empty={none}
		/>
	{:else if data.tab === 'stars'}
		{#if data.stars}
			{#snippet unstarred()}<Empty title="No starred repositories yet" />{/snippet}
			<RepoList repos={data.stars.repos} empty={unstarred} />
		{:else}
			<div class="box">
				<Empty title="Stars are not shown here"
					>This server keeps no index, so it cannot say what the account starred.</Empty
				>
			</div>
		{/if}
	{:else if data.tab === 'followers' || data.tab === 'following'}
		<div class="section"><h2>{data.tab === 'followers' ? 'Followers' : 'Following'}</h2></div>
		{#if data.follows}
			{#snippet nobody()}<Empty
					title={data.tab === 'followers' ? 'No followers yet' : 'Not following anyone yet'}
				/>{/snippet}
			<ActorList actors={follows.items} empty={nobody} />
			<More pages={follows} label="More" />
		{:else}
			<div class="box">
				<Empty title="Follows are not shown here"
					>This server keeps no index, so it cannot say who follows whom.</Empty
				>
			</div>
		{/if}
	{:else if data.tab === 'members'}
		{#if data.org && (data.org.organization || me === p.did)}
			<OrgMembers
				org={data.org}
				did={p.did}
				{handle}
				{me}
				delegated={data.viewer?.delegated ?? false}
			/>
		{:else}
			<div class="box">
				<div class="empty">{handle} is not an organization, so it has no members.</div>
			</div>
		{/if}
	{:else if data.tab === 'activity'}
		{#if data.feed}
			{#snippet idle()}<Empty title="Nothing done yet" />{/snippet}
			<Feed events={feed.items} owner={data.profile.did} empty={idle} />
			<More pages={feed} label="Older" />
		{:else}
			<div class="box">
				<Empty title="Activity is not shown here"
					>This server keeps no index, so it cannot say what the account did.</Empty
				>
			</div>
		{/if}
	{:else}
		{#if data.activity}<ActivityStrip days={data.activity.days} today={data.today} />{/if}
		{#if recent.length}
			<div class="section">
				<h2>Recently active</h2>
				{#if data.repos.length > recent.length}<a class="end mute" href="{base}?tab=repos"
						>{`All ${data.repos.length} repositories`}</a
					>{/if}
			</div>
			<RepoCards repos={recent} />
		{:else}
			<div class="box no-cards">{@render none()}</div>
		{/if}
		{#if data.shared.length}
			<div class="section">
				<h2>Shared with you</h2>
				{#if data.shared.length > SHARED}<a class="end mute" href="{base}?tab=repos&kind=shared"
						>{`All ${data.shared.length} repositories`}</a
					>{/if}
			</div>
			<RepoCards repos={data.shared.slice(0, SHARED)} owned={false} />
		{/if}
		{#if data.activity}<ActivityRollup {months} {base} all="{base}?tab=activity" />{/if}
	{/if}
</ProfilePage>