johnandersen777.bsky.social/knotless
git that lives in your Atmosphere account
Forked from chadtmiller.com/knotless
0
0
<script lang="ts">
import { repoHref, urlPath } from '#lib/format.ts';
import Icon from '#lib/atoms/Icon.svelte';
/** The revision shown, opening to every branch, and, given `tags`, every tag, each linked to the same `view` of `path` on it. */
let {
authority,
name,
rev,
view,
path,
branches,
head,
tags
}: {
authority: string;
name: string;
rev: string;
view: string;
path: string;
branches: string[];
head: string;
tags?: string[];
} = $props();
const pinned = $derived(/^([0-9a-f]{40}|[0-9a-f]{64})$/i.test(rev));
const tagged = $derived(!branches.includes(rev) && !!tags?.includes(rev));
let open = $state(false);
let filter = $state('');
let showTags = $state(false);
// Opened on a tag, it opens on the tags.
$effect(() => {
if (open) showTags = tagged;
});
const kind = $derived(showTags ? 'tag' : 'branch');
const shown = $derived(
(showTags ? (tags ?? []) : branches).filter((b) =>
b.toLowerCase().includes(filter.trim().toLowerCase())
)
);
const href = (ref: string) =>
repoHref(authority, name, `/${view}/${urlPath(ref)}${path ? `/${urlPath(path)}` : ''}`);
</script>
<details class="popover branch-menu" bind:open>
<summary class="branch" title={rev}
><Icon name={tagged ? 'tag' : 'branch'} /><span>{pinned ? rev.slice(0, 7) : rev}</span><Icon
name="caret"
/></summary
>
<div class="menu">
<div class="menu-head">{tags ? 'Switch branches or tags' : 'Switch branches'}</div>
<input
type="search"
placeholder="Find a {kind}…"
aria-label="Find a {kind}"
bind:value={filter}
/>
{#if tags}
<div class="md-tabs ref-tabs" role="tablist" aria-label="Branches or tags">
<button
type="button"
role="tab"
aria-selected={!showTags}
onclick={() => (showTags = false)}><Icon name="branch" />Branches</button
>
<button type="button" role="tab" aria-selected={showTags} onclick={() => (showTags = true)}
><Icon name="tag" />Tags</button
>
</div>
{/if}
{#if shown.length}
<ul>
{#each shown as b (b)}
<li>
<a
href={href(b)}
aria-current={b === rev ? 'true' : undefined}
onclick={() => (open = false)}
><Icon name="check" /><span class="name">{b}</span>{#if !showTags && b === head}<span
class="count">Default</span
>{/if}</a
>
</li>
{/each}
</ul>
{:else}
<div class="none">{showTags && !tags?.length ? 'No tags yet' : 'Nothing to show'}</div>
{/if}
</div>
</details>