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:
parent
affeec82f0
commit
cade2c182c
@ -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>
|
||||
149
packages/ui/src/components/changelog/ChangelogEntry.vue
Normal file
149
packages/ui/src/components/changelog/ChangelogEntry.vue
Normal file
@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="flex items-center gap-4">
|
||||
<div
|
||||
class="h-4 w-4 rounded-full border-2 border-solid border-button-border"
|
||||
:class="recent || first ? 'bg-brand' : 'bg-button-bg'"
|
||||
/>
|
||||
<AutoLink
|
||||
:to="
|
||||
hasLink ? `/news/changelog/${entry.product}/${entry.version ?? entry.date.unix()}` : ''
|
||||
"
|
||||
class="flex items-center gap-2"
|
||||
:class="{ 'hover:underline': hasLink }"
|
||||
>
|
||||
<h2 class="flex items-center gap-2 m-0 text-xl font-extrabold text-contrast">
|
||||
<template v-if="showType">
|
||||
{{ formatMessage(messages[entry.product]) }}
|
||||
<div class="w-2 h-2 rounded-full bg-secondary" />
|
||||
</template>
|
||||
<span :class="{ 'text-primary font-bold': showType }">
|
||||
{{ entry.version ?? formattedDate }}
|
||||
</span>
|
||||
</h2>
|
||||
<div v-if="entry.version" v-tooltip="dateTooltip" :class="{ 'cursor-help': dateTooltip }">
|
||||
{{ formattedDate }}
|
||||
</div>
|
||||
</AutoLink>
|
||||
</div>
|
||||
<div class="ml-8 mt-3 rounded-2xl bg-bg-raised px-4 py-3">
|
||||
<div class="changelog-body" v-html="renderHighlightedString(entry.body)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { VersionEntry } from '@modrinth/utils/changelog'
|
||||
import { renderHighlightedString } from '@modrinth/utils'
|
||||
import dayjs from 'dayjs'
|
||||
import { useVIntl, defineMessages } from '@vintl/vintl'
|
||||
import { computed, ref } from 'vue'
|
||||
import AutoLink from '../base/AutoLink.vue'
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
entry: VersionEntry
|
||||
showType?: boolean
|
||||
first?: boolean
|
||||
hasLink?: boolean
|
||||
}>(),
|
||||
{
|
||||
showType: false,
|
||||
first: false,
|
||||
hasLink: false,
|
||||
},
|
||||
)
|
||||
|
||||
const currentDate = ref(dayjs())
|
||||
const recent = computed(() => props.entry.date.isAfter(currentDate.value.subtract(1, 'week')))
|
||||
const dateTooltip = computed(() => props.entry.date.format('MMMM D, YYYY [at] h:mm A'))
|
||||
const formattedDate = computed(() =>
|
||||
props.entry.version ? props.entry.date.fromNow() : props.entry.date.format('MMMM D, YYYY'),
|
||||
)
|
||||
|
||||
const messages = defineMessages({
|
||||
web: {
|
||||
id: 'changelog.product.web',
|
||||
defaultMessage: 'Website',
|
||||
},
|
||||
servers: {
|
||||
id: 'changelog.product.servers',
|
||||
defaultMessage: 'Servers',
|
||||
},
|
||||
app: {
|
||||
id: 'changelog.product.app',
|
||||
defaultMessage: 'App',
|
||||
},
|
||||
api: {
|
||||
id: 'changelog.product.api',
|
||||
defaultMessage: 'API',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
:deep(.changelog-body) {
|
||||
line-height: 1.4;
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 1.25rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-link);
|
||||
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
filter: brightness(1.2);
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: var(--color-bg);
|
||||
font-size: var(--font-size-sm);
|
||||
padding: 0.125rem 0.25rem;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
* + p {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
h3 + * {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
* + h3 {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
|
||||
* + li {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
li ul li {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
border-radius: var(--radius-md);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -40,6 +40,9 @@ export { default as Toggle } from './base/Toggle.vue'
|
||||
export { default as AnimatedLogo } from './brand/AnimatedLogo.vue'
|
||||
export { default as TextLogo } from './brand/TextLogo.vue'
|
||||
|
||||
// Changelog
|
||||
export { default as ChangelogEntry } from './changelog/ChangelogEntry.vue'
|
||||
|
||||
// Charts
|
||||
export { default as Chart } from './chart/Chart.vue'
|
||||
export { default as CompactChart } from './chart/CompactChart.vue'
|
||||
|
||||
@ -32,6 +32,18 @@
|
||||
"button.upload-image": {
|
||||
"defaultMessage": "Upload image"
|
||||
},
|
||||
"changelog.product.api": {
|
||||
"defaultMessage": "API"
|
||||
},
|
||||
"changelog.product.app": {
|
||||
"defaultMessage": "App"
|
||||
},
|
||||
"changelog.product.servers": {
|
||||
"defaultMessage": "Servers"
|
||||
},
|
||||
"changelog.product.web": {
|
||||
"defaultMessage": "Website"
|
||||
},
|
||||
"collection.label.private": {
|
||||
"defaultMessage": "Private"
|
||||
},
|
||||
|
||||
132
packages/utils/changelog.ts
Normal file
132
packages/utils/changelog.ts
Normal file
@ -0,0 +1,132 @@
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
export type Product = 'web' | 'servers' | 'api' | 'app'
|
||||
|
||||
export type VersionEntry = {
|
||||
date: dayjs.Dayjs
|
||||
product: Product
|
||||
version?: string
|
||||
body: string
|
||||
}
|
||||
|
||||
const VERSIONS: VersionEntry[] = [
|
||||
{
|
||||
date: `2025-02-11T09:00:00-09:00`,
|
||||
product: 'web',
|
||||
body: `### Added
|
||||
- Added a changelog page to view recent changes to Modrinth.`,
|
||||
},
|
||||
{
|
||||
date: `2025-02-10T14:00:00-09:00`,
|
||||
product: 'web',
|
||||
body: `### Improvements
|
||||
- The license selector in project settings has been updated to make selecting a license a clearer process. (Contributed by [Erb3](https://github.com/modrinth/code/pull/3225))`,
|
||||
},
|
||||
{
|
||||
date: `2025-02-10T08:00:00-09:00`,
|
||||
product: 'servers',
|
||||
body: `### Added
|
||||
- You can now search and filter through your server's console in the Overview tab, jump to specific results to see the log in context, select them, and copy them.
|
||||
- You can now drag and select any number of lines in the console, copy them. and view them formatted.
|
||||
- Hide your server's \`.modrinth.gg\` custom URL using the new **Hide subdomain label** toggle in Options > Preferences.
|
||||
- The Content page has been updated to make managing your server's mods and plugins easier than ever. Now, only versions that are available for your server's Minecraft version and platform are shown by default, and you can now show beta and alpha versions in the selector.
|
||||
### Improvements
|
||||
- The Overview page loads faster.
|
||||
- The Options > Properties page loads faster.
|
||||
- The server hardware graphs in the Overview page have been rewritten to improve power efficiency and fix rendering bugs.
|
||||
- The modpack selector in Options > Platform now shows more information about a modpack, like its tags, downloads, and followers.
|
||||
- Reinstalling your server no longer requires the browser to refresh the page in order to work properly. We now also lock more options while a server installs to prevent your server from bricking itself.
|
||||
- The server console has been rewritten to implement proper batching. All performance issues with the console previously have now been fixed.
|
||||
- An error state has been added in the server list if servers are unable to be fetched.
|
||||
- Sorting in the Files tab is now accessible by clicking the column headers.
|
||||
- Backing up a server and erasing all its data simultaneously in the Platform page now works as expected.
|
||||
- Opening a platform modal, then opening another, no longer causes versions of that platform to fail to load.`,
|
||||
},
|
||||
{
|
||||
date: `2025-02-06T10:00:00-09:00`,
|
||||
product: 'app',
|
||||
version: `0.9.3`,
|
||||
body: `### Improvements
|
||||
- Prevent ads from being able to open additional windows.
|
||||
- Fixed update checking only checking for mod updates.
|
||||
- Fixed issue importing newer Prism instances.
|
||||
- Fixed issue where instances get stuck "Installing" forever when the app is closed during an install.
|
||||
- Minecraft profile is now updated every time the user's token is refreshed.
|
||||
- Improved ability for package managers to update Modrinth App by skipping the updater at runtime with an environment variable.`,
|
||||
},
|
||||
{
|
||||
date: `2025-02-02T14:00:00-09:00`,
|
||||
product: 'web',
|
||||
body: `### Improvements
|
||||
- The report form has been updated to walk you through the report process better and clarify some things like that the form is for Modrinth rules and terms violations, not for bug reports or DMCA takedowns.
|
||||
|
||||
`,
|
||||
},
|
||||
{
|
||||
date: `2025-01-28T19:00:00-09:00`,
|
||||
product: 'web',
|
||||
body: `### Improvements
|
||||
- The UI for analytics has been updated to make it way more useful. What was previously called "Last month" really meant "Previous 30 days". Now, many more options have been added such as:
|
||||
- "This month" which refers to the current calendar month (Jan 1st - Jan 28th, currently)
|
||||
- "Last month" which refers to the previous calendar month (currently, Dec 1st thru Dec 31st)
|
||||
|
||||
Contributed by [IMB11](https://github.com/modrinth/code/pull/1301).`,
|
||||
},
|
||||
{
|
||||
date: `2025-01-10T09:00:00-09:00`,
|
||||
product: 'servers',
|
||||
body: `### Improvements
|
||||
- The content page layout has been enhanced, now showing the file name and author of each installed item.
|
||||
- You can now upload directly from the content page, instead of having to go to the Files page.`,
|
||||
},
|
||||
{
|
||||
date: `2025-01-10T09:00:00-09:00`,
|
||||
product: 'web',
|
||||
body: `### Improvements
|
||||
- Tags on project pages are now clickable to view other projects with that tag (Contributed by [Neddo](https://github.com/modrinth/code/pull/3126))
|
||||
- You can now send someone a link to the download interface with a specific version and loader selected, like so: https://modrinth.com/mod/sodium?version=1.21.2&loader=quilt#download (Contributed by [AwakenedRedstone](https://github.com/modrinth/code/pull/3138)`,
|
||||
},
|
||||
{
|
||||
date: `2024-12-25T14:00:00-09:00`,
|
||||
product: 'app',
|
||||
version: `0.9.2`,
|
||||
body: `### Improvements
|
||||
- Prevent ads from being able to play audio.`,
|
||||
},
|
||||
{
|
||||
date: `2024-12-24T22:00:00-09:00`,
|
||||
product: 'app',
|
||||
version: `0.9.1`,
|
||||
body: `### Added
|
||||
- Added filter to filter projects by disabled.
|
||||
- Re-added back/forward navigation buttons.
|
||||
### Improvements
|
||||
- Fixed environment tags missing from search.
|
||||
- Fixed an issue where ads could play audio.
|
||||
- Changed content enable/disable buttons to toggle switches.
|
||||
- Show "install" button at all time on project cards.
|
||||
- Fixed issue where cards would shrink when clicking button inside them causing click not to register.
|
||||
- Made sidebar hide instantly.`,
|
||||
},
|
||||
{
|
||||
date: `2024-12-23T22:16:00-09:00`,
|
||||
product: 'app',
|
||||
version: `0.9.0`,
|
||||
body: `### Improvements
|
||||
- New, updated design that brings the app in-line with the website.
|
||||
- A dynamic sidebar that adjusts to the most relevant content for each page, and keeps the ad in a consistent place instead of moving all around your screen.
|
||||
- More organized settings interfaces that makes each option clearer and easier to find.
|
||||
- Managing your content is much easier with enhanced filters for content types or checking for updates.
|
||||
- Content discovery has been overhauled and now has fully-featured project pages that match the website.
|
||||
- Instances now show your total play time, and will show the last time you played on the Home screen.
|
||||
- The library page now gives responsive feedback as instances are installing.
|
||||
- The beginnings of a Friends system. In the future, you will be able to share the instances you’re playing and invite them to servers.
|
||||
- Access your most recent instances with ease with Quick Instances.
|
||||
- Fixed “Database is locked” errors on devices with slow disks.
|
||||
- Fixed a few edge cases where API downtime could lead to an invalid state.`,
|
||||
},
|
||||
].map((x) => ({ ...x, date: dayjs(x.date) }) as VersionEntry)
|
||||
|
||||
export function getChangelog() {
|
||||
return VERSIONS
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
export * from './billing'
|
||||
export * from './changelog'
|
||||
export * from './highlight'
|
||||
export * from './licenses'
|
||||
export * from './parse'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user