mirror of
https://github.com/Grasscutters/Meadow.git
synced 2024-11-23 12:29:41 +00:00
Downloads
This commit is contained in:
parent
25cddb3036
commit
7c72de36bf
BIN
public/java.png
Normal file
BIN
public/java.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
public/windows.png
Normal file
BIN
public/windows.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 818 B |
162
src/css/pages/Downloads.css
Normal file
162
src/css/pages/Downloads.css
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
.Downloads {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Downloads_Container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin-top: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Downloads_Container h3 {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #c5c5c5;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Downloads_Cards {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 40px;
|
||||||
|
margin: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.DownloadCard {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #000000;
|
||||||
|
padding: 20px;
|
||||||
|
width: 300px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.75);
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.DownloadCard:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
.DownloadCard_Version {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #7a7a7a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.DownloadCard_Icon {
|
||||||
|
height: 64px;
|
||||||
|
width: 64px;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.DownloadCard_Info {
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.DownloadCard_Info h4 {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.DownloadCard_Info p {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 400;
|
||||||
|
margin: 5px;
|
||||||
|
color: #7a7a7a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.DownloadCard_Download {
|
||||||
|
color: #1969c9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Downloads_More {
|
||||||
|
color: #ffffff;
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 500px;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 40px;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Downloads_More h4 {
|
||||||
|
font-size: 35px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Downloads_More_Grasscutter {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
gap: 20px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.75);
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
text-align: center;
|
||||||
|
padding: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Downloads_More_Grasscutter h5 {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 0;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Downloads_More_Cultivation {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
gap: 20px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.75);
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
text-align: center;
|
||||||
|
padding: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Downloads_More_Cultivation h5 {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 0;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
.Downloads_More_Grasscutter {
|
||||||
|
flex-direction: column;
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Downloads_More_Cultivation {
|
||||||
|
flex-direction: column;
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ import { Routes, Route } from "react-router-dom";
|
|||||||
import Header from "@components/Header";
|
import Header from "@components/Header";
|
||||||
|
|
||||||
import Home from "@pages/Home";
|
import Home from "@pages/Home";
|
||||||
|
import Downloads from "@pages/Downloads";
|
||||||
|
|
||||||
import "@css/App.css";
|
import "@css/App.css";
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ class App extends React.Component {
|
|||||||
<Header />
|
<Header />
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path={"/"} element={<Home />} />
|
<Route path={"/"} element={<Home />} />
|
||||||
<Route path={"/downloads"} element={<p>Downloads</p>} />
|
<Route path={"/downloads"} element={<Downloads />} />
|
||||||
<Route path={"/wiki"} element={<p>Wiki</p>} />
|
<Route path={"/wiki"} element={<p>Wiki</p>} />
|
||||||
<Route path={"/features"} element={<p>Features</p>} />
|
<Route path={"/features"} element={<p>Features</p>} />
|
||||||
<Route path={"/config"} element={<p>Config Generator</p>} />
|
<Route path={"/config"} element={<p>Config Generator</p>} />
|
||||||
|
33
src/ui/components/downloads/DownloadCard.tsx
Normal file
33
src/ui/components/downloads/DownloadCard.tsx
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
downloadLink: string;
|
||||||
|
downloadVersion: string;
|
||||||
|
icon: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DownloadCard extends React.Component<IProps, never> {
|
||||||
|
constructor(props: IProps) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className={"DownloadCard"} onClick={() => window.open(this.props.downloadLink)}>
|
||||||
|
<p className={"DownloadCard_Version"}>{this.props.downloadVersion}</p>
|
||||||
|
<img className={"DownloadCard_Icon"} src={this.props.icon} alt={"Icon"} />
|
||||||
|
<div className={"DownloadCard_Info"}>
|
||||||
|
<h4>{this.props.title}</h4>
|
||||||
|
<p>{this.props.description}</p>
|
||||||
|
</div>
|
||||||
|
<div className={"DownloadCard_Download"}>
|
||||||
|
<p>Download</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DownloadCard;
|
109
src/ui/pages/Downloads.tsx
Normal file
109
src/ui/pages/Downloads.tsx
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import StyledHeading from "@components/common/StyledHeading";
|
||||||
|
import DownloadCard from "@components/downloads/DownloadCard";
|
||||||
|
import BasicButton from "@components/common/BasicButton";
|
||||||
|
|
||||||
|
import { getLatestReleaseAsync } from "@app/utils";
|
||||||
|
|
||||||
|
import "@css/pages/Downloads.css";
|
||||||
|
|
||||||
|
interface IState {
|
||||||
|
grasscutterVersion: string;
|
||||||
|
grasscutterDownloadLink: string;
|
||||||
|
cultivationVersion: string;
|
||||||
|
cultivationDownloadLink: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Downloads extends React.Component<{}, IState> {
|
||||||
|
constructor(props: {}) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
grasscutterVersion: "",
|
||||||
|
grasscutterDownloadLink: "",
|
||||||
|
cultivationVersion: "",
|
||||||
|
cultivationDownloadLink: ""
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
setDownloads = async () => {
|
||||||
|
const data = await getLatestReleaseAsync();
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
grasscutterVersion: data.grasscutter.version,
|
||||||
|
grasscutterDownloadLink: data.grasscutter.url,
|
||||||
|
cultivationVersion: data.cultivation.version,
|
||||||
|
cultivationDownloadLink: data.cultivation.url
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async componentDidMount() {
|
||||||
|
await this.setDownloads();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className={"Downloads"}>
|
||||||
|
<div className={"Downloads_Container"}>
|
||||||
|
<StyledHeading text={"Latest Downloads"} />
|
||||||
|
<h3>We recommend using Cultivation to launch your server<br /> if you do not know what a JAR file is.</h3>
|
||||||
|
|
||||||
|
<div className={"Downloads_Cards"}>
|
||||||
|
<DownloadCard
|
||||||
|
title={"Grasscutter"}
|
||||||
|
description={"Server JAR File"}
|
||||||
|
icon={"java.png"}
|
||||||
|
downloadLink={this.state.grasscutterDownloadLink}
|
||||||
|
downloadVersion={this.state.grasscutterVersion}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<DownloadCard
|
||||||
|
title={"Cultivation"}
|
||||||
|
description={"For Windows"}
|
||||||
|
icon={"windows.png"}
|
||||||
|
downloadLink={this.state.cultivationDownloadLink}
|
||||||
|
downloadVersion={this.state.cultivationVersion}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={"Downloads_More"}>
|
||||||
|
<h4>Looking for more builds?</h4>
|
||||||
|
|
||||||
|
<div className={"Downloads_More_Grasscutter"}>
|
||||||
|
<h5>Grasscutter: </h5>
|
||||||
|
<BasicButton
|
||||||
|
text={"Latest Unstable"}
|
||||||
|
color={"#0095ff"}
|
||||||
|
onClick={() => window.open("https://nightly.link/Grasscutters/Grasscutter/workflows/build/unstable/Grasscutter.zip")}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<BasicButton
|
||||||
|
text={"Older Builds"}
|
||||||
|
color={"#121928"}
|
||||||
|
onClick={() => window.open("https://github.com/Grasscutters/Grasscutter/releases")}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={"Downloads_More_Cultivation"}>
|
||||||
|
<h5>Cultivation: </h5>
|
||||||
|
<BasicButton
|
||||||
|
text={"Latest Commit"}
|
||||||
|
color={"#0095ff"}
|
||||||
|
onClick={() => window.open("https://nightly.link/Grasscutters/Cultivation/workflows/build/main/CultivationWin.zip")}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<BasicButton
|
||||||
|
text={"Older Builds"}
|
||||||
|
color={"#121928"}
|
||||||
|
onClick={() => window.open("https://github.com/Grasscutters/Cultivation/releases")}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Downloads;
|
40
src/utils.ts
40
src/utils.ts
@ -1,10 +1,11 @@
|
|||||||
const repo: string = "grasscutters/grasscutter";
|
const grasscutter: string = "grasscutters/grasscutter";
|
||||||
|
const cultivation: string = "grasscutters/cultivation";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of stars, forks and watchers of the repo
|
* Get the number of stars, forks and watchers of the repo
|
||||||
*/
|
*/
|
||||||
export async function getStatsAsync() {
|
export async function getStatsAsync() {
|
||||||
const res = await fetch(`https://api.github.com/repos/${repo}`, {
|
const res = await fetch(`https://api.github.com/repos/${grasscutter}`, {
|
||||||
headers: { Accept: "application/vnd.github.v3+json" }
|
headers: { Accept: "application/vnd.github.v3+json" }
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -16,3 +17,38 @@ export async function getStatsAsync() {
|
|||||||
watchers: data.subscribers_count
|
watchers: data.subscribers_count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the latest release of the repos
|
||||||
|
*/
|
||||||
|
export async function getLatestReleaseAsync() {
|
||||||
|
const resGC = await fetch(`https://api.github.com/repos/${grasscutter}/releases/latest`, {
|
||||||
|
headers: { Accept: "application/vnd.github.v3+json" }
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataGC = await resGC.json();
|
||||||
|
|
||||||
|
const resC = await fetch(`https://api.github.com/repos/${cultivation}/releases/latest`, {
|
||||||
|
headers: { Accept: "application/vnd.github.v3+json" }
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataC = await resC.json();
|
||||||
|
|
||||||
|
for (const asset of dataC.assets) {
|
||||||
|
if (asset.browser_download_url.endsWith(".msi")) {
|
||||||
|
dataC.assets[0] = asset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
grasscutter: {
|
||||||
|
version: dataGC.tag_name,
|
||||||
|
url: dataGC.assets[0].browser_download_url
|
||||||
|
},
|
||||||
|
cultivation: {
|
||||||
|
version: dataC.tag_name,
|
||||||
|
url: dataC.assets[0].browser_download_url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user