diff --git a/web/src/components/misc/ChangelogEntry.svelte b/web/src/components/misc/ChangelogEntry.svelte new file mode 100644 index 00000000..1b278498 --- /dev/null +++ b/web/src/components/misc/ChangelogEntry.svelte @@ -0,0 +1,36 @@ +<script lang="ts"> + export let version: string; + export let title: string; + export let date: string; + export let banner: { file: string, alt: string } | undefined; +</script> +<style> + img { + max-width: 100%; + } + + h1, h2 { + padding-top: 1em; + } + + .contents :global(.text-backdrop) { + border-radius: 4px; + background-color: var(--button); + color: var(--background); + padding: 0.3rem; + } + + .contents :global(.text-backdrop.link) { + text-decoration: underline; + } +</style> +<div> + <h1>{ version }: { title }</h1> + <h2>{ date }</h2> + {#if banner} + <img src={`/update-banners/${banner.file}`} alt={banner.alt} /> + {/if} + <div class="contents"> + <slot></slot> + </div> +</div> \ No newline at end of file diff --git a/web/src/components/misc/ChangelogEntryWrapper.svelte b/web/src/components/misc/ChangelogEntryWrapper.svelte new file mode 100644 index 00000000..3821fa42 --- /dev/null +++ b/web/src/components/misc/ChangelogEntryWrapper.svelte @@ -0,0 +1,11 @@ +<!-- Workaround for https://github.com/pngwn/MDsveX/issues/116 --> +<script lang="ts"> + import ChangelogEntry from "./ChangelogEntry.svelte"; + export let version = ''; + export let title = ''; + export let date = ''; + export let banner = undefined; +</script> +<ChangelogEntry {version} {title} {date} {banner}> + <slot></slot> +</ChangelogEntry> diff --git a/web/src/lib/changelogs.ts b/web/src/lib/changelogs.ts new file mode 100644 index 00000000..78e7df75 --- /dev/null +++ b/web/src/lib/changelogs.ts @@ -0,0 +1,22 @@ +import { compareVersions } from 'compare-versions'; + +export function getVersionFromPath(path: string) { + return path.split('/').pop()?.split('.md').shift()!; +} + +export function getAllChangelogs() { + const changelogImports = import.meta.glob("/changelogs/*.md"); + + const sortedVersions = Object.keys(changelogImports) + .map(path => [path, getVersionFromPath(path)]) + .sort(([, a], [, b]) => compareVersions(a, b)); + + const sortedChangelogs = sortedVersions.reduce( + (obj, [path, version]) => ({ + [version]: changelogImports[path], + ...obj + }), {} as typeof changelogImports + ); + + return sortedChangelogs; +} diff --git a/web/src/lib/types/changelogs.ts b/web/src/lib/types/changelogs.ts new file mode 100644 index 00000000..3dd41afc --- /dev/null +++ b/web/src/lib/types/changelogs.ts @@ -0,0 +1,19 @@ +import type { SvelteComponent } from "svelte" + +export interface ChangelogMetadata { + title: string, + date?: string + banner?: { + file: string, + alt: string + } +}; + +export interface MarkdownMetadata { + metadata: ChangelogMetadata +}; + +export type ChangelogImport = { + default: SvelteComponent, + metadata: ChangelogMetadata +} | undefined; diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index dc9670fa..4809d0fa 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -1,13 +1,61 @@ -<script> - import { t } from "$lib/i18n/translations"; +<script lang="ts"> + import { SvelteComponent, onMount } from 'svelte'; + import type { ChangelogImport, ChangelogMetadata } from '$lib/types/changelogs'; + import { t } from '$lib/i18n/translations'; + import { getAllChangelogs } from '$lib/changelogs'; - import Placeholder from "$components/misc/Placeholder.svelte"; + const changelogs = getAllChangelogs(); + const versions = Object.keys(changelogs); + + let changelog: ChangelogImport & { version: string } | undefined; + let currentIndex = -1; + + const loadChangelog = async () => { + const version = versions[currentIndex]; + const log = await changelogs[version]() as ChangelogImport; + if (!log) { + return; // FIXME: now wot + } + + changelog = { + ...log, + version + }; + } + + const nextChangelog = async () => { + ++currentIndex; + await loadChangelog(); + } + + onMount(async () => { + if (versions.length > 0) { + await nextChangelog() + } else { + // TODO: handle if no changelogs are present + // (can this happen? maybe) + } + }); </script> +<style> + .news { + max-width: 768px; + margin: 0 auto; + } +</style> + <svelte:head> <title> - {$t("general.cobalt")}: {$t("tabs.donate")} + {$t("general.cobalt")}: {$t("tabs.updates")} </title> </svelte:head> -<Placeholder pageName="updates" /> +<div class="news"> + {#if changelog} + <svelte:component this={changelog.default} version={changelog.version} /> + {/if} + {#if versions[currentIndex + 1]} + <button on:click={nextChangelog}>next</button> + {/if} +</div> \ No newline at end of file