|
1 | 1 | <script lang="ts">
|
2 | 2 | import { resolve } from "$app/paths";
|
3 |
| - import { Image, Info } from "@lucide/svelte"; |
| 3 | + import { Image, Info, LoaderCircle } from "@lucide/svelte"; |
4 | 4 | import { Transparent } from "svelte-exmarkdown";
|
5 | 5 | import { buttonVariants } from "$lib/components/ui/button";
|
6 | 6 | import * as Dialog from "$lib/components/ui/dialog";
|
|
11 | 11 | let { data, params } = $props();
|
12 | 12 |
|
13 | 13 | type Item =
|
14 |
| - | NonNullable<typeof data.issues>[number] |
15 |
| - | NonNullable<typeof data.prs>[number] |
16 |
| - | NonNullable<typeof data.discussions>[number]; |
| 14 | + | Awaited<NonNullable<typeof data.issues>>[number] |
| 15 | + | Awaited<NonNullable<typeof data.prs>>[number] |
| 16 | + | Awaited<NonNullable<typeof data.discussions>>[number]; |
17 | 17 |
|
18 | 18 | /**
|
19 | 19 | * Checks whether a date is more recent than a month.
|
|
52 | 52 | }
|
53 | 53 | </script>
|
54 | 54 |
|
55 |
| -{#snippet list<T extends Item>(title: string, items: T[], itemToLink: (item: T) => string)} |
| 55 | +{#snippet list<T extends Item>( |
| 56 | + title: string, |
| 57 | + items: T[] | Promise<T[]>, |
| 58 | + itemToLink: (item: T) => string |
| 59 | +)} |
56 | 60 | <div>
|
57 | 61 | <h2 class="mt-12 mb-4 text-3xl font-semibold tracking-tight">{title}</h2>
|
58 |
| - {#each items as item, i (item.id)} |
59 |
| - {#if i > 0} |
60 |
| - <Separator class="my-1" /> |
61 |
| - {/if} |
62 |
| - {@render listItem(item, itemToLink(item))} |
63 |
| - {/each} |
| 62 | + {#await items} |
| 63 | + <p class="mt-2 mb-4 inline-flex justify-center text-xl"> |
| 64 | + <LoaderCircle class="mr-2 h-lh shrink-0 animate-spin" /> |
| 65 | + Loading (this may take a while)... |
| 66 | + </p> |
| 67 | + {:then loadedItems} |
| 68 | + {#each loadedItems as item, i (item.id)} |
| 69 | + {#if i > 0} |
| 70 | + <Separator class="my-1" /> |
| 71 | + {/if} |
| 72 | + {@render listItem(item, itemToLink(item))} |
| 73 | + {:else} |
| 74 | + <p class="text-lg">Nothing to show there :/</p> |
| 75 | + {/each} |
| 76 | + {:catch e} |
| 77 | + <p class="text-lg text-destructive">Failed to load elements: {e}</p> |
| 78 | + {/await} |
64 | 79 | </div>
|
65 | 80 | {/snippet}
|
66 | 81 |
|
|
188 | 203 | </div>
|
189 | 204 | </div>
|
190 | 205 |
|
191 |
| -{#if data.prs.length} |
192 |
| - {@render list("Pull requests", data.prs, pr => |
193 |
| - resolve("/[pid=pid]/[org]/[repo]/[id=number]", { |
194 |
| - pid: "pull", |
195 |
| - org: pr.base.repo.owner.login, |
196 |
| - repo: pr.base.repo.name, |
197 |
| - id: `${pr.number}` |
198 |
| - }) |
199 |
| - )} |
200 |
| -{/if} |
| 206 | +{@render list("Pull requests", data.prs, pr => |
| 207 | + resolve("/[pid=pid]/[org]/[repo]/[id=number]", { |
| 208 | + pid: "pull", |
| 209 | + org: pr.base.repo.owner.login, |
| 210 | + repo: pr.base.repo.name, |
| 211 | + id: `${pr.number}` |
| 212 | + }) |
| 213 | +)} |
201 | 214 |
|
202 |
| -{#if data.discussions.length} |
203 |
| - {@render list("Discussions", data.discussions, d => { |
204 |
| - const [org = "", repo = ""] = d.repository_url |
205 |
| - .replace("https://api.github.com/repos/", "") |
206 |
| - .split("/"); |
207 |
| - return resolve("/[pid=pid]/[org]/[repo]/[id=number]", { |
208 |
| - pid: "discussions", |
209 |
| - org, |
210 |
| - repo, |
211 |
| - id: `${d.number}` |
212 |
| - }); |
213 |
| - })} |
214 |
| -{/if} |
| 215 | +{@render list("Discussions", data.discussions, d => { |
| 216 | + const [org = "", repo = ""] = d.repository_url |
| 217 | + .replace("https://api.github.com/repos/", "") |
| 218 | + .split("/"); |
| 219 | + return resolve("/[pid=pid]/[org]/[repo]/[id=number]", { |
| 220 | + pid: "discussions", |
| 221 | + org, |
| 222 | + repo, |
| 223 | + id: `${d.number}` |
| 224 | + }); |
| 225 | +})} |
215 | 226 |
|
216 |
| -{#if data.issues.length} |
217 |
| - {@render list("Issues", data.issues, issue => { |
218 |
| - const [org = "", repo = ""] = issue.html_url |
219 |
| - .replace("https://github.com/", "") |
220 |
| - .replace(/\/[A-z]+\/\d+$/, "") |
221 |
| - .split("/"); |
222 |
| - return resolve("/[pid=pid]/[org]/[repo]/[id=number]", { |
223 |
| - pid: "issues", |
224 |
| - org, |
225 |
| - repo, |
226 |
| - id: `${issue.number}` |
227 |
| - }); |
228 |
| - })} |
229 |
| -{/if} |
230 |
| - |
231 |
| -{#if [data.prs.length, data.discussions.length, data.issues.length].every(len => !len)} |
232 |
| - <div class="mt-16 text-2xl">Nothing interesting to show here :/</div> |
233 |
| -{/if} |
| 227 | +{@render list("Issues", data.issues, issue => { |
| 228 | + const [org = "", repo = ""] = issue.html_url |
| 229 | + .replace("https://github.com/", "") |
| 230 | + .replace(/\/[A-z]+\/\d+$/, "") |
| 231 | + .split("/"); |
| 232 | + return resolve("/[pid=pid]/[org]/[repo]/[id=number]", { |
| 233 | + pid: "issues", |
| 234 | + org, |
| 235 | + repo, |
| 236 | + id: `${issue.number}` |
| 237 | + }); |
| 238 | +})} |
0 commit comments