mirror of
https://github.com/misode/misode.github.io.git
synced 2026-04-26 00:16:51 +00:00
Add what's new page
This commit is contained in:
@@ -5,7 +5,7 @@ import '../styles/nodes.css'
|
||||
import { Analytics } from './Analytics.js'
|
||||
import { cleanUrl } from './Utils.js'
|
||||
import { Header } from './components/index.js'
|
||||
import { Changelog, Customized, Generator, Generators, Guide, Guides, Home, Partners, Sounds, Transformation, Versions, Worldgen } from './pages/index.js'
|
||||
import { Changelog, Customized, Generator, Generators, Guide, Guides, Home, Partners, Sounds, Transformation, Versions, WhatsNew, Worldgen } from './pages/index.js'
|
||||
|
||||
export function App() {
|
||||
const changeRoute = (e: RouterOnChangeArgs) => {
|
||||
@@ -26,6 +26,7 @@ export function App() {
|
||||
<Versions path="/versions" />
|
||||
<Transformation path="/transformation" />
|
||||
<Customized path="/customized" />
|
||||
<WhatsNew path="/whats-new" />
|
||||
<Guides path="/guides" />
|
||||
<Guide path="/guides/:id" />
|
||||
<Generator default />
|
||||
|
||||
@@ -36,6 +36,7 @@ export const Octicon = {
|
||||
link_external: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M10.604 1h4.146a.25.25 0 01.25.25v4.146a.25.25 0 01-.427.177L13.03 4.03 9.28 7.78a.75.75 0 01-1.06-1.06l3.75-3.75-1.543-1.543A.25.25 0 0110.604 1zM3.75 2A1.75 1.75 0 002 3.75v8.5c0 .966.784 1.75 1.75 1.75h8.5A1.75 1.75 0 0014 12.25v-3.5a.75.75 0 00-1.5 0v3.5a.25.25 0 01-.25.25h-8.5a.25.25 0 01-.25-.25v-8.5a.25.25 0 01.25-.25h3.5a.75.75 0 000-1.5h-3.5z"></path></svg>,
|
||||
lock: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M4 4a4 4 0 0 1 8 0v2h.25c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 12.25 15h-8.5A1.75 1.75 0 0 1 2 13.25v-5.5C2 6.784 2.784 6 3.75 6H4Zm8.25 3.5h-8.5a.25.25 0 0 0-.25.25v5.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25ZM10.5 6V4a2.5 2.5 0 1 0-5 0v2Z"></path></svg>,
|
||||
mark_github: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path></svg>,
|
||||
megaphone: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M3.25 9a.75.75 0 0 1 .75.75c0 2.142.456 3.828.733 4.653a.122.122 0 0 0 .05.064.212.212 0 0 0 .117.033h1.31c.085 0 .18-.042.258-.152a.45.45 0 0 0 .075-.366A16.743 16.743 0 0 1 6 9.75a.75.75 0 0 1 1.5 0c0 1.588.25 2.926.494 3.85.293 1.113-.504 2.4-1.783 2.4H4.9c-.686 0-1.35-.41-1.589-1.12A16.4 16.4 0 0 1 2.5 9.75.75.75 0 0 1 3.25 9Z"></path><path d="M0 6a4 4 0 0 1 4-4h2.75a.75.75 0 0 1 .75.75v6.5a.75.75 0 0 1-.75.75H4a4 4 0 0 1-4-4Zm4-2.5a2.5 2.5 0 1 0 0 5h2v-5Z"></path><path d="M15.59.082A.75.75 0 0 1 16 .75v10.5a.75.75 0 0 1-1.189.608l-.002-.001h.001l-.014-.01a5.775 5.775 0 0 0-.422-.25 10.63 10.63 0 0 0-1.469-.64C11.576 10.484 9.536 10 6.75 10a.75.75 0 0 1 0-1.5c2.964 0 5.174.516 6.658 1.043.423.151.787.302 1.092.443V2.014c-.305.14-.669.292-1.092.443C11.924 2.984 9.713 3.5 6.75 3.5a.75.75 0 0 1 0-1.5c2.786 0 4.826-.484 6.155-.957.665-.236 1.154-.47 1.47-.64.144-.077.284-.161.421-.25l.014-.01a.75.75 0 0 1 .78-.061Z"></path></svg>,
|
||||
moon: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M9.598 1.591a.75.75 0 01.785-.175 7 7 0 11-8.967 8.967.75.75 0 01.961-.96 5.5 5.5 0 007.046-7.046.75.75 0 01.175-.786zm1.616 1.945a7 7 0 01-7.678 7.678 5.5 5.5 0 107.678-7.678z"></path></svg>,
|
||||
mortar_board: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M7.693 1.066a.747.747 0 0 1 .614 0l7.25 3.25a.75.75 0 0 1 0 1.368L13 6.831v2.794c0 1.024-.81 1.749-1.66 2.173-.893.447-2.075.702-3.34.702-.278 0-.55-.012-.816-.036a.75.75 0 0 1 .133-1.494c.22.02.45.03.683.03 1.082 0 2.025-.221 2.67-.543.69-.345.83-.682.83-.832V7.503L8.307 8.934a.747.747 0 0 1-.614 0L4 7.28v1.663c.296.105.575.275.812.512.438.438.688 1.059.688 1.796v3a.75.75 0 0 1-.75.75h-3a.75.75 0 0 1-.75-.75v-3c0-.737.25-1.358.688-1.796.237-.237.516-.407.812-.512V6.606L.443 5.684a.75.75 0 0 1 0-1.368ZM2.583 5 8 7.428 13.416 5 8 2.572ZM2.5 11.25v2.25H4v-2.25c0-.388-.125-.611-.25-.735a.697.697 0 0 0-.5-.203.707.707 0 0 0-.5.203c-.125.124-.25.347-.25.735Z"></path></svg>,
|
||||
package: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8.878.392a1.75 1.75 0 00-1.756 0l-5.25 3.045A1.75 1.75 0 001 4.951v6.098c0 .624.332 1.2.872 1.514l5.25 3.045a1.75 1.75 0 001.756 0l5.25-3.045c.54-.313.872-.89.872-1.514V4.951c0-.624-.332-1.2-.872-1.514L8.878.392zM7.875 1.69a.25.25 0 01.25 0l4.63 2.685L8 7.133 3.245 4.375l4.63-2.685zM2.5 5.677v5.372c0 .09.047.171.125.216l4.625 2.683V8.432L2.5 5.677zm6.25 8.271l4.625-2.683a.25.25 0 00.125-.216V5.677L8.75 8.432v5.516z"></path></svg>,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { useMemo } from 'preact/hooks'
|
||||
import contributors from '../../contributors.json'
|
||||
import { ChangelogEntry, Footer, GeneratorCard, Giscus, GuideCard, ToolCard, ToolGroup } from '../components/index.js'
|
||||
import { Store } from '../Store.js'
|
||||
import { shuffle } from '../Utils.js'
|
||||
import { Card, ChangelogEntry, Footer, GeneratorCard, Giscus, GuideCard, ToolCard, ToolGroup } from '../components/index.js'
|
||||
import { useLocale, useTitle } from '../contexts/index.js'
|
||||
import { useAsync } from '../hooks/useAsync.js'
|
||||
import { useMediaQuery } from '../hooks/useMediaQuery.js'
|
||||
import { fetchChangelogs, fetchVersions } from '../services/DataFetcher.js'
|
||||
import { Store } from '../Store.js'
|
||||
import { shuffle } from '../Utils.js'
|
||||
import { fetchChangelogs, fetchVersions, fetchWhatsNew } from '../services/DataFetcher.js'
|
||||
|
||||
const MIN_FAVORITES = 2
|
||||
const MAX_FAVORITES = 5
|
||||
@@ -30,6 +30,7 @@ export function Home({}: Props) {
|
||||
{smallScreen && <Guides />}
|
||||
<Versions />
|
||||
{smallScreen && <Tools />}
|
||||
<WhatsNew />
|
||||
</div>
|
||||
{!smallScreen && <div class="card-column">
|
||||
<FavoriteGenerators />
|
||||
@@ -135,7 +136,15 @@ function Changelog() {
|
||||
</ToolGroup>
|
||||
}
|
||||
|
||||
function WhatsNew() {
|
||||
const { locale } = useLocale()
|
||||
|
||||
const { value: items } = useAsync(fetchWhatsNew)
|
||||
|
||||
return <ToolGroup title={locale('whats_new')} link="/whats-new/" titleIcon="megaphone">
|
||||
{items?.slice(0, 3).map(item => <Card overlay={Intl.DateTimeFormat(undefined, { day: 'numeric',month: 'long', year: 'numeric' }).format(new Date(item.createdAt))}>{item.title}</Card>)}
|
||||
</ToolGroup>
|
||||
}
|
||||
|
||||
function Contributors() {
|
||||
const supporters = useMemo(() => {
|
||||
|
||||
38
src/app/pages/WhatsNew.tsx
Normal file
38
src/app/pages/WhatsNew.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import { marked } from 'marked'
|
||||
import { ErrorPanel, Footer } from '../components/index.js'
|
||||
import { useLocale, useTitle } from '../contexts/index.js'
|
||||
import { useAsync } from '../hooks/useAsync.js'
|
||||
import type { WhatsNewItem } from '../services/DataFetcher.js'
|
||||
import { fetchWhatsNew } from '../services/DataFetcher.js'
|
||||
|
||||
interface Props {
|
||||
path?: string,
|
||||
}
|
||||
export function WhatsNew({}: Props) {
|
||||
const { locale } = useLocale()
|
||||
useTitle(locale('title.whats_new'))
|
||||
|
||||
const { value: items, error } = useAsync(fetchWhatsNew)
|
||||
|
||||
return <main>
|
||||
<div class="container whats-new">
|
||||
<p>{locale('whats_new.description')}</p>
|
||||
{error && <ErrorPanel error={error} />}
|
||||
{items?.map(item => <WhatsNewEntry item={item} />)}
|
||||
</div>
|
||||
<Footer />
|
||||
</main>
|
||||
}
|
||||
|
||||
interface EntryProps {
|
||||
item: WhatsNewItem,
|
||||
}
|
||||
function WhatsNewEntry({ item }: EntryProps) {
|
||||
return <article class="whats-new-entry">
|
||||
<a href={item.url} target="_blank">
|
||||
<time dateTime={item.createdAt} title={Intl.DateTimeFormat(undefined, { dateStyle: 'full', timeStyle: 'long' }).format(new Date(item.createdAt))}>{Intl.DateTimeFormat(undefined, { day: 'numeric',month: 'long', year: 'numeric' }).format(new Date(item.createdAt))}</time>
|
||||
<h2>{item.title}</h2>
|
||||
</a>
|
||||
<div class="guide-content" dangerouslySetInnerHTML={{ __html: marked(item.body) }} />
|
||||
</article>
|
||||
}
|
||||
@@ -9,4 +9,5 @@ export * from './Partners.js'
|
||||
export * from './Sounds.js'
|
||||
export * from './Transformation.jsx'
|
||||
export * from './Versions.js'
|
||||
export * from './WhatsNew.jsx'
|
||||
export * from './Worldgen.jsx'
|
||||
|
||||
@@ -19,6 +19,7 @@ const mcmetaUrl = 'https://raw.githubusercontent.com/misode/mcmeta'
|
||||
const mcmetaTarballUrl = 'https://github.com/misode/mcmeta/tarball'
|
||||
const changesUrl = 'https://raw.githubusercontent.com/misode/technical-changes'
|
||||
const fixesUrl = 'https://raw.githubusercontent.com/misode/mcfixes'
|
||||
const whatsNewUrl = 'https://whats-new.misode.workers.dev/'
|
||||
|
||||
type McmetaTypes = 'summary' | 'data' | 'data-json' | 'assets' | 'assets-json' | 'registries' | 'atlas'
|
||||
|
||||
@@ -280,6 +281,23 @@ export async function fetchBugfixes(version: VersionId): Promise<Bugfix[]> {
|
||||
}
|
||||
}
|
||||
|
||||
export interface WhatsNewItem {
|
||||
id: string,
|
||||
title: string,
|
||||
body: string,
|
||||
url: string,
|
||||
createdAt: string,
|
||||
}
|
||||
|
||||
export async function fetchWhatsNew(): Promise<WhatsNewItem[]> {
|
||||
try {
|
||||
const whatsNew = await cachedFetch<WhatsNewItem[]>(whatsNewUrl, { refresh: true })
|
||||
return whatsNew
|
||||
} catch (e) {
|
||||
throw new Error(`Error occured while fetching what's new: ${message(e)}`)
|
||||
}
|
||||
}
|
||||
|
||||
interface FetchOptions<D> {
|
||||
decode?: (r: Response) => Promise<D>
|
||||
refresh?: boolean
|
||||
|
||||
@@ -144,6 +144,7 @@
|
||||
"title.sounds": "Sound Explorer",
|
||||
"title.transformation": "Transformation Visualizer",
|
||||
"title.versions": "Versions Explorer",
|
||||
"title.whats_new": "What's new?",
|
||||
"title.worldgen": "Worldgen Generators and Guides",
|
||||
"tools": "Tools",
|
||||
"transformation.matrix": "Matrix",
|
||||
@@ -252,6 +253,8 @@
|
||||
"versions.latest_snapshot": "Latest snapshot",
|
||||
"versions.latest_release": "Latest release",
|
||||
"weight": "Weight",
|
||||
"whats_new": "What's new?",
|
||||
"whats_new.description": "Stay informed about all the latest development on misode.github.io. Read below to find out which features have recently been added.",
|
||||
"world": "World Settings",
|
||||
"worldgen": "Worldgen",
|
||||
"worldgen/biome": "Biome",
|
||||
|
||||
@@ -2369,6 +2369,69 @@ hr {
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.whats-new > p {
|
||||
color: var(--text-2);
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
||||
.whats-new-entry {
|
||||
padding-bottom: 50px;
|
||||
position: relative;
|
||||
padding-left: 46px;
|
||||
}
|
||||
|
||||
.whats-new-entry:last-child {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.whats-new-entry::before {
|
||||
content: '';
|
||||
background-color: var(--background-6);
|
||||
position: absolute;
|
||||
top: 17px;
|
||||
bottom: -2px;
|
||||
left: 20px;
|
||||
width: 2px;
|
||||
}
|
||||
|
||||
.whats-new-entry::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 13px;
|
||||
background-color: var(--background-1);
|
||||
border: 3px solid var(--text-1);
|
||||
border-radius: 10px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.whats-new-entry > a {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.whats-new-entry time {
|
||||
color: var(--text-3);
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.whats-new-entry h2 {
|
||||
color: var(--text-1);
|
||||
padding: 10px 0 15px;
|
||||
}
|
||||
|
||||
.whats-new-entry .guide-content {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.whats-new-entry .guide-content img {
|
||||
max-width: min(calc(100vw - 78px), 600px);
|
||||
background: linear-gradient(150deg, var(--background-6) 0%, var(--background-5) 100%);
|
||||
padding: 20px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ace_editor,
|
||||
.ace_gutter,
|
||||
.ace_gutter .ace_layer,
|
||||
|
||||
Reference in New Issue
Block a user