~james/core

core/web/src/lib/components/timeline/Timeline.svelte -rw-r--r-- 2.2 KiB
452f17b7 — james chore(import): snapshot james.dad.town/core at f70c71c7696a 16 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<script lang="ts">
	import type { Snippet } from "svelte";
	import EmptyState from "#lib/components/ui/EmptyState.svelte";
	import TimelineRepoEvent from "#lib/components/timeline/TimelineRepoEvent.svelte";
	import TimelineStarEvent from "#lib/components/timeline/TimelineStarEvent.svelte";
	import TimelineFollowEvent from "#lib/components/timeline/TimelineFollowEvent.svelte";
	import TimelineFollowers from "#lib/components/timeline/TimelineFollowers.svelte";
	import TimelineStargazers from "#lib/components/timeline/TimelineStargazers.svelte";
	import TimelineForkers from "#lib/components/timeline/TimelineForkers.svelte";
	import { groupTimeline } from "#lib/components/timeline/group.ts";
	import type * as OrgTangledFeedGetTimeline from "#lib/api/lexicons/types/org/tangled/feed/getTimeline.ts";

	let {
		feed,
		emptyMessage = "Nothing here yet.",
		emptyAction,
		signedIn = false
	}: {
		feed: OrgTangledFeedGetTimeline.$output["feed"];
		emptyMessage?: string;
		emptyAction?: Snippet;
		signedIn?: boolean;
	} = $props();

	const entries = $derived(groupTimeline(feed));
</script>

{#if entries.length > 0}
	<div class="flex flex-col gap-md">
		{#each entries as entry, i (entry.key)}
			<div class="relative">
				<!-- connector bridging the gap up to the previous card -->
				{#if i !== 0}
					<div
						class="absolute -top-4 left-6.5 h-4 w-px bg-border-default"
						aria-hidden="true"
					></div>
				{/if}
				{#if entry.kind === "follow"}
					<TimelineFollowEvent actor={entry.actor} items={entry.items} {signedIn} />
				{:else if entry.kind === "star"}
					<TimelineStarEvent actor={entry.actor} items={entry.items} {signedIn} />
				{:else if entry.kind === "create" || entry.kind === "fork"}
					<TimelineRepoEvent actor={entry.actor} items={entry.items} {signedIn} />
				{:else if entry.kind === "followers"}
					<TimelineFollowers items={entry.items} {signedIn} />
				{:else if entry.kind === "stargazers"}
					<TimelineStargazers items={entry.items} {signedIn} />
				{:else}
					<TimelineForkers items={entry.items} {signedIn} />
				{/if}
			</div>
		{/each}
	</div>
{:else}
	<EmptyState message={emptyMessage} messageDirection="vertical" children={emptyAction} />
{/if}