mirror of
https://github.com/misode/misode.github.io.git
synced 2026-04-23 07:10:41 +00:00
Improve version and article linking
This commit is contained in:
@@ -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 <GiscusReact
|
||||
repo="misode/misode.github.io"
|
||||
repoId="MDEwOlJlcG9zaXRvcnkxOTIyNTQyMzA="
|
||||
category="Site"
|
||||
categoryId="DIC_kwDOC3WRFs4COB8r"
|
||||
mapping={term ? 'specific' : 'pathname'}
|
||||
term={term}
|
||||
reactionsEnabled="1"
|
||||
emitMetadata="0"
|
||||
inputPosition="top"
|
||||
theme={themeUrl}
|
||||
lang="en" />
|
||||
return <div class="giscus-container">
|
||||
<GiscusReact
|
||||
repo="misode/misode.github.io"
|
||||
repoId="MDEwOlJlcG9zaXRvcnkxOTIyNTQyMzA="
|
||||
category="Site"
|
||||
categoryId="DIC_kwDOC3WRFs4COB8r"
|
||||
mapping={term ? 'specific' : 'pathname'}
|
||||
term={term}
|
||||
reactionsEnabled="1"
|
||||
emitMetadata="0"
|
||||
inputPosition="top"
|
||||
theme={themeUrl}
|
||||
lang="en" />
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -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 <div class="changelog-entry">
|
||||
<div class="changelog-version">
|
||||
<ArticleLink {...change.version}/>
|
||||
<ArticleLink {...change.group}/>
|
||||
<a href={`/versions/?id=${change.version}`}>{change.version}</a>
|
||||
<a href={`/versions/?id=${change.group}`}>{change.group}</a>
|
||||
</div>
|
||||
<div class="changelog-tags">
|
||||
{change.tags.map(tag => <ChangelogTag label={tag} onClick={toggleTag ? () => toggleTag(tag) : undefined} active={activeTags?.includes(tag)} />)}
|
||||
@@ -19,9 +19,3 @@ export function ChangelogEntry({ change, activeTags, toggleTag }: Props) {
|
||||
<div class="changelog-content" dangerouslySetInnerHTML={{ __html: marked(change.content) }} />
|
||||
</div>
|
||||
}
|
||||
|
||||
function ArticleLink({ id, article }: ChangelogVersion) {
|
||||
return article === null
|
||||
? <span>{id}</span>
|
||||
: <a href={`https://www.minecraft.net/en-us/article/${article}`} target="_blank">{id}</a>
|
||||
}
|
||||
|
||||
@@ -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<Tab>('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 <>
|
||||
<div class="version-detail">
|
||||
<h2>{version.name}</h2>
|
||||
<h2>{version?.name ?? id}</h2>
|
||||
<div class="version-info">
|
||||
<VersionMetaData label={locale('versions.released')} value={releaseDate(version)} />
|
||||
<VersionMetaData label={locale('versions.release_target')} value={version.release_target} link={version.id !== version.release_target ? `/versions/?id=${version.release_target}` : undefined} />
|
||||
<VersionMetaData label={locale('versions.data_version')} value={version.data_version} />
|
||||
<VersionMetaData label={locale('versions.protocol_version')} value={version.protocol_version} />
|
||||
<VersionMetaData label={locale('versions.data_pack_format')} value={version.data_pack_version} />
|
||||
<VersionMetaData label={locale('versions.resource_pack_format')} value={version.resource_pack_version} />
|
||||
{version ? <>
|
||||
<VersionMetaData label={locale('versions.released')} value={releaseDate(version)} />
|
||||
<VersionMetaData label={locale('versions.release_target')} value={version.release_target} link={version.id !== version.release_target ? `/versions/?id=${version.release_target}` : undefined} />
|
||||
<VersionMetaData label={locale('versions.data_version')} value={version.data_version} />
|
||||
<VersionMetaData label={locale('versions.protocol_version')} value={version.protocol_version} />
|
||||
<VersionMetaData label={locale('versions.data_pack_format')} value={version.data_pack_version} />
|
||||
<VersionMetaData label={locale('versions.resource_pack_format')} value={version.resource_pack_version} />
|
||||
</> : filteredChangelogs?.length ?? 0 > 1 ? <p>
|
||||
This version is not released yet.
|
||||
</p> : <p>
|
||||
This version does not exist. Only versions since 1.14 are tracked, or it may be too recent.
|
||||
</p>}
|
||||
</div>
|
||||
<div class="version-tabs">
|
||||
<span class={tab === 'changelog' ? 'selected' : ''} onClick={() => setTab('changelog')}>{locale('versions.technical_changes')}</span>
|
||||
<span class={tab === 'discussion' ? 'selected' : ''} onClick={() => setTab('discussion')}>{locale('versions.discussion')}</span>
|
||||
{articleLink && <a href={articleLink} target="_blank">
|
||||
{locale('versions.article')}
|
||||
{Octicon.link_external}
|
||||
</a>}
|
||||
</div>
|
||||
<div class="version-tab">
|
||||
{tab === 'changelog' && <ChangelogList changes={filteredChangelogs} defaultOrder="asc" />}
|
||||
{tab === 'discussion' && <Giscus term={`version/${version.id}`} />}
|
||||
{tab === 'discussion' && <Giscus term={`version/${id}/`} />}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -43,13 +43,7 @@ export function Versions({}: Props) {
|
||||
{Octicon.arrow_right}
|
||||
</a>
|
||||
</div>
|
||||
{selected ? <VersionDetail version={selected} />
|
||||
: <div class="version-detail">
|
||||
<h2>{selectedId}</h2>
|
||||
<div class="version-info">
|
||||
<p>This version does not exist. Only versions since 1.14 are tracked, or it may be too recent.</p>
|
||||
</div>
|
||||
</div>}
|
||||
<VersionDetail id={selectedId} version={selected} />
|
||||
</> : <VersionList versions={versions ?? []} link={id => `/versions/?id=${id}`} />}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@@ -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<Change[]> | 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 => ({
|
||||
...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
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user