Bring in line with new downloads page

Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com>
This commit is contained in:
Joshua Castle committed 2024-02-24 22:57:01 -08:00
1 parent 147a91efdd
commit 54f580a589
7 files changed
+271 -96

No files matched your search

-44
View File
@@ -1,44 +0,0 @@
import { faFileArrowDown } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import React, { useState, useEffect } from 'react';
export const APIDownloadButton = ({ projectId, platformId, header }) => {
const [buildInfo, setBuildInfo] = useState({ buildNumber: '', versionString: '', date: '' });
useEffect(() => {
const fetchBuildInfo = async () => {
try {
const response = await fetch(`https://download.geysermc.org/v2/projects/${projectId}/versions/latest/builds/latest`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
const data = await response.json();
const { build, version } = data;
const response2 = await fetch(`https://download.geysermc.org/v2/projects/${projectId}/versions/${version}/builds/${build}`);
if (!response2.ok) {
throw new Error('Network response was not ok');
}
const data2 = await response2.json();
const { time } = data2;
const formattedDate = new Date(time).toLocaleDateString();
setBuildInfo({ buildNumber: build, versionString: version, date: formattedDate });
} catch (error) {
console.error('Failed to fetch build info:', error);
}
};
fetchBuildInfo();
}, [projectId]);
return (
<a href={`https://download.geysermc.org/v2/projects/${projectId}/versions/latest/builds/latest/downloads/${platformId}`}>
<div className='download-button'>
<FontAwesomeIcon icon={faFileArrowDown}/> <b>{header}</b><br/>
#{buildInfo.buildNumber} · {buildInfo.date}
</div>
</a>
);
};
+25
View File
@@ -0,0 +1,25 @@
import React from 'react';
interface GridProps {
children: React.ReactNode;
elementsPerRow: number;
gap?: string;
}
export const Grid: React.FC<GridProps> = ({ children, elementsPerRow, gap }) => {
const gridStyle = {
display: 'grid',
gridTemplateColumns: `repeat(${elementsPerRow}, 1fr)`,
gap: gap || '0px'
};
return <div className="grid" style={gridStyle}>{children}</div>;
};
interface GridItemProps {
children: React.ReactNode;
}
export const GridItem: React.FC<GridItemProps> = ({ children }) => {
return <div className="grid-item">{children}</div>;
};
+133
View File
@@ -0,0 +1,133 @@
import { faFileArrowDown, faBook } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import React, { useState, useEffect } from 'react';
import { Downloads } from '../types/downloads';
import { Column, Columns } from './Columns';
import { Grid } from './Grid';
interface ProjectDownloadProps {
projectId: string;
description: string;
setup?: string;
downloadsInfo: {
[key: string]: string;
};
gridColumns?: number;
}
export const ProjectDownload: React.FC<ProjectDownloadProps> = ({ projectId, description, setup, downloadsInfo, gridColumns }) => {
const [platformInfo, setPlatformInfo] = useState<Downloads.Builds>({
project_id: '',
project_name: '',
version: '',
builds: []
});
const [latestBuild, setLatestBuild] = useState<Downloads.Build>({
project_id: '',
project_name: '',
version: '',
build: 0,
time: new Date().toLocaleDateString(),
channel: '',
promoted: false,
changes: [],
downloads: {}
});
const [changes, setChanges] = useState<Downloads.BaseBuild['changes']>([]);
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
const fetchPlatformInfo = async () => {
try {
const response = await fetch(new URL(`/v2/projects/${projectId}/versions/latest/builds`, 'https://download.geysermc.org'));
if (!response.ok) {
throw new Error('Network response was not ok');
}
const data: Downloads.Builds = await response.json();
setPlatformInfo(data);
setLatestBuild(data.builds[data.builds.length - 1]);
const allChanges: Downloads.BaseBuild['changes'] = [];
data.builds.forEach(build => {
allChanges.push(...build.changes);
});
setChanges(allChanges.reverse().slice(0, 12));
setIsLoaded(true);
} catch (error) {
console.error('Failed to fetch platform info:', error);
}
};
fetchPlatformInfo();
}, [projectId]);
const fadeInStyle = {
opacity: isLoaded ? 1 : 0,
transition: 'opacity 1s ease-in-out',
};
return (
<div style={fadeInStyle}>
<p>{description}</p>
<Columns>
<Column>
<h2>Build #{latestBuild.build} · {new Date(latestBuild.time).toLocaleDateString()}:</h2>
<Grid elementsPerRow={gridColumns || 2} gap="8px">
{ setup &&
<a href={setup} className='no-underline'>
<div className='setup-button'>
<b>Setup Instructions</b><br/>
<FontAwesomeIcon icon={faBook}/>
</div>
</a>
}
{
Object.keys(latestBuild.downloads).map((platformId, i) => {
return (
<a href={`https://download.geysermc.org/v2/projects/${projectId}/versions/latest/builds/latest/downloads/${platformId}`} key={i} className='no-underline'>
<div className='download-button'>
<b>{downloadsInfo[platformId]}</b><br/>
<FontAwesomeIcon icon={faFileArrowDown}/> {latestBuild.downloads[platformId].name}
</div>
</a>
)
})
}
</Grid>
</Column>
<Column>
<h2>Recent Changes:</h2>
<ul>
{
changes.map((change, i) => {
return (
<li key={i}><b>{
<a href={`https://github.com/GeyserMC/${platformInfo.project_name}/commit/${change.commit}`}>{change.commit.substring(0, 7)}</a>
}</b> · {<LinkedCommitMessage message={change.summary} repo={platformInfo.project_name}/>}</li>
)
})
}
</ul>
</Column>
</Columns>
</div>
);
};
function LinkedCommitMessage({ message, repo }) {
const regex = /#(\d+)/g;
const parts = message.split(/(#\d+)/).filter((part: string) => part);
const linked = parts.map((part, index) => {
if (part.match(regex)) {
const number = part.replace('#', '');
return <a key={index} href={`https://github.com/GeyserMC/${repo}/pull/${number}`}>{part}</a>;
}
return part;
});
return <>{linked}</>;
}
+25 -1
View File
@@ -7,6 +7,7 @@
/* You can override the default Infima variables here. */
:root {
--ifm-color-primary: #2e8555;
--ifm-color-secondary: #0097c5;
--ifm-color-primary-dark: #29784c;
--ifm-color-primary-darker: #277148;
--ifm-color-primary-darkest: #205d3b;
@@ -21,6 +22,7 @@
/* For readability concerns, you should choose a lighter palette in dark mode. */
[data-theme='dark'] {
--ifm-color-primary: #25c2a0;
--ifm-color-secondary: #00d5ff;
--ifm-color-primary-dark: #21af90;
--ifm-color-primary-darker: #1fa588;
--ifm-color-primary-darkest: #1a8870;
@@ -112,7 +114,6 @@
transition: background-color 0.5s ease, color 0.5s ease;
padding-top: 10px;
padding-bottom: 10px;
margin-bottom: 10px;
}
.download-button:hover {
@@ -182,6 +183,29 @@
font-size: 18px;
}
.no-underline {
text-decoration: transparent !important;
}
.setup-button {
width: 100%;
outline: 3px solid var(--ifm-color-secondary);
outline-offset: -3px;
border: 0;
border-radius: var(--ifm-global-radius);
text-align: center;
font-size: 18px;
transition: background-color 0.5s ease, color 0.5s ease;
padding-top: 10px;
padding-bottom: 10px;
color: var(--ifm-color-secondary);
}
.setup-button:hover {
background-color: var(--ifm-color-secondary);
color: #fff;
}
.tabs {
flex-wrap: wrap;
border-bottom-color: var(--ifm-horizontal-line-color);
+58 -51
View File
@@ -8,6 +8,9 @@ import Admonition from '@theme/Admonition';
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
import { faTowerCell, faFileZipper } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import HeroBanner from '@site/src/components/HeroBanner';
import HeroBackground from '@site/static/img/site/split-background.png';
@@ -22,69 +25,73 @@ import PaperSpigotIcon from '@site/static/img/icons/paper.png';
import VelocityIcon from '@site/static/img/icons/velocity.png';
import WaterfallBungeeCordIcon from '@site/static/img/icons/waterfall.svg';
import FabricIcon from '@site/static/img/icons/fabric.png';
import NeoForgeIcon from '@site/static/img/icons/neoforge.png';
import ViaProxyIcon from '@site/static/img/icons/viaproxy.png';
import StandaloneIcon from '@site/static/img/icons/geyser.png';
import { Columns, Column } from '@site/src/components/Columns';
import { ProviderSelector } from '@site/src/components/Provider';
import { APIDownloadButton } from '@site/src/components/DownloadButton';
import { ProjectDownload } from '@site/src/components/ProjectDownload';
<HeroBanner
title="Download"
subheading="Choose which platform to download Geyser or Floodgate for."
subheading="Download the latest versions of our various projects."
backgroundImage={HeroBackground}
/>
<Tabs>
<TabItem value="paper-spigot" label={<PlatformIcon img={PaperSpigotIcon} text="Paper / Spigot"/>} default>
<Columns>
<Column>
<APIDownloadButton projectId="geyser" platformId="spigot" header="Download Geyser" />
## Geyser Installation Instructions
Geyser allows Bedrock players to join your server, but also requires Floodgate if you wish to allow them to join with their Bedrock account.
<Tabs>
<TabItem value="simple" label="Simple">
1. Download Geyser using the download button.
2. Place Geyser in the plugins folder.
3. Start up your server and Geyser should be installed.
<Admonition type="note">
Keep in mind that there may be additional steps involved, such as portforwarding. Please see the detailed setup options for more information.
</Admonition>
</TabItem>
<TabItem value="provider" label="Host Provider">
<ProviderSelector/>
<PaperSpigot/>
</TabItem>
<TabItem value="self" label= "Self Host">
<PaperSpigotSelf/>
</TabItem>
</Tabs>
</Column>
<Column>
<APIDownloadButton projectId="floodgate" platformId="spigot" header="Download Floodgate" />
## Floodgate Installation Instructions
By using our Floodgate plugin, you can allow Xbox Live authenticated Bedrock clients to securely join your online-mode server without a Java Edition account.
<FloodgatePaperSpigot/>
<Admonition type="note">
Floodgate uses global linking by default, which allows Bedrock players to link and join as their Java ccount by connecting it to our global linking server. You can disable this or enable local linking in the Floodgate config. More info is available on the [wiki](/floodgate/linking).
</Admonition>
</Column>
</Columns>
<TabItem value="geyser" label="Geyser" default>
<ProjectDownload
projectId="geyser"
description="A bridge/proxy allowing you to connect to Minecraft: Java Edition servers with Minecraft: Bedrock Edition."
setup="/geyser/setup"
downloadsInfo={{
bungeecord: <PlatformIcon svg={WaterfallBungeeCordIcon} text="BungeeCord"/>,
fabric: <PlatformIcon img={FabricIcon} text="Fabric"/>,
neoforge: <PlatformIcon img={NeoForgeIcon} text="NeoForge"/>,
spigot: <PlatformIcon img={PaperSpigotIcon} text="Spigot/Paper"/>,
standalone: <PlatformIcon img={StandaloneIcon} text="Standalone"/>,
velocity: <PlatformIcon img={VelocityIcon} text="Velocity"/>,
viaproxy: <PlatformIcon img={ViaProxyIcon} text="ViaProxy"/>,
}}
/>
</TabItem>
<TabItem value="velocity" label={<PlatformIcon img={VelocityIcon} text="Velocity"/>}>
Velocity
<TabItem value="floodgate" label="Floodgate">
<ProjectDownload
projectId="floodgate"
description="Hybrid mode plugin to allow for connections from Geyser to join online mode servers."
setup="/floodgate/setup"
downloadsInfo={{
bungee: <PlatformIcon svg={WaterfallBungeeCordIcon} text="BungeeCord"/>,
spigot: <PlatformIcon img={PaperSpigotIcon} text="Spigot/Paper"/>,
velocity: <PlatformIcon img={VelocityIcon} text="Velocity"/>,
}}
/>
</TabItem>
<TabItem value="waterfall-bungeecord" label={<PlatformIcon svg={WaterfallBungeeCordIcon} text="Waterfall / BungeeCord"/>}>
Waterfall Bungee
</TabItem>
<TabItem value="fabric" label={<PlatformIcon img={FabricIcon} text="Fabric"/>}>
Fabric
</TabItem>
<TabItem value="standalone" label={<PlatformIcon img={StandaloneIcon} text="Standalone"/>}>
Standalone
<TabItem value="other-projects" label="Other Projects">
<Tabs>
<TabItem value='geyserconnect' label='GeyserConnect'>
<ProjectDownload
projectId="geyserconnect"
description="An easy way for Bedrock Edition clients to connect to any Java Edition servers without having to run anything."
setup='/other/geyserconnect'
downloadsInfo={{
geyserconnect: <><FontAwesomeIcon icon={faTowerCell}/> GeyserConnect</>,
}}
gridColumns={1}
/>
</TabItem>
<TabItem value='geyseroptionalpack' label='GeyserOptionalPack'>
<ProjectDownload
projectId="geyseroptionalpack"
description="Optional Bedrock resource pack to extend Geyser functionality."
setup='/other/geyseroptionalpack'
downloadsInfo={{
geyseroptionalpack: <><FontAwesomeIcon icon={faFileZipper}/> GeyserOptionalPack</>,
}}
gridColumns={1}
/>
</TabItem>
</Tabs>
</TabItem>
</Tabs>
+30
View File
@@ -0,0 +1,30 @@
export namespace Downloads {
export interface Builds {
project_id: string;
project_name: string;
version: string;
builds: Build[];
}
export interface BaseBuild {
build: number;
time: string;
channel: string;
promoted: boolean;
changes: {
commit: string;
summary: string;
message: string;
}[];
downloads: {
[key: string]: {
name: string;
sha256: string;
};
};
}
export interface Build extends BaseBuild {
project_id: string;
project_name: string;
version: string;
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB