diff --git a/main_controller.py b/main_controller.py index 707c9f7..9692ce0 100644 --- a/main_controller.py +++ b/main_controller.py @@ -25,6 +25,7 @@ game_states = [] @socketio.on("recieved") def handle_new_conn(data): + print("new connection") socketio.emit("states_update", game_states, room=request.sid) def update_loop(): diff --git a/simmadome/src/App.tsx b/simmadome/src/App.tsx index 20fd97b..c7e165e 100644 --- a/simmadome/src/App.tsx +++ b/simmadome/src/App.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, {useState, useRef, useEffect} from 'react'; import io from 'socket.io-client'; import './App.css'; import Game from './Game'; @@ -26,120 +26,95 @@ interface GameState { type GameList = ([id: string, game: GameState] | null)[]; -interface AppProps { - filter: string | null - gameId: string | null -} +function App(props: {filter: string | null, gameId: string | null}) { -interface AppState { - filter: string - games: [string, GameState][] -} + let [games, setGames] = useState(new Array<[string, GameState]>()); + let [filter, setFilter] = useState(""); + useListener(setGames); -class App extends React.Component { - gameList: GameList; + let filters: string[] = []; + games.forEach((game, id) => { if (game[1].is_league && !filters.includes(game[1].leagueoruser)) { filters.push(game[1].leagueoruser) }}); - constructor(props: AppProps) { - super(props); - - let socket = io(); - socket.on('connect', () => socket.emit('recieved', {})); - socket.on('states_update', (update: [string, GameState][]) => this.onStatesUpdate(update)); - - this.gameList = []; - this.state = { - filter: props.filter ?? "", - games: [] - }; - this.onSelectNewFilter = this.onSelectNewFilter.bind(this); - } - - onStatesUpdate(newStates: [string, GameState][]) { - console.log(newStates); - this.setState({ games: newStates }); - } - - onSelectNewFilter(newFilter: string) { - this.setState({ filter: newFilter }); - this.gameList = []; - } - - updateGameList() { - let filterGames = this.state.games.filter((game, i) => this.state.filter === "" || game[1].leagueoruser === this.state.filter) - - //remove games no longer present, update games with new info - for (let i = 0; i < this.gameList.length; i ++) { - if (this.gameList[i] !== null) { - let newState = filterGames.find((val) => val[0] === this.gameList[i]![0]); - if (newState !== undefined) { - this.gameList[i] = newState; - } else { - this.gameList[i] = null; - } - } - } - - // add games not present - for (let game of filterGames) { - if (!this.gameList.find((val) => val !== null && val[0] === game[0])) { - let firstEmpty = this.gameList.indexOf(null); - if (firstEmpty < 0) { - this.gameList.push(game) - } else { - this.gameList[firstEmpty] = game; - } - } - } - - //remove trailing empty cells - while (this.gameList[this.gameList.length-1] === null) { - this.gameList.pop(); - } - } - - render() { - this.updateGameList(); - - let filters: string[] = []; - this.state.games.forEach((game, id) => { if (game[1].is_league && !filters.includes(game[1].leagueoruser)) { filters.push(game[1].leagueoruser) }}); - return ( -
- - -
0}/> -
- ); - } -} - -function Filters (props: {filterList: string[], selectedFilter: string, onSelectNewFilter: (newFilter: string) => void}) { - let filters = props.filterList.map((filter: string) => - - ) + let gameList = useRef(new Array<(string | null)>()); + let filterGames = games.filter((game, i) => filter === "" || game[1].leagueoruser === filter); + updateList(gameList.current, filterGames); return ( -
-
Filter:
- - {filters} +
+ {gameList.current = []; setFilter(filter)}}/> + val !== null ? filterGames.find((game) => game[0] === val) as [string, GameState] : null )}/> +
0}/>
); } +// App Utils + +// connects to the given url (or host if none) and waits for state updates +const useListener = (onUpdate: (update: [string, GameState][]) => void, url: string | null = null) => { + useEffect(() => { + let socket = url ? io(url) : io(); + socket.on('connect', () => socket.emit('recieved', {})); + socket.on('states_update', onUpdate); + return () => {socket.disconnect()} + }, [url]) +} + +// adds and removes games from list to keep it up to date, without relocating games already in place +function updateList(gameList: (string | null)[], games: [string, GameState][]) { + + //remove games no longer present + for (let i = 0; i < gameList.length; i ++) { + if (gameList[i] !== null && games.findIndex((val) => val[0] === gameList[i]) < 0) { + gameList[i] = null; + } + } + + // add games not present + for (let game of games) { + if (!gameList.find((val) => val !== null && val === game[0])) { + let firstEmpty = gameList.indexOf(null); + if (firstEmpty < 0) { + gameList.push(game[0]) + } else { + gameList[firstEmpty] = game[0]; + } + } + } + + //remove trailing empty cells + while (gameList[gameList.length-1] === null) { + gameList.pop(); + } +} + +function Filters (props: {filterList: string[], selectedFilter: string, onSelectNewFilter: (newFilter: string) => void}) { + function Filter(innerprops: {title: string, filter:string} ) { + return ( + + ); + } + + return ( +
+
Filter:
+ + {props.filterList.map((filter: string) => + + )} +
+ ); +} function Grid(props: { gameList: GameList }) { return (
{props.gameList.map((game) => {if (game) { - return + return } else { return
}})}