Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | <script> import { onMount } from "svelte"; import { get } from "../lib/api.js"; let repos = $state([]); let commits = $state([]); let selectedRepo = $state(""); let loading = $state(true); let loadingCommits = $state(false); async function load() { loading = true; const data = await get("/gitea/repos"); repos = Array.isArray(data) ? data : data?.data || []; loading = false; } async function showCommits(owner, repo) { selectedRepo = `${owner}/${repo}`; loadingCommits = true; const data = await get(`/gitea/repos/${owner}/${repo}/commits`); commits = Array.isArray(data) ? data : []; loadingCommits = false; } function timeAgo(d) { const s = Math.floor((Date.now() - new Date(d)) / 1000); if (s < 60) return "just now"; if (s < 3600) return Math.floor(s / 60) + "m ago"; if (s < 86400) return Math.floor(s / 3600) + "h ago"; return Math.floor(s / 86400) + "d ago"; } const langColors = { Python: "#3572A5", JavaScript: "#f1e05a", Shell: "#89e051", Go: "#00ADD8", TypeScript: "#3178c6", Markdown: "#083fa1", CSS: "#563d7c", HTML: "#e34c26", }; onMount(load); </script> <div class="space-y-6"> <div> <h1 class="text-2xl font-bold text-surface-900 dark:text-white tracking-tight">Repositories</h1> <p class="text-sm text-surface-400 mt-1">{repos.length} repositories on Gitea</p> </div> {#if loading} <div class="grid grid-cols-1 md:grid-cols-2 gap-3"> {#each Array(4) as _} <div class="h-[100px] rounded-xl bg-surface-100 dark:bg-surface-800 animate-pulse"></div> {/each} </div> {:else} <div class="grid grid-cols-1 md:grid-cols-2 gap-3"> {#each repos as r} <button class="bg-white dark:bg-surface-800 rounded-xl border border-surface-200 dark:border-surface-700 p-4 text-left shadow-sm hover:shadow-md hover:border-primary-200 dark:hover:border-primary-700 transition-all duration-200 group {selectedRepo === `${r.owner?.login}/${r.name}` ? 'ring-2 ring-primary-500 border-primary-300' : ''}" onclick={() => showCommits(r.owner?.login, r.name)} > <div class="flex items-start justify-between"> <div class="min-w-0"> <p class="text-sm font-semibold text-surface-800 dark:text-surface-100 group-hover:text-primary-600 transition-colors truncate">{r.name}</p> <p class="text-xs text-surface-400 mt-1 line-clamp-1">{r.description || "No description"}</p> </div> {#if r.language} <span class="flex items-center gap-1 text-[11px] text-surface-500 shrink-0 ml-2"> <span class="w-2 h-2 rounded-full" style="background: {langColors[r.language] || '#888'}"></span> {r.language} </span> {/if} </div> <p class="text-[11px] text-surface-400 mt-2.5">Updated {timeAgo(r.updated_at)}</p> </button> {/each} </div> {/if} <!-- Commits Panel --> {#if selectedRepo} <div class="bg-white dark:bg-surface-800 rounded-xl border border-surface-200 dark:border-surface-700 p-5 shadow-sm"> <div class="flex items-center justify-between mb-4"> <div> <h3 class="text-sm font-bold text-surface-800 dark:text-surface-100">Recent Commits</h3> <p class="text-xs text-surface-400 mt-0.5">{selectedRepo}</p> </div> <button aria-label="Close commits" class="text-xs text-surface-400 hover:text-surface-600 transition-colors" onclick={() => { selectedRepo = ""; commits = []; }} > <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg> </button> </div> {#if loadingCommits} <div class="space-y-3"> {#each Array(3) as _} <div class="h-12 rounded-lg bg-surface-100 animate-pulse"></div> {/each} </div> {:else} <div class="space-y-0"> {#each commits.slice(0, 15) as c, i} <div class="flex gap-3 py-2.5 {i < commits.length - 1 ? 'border-b border-surface-100 dark:border-surface-700' : ''}"> <div class="flex flex-col items-center pt-1"> <div class="w-2 h-2 rounded-full bg-primary-400 shrink-0"></div> {#if i < commits.length - 1} <div class="w-px flex-1 bg-surface-200 mt-1"></div> {/if} </div> <div class="min-w-0 flex-1"> <p class="text-sm text-surface-700 dark:text-surface-200 truncate">{c.commit?.message?.split("\n")[0]}</p> <p class="text-[11px] text-surface-400 mt-0.5"> <span class="font-medium">{c.commit?.author?.name}</span> ยท {timeAgo(c.commit?.author?.date)} </p> </div> <span class="text-[10px] font-mono text-surface-400 bg-surface-50 dark:bg-surface-700 px-1.5 py-0.5 rounded h-fit shrink-0">{c.sha?.slice(0, 7)}</span> </div> {/each} </div> {/if} </div> {/if} </div> |