81 lines
2.0 KiB
Svelte
81 lines
2.0 KiB
Svelte
|
|
<script lang="ts">
|
|||
|
|
import { onMount } from 'svelte';
|
|||
|
|
import type { NostrEvent } from '$lib/nostr/loaders';
|
|||
|
|
import { loadPostList } from '$lib/nostr/loaders';
|
|||
|
|
import PostCard from '$lib/components/PostCard.svelte';
|
|||
|
|
import LoadingOrError from '$lib/components/LoadingOrError.svelte';
|
|||
|
|
|
|||
|
|
let posts: NostrEvent[] = $state([]);
|
|||
|
|
let loading = $state(true);
|
|||
|
|
let error: string | null = $state(null);
|
|||
|
|
|
|||
|
|
onMount(async () => {
|
|||
|
|
try {
|
|||
|
|
posts = await loadPostList();
|
|||
|
|
loading = false;
|
|||
|
|
if (posts.length === 0) {
|
|||
|
|
error = 'Keine Posts gefunden auf den abgefragten Relays.';
|
|||
|
|
}
|
|||
|
|
} catch (e) {
|
|||
|
|
loading = false;
|
|||
|
|
error = e instanceof Error ? e.message : 'Unbekannter Fehler';
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Posts nach Jahr gruppieren (neueste zuerst)
|
|||
|
|
type YearGroup = { year: number; posts: NostrEvent[] };
|
|||
|
|
const groupsByYear = $derived.by<YearGroup[]>(() => {
|
|||
|
|
const byYear = new Map<number, NostrEvent[]>();
|
|||
|
|
for (const p of posts) {
|
|||
|
|
const ts = Number(p.tags.find((t) => t[0] === 'published_at')?.[1] ?? p.created_at);
|
|||
|
|
const year = new Date(ts * 1000).getUTCFullYear();
|
|||
|
|
if (!byYear.has(year)) byYear.set(year, []);
|
|||
|
|
byYear.get(year)!.push(p);
|
|||
|
|
}
|
|||
|
|
return [...byYear.entries()]
|
|||
|
|
.map(([year, p]) => ({ year, posts: p }))
|
|||
|
|
.sort((a, b) => b.year - a.year);
|
|||
|
|
});
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<svelte:head>
|
|||
|
|
<title>Archiv – Jörg Lohrer</title>
|
|||
|
|
</svelte:head>
|
|||
|
|
|
|||
|
|
<h1 class="title">Archiv</h1>
|
|||
|
|
<p class="meta">Alle Beiträge, nach Jahr gruppiert.</p>
|
|||
|
|
|
|||
|
|
<LoadingOrError {loading} {error} />
|
|||
|
|
|
|||
|
|
{#each groupsByYear as group (group.year)}
|
|||
|
|
<section class="year-group">
|
|||
|
|
<h2 class="year">{group.year}</h2>
|
|||
|
|
{#each group.posts as post (post.id)}
|
|||
|
|
<PostCard event={post} />
|
|||
|
|
{/each}
|
|||
|
|
</section>
|
|||
|
|
{/each}
|
|||
|
|
|
|||
|
|
<style>
|
|||
|
|
.title {
|
|||
|
|
margin: 0 0 0.3rem;
|
|||
|
|
font-size: 1.8rem;
|
|||
|
|
}
|
|||
|
|
.meta {
|
|||
|
|
color: var(--muted);
|
|||
|
|
margin: 0 0 2rem;
|
|||
|
|
font-size: 0.95rem;
|
|||
|
|
}
|
|||
|
|
.year-group {
|
|||
|
|
margin-bottom: 2.5rem;
|
|||
|
|
}
|
|||
|
|
.year {
|
|||
|
|
font-size: 1.2rem;
|
|||
|
|
font-weight: 600;
|
|||
|
|
margin: 0 0 1rem;
|
|||
|
|
padding-bottom: 0.3rem;
|
|||
|
|
border-bottom: 1px solid var(--border);
|
|||
|
|
color: var(--muted);
|
|||
|
|
}
|
|||
|
|
</style>
|