mirror of
https://github.com/Grasscutters/Meadow.git
synced 2024-11-23 04:19:40 +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 Home from "@pages/Home";
|
||||
import Downloads from "@pages/Downloads";
|
||||
|
||||
import "@css/App.css";
|
||||
|
||||
@ -14,7 +15,7 @@ class App extends React.Component {
|
||||
<Header />
|
||||
<Routes>
|
||||
<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={"/features"} element={<p>Features</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
|
||||
*/
|
||||
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" }
|
||||
});
|
||||
|
||||
@ -16,3 +17,38 @@ export async function getStatsAsync() {
|
||||
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