diff --git a/ui/src/routes/admin/+layout.svelte b/ui/src/routes/admin/+layout.svelte index 671a64c..e6b5c96 100644 --- a/ui/src/routes/admin/+layout.svelte +++ b/ui/src/routes/admin/+layout.svelte @@ -3,7 +3,8 @@ const internalLinks = [ { href: '/admin/scrape', label: 'Scrape' }, - { href: '/admin/audio', label: 'Audio' } + { href: '/admin/audio', label: 'Audio' }, + { href: '/admin/changelog', label: 'Changelog' } ]; const externalLinks = [ diff --git a/ui/src/routes/admin/changelog/+page.server.ts b/ui/src/routes/admin/changelog/+page.server.ts new file mode 100644 index 0000000..a47ad03 --- /dev/null +++ b/ui/src/routes/admin/changelog/+page.server.ts @@ -0,0 +1,27 @@ +import type { PageServerLoad } from './$types'; + +export interface Release { + id: number; + tag_name: string; + name: string; + body: string; + published_at: string; + prerelease: boolean; + draft: boolean; +} + +export const load: PageServerLoad = async ({ fetch }) => { + try { + const res = await fetch( + 'https://gitea.kalekber.cc/api/v1/repos/kamil/libnovel/releases?limit=50&page=1', + { headers: { Accept: 'application/json' } } + ); + if (!res.ok) throw new Error(`Gitea API returned ${res.status}`); + const releases: Release[] = await res.json(); + return { + releases: releases.filter((r) => !r.draft) + }; + } catch (e) { + return { releases: [], error: String(e) }; + } +}; diff --git a/ui/src/routes/admin/changelog/+page.svelte b/ui/src/routes/admin/changelog/+page.svelte new file mode 100644 index 0000000..eae4134 --- /dev/null +++ b/ui/src/routes/admin/changelog/+page.svelte @@ -0,0 +1,59 @@ + + + + Changelog — libnovel admin + + +
+
+

Changelog

+ + Gitea releases + + + + +
+ + {#if data.error} +

Could not load releases: {data.error}

+ {:else if data.releases.length === 0} +

No releases found.

+ {:else} +
+ {#each data.releases as release} +
+
+ {release.tag_name} + {#if release.name && release.name !== release.tag_name} + {release.name} + {/if} + {#if release.prerelease} + pre-release + {/if} + {fmtDate(release.published_at)} +
+ {#if release.body.trim()} +

{release.body.trim()}

+ {/if} +
+ {/each} +
+ {/if} +
diff --git a/ui/src/routes/admin/scrape/+page.svelte b/ui/src/routes/admin/scrape/+page.svelte index 9791a62..bdf549b 100644 --- a/ui/src/routes/admin/scrape/+page.svelte +++ b/ui/src/routes/admin/scrape/+page.svelte @@ -231,131 +231,110 @@ Scrape tasks — libnovel admin -
+
-
-
-

Scrape tasks

-

- Job status: - {#if running} - Running - {:else} - Idle - {/if} -

-
+
+

Scrape

+ + ● {running ? 'Running' : 'Idle'} +
- -
+ +
-
-
-

Scrape full catalogue

-

Re-crawls all novelfire.net pages and picks up new books.

-
+
+ Full catalogue - {#if catalogueError} -

{catalogueError}

- {/if} + {#if catalogueError}{catalogueError}{/if}
-
-

Scrape a single book

-
- - -
- {#if scrapeError} -

{scrapeError}

- {/if} +
+ Single book + + + {#if scrapeError}{scrapeError}{/if}
-
-

Scrape chapter range

+
+ Chapter range -
- - - -
- {#if rangeError} -

{rangeError}

- {/if} -
-
- - -
-

Quick genre refresh

-

Paste one of these into the single-book scraper to re-index a genre, or use them as starting points for range scrapes.

-
- {#each quickScrapes as qs} - - {/each} - + + + {#if rangeError}{rangeError}{/if} +
+ + +
+ Quick genres +
+ {#each quickScrapes as qs} + + {/each} + + novelfire.net ↗ + +
-

Task history

+

Task history