From 1fee6376086a2936bd33e6ff6b09b218ac936417 Mon Sep 17 00:00:00 2001 From: Elijah Steres Date: Sun, 17 Jan 2021 17:14:02 -0500 Subject: [PATCH 1/5] quick fixes --- .gitignore | 1 + main_controller.py | 2 +- simmadome/.eslintcache | 1 - simmadome/public/index.html | 10 ---------- simmadome/src/Game.css | 2 ++ simmadome/src/GamesPage.css | 5 ----- simmadome/src/GamesPage.tsx | 8 +++++++- simmadome/src/index.css | 27 +++++++++++++++++++++------ simmadome/src/index.tsx | 12 +++++++----- 9 files changed, 39 insertions(+), 29 deletions(-) delete mode 100644 simmadome/.eslintcache diff --git a/.gitignore b/.gitignore index 01a7145..473c2b0 100644 --- a/.gitignore +++ b/.gitignore @@ -357,3 +357,4 @@ Pipfile env /data/leagues /simmadome/build +/simmadome/.eslintcache diff --git a/main_controller.py b/main_controller.py index 997a692..5da83c5 100644 --- a/main_controller.py +++ b/main_controller.py @@ -93,7 +93,7 @@ def create_league(): new_league = league_structure(config['name']) new_league.setup( league_dic, - division_games=config['division_series'], # need to add a check that makes sure these values are ok + division_games=config['division_series'], inter_division_games=config['inter_division_series'], inter_league_games=config['inter_league_series'], ) diff --git a/simmadome/.eslintcache b/simmadome/.eslintcache deleted file mode 100644 index 32ab91c..0000000 --- a/simmadome/.eslintcache +++ /dev/null @@ -1 +0,0 @@ -[{"/Users/elijah/Documents/Projects/matteo/simmadome/src/index.tsx":"1","/Users/elijah/Documents/Projects/matteo/simmadome/src/reportWebVitals.ts":"2","/Users/elijah/Documents/Projects/matteo/simmadome/src/GamesPage.tsx":"3","/Users/elijah/Documents/Projects/matteo/simmadome/src/GamePage.tsx":"4","/Users/elijah/Documents/Projects/matteo/simmadome/src/CreateLeague.tsx":"5","/Users/elijah/Documents/Projects/matteo/simmadome/src/GamesUtil.tsx":"6","/Users/elijah/Documents/Projects/matteo/simmadome/src/util.tsx":"7","/Users/elijah/Documents/Projects/matteo/simmadome/src/Game.tsx":"8"},{"size":2368,"mtime":1610663769654,"results":"9","hashOfConfig":"10"},{"size":425,"mtime":1610566206674,"results":"11","hashOfConfig":"10"},{"size":4725,"mtime":1610664926203,"results":"12","hashOfConfig":"10"},{"size":1836,"mtime":1610677519051,"results":"13","hashOfConfig":"10"},{"size":18825,"mtime":1610778204901,"results":"14","hashOfConfig":"10"},{"size":1116,"mtime":1610677473305,"results":"15","hashOfConfig":"10"},{"size":961,"mtime":1610694553519,"results":"16","hashOfConfig":"10"},{"size":3089,"mtime":1610572714752,"results":"17","hashOfConfig":"10"},{"filePath":"18","messages":"19","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"1bvn6qu",{"filePath":"20","messages":"21","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"22","messages":"23","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"24","messages":"25","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"26","messages":"27","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"28","messages":"29","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"30","messages":"31","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"32","messages":"33","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/Users/elijah/Documents/Projects/matteo/simmadome/src/index.tsx",[],"/Users/elijah/Documents/Projects/matteo/simmadome/src/reportWebVitals.ts",[],"/Users/elijah/Documents/Projects/matteo/simmadome/src/GamesPage.tsx",[],"/Users/elijah/Documents/Projects/matteo/simmadome/src/GamePage.tsx",[],"/Users/elijah/Documents/Projects/matteo/simmadome/src/CreateLeague.tsx",[],"/Users/elijah/Documents/Projects/matteo/simmadome/src/GamesUtil.tsx",[],"/Users/elijah/Documents/Projects/matteo/simmadome/src/util.tsx",[],"/Users/elijah/Documents/Projects/matteo/simmadome/src/Game.tsx",[]] \ No newline at end of file diff --git a/simmadome/public/index.html b/simmadome/public/index.html index ddec811..825a173 100644 --- a/simmadome/public/index.html +++ b/simmadome/public/index.html @@ -16,15 +16,5 @@
- diff --git a/simmadome/src/Game.css b/simmadome/src/Game.css index ca73b4d..6f3e745 100644 --- a/simmadome/src/Game.css +++ b/simmadome/src/Game.css @@ -171,6 +171,8 @@ .update_text { text-align: start; + margin-top: 0.2rem; + margin-bottom: 0.2rem; } .field { diff --git a/simmadome/src/GamesPage.css b/simmadome/src/GamesPage.css index 8baef47..4ace427 100644 --- a/simmadome/src/GamesPage.css +++ b/simmadome/src/GamesPage.css @@ -70,10 +70,5 @@ @media only screen and (max-device-width: 800px) { .container { - display: grid; - grid-template-columns: repeat(1, minmax(700px, 90%)); - position: absolute; - left: 50%; - transform: translate(-50%, 0); } } diff --git a/simmadome/src/GamesPage.tsx b/simmadome/src/GamesPage.tsx index 4fdaacb..4877f55 100644 --- a/simmadome/src/GamesPage.tsx +++ b/simmadome/src/GamesPage.tsx @@ -5,23 +5,29 @@ import './GamesPage.css'; import Game from './Game'; function GamesPage() { + let gameList = useRef<(string | null)[]>([]); + let [search, setSearch] = useState(window.location.search); useEffect(() => { setSearch(window.location.search); + gameList.current = []; //eslint-disable-next-line react-hooks/exhaustive-deps }, [window.location.search]) + // get filter term let searchparams = new URLSearchParams(search); let filter = searchparams.get('league') ?? "" + // set up socket listener let [games, setGames] = useState<[string, GameState][]>([]); useListener(setGames); + // build filter list let filters = useRef(filter !== "" ? [filter] : []); games.forEach((game) => { if (game[1].is_league && !filters.current.includes(game[1].leagueoruser)) { filters.current.push(game[1].leagueoruser) }}); filters.current = filters.current.filter((f) => games.find((game) => game && game[1].is_league && game[1].leagueoruser === f) || f === filter); - let gameList = useRef<(string | null)[]>([]); + // update game list let filterGames = games.filter((game, i) => filter === "" || game[1].leagueoruser === filter); updateList(gameList.current, filterGames, searchparams.get('game')); diff --git a/simmadome/src/index.css b/simmadome/src/index.css index 9cf2b34..754da75 100644 --- a/simmadome/src/index.css +++ b/simmadome/src/index.css @@ -55,6 +55,12 @@ h2 { margin: auto; } +#links { + display: flex; + width: 100%; + justify-content: space-between; +} + #link_div { text-align: right; position: absolute; @@ -63,6 +69,12 @@ h2 { display: flex; } +#nav_links { + position: absolute; + top: 1rem; + left: 2rem; +} + .github_logo, .twitter_logo, .patreon_container { height: 2rem; width: 2rem; @@ -97,15 +109,18 @@ a:hover { color: white; } -#utility_links { - position: absolute; - top: 1rem; - left: 2rem; -} - img.emoji { height: 1em; width: 1em; margin: 0 .05em 0 .1em; vertical-align: -0.1em; +} + +@media only screen and (max-width: 800px) { + #link_div, #nav_links { + position: static; + margin-top: 0.5rem; + margin-left: 2rem; + margin-right: 2rem; + } } \ No newline at end of file diff --git a/simmadome/src/index.tsx b/simmadome/src/index.tsx index b0ec638..a6f4b73 100644 --- a/simmadome/src/index.tsx +++ b/simmadome/src/index.tsx @@ -29,6 +29,10 @@ ReactDOM.render( function Header() { return ( - +
- +
- +
{ !validRequest(name, structure, options) && showError ? "Cannot create league. Some information is missing or invalid." : "" @@ -283,8 +297,6 @@ function makeRequest(name:string, structure: LeagueStructureState, options:Leagu } function validRequest(name:string, structure: LeagueStructureState, options:LeagueOptionsState) { - - return ( name !== "" && @@ -296,6 +308,7 @@ function validRequest(name:string, structure: LeagueStructureState, options:Leag validNumber(options.wildcards, 0) && structure.subleagues.length % 2 === 0 && + getDuplicateTeams(structure).size === 0 && structure.subleagues.every((subleague, si) => subleague.name !== "" && @@ -314,9 +327,27 @@ function validNumber(value: string, min = 1) { return !isNaN(Number(value)) && Number(value) >= min; } +function getDuplicateTeams(structure: LeagueStructureState) { + return new Set( + structure.subleagues.map(subleague => + subleague.divisions.map(division => + division.teams.map(team => team.name) + ).reduce((prev, curr) => prev.concat(curr), []) + ).reduce((prev, curr) => prev.concat(curr), []) + .filter((val, i, arr) => arr.slice(0, i).indexOf(val) >= 0) + ) +} + // LEAGUE STRUCUTRE -function LeagueStructre(props: {state: LeagueStructureState, dispatch: React.Dispatch, deletedTeams: string[], showError: boolean}) { +function LeagueStructre(props: { + state: LeagueStructureState, + dispatch: React.Dispatch, + deletedTeams: Set, + duplicateTeams: Set, + showError: boolean + }) { + let nSubleagues = props.state.subleagues.length; let nDivisions = props.state.subleagues[0].divisions.length; return ( @@ -324,8 +355,18 @@ function LeagueStructre(props: {state: LeagueStructureState, dispatch: React.Dis
- - + +
{ (nSubleagues+1) * (nDivisions+1) < MAX_SUBLEAGUE_DIVISION_TOTAL ? : @@ -380,7 +421,14 @@ function SubleageHeader(props: {state: SubleagueState, canDelete: boolean, dispa ); } -function Divisions(props: {subleagues: SubleagueState[], dispatch: React.Dispatch, deletedTeams: string[], showError: boolean}) { +function Divisions(props: { + subleagues: SubleagueState[], + dispatch: React.Dispatch, + deletedTeams: Set, + duplicateTeams: Set, + showError: boolean + }) { + return (<> {props.subleagues[0].divisions.map((val, di) => (
@@ -393,11 +441,16 @@ function Divisions(props: {subleagues: SubleagueState[], dispatch: React.Dispatc {props.subleagues.map((subleague, si) => (
- - props.dispatch(Object.assign({subleague_index: si, division_index: di}, action)) - } - isDuplicate={subleague.divisions.slice(0, di).some(val => val.name === subleague.divisions[di].name)} - deletedTeams={props.deletedTeams} showError={props.showError} /> + + props.dispatch(Object.assign({subleague_index: si, division_index: di}, action)) + } + isDuplicate={subleague.divisions.slice(0, di).some(val => val.name === subleague.divisions[di].name)} + deletedTeams={props.deletedTeams} + duplicateTeams={props.duplicateTeams} + showError={props.showError} + />
))} @@ -410,7 +463,8 @@ function Division(props: { state: DivisionState, dispatch: (action: DistributiveOmit) => void, isDuplicate: boolean, - deletedTeams: string[], + deletedTeams: Set, + duplicateTeams: Set, showError: boolean }) { @@ -442,24 +496,27 @@ function Division(props: { }/>
{props.showError ? divisionErr : ""}
- {props.state.teams.map((team, i) => { - let showDeleted = props.showError && props.deletedTeams.includes(team.name) - return (<> -
-
{team.name}
- -
-
{showDeleted ? "This team was deleted" : ""}
- ) - })} - { props.state.teams.length < MAX_TEAMS_PER_DIVISION ? <> + {props.state.teams.map((team, i) => ( + + ))} + {props.state.teams.length < MAX_TEAMS_PER_DIVISION ? <>
{ - let params = new URLSearchParams({query: e.target.value, page_len: '5', page_num: '0'}); - fetch("/api/teams/search?" + params.toString()) - .then(response => response.json()) - .then(data => setSearchResults(data)); + if (e.target.value === "") { + setSearchResults([]); + } else { + let params = new URLSearchParams({query: e.target.value, page_len: '5', page_num: '0'}); + fetch("/api/teams/search?" + params.toString()) + .then(response => response.json()) + .then(data => setSearchResults(data)); + } setNewName(e.target.value); }}/>
@@ -485,6 +542,30 @@ function Division(props: { ); } +function Team(props: { + state: TeamState, + dispatch: (action: DistributiveOmit) => void, + isDuplicate: boolean, + isDeleted: boolean, + showError: boolean + }) { + + let errMsg = + props.isDeleted ? + "This team was deleted" : + props.isDuplicate ? + "Each team in a league must be unique" : + ""; + + return (<> +
+
{props.state.name}
+ +
+
{props.showError ? errMsg : ""}
+ ); +} + // LEAGUE OPTIONS function LeagueOptions(props: {state: LeagueOptionsState, dispatch: React.Dispatch, showError: boolean}) { diff --git a/simmadome/src/Game.css b/simmadome/src/Game.css index ca73b4d..8388824 100644 --- a/simmadome/src/Game.css +++ b/simmadome/src/Game.css @@ -171,6 +171,8 @@ .update_text { text-align: start; + margin-top: 0.25rem; + margin-bottom: 0.25rem; } .field { From 671a5c2fdd237bb8cc579e7beb5f19b9c9ae45e4 Mon Sep 17 00:00:00 2001 From: Sakimori Date: Sat, 23 Jan 2021 01:27:59 -0500 Subject: [PATCH 4/5] fixed some divisions not getting interdivision matchups --- leagues.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/leagues.py b/leagues.py index 422c261..96ab48e 100644 --- a/leagues.py +++ b/leagues.py @@ -167,7 +167,7 @@ class league_structure(object): if division_max % 2 != 0: divisions.append(["OFF" for i in range(0, division_max)]) else: - last_div = divisions.pop + last_div = divisions.pop() divs_a = list(chain(divisions[int(len(divisions)/2):]))[0] if last_div is not None: From ccede38d493b6e47b9d5df47a191f705d50b150c Mon Sep 17 00:00:00 2001 From: Sakimori Date: Sat, 23 Jan 2021 01:43:49 -0500 Subject: [PATCH 5/5] closes #172 --- the_prestige.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/the_prestige.py b/the_prestige.py index 5fb7ea2..dd4d13c 100644 --- a/the_prestige.py +++ b/the_prestige.py @@ -997,6 +997,7 @@ client = discord.Client() gamesarray = [] active_tournaments = [] active_leagues = [] +active_standings = {} setupmessages = {} thread1 = threading.Thread(target=main_controller.update_loop) @@ -1827,9 +1828,11 @@ async def league_day_watcher(channel, league, games_list, filter_url, last = Fal wait_seconds = (next_start - now).seconds leagues.save_league(league) - await channel.send(embed=league.standings_embed()) + if league in active_standings.keys(): + await active_standings[league].unpin() + active_standings[league] = await channel.send(embed=league.standings_embed()) + active_standings[league].pin() await channel.send(f"The day {league.day} games for the {league.name} will start in {math.ceil(wait_seconds/60)} minutes.") - leagues.save_league(league) await asyncio.sleep(wait_seconds) await channel.send(f"A {league.name} series is continuing now at {filter_url}") games_list = await continue_league_series(league, queued_games, games_list, series_results, missed) @@ -1837,7 +1840,10 @@ async def league_day_watcher(channel, league, games_list, filter_url, last = Fal league.active = False if league.autoplay == 0 or config()["game_freeze"]: #if number of series to autoplay has been reached - await channel.send(embed=league.standings_embed()) + if league in active_standings.keys(): + await active_standings[league].unpin() + active_standings[league] = await channel.send(embed=league.standings_embed()) + active_standings[league].pin() await channel.send(f"The {league.name} is no longer autoplaying.") if config()["game_freeze"]: await channel.send("Patch incoming.") @@ -1901,7 +1907,10 @@ async def league_day_watcher(channel, league, games_list, filter_url, last = Fal wait_seconds = (next_start - now).seconds leagues.save_league(league) - await channel.send(embed=league.standings_embed()) + if league in active_standings.keys(): + await active_standings[league].unpin() + active_standings[league] = await channel.send(embed=league.standings_embed()) + active_standings[league].pin() await channel.send(f"""This {league.name} series is now complete! The next series will be starting in {int(wait_seconds/60)} minutes.""") await asyncio.sleep(wait_seconds)