You've already forked AstralRinth
forked from didirus/AstralRinth
Add changelog page to website (#3242)
* Add changelog page to website * Add pages for individual changelog entries that can be linked to * Handle first case for individual page * Add some more changelog entries, improve some spacing
This commit is contained in:
@@ -76,7 +76,12 @@ function pickLink() {
|
||||
subpageSelected.value = false;
|
||||
for (let i = filteredLinks.value.length - 1; i >= 0; i--) {
|
||||
const link = filteredLinks.value[i];
|
||||
if (decodeURIComponent(route.path) === link.href) {
|
||||
if (props.query) {
|
||||
if (route.query[props.query] === link.href || (!route.query[props.query] && !link.href)) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
} else if (decodeURIComponent(route.path) === link.href) {
|
||||
index = i;
|
||||
break;
|
||||
} else if (
|
||||
@@ -150,7 +155,7 @@ onMounted(() => {
|
||||
});
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => [route.path, route.query],
|
||||
() => pickLink(),
|
||||
);
|
||||
</script>
|
||||
|
||||
86
apps/frontend/src/pages/news/changelog/[product]/[date].vue
Normal file
86
apps/frontend/src/pages/news/changelog/[product]/[date].vue
Normal file
@@ -0,0 +1,86 @@
|
||||
<script setup lang="ts">
|
||||
import { getChangelog } from "@modrinth/utils";
|
||||
import { ChangelogEntry } from "@modrinth/ui";
|
||||
import { ChevronLeftIcon } from "@modrinth/assets";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const changelogEntry = computed(() =>
|
||||
route.params.date
|
||||
? getChangelog().find((x) => {
|
||||
if (x.product === route.params.product) {
|
||||
console.log("Found matching product!");
|
||||
|
||||
if (x.version && x.version === route.params.date) {
|
||||
console.log("Found matching version!");
|
||||
return x;
|
||||
} else if (x.date.unix() === Number(route.params.date as string)) {
|
||||
console.log("Found matching date!");
|
||||
return x;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
})
|
||||
: undefined,
|
||||
);
|
||||
|
||||
const isFirst = computed(() => changelogEntry.value?.date === getChangelog()[0].date);
|
||||
|
||||
if (!changelogEntry.value) {
|
||||
createError({ statusCode: 404, statusMessage: "Version not found" });
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="changelogEntry" class="page experimental-styles-within">
|
||||
<nuxt-link
|
||||
:to="`/news/changelog?filter=${changelogEntry.product}`"
|
||||
class="mb-4 flex w-fit items-center gap-2 text-link"
|
||||
>
|
||||
<ChevronLeftIcon /> View full changelog
|
||||
</nuxt-link>
|
||||
<div class="relative flex flex-col gap-4 pb-6">
|
||||
<div class="absolute flex h-full w-4 justify-center">
|
||||
<div class="timeline-indicator" :class="{ first: isFirst }" />
|
||||
</div>
|
||||
<ChangelogEntry :entry="changelogEntry" :first="isFirst" show-type class="relative z-10" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page {
|
||||
padding: 0.5rem;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: 56rem;
|
||||
}
|
||||
|
||||
.timeline-indicator {
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--color-raised-bg) 66%,
|
||||
rgba(255, 255, 255, 0) 0%
|
||||
);
|
||||
background-size: 100% 30px;
|
||||
background-repeat: repeat-y;
|
||||
|
||||
height: calc(100% + 2rem);
|
||||
width: 4px;
|
||||
margin-top: -2rem;
|
||||
|
||||
mask-image: linear-gradient(
|
||||
to bottom,
|
||||
transparent 0%,
|
||||
black 8rem,
|
||||
black calc(100% - 8rem),
|
||||
transparent 100%
|
||||
);
|
||||
|
||||
&.first {
|
||||
margin-top: 1rem;
|
||||
|
||||
mask-image: linear-gradient(black calc(100% - 15rem), transparent 100%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
97
apps/frontend/src/pages/news/changelog/index.vue
Normal file
97
apps/frontend/src/pages/news/changelog/index.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<script setup lang="ts">
|
||||
import { type Product, getChangelog } from "@modrinth/utils";
|
||||
import { ChangelogEntry } from "@modrinth/ui";
|
||||
import NavTabs from "~/components/ui/NavTabs.vue";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const filter = ref<Product | undefined>(undefined);
|
||||
const allChangelogEntries = ref(getChangelog());
|
||||
|
||||
function updateFilter() {
|
||||
if (route.query.filter) {
|
||||
filter.value = route.query.filter as Product;
|
||||
} else {
|
||||
filter.value = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
updateFilter();
|
||||
|
||||
watch(
|
||||
() => route.query,
|
||||
() => updateFilter(),
|
||||
);
|
||||
|
||||
const changelogEntries = computed(() =>
|
||||
allChangelogEntries.value.filter((x) => !filter.value || x.product === filter.value),
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="page experimental-styles-within">
|
||||
<h1 class="m-0 text-3xl font-extrabold">Changelog</h1>
|
||||
<p class="my-3">Keep up-to-date on what's new with Modrinth.</p>
|
||||
<NavTabs
|
||||
:links="[
|
||||
{
|
||||
label: 'All',
|
||||
href: '',
|
||||
},
|
||||
{
|
||||
label: 'Website',
|
||||
href: 'web',
|
||||
},
|
||||
{
|
||||
label: 'Servers',
|
||||
href: 'servers',
|
||||
},
|
||||
{
|
||||
label: 'App',
|
||||
href: 'app',
|
||||
},
|
||||
]"
|
||||
query="filter"
|
||||
class="mb-4"
|
||||
/>
|
||||
<div class="relative flex flex-col gap-4 pb-6">
|
||||
<div class="absolute flex h-full w-4 justify-center">
|
||||
<div class="timeline-indicator" />
|
||||
</div>
|
||||
<ChangelogEntry
|
||||
v-for="(entry, index) in changelogEntries"
|
||||
:key="entry.date"
|
||||
:entry="entry"
|
||||
:first="index === 0"
|
||||
:show-type="filter === undefined"
|
||||
has-link
|
||||
class="relative z-10"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page {
|
||||
padding: 0.5rem;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: 56rem;
|
||||
}
|
||||
|
||||
.timeline-indicator {
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--color-raised-bg) 66%,
|
||||
rgba(255, 255, 255, 0) 0%
|
||||
);
|
||||
background-size: 100% 30px;
|
||||
background-repeat: repeat-y;
|
||||
margin-top: 1rem;
|
||||
|
||||
height: calc(100% - 1rem);
|
||||
width: 4px;
|
||||
|
||||
mask-image: linear-gradient(to bottom, black calc(100% - 15rem), transparent 100%);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user