diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0191d89 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +SOURCES = $(wildcard ./simmadome/src/*) $(wildcard ./simmadome/public/*) +OUTPUTS = $(wildcard ./simmadome/build/*) + +.PHONY: run frontend + +run: $(OUTPUTS) + python3 the_prestige.py + +frontend: + (cd simmadome && npm run build) + +$(OUTPUTS): $(SOURCES) + (cd simmadome && npm run build) \ No newline at end of file diff --git a/README.md b/README.md index 04105fa..9389d03 100644 --- a/README.md +++ b/README.md @@ -23,26 +23,26 @@ accepting pull requests, check the issues for to-dos. - then another blank line seperating your batters and your pitchers. - the final lines are the names of the pitchers in your rotation, rotations can contain any number of pitchers between 1 and 8. - if you did it correctly, you'll get a team embed with a prompt to confirm. hit the 👍 and your team will be saved! -- m;deleteteam [teamname] (requires team ownership) +- m;deleteteam [teamname] \(requires team ownership) - allows you to delete the team with the provided name. you'll get an embed with a confirmation to prevent accidental deletions. hit the 👍 and your team will be deleted. - m;import - imports an onomancer collection as a new team. you can use the new onomancer simsim setting to ensure compatibility. similarly to saveteam, you'll get a team embed with a prompt to confirm, hit the 👍 and your team will be saved! #### editing (all of these commands require ownership and exact spelling of the team name): -- m;addplayer batter/pitcher [team name] [player name] +- m;addplayer batter/pitcher [team name] \[player name] - adds a new player to the end of your team, either in the lineup or the rotation depending on which version you use. use addplayer batter or addplayer pitcher at the top of a list with entries separated by new lines: - the name of the team you want to add the player to. - the name of the player you want to add to the team. -- m;moveplayer [team name] [player name] [new lineup/rotation position number] +- m;moveplayer [team name] \[player name] [new lineup/rotation position number] - moves a player within your lineup or rotation. if you want to instead move a player from your rotation to your lineup or vice versa, use m;swapsection instead. use this command at the top of a list with entries separated by new lines: - the name of the team you want to move the player on. - the name of the player you want to move. - the position you want to move them too, indexed with 1 being the first position of the lineup or rotation. all players below the specified position in the lineup or rotation will be pushed down. -- m;swapsection [team name] [player name] +- m;swapsection [team name] \[player name] - swaps a player from your lineup to the end of your rotation or your rotation to the end of your lineup. use this command at the top of a list with entries separated by new lines: - the name of the team you want to swap the player on. - the name of the player you want to swap. -- m;removeplayer [team name] [player name] +- m;removeplayer [team name] \[player name] - removes a player from your team. if there are multiple copies of the same player on a team this will only delete the first one. use this command at the top of a list with entries separated by new lines: - the name of the team you want to remove the player from. - the name of the player you want to remove. @@ -96,3 +96,7 @@ these folks are helping me a *ton* via patreon, and i cannot possibly thank them - Chris Denmark - Astrid Bek - Kameleon + +## Attribution + +Twemoji is copyright 2020 Twitter, Inc and other contributors; code licensed under [the MIT License](http://opensource.org/licenses/MIT), graphics licensed under [CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/) \ No newline at end of file diff --git a/simmadome/package-lock.json b/simmadome/package-lock.json index 25e47fa..cccf2db 100644 --- a/simmadome/package-lock.json +++ b/simmadome/package-lock.json @@ -2214,6 +2214,11 @@ "@types/node": "*" } }, + "@types/history": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.8.tgz", + "integrity": "sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==" + }, "@types/html-minifier-terser": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", @@ -2311,6 +2316,25 @@ "@types/react": "^16" } }, + "@types/react-router": { + "version": "5.1.10", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.10.tgz", + "integrity": "sha512-yu11Hu16CfGvvBWc7wluRlxbwfuSlY0snEntbbOTvfgMvyO6uLaEpAbnVOntr+9TNIpR++OOlPkmDcJPxOXRaQ==", + "requires": { + "@types/history": "*", + "@types/react": "*" + } + }, + "@types/react-router-dom": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.7.tgz", + "integrity": "sha512-D5mHD6TbdV/DNHYsnwBTv+y73ei+mMjrkGrla86HthE4/PVvL1J94Bu3qABU+COXzpL23T1EZapVVpwHuBXiUg==", + "requires": { + "@types/history": "*", + "@types/react": "*", + "@types/react-router": "*" + } + }, "@types/resolve": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", @@ -2347,6 +2371,11 @@ "@types/jest": "*" } }, + "@types/twemoji": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/@types/twemoji/-/twemoji-12.1.1.tgz", + "integrity": "sha512-dW1B1WHTfrWmEzXb/tp8xsZqQHAyMB9JwLwbBqkIQVzmNUI02R7lJqxUpKFM114ygNZHKA1r74oPugCAiYHt1A==" + }, "@types/uglify-js": { "version": "3.11.1", "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.11.1.tgz", @@ -7080,6 +7109,19 @@ "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" }, + "history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "requires": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -7090,6 +7132,14 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + }, "hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -9946,6 +9996,15 @@ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==" }, + "mini-create-react-context": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz", + "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==", + "requires": { + "@babel/runtime": "^7.12.1", + "tiny-warning": "^1.0.3" + } + }, "mini-css-extract-plugin": { "version": "0.11.3", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.11.3.tgz", @@ -12389,6 +12448,52 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", "integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==" }, + "react-router": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz", + "integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==", + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "mini-create-react-context": "^0.4.0", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "requires": { + "isarray": "0.0.1" + } + } + } + }, + "react-router-dom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz", + "integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==", + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.2.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + } + }, "react-scripts": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-4.0.1.tgz", @@ -12845,6 +12950,11 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, + "resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -14543,6 +14653,16 @@ "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" }, + "tiny-invariant": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", + "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" + }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -14680,6 +14800,58 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "twemoji": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/twemoji/-/twemoji-13.0.1.tgz", + "integrity": "sha512-mrTBq+XpCLM4zm76NJOjLHoQNV9mHdBt3Cba/T5lS1rxn8ArwpqE47mqTocupNlkvcLxoeZJjYSUW0DU5ZwqZg==", + "requires": { + "fs-extra": "^8.0.1", + "jsonfile": "^5.0.0", + "twemoji-parser": "13.0.0", + "universalify": "^0.1.2" + }, + "dependencies": { + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "dependencies": { + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + } + } + }, + "jsonfile": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-5.0.0.tgz", + "integrity": "sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^0.1.2" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + } + } + }, + "twemoji-parser": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-13.0.0.tgz", + "integrity": "sha512-zMaGdskpH8yKjT2RSE/HwE340R4Fm+fbie4AaqjDa4H/l07YUmAvxkSfNl6awVWNRRQ0zdzLQ8SAJZuY5MgstQ==" + }, "type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", @@ -15018,6 +15190,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/simmadome/package.json b/simmadome/package.json index 2d10414..e37f8ef 100644 --- a/simmadome/package.json +++ b/simmadome/package.json @@ -11,11 +11,17 @@ "@types/node": "^12.19.12", "@types/react": "^16.14.2", "@types/react-dom": "^16.9.10", + "@types/react-router": "^5.1.10", + "@types/react-router-dom": "^5.1.7", "@types/socket.io-client": "^1.4.34", + "@types/twemoji": "^12.1.1", "react": "^17.0.1", "react-dom": "^17.0.1", + "react-router": "^5.2.0", + "react-router-dom": "^5.2.0", "react-scripts": "4.0.1", "socket.io-client": "^3.0.5", + "twemoji": "^13.0.1", "typescript": "^4.1.3", "web-vitals": "^0.2.4" }, diff --git a/simmadome/public/favicon.ico b/simmadome/public/favicon.ico deleted file mode 100644 index a11777c..0000000 Binary files a/simmadome/public/favicon.ico and /dev/null differ diff --git a/simmadome/public/index.html b/simmadome/public/index.html index aa069f2..ddec811 100644 --- a/simmadome/public/index.html +++ b/simmadome/public/index.html @@ -5,26 +5,13 @@ - - - - - - React App + + + + diff --git a/simmadome/public/logo192.png b/simmadome/public/logo192.png deleted file mode 100644 index fc44b0a..0000000 Binary files a/simmadome/public/logo192.png and /dev/null differ diff --git a/simmadome/public/logo512.png b/simmadome/public/logo512.png deleted file mode 100644 index a4e47a6..0000000 Binary files a/simmadome/public/logo512.png and /dev/null differ diff --git a/simmadome/public/manifest.json b/simmadome/public/manifest.json deleted file mode 100644 index 080d6c7..0000000 --- a/simmadome/public/manifest.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "short_name": "React App", - "name": "Create React App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/simmadome/src/Game.css b/simmadome/src/Game.css index 59ae0c5..1832cad 100644 --- a/simmadome/src/Game.css +++ b/simmadome/src/Game.css @@ -169,7 +169,7 @@ border-radius: 4px; align-items: center; display: flex; - justify-content: start; + justify-content: flex-start; } .update_emoji { diff --git a/simmadome/src/Game.tsx b/simmadome/src/Game.tsx index f96fcd8..95024f2 100644 --- a/simmadome/src/Game.tsx +++ b/simmadome/src/Game.tsx @@ -1,4 +1,6 @@ -import { GameState } from './App'; +import { GameState } from './GamesUtil'; +import twemoji from 'twemoji'; +import React, { useRef, useLayoutEffect } from 'react'; import './Game.css'; import base_filled from './img/base_filled.png'; import base_empty from './img/base_empty.png'; @@ -6,9 +8,16 @@ import out_filled from './img/out_out.png'; import out_empty from './img/out_in.png'; function Game(props: {gameId: string, state : GameState}) { + let self: React.MutableRefObject = useRef(null); + useLayoutEffect(() => { + if (self.current) { + twemoji.parse(self.current); + } + }) + let state = props.state; return ( -
+
Inning: {state.display_top_of_inning ? "🔼" : "🔽"} {state.display_inning}/{state.max_innings}
{state.title}
diff --git a/simmadome/src/GamePage.css b/simmadome/src/GamePage.css new file mode 100644 index 0000000..69f0cc7 --- /dev/null +++ b/simmadome/src/GamePage.css @@ -0,0 +1,7 @@ +#game_container { + margin-top: 3rem; + margin-left: 1rem; + margin-right: 1rem; + display: flex; + justify-content: space-around; +} \ No newline at end of file diff --git a/simmadome/src/GamePage.tsx b/simmadome/src/GamePage.tsx new file mode 100644 index 0000000..76ef9b6 --- /dev/null +++ b/simmadome/src/GamePage.tsx @@ -0,0 +1,24 @@ +import React, {useState} from 'react'; +import {GameState, useListener} from './GamesUtil'; +import './GamePage.css'; +import Game from './Game'; + +function GamePage() { + let searchparams = new URLSearchParams(window.location.search); + let gameId = searchparams.get('id'); + + let [games, setGames] = useState(new Array<[string, GameState]>()); + useListener((newGames) => setGames(newGames)); + + let game = games.find((game) => game[0] === gameId) + return ( +
+ { game ? + : + "The game you're looking for either doesn't exist or has already ended." + } +
+ ); +} + +export default GamePage; \ No newline at end of file diff --git a/simmadome/src/App.css b/simmadome/src/GamesPage.css similarity index 100% rename from simmadome/src/App.css rename to simmadome/src/GamesPage.css diff --git a/simmadome/src/App.tsx b/simmadome/src/GamesPage.tsx similarity index 58% rename from simmadome/src/App.tsx rename to simmadome/src/GamesPage.tsx index 58dc594..236fc48 100644 --- a/simmadome/src/App.tsx +++ b/simmadome/src/GamesPage.tsx @@ -1,67 +1,47 @@ import React, {useState, useRef, useEffect, useLayoutEffect} from 'react'; -import io from 'socket.io-client'; -import './App.css'; +import {GameState, GameList, useListener} from './GamesUtil'; +import {Link} from 'react-router-dom'; +import './GamesPage.css'; import Game from './Game'; -interface GameState { - bases: (string | null)[]; - outs: number; - display_top_of_inning: boolean - display_inning: number - max_innings: number - title: string - weather_emoji: string - weather_text: string - away_name: string - away_score: number - home_name: string - home_score: number - pitcher: string - batter: string - update_emoji: string - update_text: string - is_league: boolean - leagueoruser: string -} +function GamesPage() { + let [search, setSearch] = useState(window.location.search); + useEffect(() => { + setSearch(window.location.search); + }, [window.location.search]) -type GameList = ([id: string, game: GameState] | null)[]; - -function App(props: {filter: string | null, gameId: string | null}) { + let searchparams = new URLSearchParams(search); + let filter = searchparams.get('league') ?? "" let [games, setGames] = useState(new Array<[string, GameState]>()); - let [filter, setFilter] = useState(""); useListener(setGames); - let filters: string[] = []; - games.forEach((game, id) => { if (game[1].is_league && !filters.includes(game[1].leagueoruser)) { filters.push(game[1].leagueoruser) }}); + 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(new Array<(string | null)>()); let filterGames = games.filter((game, i) => filter === "" || game[1].leagueoruser === filter); - updateList(gameList.current, filterGames); + updateList(gameList.current, filterGames, searchparams.get('gameId')); return ( -
- {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][]) { +function updateList(gameList: (string | null)[], games: [string, GameState][], firstGame: string | null) { + // insert firstGame into first slot, if necessary + if (firstGame !== null && games.find((game) => game[0] === firstGame)) { + if (gameList.includes(firstGame)) { + gameList[gameList.indexOf(firstGame)] = null; + } + gameList[0] = firstGame; + } //remove games no longer present for (let i = 0; i < gameList.length; i ++) { @@ -88,14 +68,15 @@ function updateList(gameList: (string | null)[], games: [string, GameState][]) { } } -function Filters (props: {filterList: string[], selectedFilter: string, onSelectNewFilter: (newFilter: string) => void}) { +function Filters (props: {filterList: string[], selectedFilter: string}) { function Filter(innerprops: {title: string, filter:string} ) { + let search = new URLSearchParams(); + search.append('league', innerprops.filter); + return ( - + + {innerprops.title} + ); } @@ -127,29 +108,27 @@ function Grid(props: { gameList: GameList }) { return 3; } } - + + //set num cols after page loads useLayoutEffect(() => { setNumcols(getCols()); }, []) + //set num cols on page resize useEffect(() => { window.addEventListener('resize', (event) => { setNumcols(getCols()); }) }) - - let slots = newList.map((game) => { - if (game) { - return - } else { - return
- } - }) - + let emptyKey = 0; return (
- {slots.map((elem) =>
{elem}
)} + {newList.map((game) => ( +
+ {game ? :
} +
+ ))}
); } @@ -163,5 +142,4 @@ function Footer(props: { has_games: boolean }) { ); } -export default App; -export type { GameState }; \ No newline at end of file +export default GamesPage; \ No newline at end of file diff --git a/simmadome/src/GamesUtil.tsx b/simmadome/src/GamesUtil.tsx new file mode 100644 index 0000000..8002c02 --- /dev/null +++ b/simmadome/src/GamesUtil.tsx @@ -0,0 +1,39 @@ +import {useLayoutEffect} from 'react'; +import io from 'socket.io-client'; + +interface GameState { + bases: (string | null)[]; + outs: number; + display_top_of_inning: boolean + display_inning: number + max_innings: number + title: string + weather_emoji: string + weather_text: string + away_name: string + away_score: number + home_name: string + home_score: number + pitcher: string + batter: string + update_emoji: string + update_text: string + is_league: boolean + leagueoruser: string +} + +type GameList = ([id: string, game: GameState] | null)[]; + + +// 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) => { + useLayoutEffect(() => { + let socket = url ? io(url) : io(); + socket.on('connect', () => socket.emit('recieved', {})); + socket.on('states_update', onUpdate); + return () => {socket.disconnect()}; + }, [url]) +} + +export { useListener }; +export type { GameState, GameList }; \ No newline at end of file diff --git a/simmadome/src/index.css b/simmadome/src/index.css index 922dcd5..c08c49e 100644 --- a/simmadome/src/index.css +++ b/simmadome/src/index.css @@ -65,5 +65,8 @@ h2 { } img.emoji { - height: 14px; + height: 1em; + width: 1em; + margin: 0 .05em 0 .1em; + vertical-align: -0.1em; } \ No newline at end of file diff --git a/simmadome/src/index.tsx b/simmadome/src/index.tsx index cb02d92..9694cdd 100644 --- a/simmadome/src/index.tsx +++ b/simmadome/src/index.tsx @@ -1,19 +1,25 @@ import React from 'react'; import ReactDOM from 'react-dom'; +import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'; import './index.css'; -import App from './App'; +import GamesPage from './GamesPage'; +import GamePage from './GamePage'; import discordlogo from "./img/discord.png"; import reportWebVitals from './reportWebVitals'; ReactDOM.render( -
- + +
+ + }/> + }/> + + , document.getElementById('root') ); - function Header() { return (