johnandersen777.bsky.social/knotless
git that lives in your Atmosphere account
Forked from chadtmiller.com/knotless
0
0
<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>