smart-monopoly/src/web/Setup.tsx
2024-04-11 01:21:53 +02:00

416 lines
14 KiB
TypeScript

import React, {Component} from "react";
import {
Button,
Chip,
FormControl,
FormControlLabel,
FormGroup,
FormLabel,
Grid,
Snackbar,
Switch,
TextField,
Typography
} from "@mui/material";
import RestartAltIcon from '@mui/icons-material/RestartAlt';
import CloseIcon from '@mui/icons-material/Close';
import SaveIcon from '@mui/icons-material/Save';
import {PAGE} from "./App";
import {
Config,
GameInput,
GameRules,
GameSwitch,
GameSwitchNames,
IPCListenChannels,
NFCCard,
NFCCardType,
NFCPropertyCard,
PropertyColor
} from "../RawConstants";
import NfcIcon from "@mui/icons-material/Nfc";
import IPCRendererListener from "./IPCRendererListener";
import CardSetup from "./CardSetup";
interface InitialSetupState {
open: boolean,
switchValues: GameSwitch[],
inputValues: GameInput[],
savedMsg: boolean,
openNFCModal: boolean,
nfcCard: NFCCard,
validCard: boolean
}
const defaultConf: InitialSetupState = {
open: true,
savedMsg: false,
openNFCModal: false,
nfcCard: null,
validCard: false,
switchValues: [
{
name: "GET_BONUS_PASSING_START",
label: "Über Los Bonus einziehen",
value: true
},
{
name: "DOUBLE_BONUS_ON_GO",
label: "Wenn auf Los, doppelten Bonus einziehen",
depends: "GET_BONUS_PASSING_START",
value: true
},
{
name: "PUT_PAID_PENALTIES_IN_MIDDLE",
label: "Gezahlte Strafen in die 'Mitte' legen",
value: true
},
{
name: "RECEIVE_PENALTIES_AT_FREE_PARKING",
label: "Bei 'Frei Parken' Strafen aus der 'Mitte' einziehen",
depends: "PUT_PAID_PENALTIES_IN_MIDDLE",
value: true
},
{
name: "PUT_10_IN_MIDDLE_AFTER_EACH_GO",
label: "Nach jedem Los 10 in die Mitte",
depends: "PUT_PAID_PENALTIES_IN_MIDDLE",
value: false
},
{
name: "STREET_MUST_BE_AUCTIONED_IF_NOT_PURCHASED",
label: "Straße muss versteigert werden bei Nichtkauf",
value: true
},
{
name: "TWO_HOTELS_PER_STREET_ALLOWED",
label: "Zwei Hotels pro Straße erlaubt",
value: false
},
{
name: "MORTGAGE_REDUCES_RENT",
label: "Hypothek verringert Miete",
value: false
},
{
name: "GOODS_GO_TO_OTHER_PLAYERS_UPON_BANKRUPTCY",
label: "Güter gehen an anderen Spieler über bei Bankrott",
value: true
},
{
name: "STREETS_CAN_BE_SOLD_BACK_TO_THE_BANK",
label: "Straßen können zurück an die Bank verkauft werden",
value: true
},
{
name: "PRISON_CAN_BE_PURCHASED_RENT_GOES_TO_PLAYER",
label: "Gefängnis kann erworben werden, Miete geht an den Spieler",
value: false
},
{
name: "KEEP_MONEY_MORE_SECRET",
label: "Geld von anderen Spielern ungenauer anzeigen",
value: false
}
],
inputValues: [
{
name: "STARTING_CASH",
type: "number",
label: "Start Guthaben",
value: "1500"
},
{
name: "PASSING_GO_CASH",
type: "number",
label: "Lohn über Los",
value: "200"
},
{
name: "PRISON_RELEASE_FEE",
type: "number",
label: "Gefängnis Gebühren",
value: "50"
},
{
name: "CURRENCY",
type: "text",
label: "Währung",
value: "€"
}
]
}
export default class Setup extends Component<{}, InitialSetupState> {
constructor(props: {}) {
super(props);
let x: NFCPropertyCard = {
cardType: NFCCardType.PROPERTY,
"name": "Test",
mortgageValue: 2,
rent: 100,
buyValue: 200,
specialProperties: "",
color: PropertyColor.BEIGE,
fullSetAmount: 2,
}
this.state = {
...defaultConf,
}
}
reset = () => {
this.setState(prevState => ({
...prevState,
...defaultConf
}))
//window.api.request("")
}
style = {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: '50%',
bgcolor: 'background.paper',
border: '2px solid #000',
boxShadow: 24,
p: 4,
};
onSwitch = (event: React.ChangeEvent<HTMLInputElement>) => {
const {name, checked} = event.target;
this.setState((prevState) => ({
...prevState,
switchValues: prevState.switchValues.map((switchObj) => {
if (switchObj.name === name) {
return {
...switchObj,
value: checked
};
}
return switchObj;
})
}));
}
onInput = (event: React.ChangeEvent<HTMLInputElement>) => {
const {name, value} = event.target;
this.setState((prevState) => ({
...prevState,
inputValues: prevState.inputValues.map((switchObj) => {
if (switchObj.name === name) {
return {
...switchObj,
value: value
};
}
return switchObj;
})
}));
}
getSettings = () => {
return new Promise<void>((resolve, reject) => {
window.api.request("SETTINGS", {}).then(answer => {
try {
let data = answer.data as Config;
for (let [sw, state] of Object.entries(data.rules.switchValues)) {
this.setState((prevState) => ({
...prevState,
switchValues: prevState.switchValues.map((obj) => {
if (obj.name === sw) {
return {
...obj,
value: state
};
}
return obj;
})
}));
}
for (let [sw, state] of Object.entries(data.rules.inputValues)) {
this.setState((prevState) => ({
...prevState,
inputValues: prevState.inputValues.map((obj) => {
if (obj.name === sw) {
return {
...obj,
value: state
};
}
return obj;
})
}));
}
resolve();
} catch (e) {
reject(e);
}
})
})
}
saveSettings = (silent = false) => {
let gameSettings: any = {
switchValues: {},
inputValues: {}
};
for (let ele of this.state.switchValues) {
gameSettings.switchValues[ele.name] = ele.value;
if (!!ele.depends && ele.value)
gameSettings.switchValues[ele.name] = this.checkDependsValue(ele.depends);
}
for (let ele of this.state.inputValues) {
gameSettings.inputValues[ele.name] = ele.value;
}
window.api.request("SETTINGS", {data: {rules: gameSettings as GameRules}}).then();
if (!silent)
this.setState(prevState => ({
...prevState,
savedMsg: true
}));
}
onNFCRawEvent = (card: NFCCard|null, isComplete: boolean) => {
this.setState(prevState => ({
...prevState,
openNFCModal: true,
nfcCard: card,
validCard: isComplete
}));
console.log(card);
}
private rawNFCListener: number = 0;
componentDidMount() {
this.rawNFCListener = IPCRendererListener.attach(IPCListenChannels.NFC_RAW, (message) => {
this.onNFCRawEvent(message.data, message.status);
console.log("Got an raw nfc event")
})
this.getSettings().then();
}
componentWillUnmount() {
IPCRendererListener.detach(this.rawNFCListener);
}
handleClose = () => {
window.app.toggleWiFiSettings(false);
}
checkDependsValue = (depends: GameSwitchNames) => {
for (let x of this.state.switchValues) {
if (x.name == depends)
return x.value;
}
}
render() {
return <div className="setup">
<Snackbar
open={this.state.savedMsg}
autoHideDuration={6000}
onClose={() => {
this.setState(prevState => ({
...prevState,
savedMsg: false
}))
}}
message={"Einstellungen gespeichert!"}
/>
{this.state.openNFCModal &&
<CardSetup card={this.state.nfcCard} validCard={this.state.validCard} closeCallback={() => this.setState(prevState => ({
...prevState,
openNFCModal: false
}))}/>}
<Typography variant="h2" sx={{mb: 2}}>Einstellungen</Typography>
<Grid container spacing={3}>
<Grid item xs={6}>
<FormControl component="fieldset" variant="standard">
<FormLabel component="legend">Schalter-Regeln</FormLabel>
<FormGroup>
{Object.values(this.state.switchValues).map(value => {
return (
<FormControlLabel key={value.name} sx={{mb: 1}}
control={
<Switch
checked={(value.value && !value.depends) || (value.value && !!value.depends && this.checkDependsValue(value.depends))}
disabled={!!value.depends && !this.checkDependsValue(value.depends)}
onChange={this.onSwitch}
name={value.name}/>
} label={value.label}
/>)
})}
</FormGroup>
</FormControl>
</Grid>
<Grid item xs={6}>
<FormControl component="fieldset" variant="standard">
<FormLabel component="legend">Werte-Regeln</FormLabel>
<FormGroup>
{Object.values(this.state.inputValues).map(value => {
return (
<FormControlLabel key={value.name} sx={{mb: 2}}
control={
<TextField type={value.type} variant="standard"
value={value.value}
disabled={!!value.depends && !this.checkDependsValue(value.depends)}
onChange={this.onInput}
name={value.name}/>
} label={value.label}
/>)
})}
</FormGroup>
</FormControl>
<FormControl sx={{mt: 5, mb: 1}} component="fieldset" variant="standard">
<FormLabel component="legend">Spielkarten</FormLabel>
<Typography sx={{ml: -2}} width={"95%"} variant="body1"><Chip
label={<div><NfcIcon sx={{marginTop: 0.9}} className={"animationBreathe"}
color="primary"/> NFC</div>} color="secondary"
variant="outlined"/><br/>Bitte die Karte an das Lesegerät halten, um sie zu
konfigurieren.<br/>Anschließend können die Einstellungen der Karte im Dialog angepasst
werden.</Typography>
</FormControl>
</Grid>
<Grid item xs={3.5}></Grid>
<Grid item xs={"auto"} alignItems="center">
<Button variant="contained" color="secondary" onClick={() => {
this.getSettings().then(r => window.app.setPage(PAGE.STARTUP));
}}>Abbrechen <CloseIcon/></Button>
<Button sx={{ml: 2}} variant="outlined" color="error"
onClick={() => this.reset()}>Zurücksetzen <RestartAltIcon/></Button>
<Button sx={{ml: 2}} variant="contained" color="success" onClick={() => {
this.saveSettings();
window.app.setPage(PAGE.STARTUP);
}}>Speichern <SaveIcon/></Button>
</Grid>
</Grid>
</div>
}
}