From 5d5c65016226ae993cf6e62392bf392c3d467ddd Mon Sep 17 00:00:00 2001 From: Pax1601 Date: Tue, 2 Apr 2024 15:18:10 +0200 Subject: [PATCH] Added state and events context --- frontend/react/src/App.tsx | 148 ++++++++++++++++++++++--- frontend/react/src/eventscontext.tsx | 15 +++ frontend/react/src/index.css | 2 +- frontend/react/src/main.jsx | 2 +- frontend/react/src/statecontext.tsx | 12 ++ frontend/react/src/ui/header.tsx | 46 ++++---- frontend/react/src/ui/statebuttons.tsx | 16 ++- 7 files changed, 193 insertions(+), 48 deletions(-) create mode 100644 frontend/react/src/eventscontext.tsx create mode 100644 frontend/react/src/statecontext.tsx diff --git a/frontend/react/src/App.tsx b/frontend/react/src/App.tsx index c29ca811..7d9fd16f 100644 --- a/frontend/react/src/App.tsx +++ b/frontend/react/src/App.tsx @@ -1,28 +1,142 @@ import React from 'react' -import { useState } from 'react' -import './App.css' +import './app.css' import { MapContainer, TileLayer } from 'react-leaflet' import { Map } from './map/map' import { Header } from './ui/header' +import { EventsProvider } from './eventscontext' +import { StateProvider } from './statecontext' -var map: Map; const position = [51.505, -0.09] -function App() { - const [count, setCount] = useState(0) - - return ( -
- - - -
-
- ) +export type OlympusState = { + spawnMenuVisible: boolean, + unitControlMenuVisible: boolean, + measureMenuVisible: boolean, + drawingMenuVisible: boolean } -export default App +export default class App extends React.Component<{}, OlympusState> { + constructor(props) { + super(props); + + /* State initialization */ + this.state = { + spawnMenuVisible: false, + unitControlMenuVisible: false, + measureMenuVisible: false, + drawingMenuVisible: false + } + + /* Methods bindings */ + this.showSpawnMenu = this.showSpawnMenu.bind(this); + this.toggleSpawnMenu = this.toggleSpawnMenu.bind(this); + this.showUnitControlMenu = this.showUnitControlMenu.bind(this); + this.toggleUnitControlMenu = this.toggleUnitControlMenu.bind(this); + this.showMeasureMenu = this.showMeasureMenu.bind(this); + this.toggleMeasureMenu = this.toggleMeasureMenu.bind(this); + this.showDrawingMenu = this.showDrawingMenu.bind(this); + this.toggleDrawingMenu = this.toggleDrawingMenu.bind(this); + } + + showSpawnMenu(show: boolean) { + this.setState({ + spawnMenuVisible: show, + unitControlMenuVisible: false, + measureMenuVisible: false, + drawingMenuVisible: false + }); + } + + toggleSpawnMenu() { + this.setState({ + spawnMenuVisible: !this.state.spawnMenuVisible, + unitControlMenuVisible: false, + measureMenuVisible: false, + drawingMenuVisible: false + }); + } + + showUnitControlMenu(show: boolean) { + this.setState({ + spawnMenuVisible: false, + unitControlMenuVisible: show, + measureMenuVisible: false, + drawingMenuVisible: false + }); + } + + toggleUnitControlMenu() { + this.setState({ + spawnMenuVisible: false, + unitControlMenuVisible: !this.state.unitControlMenuVisible, + measureMenuVisible: false, + drawingMenuVisible: false + }); + } + + showMeasureMenu(show: boolean) { + this.setState({ + spawnMenuVisible: false, + unitControlMenuVisible: false, + measureMenuVisible: show, + drawingMenuVisible: false + }); + } + + toggleMeasureMenu() { + this.setState({ + spawnMenuVisible: false, + unitControlMenuVisible: false, + measureMenuVisible: !this.state.measureMenuVisible, + drawingMenuVisible: false + }); + } + + showDrawingMenu(show: boolean) { + this.setState({ + spawnMenuVisible: false, + unitControlMenuVisible: false, + measureMenuVisible: false, + drawingMenuVisible: show + }); + } + + toggleDrawingMenu() { + this.setState({ + spawnMenuVisible: false, + unitControlMenuVisible: false, + measureMenuVisible: false, + drawingMenuVisible: !this.state.drawingMenuVisible + }); + } + + render() { + return ( +
+ + + + + +
+
+
+
+ ) + } +} diff --git a/frontend/react/src/eventscontext.tsx b/frontend/react/src/eventscontext.tsx new file mode 100644 index 00000000..e0b0ec3c --- /dev/null +++ b/frontend/react/src/eventscontext.tsx @@ -0,0 +1,15 @@ +import { createContext } from "react"; + +export const EventsContext = createContext({ + showSpawnMenu: (e: boolean) => {}, + toggleSpawnMenu: () => {}, + showUnitControlMenu: (e: boolean) => {}, + toggleUnitControlMenu: () => {}, + showMeasureMenu: (e: boolean) => {}, + toggleMeasureMenu: () => {}, + showDrawingMenu: (e: boolean) => {}, + toggleDrawingMenu: () => {} +}) + +export const EventsProvider = EventsContext.Provider; +export const EventsConsumer = EventsContext.Consumer; diff --git a/frontend/react/src/index.css b/frontend/react/src/index.css index 4e1243e4..812d1cf2 100644 --- a/frontend/react/src/index.css +++ b/frontend/react/src/index.css @@ -1,4 +1,4 @@ -@import "./leaflet/leaflet.css"; +@import "../node_modules/leaflet/dist/leaflet.css"; :root { font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; diff --git a/frontend/react/src/main.jsx b/frontend/react/src/main.jsx index a700d3b7..d6041272 100644 --- a/frontend/react/src/main.jsx +++ b/frontend/react/src/main.jsx @@ -1,6 +1,6 @@ import React from 'react' import ReactDOM from 'react-dom/client' -import App from './App.tsx' +import App from './app.tsx' import './index.css' ReactDOM.createRoot(document.getElementById('root')).render( diff --git a/frontend/react/src/statecontext.tsx b/frontend/react/src/statecontext.tsx new file mode 100644 index 00000000..b42dfb8a --- /dev/null +++ b/frontend/react/src/statecontext.tsx @@ -0,0 +1,12 @@ +import { createContext } from "react"; +import { OlympusState } from "./App"; + +export const StateContext = createContext({ + spawnMenuVisible: false, + unitControlMenuVisible: false, + measureMenuVisible: false, + drawingMenuVisible: false +} as OlympusState) + +export const StateProvider = StateContext.Provider; +export const StateConsumer = StateContext.Consumer; diff --git a/frontend/react/src/ui/header.tsx b/frontend/react/src/ui/header.tsx index 0ef2b841..0a768bfe 100644 --- a/frontend/react/src/ui/header.tsx +++ b/frontend/react/src/ui/header.tsx @@ -2,28 +2,34 @@ import React from 'react' import { StateButton } from './statebuttons'; import { faPlus, faGamepad, faRuler, faPencil } from '@fortawesome/free-solid-svg-icons'; import { library } from '@fortawesome/fontawesome-svg-core' +import { EventsConsumer, EventsContext } from '../eventscontext'; +import { StateConsumer } from '../statecontext'; library.add(faPlus, faGamepad, faRuler, faPencil) -type HeaderProps = { +export class Header extends React.Component<{}, {}> { + constructor(props) { + super(props); + } -} - -type HeaderState = { - -} - -export class Header extends React.Component { - render() { - return ( -
-
- - - - -
-
- ); - } + render() { + return ( + + {(appState) => + + {(events) => +
+
+ + + + +
+
+ } +
+ } +
+ ); + } } diff --git a/frontend/react/src/ui/statebuttons.tsx b/frontend/react/src/ui/statebuttons.tsx index 0d412d39..965fe6f1 100644 --- a/frontend/react/src/ui/statebuttons.tsx +++ b/frontend/react/src/ui/statebuttons.tsx @@ -1,16 +1,14 @@ -import React from 'react' +import React, { MouseEventHandler } from 'react' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { IconProp } from '@fortawesome/fontawesome-svg-core' -type ButtonProperties = { - icon: string -} - -type ButtonState = { +type ButtonProps = { + icon: string, + onClick: CallableFunction, active: boolean } -export class StateButton extends React.Component { +export class StateButton extends React.Component { constructor(props) { super(props); this.state = { @@ -20,10 +18,10 @@ export class StateButton extends React.Component render() { var computedClassName = ""; - computedClassName += this.state.active? 'bg-white text-background-steel': 'bg-transparent text-white border-white'; + computedClassName += this.props.active? 'bg-white text-background-steel': 'bg-transparent text-white border-white'; return ( - this.setState({active: !this.state.active})}> + ); }