update
This commit is contained in:
35
src/App.tsx
35
src/App.tsx
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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()}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 }));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user