This commit is contained in:
Daniel Ledda
2020-12-24 12:38:52 +01:00
parent 652092f741
commit 7a58666702
5 changed files with 164 additions and 103 deletions

View File

@@ -11,6 +11,8 @@ import {SERVER_BASE_NAME} from "./index";
interface AppState {
userContext: IUserContext;
localeContext: ILocaleContext;
loading: boolean;
majorFailure: boolean;
}
interface AppProps {}
@@ -40,6 +42,8 @@ class App extends React.Component<AppProps, AppState> {
};
this.state = {
majorFailure: false,
loading: true,
userContext: {
username: "",
loggedIn: false,
@@ -54,20 +58,35 @@ class App extends React.Component<AppProps, AppState> {
}
componentDidMount(): void {
axios.get("/api/user", {baseURL: SERVER_BASE_NAME})
.then((res) => {
const data = res.data as any;
this.updateUserContext(data.username, true);
this.changeLang(data.lang);
})
.catch(err => console.log(err));
this.loadUserData();
}
async loadUserData(): Promise<void> {
try {
const response = (await axios.get("/api/user", {baseURL: SERVER_BASE_NAME})).data;
this.updateUserContext(response.username, true);
this.changeLang(response.lang);
}
catch (e) {
this.handleNoUserData();
}
finally {
this.setState({loading: false});
}
}
handleNoUserData(): void {
this.setState({majorFailure: true});
}
render(): ReactNode {
return (
<LocaleContext.Provider value={this.state.localeContext}>
<UserContext.Provider value={this.state.userContext}>
<Game/>
<Game
loading={this.state.loading}
majorFailure={this.state.majorFailure}
/>
</UserContext.Provider>
</LocaleContext.Provider>
);

View File

@@ -5,6 +5,7 @@ import GameSetup, {GameSettings} from "./GameSetup"
import Settings from "../static/settings.json";
import {SERVER_BASE_NAME} from "../index";
import axios from "axios";
import {Ruleset} from "../static/rulesets";
export interface Player {
id: string;
@@ -17,13 +18,15 @@ interface GameState {
loading: boolean;
availablePlayers: Player[]
debug: boolean;
availableRulesets: Ruleset[];
}
interface GameProps {}
interface GameProps {
loading: boolean;
majorFailure: boolean;
}
class Game extends React.Component<GameProps, GameState> {
state: GameState;
constructor(props: GameProps) {
super(props);
@@ -38,15 +41,25 @@ class Game extends React.Component<GameProps, GameState> {
loading: true,
availablePlayers: [],
debug: Settings.debug,
availableRulesets: [],
};
}
componentDidMount(): void {
axios.get(SERVER_BASE_NAME + "/api/players")
.then(response => this.addNewPlayers([...response.data.guests, response.data.mainPlayer]))
.catch(error => this.handleError(error))
.finally(() => this.setState({ loading: false }));
console.log(this.state.availablePlayers);
this.loadData();
}
async loadData(): Promise<void> {
try {
await this.loadAllPlayers();
await this.loadAllRulesets();
}
catch (e) {
this.handleRequestError(e);
}
finally {
this.setState({loading: false});
}
}
addNewPlayers(players: Player[]): void {
@@ -55,8 +68,8 @@ class Game extends React.Component<GameProps, GameState> {
this.setState({availablePlayers});
}
handleError(error: any): void {
handleRequestError(error: any): void {
console.log(error);
};
onSetupComplete: (gameSettings: GameSettings) => void = (gameSettings) => {
@@ -66,29 +79,48 @@ class Game extends React.Component<GameProps, GameState> {
});
};
returnToSetup: () => void = () => {
returnToSetup(): void {
this.setState({settingUp: true});
};
async loadAllRulesets(): Promise<void> {
const rulesetsSlug = (await axios.get(SERVER_BASE_NAME + "/api/rulesets/")).data;
this.setState({availableRulesets: rulesetsSlug.rulesets as Ruleset[]});
}
async loadAllPlayers(): Promise<void> {
const response = (await axios.get(SERVER_BASE_NAME + "/api/players")).data;
this.addNewPlayers([...response.guests, response.mainPlayer])
}
selectedRuleset(): Ruleset {
return this.state.availableRulesets.find(
ruleset => ruleset.id === this.state.currentSettings.ruleset) as Ruleset;
}
render(): ReactNode {
return (
<>
{!this.state.loading && (this.state.settingUp ?
{this.state.settingUp || this.state.loading || this.props.loading ?
(
<GameSetup
onSetupComplete={this.onSetupComplete}
loading={this.state.loading || this.props.loading}
majorFailure={this.props.majorFailure}
onSetupComplete={(s) => this.onSetupComplete(s)}
settings={this.state.currentSettings}
availablePlayers={this.state.availablePlayers}
availableRulesets={this.state.availableRulesets}
/>
) :
(
<KadiBoard
gameSchema={this.selectedRuleset()}
debug={this.state.debug}
settings={this.state.currentSettings}
returnToSetup={this.returnToSetup}
returnToSetup={() => this.returnToSetup()}
/>
)
)}
}
</>
);
}

View File

@@ -1,13 +1,16 @@
import React, {ChangeEvent, FocusEvent, KeyboardEvent, ReactNode} from "react";
import {getSchemaListings, SchemaListing} from "../static/rulesets";
import {Ruleset} from "../static/rulesets";
import LocaleContext from "../LocaleContext";
import {Button} from "semantic-ui-react";
import {Player} from "./Game";
interface GameSetupProps {
loading: boolean;
onSetupComplete: (settings: GameSettings) => void;
settings: GameSettings;
availablePlayers: Player[];
availableRulesets: Ruleset[];
majorFailure: boolean;
}
interface GameSetupState {
@@ -22,13 +25,9 @@ export interface GameSettings {
}
class GameSetup extends React.Component<GameSetupProps, GameSetupState> {
private readonly availableRulesets: SchemaListing[];
private changeLang: (lang: string) => void;
state: GameSetupState;
constructor(props: GameSetupProps) {
super(props);
this.availableRulesets = getSchemaListings();
this.changeLang = () => {};
this.state = {
selectedRuleset: this.props.settings.ruleset,
@@ -66,7 +65,7 @@ class GameSetup extends React.Component<GameSetupProps, GameSetupState> {
return this.props.availablePlayers.find(player => player.nick === playerName)?.id;
}
playerIsNew(player: Player) {
playerIsNew(player: Player): boolean {
return player.id === player.nick;
}
@@ -81,7 +80,7 @@ class GameSetup extends React.Component<GameSetupProps, GameSetupState> {
const Locale = this.context.strings;
const rulesetOptions: ReactNode[] = [];
for (const rulesetListing of this.availableRulesets) {
for (const rulesetListing of this.props.availableRulesets) {
let className = "option";
if (this.state.selectedRuleset === rulesetListing.id) {
className += " selected";
@@ -122,36 +121,61 @@ class GameSetup extends React.Component<GameSetupProps, GameSetupState> {
<div className={"gameSetup"}>
<div className={"setupFormContainer"}>
<div className={"setupForm"}>
<div className={"optionGroup"}>
<div className={"optionGroupTitleContainer"}>
<span className={"optionGroupTitle"}>
{Locale.setupScreen.players}
</span>
{this.props.majorFailure && (
<div className={"optionGroup"}>
<div className={"optionGroupTitleContainer"}>
<span className={"optionGroupTitle"}>
An Error Occurred
</span>
</div>
<div className={"optionList"}>
The necessary data couldn't be loaded to play. Try reloading the page.
</div>
</div>
<div className={"playerList optionList"}>
{playerListing}
)}
{this.props.loading && (
<div className={"optionGroup"}>
<div className={"optionGroupTitleContainer"}>
<span className={"optionGroupTitle"}>
Loading...
</span>
</div>
</div>
</div>
<div className={"optionGroup"}>
<div className={"optionGroupTitleContainer"}>
<span className={"optionGroupTitle"}>
{Locale.setupScreen.selectRuleset}
</span>
</div>
<div className={"rulesetOptions optionList"}>
{rulesetOptions}
</div>
</div>
<div className={"playButtonContainer"}>
<Button
size={"huge"}
color={"blue"}
onClick={this.submitSettings}
disabled={this.state.enteredPlayers.length < 1}
>
{Locale.setupScreen.startGame}
</Button>
</div>
)}
{!this.props.loading && !this.props.majorFailure && (
<>
<div className={"optionGroup"}>
<div className={"optionGroupTitleContainer"}>
<span className={"optionGroupTitle"}>
{Locale.setupScreen.players}
</span>
</div>
<div className={"playerList optionList"}>
{playerListing}
</div>
</div>
<div className={"optionGroup"}>
<div className={"optionGroupTitleContainer"}>
<span className={"optionGroupTitle"}>
{Locale.setupScreen.selectRuleset}
</span>
</div>
<div className={"rulesetOptions optionList"}>
{rulesetOptions}
</div>
</div>
<div className={"playButtonContainer"}>
<Button
size={"huge"}
color={"blue"}
onClick={this.submitSettings}
disabled={this.state.enteredPlayers.length < 1}
>
{Locale.setupScreen.startGame}
</Button>
</div>
</>
)}
</div>
</div>
</div>
@@ -233,24 +257,22 @@ const ActivePlayerListItem: React.FunctionComponent<ActivePlayerListItemProps> =
const {removePlayer, playerName, playerIsNew} = props;
const Locale = React.useContext(LocaleContext).strings;
return (
<>
<div
className={"option playerOption"}
>
<div className={"playerText"}>
{playerName}
{playerIsNew &&
<span className={"newPlayerText"}>
{Locale.setupScreen.playerNew}
</span>
}
</div>
<div
className={"trashButton"}
onClick={removePlayer}
/>
<div
className={"option playerOption"}
>
<div className={"playerText"}>
{playerName}
{playerIsNew && (
<span className={"newPlayerText"}>
{Locale.setupScreen.playerNew}
</span>
)}
</div>
</>
<div
className={"trashButton"}
onClick={removePlayer}
/>
</div>
);
};

View File

@@ -38,6 +38,7 @@ export interface KadiBoardProps {
settings: GameSettings;
returnToSetup: () => void;
debug: boolean;
gameSchema: Ruleset;
}
interface KadiBoardState {
@@ -57,12 +58,11 @@ interface ScoreSheet {
class KadiBoard extends React.Component<KadiBoardProps, KadiBoardState> {
private readonly gameSchema: Ruleset;
private readonly caretaker: CaretakerSet;
state: KadiBoardState;
constructor(props: KadiBoardProps) {
super(props);
this.gameSchema = getGameSchemaById(this.props.settings.ruleset);
this.gameSchema = this.props.gameSchema;
this.state = {
scoreSheet: this.generateNewScoreSheet(this.props.settings.players),
@@ -166,25 +166,22 @@ class KadiBoard extends React.Component<KadiBoardProps, KadiBoardState> {
}
private saveGame: () => void = async () => {
this.setState({savingGame: true}, () => {
axios.post(SERVER_BASE_NAME + "/api/games",
this.getJSONRepresentationForBoard(),
{headers: {"Content-Type": "application/json"}}
)
.then(response => this.onGameSave(response.data))
.catch(error => this.onSaveError(error))
.finally(() => this.setState({ savingGame: false }));
console.log(this.getJSONRepresentationForBoard());
this.setState({savingGame: true}, async () => {
try {
const response = await axios.post(SERVER_BASE_NAME + "/api/games",
this.getJSONRepresentationForBoard(), {headers: {"Content-Type": "application/json"}});
this.setState({locked: true, saved: true});
}
catch (e) {
console.log("Error saving:", e);
}
finally {
this.setState({ savingGame: false });
}
});
};
private onGameSave = (serverResponse: string) => {
this.setState({locked: true, saved: true});
};
private onSaveError = (error: any) => {
console.log("Error saving:", error);
};
private fillOutRandomly(): void {
for (const player of this.state.players) {
for (const blockId in this.gameSchema.blocks) {

View File

@@ -193,12 +193,3 @@ export function getGameSchemaById(schemaId: string): Ruleset {
}
throw new RangeError("No such GameSchema with id '" + schemaId + "'!");
}
export interface SchemaListing {
id: string;
label: string;
}
export function getSchemaListings(): SchemaListing[] {
return gameSchemas.map((s) => ({ id: s.id, label: s.label }));
}