This repository has been archived on 2023-11-06. You can view files and clone it, but cannot push or open issues or pull requests.
beatsaber-overlay/pages/index.js

348 lines
8.0 KiB
JavaScript
Raw Normal View History

2022-10-14 19:00:47 +00:00
import {
Button,
Card,
Container,
Grid,
Input,
Link,
Modal,
2022-10-19 15:37:20 +00:00
Radio,
2022-10-14 19:00:47 +00:00
Spacer,
Spinner,
2022-10-14 19:00:47 +00:00
Switch,
Text,
} from "@nextui-org/react";
import { Component } from "react";
import NavBar from "../src/components/Navbar";
2022-10-10 12:14:25 +00:00
2022-10-14 19:00:47 +00:00
import { toast, ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
2022-10-10 18:43:29 +00:00
2022-10-19 15:52:50 +00:00
import Utils from "../src/utils/utils";
2022-10-14 19:00:47 +00:00
import styles from "../styles/main.module.css";
2022-10-10 12:14:25 +00:00
export default class Home extends Component {
constructor(props) {
super(props);
2022-10-10 17:38:06 +00:00
this._mounted = false;
2022-10-10 17:38:06 +00:00
this.state = {
2022-10-10 19:01:11 +00:00
loading: true,
2022-10-10 17:38:06 +00:00
steamId: undefined,
2022-10-10 18:43:29 +00:00
isPreviewVisible: false,
previewUrl: undefined,
overlayUrl: undefined,
2022-10-19 16:26:46 +00:00
avatarUrl: undefined,
2022-10-10 18:43:29 +00:00
values: {
socketAddr: undefined,
2022-10-19 15:37:20 +00:00
leaderboard: "ScoreSaber",
2022-10-10 18:43:29 +00:00
showPlayerStats: true,
showScoreInfo: false,
showSongInfo: false,
},
2022-10-14 19:00:47 +00:00
};
}
async componentDidMount() {
if (this._mounted === true) {
return;
}
this._mounted = true;
2022-10-10 12:14:25 +00:00
const urlSearchParams = new URLSearchParams(window.location.search);
const params = Object.fromEntries(urlSearchParams.entries());
if (params.id) {
2022-10-14 19:00:47 +00:00
document.location.href = "/overlay/" + window.location.search;
2022-10-10 17:38:06 +00:00
return;
2022-10-10 12:14:25 +00:00
}
2022-10-10 17:38:06 +00:00
2022-10-14 19:00:47 +00:00
if (localStorage.getItem("values") == undefined) {
localStorage.setItem(
"values",
JSON.stringify({
steamId: this.state.steamId,
values: this.state.values,
})
);
2022-10-10 18:43:29 +00:00
} else {
2022-10-14 19:00:47 +00:00
const json = JSON.parse(localStorage.getItem("values"));
2022-10-19 15:37:20 +00:00
let values = {};
Object.entries(json.values).forEach((value) => {
2022-10-19 17:00:06 +00:00
if (value[0] !== undefined) {
values[value[0]] = value[1];
2022-10-19 15:37:20 +00:00
}
});
this.setState({ steamId: json.steamId, values: values });
2022-10-19 17:00:06 +00:00
this.validateSteamId(json.steamId || "");
2022-10-10 18:43:29 +00:00
}
2022-10-10 19:01:11 +00:00
this.setState({ loading: false });
2022-10-10 17:38:06 +00:00
}
loadPreview() {
2022-10-14 19:00:47 +00:00
this.setState({
isPreviewVisible: true,
2022-10-20 09:55:31 +00:00
previewUrl: this.generateUrl(),
2022-10-14 19:00:47 +00:00
});
2022-10-10 18:43:29 +00:00
}
2022-10-20 09:55:31 +00:00
generateUrl() {
2022-10-10 18:43:29 +00:00
let values = "";
2022-10-14 19:00:47 +00:00
Object.entries(this.state.values).forEach((value) => {
2022-10-10 18:43:29 +00:00
if (value[1] === undefined) {
return;
}
2022-10-19 15:37:20 +00:00
if (value[0] == "leaderboard" && value[1] === "BeatLeader") {
values += `&beatLeader=true`;
2022-10-10 18:43:29 +00:00
return;
}
values += `&${value[0]}=${value[1]}`;
});
2022-10-10 17:38:06 +00:00
2022-10-14 19:00:47 +00:00
return (
2022-10-20 09:55:31 +00:00
window.location.origin + "/overlay?id=" + this.state.steamId + values
2022-10-14 19:00:47 +00:00
);
2022-10-10 17:38:06 +00:00
}
2022-10-10 18:43:29 +00:00
updateValue(key, value) {
let values = this.state.values;
values[key] = value;
this.setState({ values: values });
this.updateStorage();
}
updateStorage() {
setTimeout(() => {
2022-10-14 19:00:47 +00:00
localStorage.setItem(
"values",
JSON.stringify({
steamId: this.state.steamId,
values: this.state.values,
})
);
2022-10-10 18:43:29 +00:00
}, 5);
}
2022-10-19 16:26:46 +00:00
async validateSteamId(steamId) {
2022-10-19 16:47:30 +00:00
if (steamId.length !== 17) {
2022-10-19 16:26:46 +00:00
// Steam ID is invalid
return this.setState({ avatarUrl: undefined });
}
const data = await fetch("/api/validateid?steamid=" + steamId);
const json = await data.json();
if (json.message === "Valid") {
this.setState({
avatarUrl: `/api/steamavatar?steamid=${steamId}`,
2022-10-19 16:26:46 +00:00
});
} else {
this.setState({ avatarUrl: undefined });
}
}
render() {
2022-10-14 19:00:47 +00:00
return this.state.loading ? (
<div className={styles.loading}>
<Spinner size={"xl"}></Spinner>
</div>
2022-10-14 19:00:47 +00:00
) : (
<div className={styles.main}>
2022-10-19 16:26:46 +00:00
<NavBar avatarUrl={this.state.avatarUrl}></NavBar>
2022-10-14 19:00:47 +00:00
<Container
css={{
marginTop: "$8",
}}
>
{/* Preview */}
{this.state.isPreviewVisible ? (
<Modal
closeButton
open={this.state.isPreviewVisible}
width={"100%"}
blur
onClose={() => this.setState({ isPreviewVisible: false })}
>
<Modal.Header>
<Text size={18}>Overlay Preview</Text>
</Modal.Header>
<Modal.Body>
<iframe height={600} src={this.state.previewUrl}></iframe>
</Modal.Body>
</Modal>
) : (
<></>
)}
<Grid.Container gap={2} justify="center">
<Grid
xs={12}
css={{
color: "black",
}}
justify="center"
>
<div
style={{
textAlign: "center",
}}
>
2022-10-19 14:53:27 +00:00
<Text h1 css={{ color: "$text" }}>
BeatSaber Overlay
</Text>
<Text h4 css={{ color: "$text" }}>
Welcome to the Setup panel
</Text>
2022-10-14 19:00:47 +00:00
</div>
</Grid>
2022-10-19 14:53:27 +00:00
<Grid xs={12} lg={9}>
2022-10-14 19:00:47 +00:00
<Card>
<Card.Body>
2022-10-19 15:37:20 +00:00
<Spacer y={1.2} />
2022-10-14 19:00:47 +00:00
<Input
underlined
labelPlaceholder="Ip Address (Only set if you stream on multiple devices)"
initialValue="localhost"
value={this.state.values.socketAddr}
onChange={(event) =>
this.updateValue("socketAddr", event.target.value)
2022-10-10 18:43:29 +00:00
}
2022-10-14 19:00:47 +00:00
checked={true}
/>
<Spacer y={2} />
<Input
underlined
2022-10-20 09:47:06 +00:00
labelPlaceholder="Steam Id (NOT Username)"
2022-10-14 19:00:47 +00:00
initialValue=""
value={this.state.steamId}
2022-10-19 16:26:46 +00:00
onChange={async (event) => {
const id = event.target.value;
await this.validateSteamId(id);
this.setState({ steamId: id });
2022-10-14 19:00:47 +00:00
this.updateStorage();
}}
/>
<Spacer y={1} />
2022-10-19 15:37:20 +00:00
<Text>Ranked leaderboard</Text>
<Radio.Group
defaultValue={this.state.values.leaderboard || "ScoreSaber"}
onChange={(value) => {
this.updateValue("leaderboard", value);
}}
>
<Radio
value="ScoreSaber"
description="Uses the leaderboard from https://scoresaber.com/"
size="sm"
>
ScoreSaber
</Radio>
<Radio
value="BeatLeader"
description="Uses the leaderboard from https://www.beatleader.xyz/"
size="sm"
>
BeatLeader
</Radio>
</Radio.Group>
<Spacer y={1} />
2022-10-14 19:00:47 +00:00
<Text>
Do you want to show Player Stats (Current PP, global pos,
etc)
</Text>
<Switch
2022-10-19 15:37:20 +00:00
label="Ranked leaderboard"
2022-10-14 19:00:47 +00:00
onChange={(event) =>
this.updateValue("showPlayerStats", event.target.checked)
}
checked={this.state.values.showPlayerStats}
size="md"
/>
2022-10-19 15:37:20 +00:00
<Spacer y={1.2} />
2022-10-14 19:00:47 +00:00
<Text>
Do you want to show Score Info (Current swing values, total
score, etc)
</Text>
<Switch
onChange={(event) =>
this.updateValue("showScoreInfo", event.target.checked)
}
checked={this.state.values.showScoreInfo}
size="md"
/>
2022-10-19 15:37:20 +00:00
<Spacer y={1.2} />
2022-10-14 19:00:47 +00:00
<Text>
Do you want to show Song Info (Song name, bsr, song art,
etc)
</Text>
<Switch
onChange={(event) =>
this.updateValue("showSongInfo", event.target.checked)
}
checked={this.state.values.showSongInfo}
size="md"
/>
2022-10-19 15:37:20 +00:00
<Spacer y={1.2} />
2022-10-10 17:38:06 +00:00
2022-10-14 19:00:47 +00:00
<Button.Group>
<Button
flat
auto
2022-10-19 15:37:20 +00:00
onPress={() => {
2022-10-14 19:00:47 +00:00
if (!this.state.steamId) {
toast.error("Please provide a Steam ID");
return;
}
window.open(this.generateUrl(), "_blank");
}}
>
Open Overlay
</Button>
<Button
flat
auto
2022-10-19 15:37:20 +00:00
onPress={() => {
2022-10-14 19:00:47 +00:00
if (!this.state.steamId) {
toast.error("Please provide a Steam ID");
return;
}
this.loadPreview();
}}
>
Preview
</Button>
</Button.Group>
2022-10-19 15:52:50 +00:00
<Text
css={{
marginTop: "10px",
}}
>
<Link
onPress={(event) => {
2022-10-19 15:52:50 +00:00
Utils.openInNewTab(
"https://github.com/RealFascinated/beatsaber-overlay"
);
}}
>
If you like this project and want to support it. Come
check out the project on GitHub!
</Link>
</Text>
2022-10-14 19:00:47 +00:00
</Card.Body>
</Card>
</Grid>
</Grid.Container>
</Container>
<ToastContainer />
</div>
);
}
2022-10-10 19:01:11 +00:00
}