diff --git a/crates/moments-data/src/lib.rs b/crates/moments-data/src/lib.rs index 25ba137..1986ad4 100644 --- a/crates/moments-data/src/lib.rs +++ b/crates/moments-data/src/lib.rs @@ -54,12 +54,19 @@ impl EventReader for PgStore { AND ($2::timestamptz IS NULL OR occurred_at < $2) AND ($3::text[] IS NULL OR source = ANY($3)) AND ($4::bool OR public = true) - AND ($6::text IS NULL OR COALESCE( - payload->'repo'->>'name', - payload->'repository'->>'full_name', - payload->>'_repo', - payload->>'product' - ) = $6) + AND ($6::text IS NULL OR (CASE source + WHEN 'github' THEN COALESCE( + payload->'repo'->>'name', + payload->'repository'->>'full_name' + ) + WHEN 'gitea' THEN COALESCE( + payload->'repo'->>'full_name', + payload->'repo'->>'name' + ) + WHEN 'hg' THEN payload->>'_repo' + WHEN 'bugzilla' THEN payload->>'product' + ELSE NULL + END) = $6) ORDER BY occurred_at DESC LIMIT $5 "#, @@ -134,12 +141,19 @@ impl EventReader for PgStore { MAX(occurred_at) AS last_activity FROM ( SELECT source, occurred_at, - COALESCE( - payload->'repo'->>'name', - payload->'repository'->>'full_name', - payload->>'_repo', - payload->>'product' - ) AS repo, + CASE source + WHEN 'github' THEN COALESCE( + payload->'repo'->>'name', + payload->'repository'->>'full_name' + ) + WHEN 'gitea' THEN COALESCE( + payload->'repo'->>'full_name', + payload->'repo'->>'name' + ) + WHEN 'hg' THEN payload->>'_repo' + WHEN 'bugzilla' THEN payload->>'product' + ELSE NULL + END AS repo, CASE source WHEN 'github' THEN 'github.com' WHEN 'gitea' THEN COALESCE(payload->>'_host', 'git.lair.cafe') diff --git a/ui/src/api/client.ts b/ui/src/api/client.ts index ce4283a..9da616a 100644 --- a/ui/src/api/client.ts +++ b/ui/src/api/client.ts @@ -102,20 +102,26 @@ export async function fetchProjects(): Promise { return resp.json(); } -/** Fetch repo README as rendered HTML or raw markdown. */ +/** Fetch repo README as raw markdown. */ export async function fetchReadme(source: Source, host: string, repo: string): Promise { - const baseUrl = source === 'github' - ? `https://api.github.com/repos/${repo}/readme` - : source === 'gitea' - ? `https://${host}/api/v1/repos/${repo}/readme` - : null; - if (!baseUrl) return null; - - const resp = await fetch(baseUrl, { - headers: { 'Accept': 'application/vnd.github.raw+json' }, - }); - if (!resp.ok) return null; - return resp.text(); + if (source === 'github') { + const resp = await fetch(`https://api.github.com/repos/${repo}/readme`, { + headers: { 'Accept': 'application/vnd.github.raw+json' }, + }); + if (!resp.ok) return null; + return resp.text(); + } + if (source === 'gitea') { + // Gitea returns JSON with base64-encoded content + const resp = await fetch(`https://${host}/api/v1/repos/${repo}/contents/README.md`); + if (!resp.ok) return null; + const data = await resp.json(); + if (data.encoding === 'base64' && data.content) { + return atob(data.content); + } + return data.content ?? null; + } + return null; } /** Fetch repo languages as { language: bytes } map. */