From e2bcf2d1a79ea20017d9e6e73dfd3671439f67d3 Mon Sep 17 00:00:00 2001 From: Misode Date: Thu, 12 May 2022 16:58:10 +0200 Subject: [PATCH] Improve version and article linking --- src/app/components/Giscus.tsx | 26 +++++----- .../components/versions/ChangelogEntry.tsx | 12 ++--- src/app/components/versions/VersionDetail.tsx | 42 ++++++++++----- src/app/pages/Versions.tsx | 8 +-- src/app/services/Changelogs.ts | 51 ++++++++++++------- src/locales/en.json | 1 + src/styles/global.css | 12 ++++- 7 files changed, 90 insertions(+), 62 deletions(-) diff --git a/src/app/components/Giscus.tsx b/src/app/components/Giscus.tsx index cfc758d7..74bcf01e 100644 --- a/src/app/components/Giscus.tsx +++ b/src/app/components/Giscus.tsx @@ -11,16 +11,18 @@ export function Giscus({ term }: Props) { ? `http://localhost:3000/src/styles/giscus${themeSuffix}.css` : `${location.protocol}//${location.host}/assets/giscus${themeSuffix}.css` - return + return
+ +
} diff --git a/src/app/components/versions/ChangelogEntry.tsx b/src/app/components/versions/ChangelogEntry.tsx index c5651b7b..3ea09a5a 100644 --- a/src/app/components/versions/ChangelogEntry.tsx +++ b/src/app/components/versions/ChangelogEntry.tsx @@ -1,6 +1,6 @@ import { marked } from 'marked' import { ChangelogTag } from '.' -import type { Change, ChangelogVersion } from '../../services' +import type { Change } from '../../services' type Props = { change: Change, @@ -10,8 +10,8 @@ type Props = { export function ChangelogEntry({ change, activeTags, toggleTag }: Props) { return
{change.tags.map(tag => toggleTag(tag) : undefined} active={activeTags?.includes(tag)} />)} @@ -19,9 +19,3 @@ export function ChangelogEntry({ change, activeTags, toggleTag }: Props) {
} - -function ArticleLink({ id, article }: ChangelogVersion) { - return article === null - ? {id} - : {id} -} diff --git a/src/app/components/versions/VersionDetail.tsx b/src/app/components/versions/VersionDetail.tsx index 0a275ec3..94d91ce8 100644 --- a/src/app/components/versions/VersionDetail.tsx +++ b/src/app/components/versions/VersionDetail.tsx @@ -2,16 +2,18 @@ import { useEffect, useMemo, useState } from 'preact/hooks' import { VersionMetaData } from '.' import { useLocale } from '../../contexts' import type { Change, VersionMeta } from '../../services' -import { getChangelogs } from '../../services' +import { getArticleLink, getChangelogs } from '../../services' import { Giscus } from '../Giscus' +import { Octicon } from '../Octicon' import { ChangelogList } from './ChangelogList' type Tab = 'changelog' | 'discussion' interface Props { - version: VersionMeta + id: string, + version?: VersionMeta, } -export function VersionDetail({ version }: Props) { +export function VersionDetail({ id, version }: Props) { const { locale } = useLocale() const [tab, setTab] = useState('changelog') @@ -20,33 +22,45 @@ export function VersionDetail({ version }: Props) { useEffect(() => { getChangelogs() .then(changelogs => setChangelogs( - changelogs.map(c => ({ ...c, tags: c.tags.filter(t => t !== c.group.id) })) + changelogs.map(c => ({ ...c, tags: c.tags.filter(t => t !== c.group) })) )) .catch(e => console.error(e)) }, []) const filteredChangelogs = useMemo(() => - changelogs?.filter(c => c.version.id === version.id || c.group.id === version.id), - [version.id, changelogs]) + changelogs?.filter(c => c.version === id || c.group === id), + [id, changelogs]) + + const articleLink = version && getArticleLink(version.id) return <>
-

{version.name}

+

{version?.name ?? id}

- - - - - - + {version ? <> + + + + + + + : filteredChangelogs?.length ?? 0 > 1 ?

+ This version is not released yet. +

:

+ This version does not exist. Only versions since 1.14 are tracked, or it may be too recent. +

}
setTab('changelog')}>{locale('versions.technical_changes')} setTab('discussion')}>{locale('versions.discussion')} + {articleLink && + {locale('versions.article')} + {Octicon.link_external} + }
{tab === 'changelog' && } - {tab === 'discussion' && } + {tab === 'discussion' && }
diff --git a/src/app/pages/Versions.tsx b/src/app/pages/Versions.tsx index 203dd96e..7711efee 100644 --- a/src/app/pages/Versions.tsx +++ b/src/app/pages/Versions.tsx @@ -43,13 +43,7 @@ export function Versions({}: Props) { {Octicon.arrow_right}
- {selected ? - :
-

{selectedId}

-
-

This version does not exist. Only versions since 1.14 are tracked, or it may be too recent.

-
-
} + : `/versions/?id=${id}`} />}
diff --git a/src/app/services/Changelogs.ts b/src/app/services/Changelogs.ts index 3ab0d5ea..67c87a3a 100644 --- a/src/app/services/Changelogs.ts +++ b/src/app/services/Changelogs.ts @@ -3,18 +3,13 @@ import { isObject } from '../Utils' const repo = 'https://raw.githubusercontent.com/misode/technical-changes/main' export type Change = { - group: ChangelogVersion, - version: ChangelogVersion, + group: string, + version: string, order: number, tags: string[], content: string, } -export type ChangelogVersion = { - id: string, - article: string | null, -} - let Changelogs: Change[] | Promise | null = null export async function getChangelogs() { @@ -24,21 +19,21 @@ export async function getChangelogs() { index.map((group, i) => fetchGroup(parseVersion(group), i)) )).flat().map(change => ({ ...change, - tags: [change.group.id, ...change.tags], + tags: [change.group, ...change.tags], })) } return Changelogs } -async function fetchGroup(group: ChangelogVersion, groupIndex: number) { - const index = await (await fetch(`${repo}/${group.id}/index.json`)).json() as string[] +async function fetchGroup(group: string, groupIndex: number) { + const index = await (await fetch(`${repo}/${group}/index.json`)).json() as string[] return (await Promise.all( index.map((version, i) => fetchChangelog(group, parseVersion(version), groupIndex, i)) )).flat() } -async function fetchChangelog(group: ChangelogVersion, version: ChangelogVersion, groupIndex: number, versionIndex: number) { - const text = await (await fetch(`${repo}/${group.id}/${version.id}.md`)).text() +async function fetchChangelog(group: string, version: string, groupIndex: number, versionIndex: number) { + const text = await (await fetch(`${repo}/${group}/${version}.md`)).text() return parseChangelog(text).map(change => ({ version, group, @@ -60,14 +55,32 @@ function parseChangelog(text: string) { }) } -function parseVersion(version: unknown): ChangelogVersion { +function parseVersion(version: unknown): string { if (typeof version === 'string') { - return { - id: version, - article: version.match(/\d\dw\d\d[a-z]/) ? 'minecraft-snapshot-' + version : version.match(/\d+\.\d+(\.\d+)?-pre[0-9]+/) ? 'minecraft-' + version.replaceAll('.', '-').replaceAll('pre', 'pre-release-') : null, - } + return version } else if (isObject(version)) { - return version as ChangelogVersion + return version.id } - return { id: 'unknown', article: null } + return 'unknown' +} + +const ARTICLE_PREFIX = 'https://www.minecraft.net/article/' +const ARTICLE_OVERRIDES = new Map(Object.entries({ + 1.17: 'caves---cliffs--part-i-out-today-java', + 1.18: 'caves---cliffs--part-ii-out-today-java', + '1.18.2': 'minecraft-java-edition-1-18-2', +})) + +export function getArticleLink(version: string): string | undefined { + const override = ARTICLE_OVERRIDES.get(version) + if (override) { + return ARTICLE_PREFIX + override + } + if (version.match(/^\d\dw\d\d[a-z]$/)) { + return ARTICLE_PREFIX + 'minecraft-snapshot-' + version + } + if (version.match(/^\d+\.\d+(\.\d+)?-(pre|rc)[0-9]+$/)) { + return ARTICLE_PREFIX + 'minecraft-' + version.replaceAll('.', '-').replaceAll('pre', 'pre-release-') + } + return undefined } diff --git a/src/locales/en.json b/src/locales/en.json index 2a48e211..91ae5355 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -130,6 +130,7 @@ "terrain_settings": "Terrain settings", "text_component": "Text Component", "undo": "Undo", + "versions.article": "Article", "versions.search": "Search versions", "versions.no_results": "No results", "versions.all": "All versions", diff --git a/src/styles/global.css b/src/styles/global.css index 8019c385..d3d05d9e 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -1446,6 +1446,15 @@ hr { border-bottom: 2px solid transparent; padding: 8px 16px; cursor: pointer; + color: var(--text-3); + fill: var(--text-3); + text-decoration: none; + display: inline-flex; + align-items: center; +} + +.version-tabs > * > svg { + margin-left: 8px; } .version-tabs > .selected { @@ -1496,8 +1505,9 @@ hr { background-color: var(--selection) !important; } -.giscus { +.giscus-container { margin-top: 16px; + min-height: 325.667px; } .guide-card {