add shareeable game links

This commit is contained in:
Elijah Steres 2021-01-02 06:21:53 -05:00
parent 5bd45bacf8
commit 9a70ec02c1
12 changed files with 312 additions and 254 deletions

View File

@ -12,9 +12,14 @@ def index():
return render_template("index.html") return render_template("index.html")
@app.route('/league') @app.route('/league')
def league(): def league_page():
return render_template("index.html", league=request.args['name']) return render_template("index.html", league=request.args['name'])
@app.route('/game')
def game_page():
return render_template("game.html")
thread2 = threading.Thread(target=socketio.run,args=(app,'0.0.0.0')) thread2 = threading.Thread(target=socketio.run,args=(app,'0.0.0.0'))
thread2.start() thread2.start()
@ -125,14 +130,15 @@ def update_loop():
state["update_pause"] -= 1 state["update_pause"] -= 1
global data_to_send global data_to_send
template = jinja2.Environment(loader=jinja2.FileSystemLoader('templates')).get_template('game.html')
data_to_send = [] data_to_send = []
template = jinja2.Environment(loader=jinja2.FileSystemLoader('templates')).get_template('game_box.html')
for timestamp in game_states: for timestamp in game_states:
data_to_send.append({ data_to_send.append({
'timestamp' : timestamp, 'timestamp' : timestamp,
'league' : game_states[timestamp]['leagueoruser'] if game_states[timestamp]['is_league'] else '', 'league' : game_states[timestamp]['leagueoruser'] if game_states[timestamp]['is_league'] else '',
'state' : game_states[timestamp], 'state' : game_states[timestamp],
'html' : template.render(state=game_states[timestamp]) 'html' : template.render(state=game_states[timestamp], timestamp=timestamp)
}) })
socketio.emit("states_update", data_to_send) socketio.emit("states_update", data_to_send)

64
static/css/common.css Normal file
View File

@ -0,0 +1,64 @@
@import url('https://fonts.googleapis.com/css2?family=Alegreya&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Goldman:wght@700&display=swap');
body {
background-image: url("prism.png");
}
/* Background pattern from Toptal Subtle Patterns */
div, button, h1, h2, a {
font-family: 'Alegreya', serif;
color: white;
}
h2 {
text-align: center;
}
.link{
position: relative;
top: 10px;
}
.h1 {
margin: auto;
width: 45%;
color: white;
}
.page_header {
color: white;
font-family: 'Goldman', cursive;
}
#header {
width: 100%;
height: max-content;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
#header > .page_header {
margin: auto
}
#link_div {
text-align: right;
position: absolute;
top: 0px;
right: 30px;
}
#link_div > a {
background-color: transparent;
text-decoration: underline;
}
#link_div > a:link, #link_div > a:visited {
color: lightblue;
}
#link_div > a:hover {
color: white;
}

View File

@ -1,9 +1,3 @@
@import url('https://fonts.googleapis.com/css2?family=Alegreya&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Goldman:wght@700&display=swap');
body {
background-image: url("prism.png");
}
/* Background pattern from Toptal Subtle Patterns */
:root { :root {
--background-main: #2f3136; /*discord dark theme background-secondary - the same color as the embeds*/ --background-main: #2f3136; /*discord dark theme background-secondary - the same color as the embeds*/
@ -12,129 +6,7 @@ body {
--highlight: rgb(113, 54, 138); /*matteo purple™*/ --highlight: rgb(113, 54, 138); /*matteo purple™*/
} }
div, button {
font-family: 'Alegreya', serif;
color: white;
}
#link_div {
text-align: right;
position: absolute;
top: 0px;
right: 30px;
}
#link_div > a {
background-color: transparent;
text-decoration: underline;
}
#link_div > a:link, #link_div > a:visited {
color: lightblue;
}
#link_div > a:hover {
color: white;
}
.container {
display: grid;
grid-template-columns: repeat(3, minmax(500px, 1fr));
grid-gap: 50px 30px; /*space between rows, then columns*/
align-items: center;
justify-items: center;
grid-auto-flow: row;
}
.container > div {
min-height: 350px;
}
#header {
width: 100%;
height: 150px;
margin-bottom: 20px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
#header > .page_header {
margin: auto
}
#filters {
display: flex;
justify-content: space-around;
width: max-content;
margin-top: 10px;
}
#filters > * {
padding: 4px 8px;
margin: 0px 8px;
font-size: 16pt;
background: rgba(0,0,0,0);
}
#filters > .filter {
border-radius: 8px;
min-width: 100px;
text-align: center;
border: none;
color: white;
text-decoration: none;
}
#selected_filter {
background: rgb(113, 54, 138);
}
#footer {
display: flex;
flex-direction: column;
justify-content: center;
width: 100%;
height: 75px;
}
#footer > div {
text-align: center;
font-size: 20px;
position: relative;
top: 5px;
}
.link{
position: relative;
top: 10px;
}
.h1 {
margin: auto;
width: 45%;
color: white;
font-family: 'Alegreya', serif;
}
.page_header {
color: white;
font-family: 'Goldman', cursive;
}
.emptyslot {
border: 2px dashed white;
border-radius: 15px;
align-self: stretch;
justify-self: stretch;
text-align: center;
color: white;
}
.game { .game {
font-family: 'Alegreya', serif;
color: white;
align-self: stretch; align-self: stretch;
justify-self: stretch; justify-self: stretch;
text-align: center; text-align: center;
@ -147,13 +19,7 @@ div, button {
border-top: none; border-top: none;
border-right: none; border-right: none;
border-bottom: none; border-bottom: none;
flex: 1; height: max-content;
}
h2 {
font-family: 'Alegreya', serif;
color: white;
text-align: center;
} }
.header { .header {
@ -181,9 +47,11 @@ h2 {
display: grid; display: grid;
grid-template-columns: 66% 33%; grid-template-columns: 66% 33%;
grid-template-areas: grid-template-areas:
"teams info" "players info" "update update"; "teams info"
grid-template-rows: 90px; "players info"
grid-row-gap: 8px; "update update";
grid-template-rows: 90px 85px;
grid-row-gap: 4px;
grid-column-gap: 14px; grid-column-gap: 14px;
flex: 1; flex: 1;
} }
@ -278,7 +146,6 @@ h2 {
flex-direction: column; flex-direction: column;
justify-content: space-around; justify-content: space-around;
align-items: start; align-items: start;
height: max-content;
} }
.player { .player {
@ -286,7 +153,6 @@ h2 {
align-items: end; align-items: end;
width: 100%; width: 100%;
flex-direction: column; flex-direction: column;
margin: 5px 0px;
} }
.player_name { .player_name {
@ -295,6 +161,7 @@ h2 {
text-align: start; text-align: start;
white-space: nowrap; white-space: nowrap;
width: 95%; width: 95%;
margin-top: -4px;
} }
.update { .update {
@ -342,30 +209,6 @@ h2 {
} }
@media only screen and (max-device-width: 800px) { @media only screen and (max-device-width: 800px) {
.container {
display: grid;
grid-template-columns: repeat(1, minmax(700px, 90%));
grid-template-rows: 400px;
grid-gap: 50px 30px; /*space between rows, then columns*/
align-items: center;
justify-items: center;
grid-auto-rows: 400px;
grid-auto-flow: row;
position: absolute;
left: 50%;
transform: translate(-50%, 0);
}
.emptyslot {
border: none;
border-radius: 15px;
align-self: stretch;
justify-self: stretch;
text-align: center;
color: white;
flex: 1;
}
.batting { .batting {
font-size: 15pt; font-size: 15pt;
text-align: left; text-align: left;

9
static/css/game_page.css Normal file
View File

@ -0,0 +1,9 @@
#game_container {
margin-top: 50px;
display: flex;
justify-content: space-around;
}
.game {
width: 33%;
}

91
static/css/games_page.css Normal file
View File

@ -0,0 +1,91 @@
.container {
display: grid;
grid-template-columns: repeat(3, minmax(500px, 1fr));
grid-gap: 50px 30px; /*space between rows, then columns*/
align-items: center;
justify-items: center;
grid-auto-flow: row;
}
.container > div {
min-height: 325px;
}
#filters {
display: flex;
justify-content: center;
width: 100%;
align-items: center;
margin-top: 10px;
margin-bottom: 20px;
}
#filters > * {
padding: 4px 8px;
margin: 0px 8px;
font-size: 16pt;
background: rgba(0,0,0,0);
}
#filters > .filter {
border-radius: 8px;
min-width: 100px;
text-align: center;
border: none;
color: white;
text-decoration: none;
}
#selected_filter {
background: rgb(113, 54, 138);
}
#footer {
display: flex;
flex-direction: column;
justify-content: center;
width: 100%;
height: 75px;
}
#footer > div {
text-align: center;
font-size: 20px;
position: relative;
top: 5px;
}
.emptyslot {
border: 2px dashed white;
border-radius: 15px;
align-self: stretch;
justify-self: stretch;
text-align: center;
color: white;
}
@media only screen and (max-device-width: 800px) {
.container {
display: grid;
grid-template-columns: repeat(1, minmax(700px, 90%));
grid-template-rows: 400px;
grid-gap: 50px 30px; /*space between rows, then columns*/
align-items: center;
justify-items: center;
grid-auto-rows: 400px;
grid-auto-flow: row;
position: absolute;
left: 50%;
transform: translate(-50%, 0);
}
.emptyslot {
border: none;
border-radius: 15px;
align-self: stretch;
justify-self: stretch;
text-align: center;
color: white;
flex: 1;
}
}

View File

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

23
static/js/game_loader.js Normal file
View File

@ -0,0 +1,23 @@
$(document).ready(function (){
var socket = io.connect();
socket.on('connect', function () {
console.log("connected")
socket.emit('recieved', {});
});
socket.on("states_update", function (json) { //json is an object containing all game updates
console.log(json)
var searchparams = new URLSearchParams(window.location.search);
var exists = false;
for (game of json) {
if (searchparams.get('timestamp') == game.timestamp) {
$('.game').html(game.html);
exists = true;
}
}
if (!exists) {
// inform the user the game has ended
}
});
});

View File

@ -9,7 +9,7 @@ $(document).ready(function (){
socket.emit('recieved', {}); socket.emit('recieved', {});
}); });
socket.on("states_update", function (json) { //json is an object containing all game updates\ socket.on("states_update", function (json) { //json is an object containing all game updates
lastupdate = json; lastupdate = json;
updateGames(json, $('#selected_filter').text()); updateGames(json, $('#selected_filter').text());
updateLeagues(json); updateLeagues(json);

30
templates/base.html Normal file
View File

@ -0,0 +1,30 @@
<html lang="en-US">
<head>
<script src="//code.jquery.com/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.0.4/socket.io.js"></script>
<script type="text/javascript" async src="https://platform.twitter.com/widgets.js"></script>
<title>⚾ The Simmadome</title>
<meta property="og:title" content="Watch at the Simmadome" />
<meta property="og:description" content="The Simsim: Your players, your teams, your games." />
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@SIBR_XVI">
<link rel="stylesheet" href="/static/css/common.css">
{% block head_tags %}{% endblock %}
</head>
<body>
<div id="header">
<div id="link_div">
<a href="https://www.patreon.com/sixteen" class="link" target="_blank" rel="noopener noreferrer">Patreon</a><br />
<a href="https://github.com/Sakimori/matteo-the-prestige" class="link" target="_blank" rel="noopener noreferrer">Github</a><br />
<a href="https://twitter.com/intent/follow?screen_name=SIBR_XVI" class="link" target="_blank" rel="noopener noreferrer">Twitter</a>
</div>
<h2 class="page_header" style="font-size: 50px;">THE SIMMADOME</h2>
<h2 class="page_header">Join SIBR on <a href="https://discord.gg/UhAajY2NCW" class="link"><img src="static/discord.png" height="30"></a> to start your own games!</h2>
</div>
{% block body %}{% endblock %}
</body>
</html>

View File

@ -1,57 +1,11 @@
{% macro base(number) -%} {% extends "base.html" %}
src={% if state.bases[number] %}"/static/img/base_filled.png" alt="{{state.bases[number]}}"{% else %}"/static/img/base_empty.png"{% endif %} {% block head_tags %}
{%- endmacro %} <link rel="stylesheet" href="/static/css/game.css">
{% macro out(number) -%} <link rel="stylesheet" href="/static/css/game_page.css">
{% if number <= state.outs %}/static/img/out_out.png{% else %}/static/img/out_in.png{% endif %} <script type="text/javascript" src="static/js/game_loader.js"></script>
{%- endmacro %} {% endblock %}
{% block body %}
<div class="header"> <div id="game_container">
<div class="inning">Inning: {% if state.display_top_of_inning == true %}🔼{% else %}🔽{% endif %} {{ state.display_inning }}/{{ state.max_innings }}</div> <div class="game"></div>
<div class="weather">{{ state.weather_emoji }} {{ state.weather_text }}</div>
</div>
<div class="body">
<div class="teams">
<div class="team">
<div class="team_name">{{ state.away_name }}</div>
<div class="score">{{ state.away_score }}</div>
</div>
<div class="team">
<div class="team_name">{{ state.home_name }}</div>
<div class="score">{{ state.home_score }}</div>
</div>
</div>
<div class="info">
<div class="field">
<img class="base base_2" {{ base(2) }}/>
<div style="display: flex;">
<img class="base base_3" {{ base(3) }}/>
<img class="base base_1" {{ base(1) }}/>
</div>
</div>
<div class="outs">
<div class="outs_title">OUTS</div>
<div class="outs_count">
<img class="out" src="{{ out(1) }}"/>
<img class="out" src="{{ out(2) }}"/>
</div>
</div>
</div>
<div class="players">
<div class="player pitcher">
<div class="player_type">PITCHER</div>
<div class="player_name pitcher_name">{{ state.pitcher }}</div>
</div>
<div class="player batter">
<div class="player_type">BATTER</div>
<div class="player_name batter_name">{{ state.batter }}</div>
</div>
</div>
<div class="update">
<div class="update_emoji">{{ state.update_emoji }}</div>
<div class="update_text">{{ state.update_text }}</div>
</div>
</div>
<div class="footer">
<div class="batting">{% if state.display_top_of_inning == true %}{{ state.away_name }}{% else %}{{ state.home_name }}{% endif %} batting.</div>
<div class="leagueoruser">{{ state.leagueoruser }}</div>
</div> </div>
{% endblock %}

56
templates/game_box.html Normal file
View File

@ -0,0 +1,56 @@
{% macro base(number) -%}
src={% if state.bases[number] %}"/static/img/base_filled.png" alt="{{state.bases[number]}}"{% else %}"/static/img/base_empty.png"{% endif %}
{%- endmacro %}
{% macro out(number) -%}
{% if number <= state.outs %}/static/img/out_out.png{% else %}/static/img/out_in.png{% endif %}
{%- endmacro %}
<div class="header">
<div class="inning">Inning: {% if state.display_top_of_inning == true %}🔼{% else %}🔽{% endif %} {{ state.display_inning }}/{{ state.max_innings }}</div>
<div class="weather">{{ state.weather_emoji }} {{ state.weather_text }}</div>
</div>
<div class="body">
<div class="teams">
<div class="team">
<div class="team_name">{{ state.away_name }}</div>
<div class="score">{{ state.away_score }}</div>
</div>
<div class="team">
<div class="team_name">{{ state.home_name }}</div>
<div class="score">{{ state.home_score }}</div>
</div>
</div>
<div class="info">
<div class="field">
<img class="base base_2" {{ base(2) }}/>
<div style="display: flex;">
<img class="base base_3" {{ base(3) }}/>
<img class="base base_1" {{ base(1) }}/>
</div>
</div>
<div class="outs">
<div class="outs_title">OUTS</div>
<div class="outs_count">
<img class="out" src="{{ out(1) }}"/>
<img class="out" src="{{ out(2) }}"/>
</div>
</div>
</div>
<div class="players">
<div class="player pitcher">
<div class="player_type">PITCHER</div>
<div class="player_name pitcher_name">{{ state.pitcher }}</div>
</div>
<div class="player batter">
<div class="player_type">BATTER</div>
<div class="player_name batter_name">{{ state.batter }}</div>
</div>
</div>
<div class="update">
<div class="update_emoji">{{ state.update_emoji }}</div>
<div class="update_text">{{ state.update_text }}</div>
</div>
</div>
<div class="footer">
<div class="batting">{% if state.display_top_of_inning == true %}{{ state.away_name }}{% else %}{{ state.home_name }}{% endif %} batting.</div>
<div class="leagueoruser">{{ state.leagueoruser }} (<a href="/game?timestamp={{ timestamp }}">share</a>)</div>
</div>

View File

@ -1,32 +1,15 @@
<html lang="en-US"> {% extends "base.html" %}
<head> {% block head_tags %}
<script src="//code.jquery.com/jquery-3.5.1.min.js"></script> <link rel="stylesheet" href="/static/css/games_page.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.0.4/socket.io.js"></script> <link rel="stylesheet" href="/static/css/game.css">
<script type="text/javascript" async src="https://platform.twitter.com/widgets.js"></script> <script type="text/javascript" src="static/js/grid_loader.js"></script>
<script type="text/javascript" src="static/loader.js"></script> {% endblock %}
<link rel="stylesheet" href="/static/games_page.css"> {% block body %}
<title>⚾ The Simmadome</title>
<meta property="og:title" content="Watch at the Simmadome" />
<meta property="og:description" content="The Simsim: Your players, your teams, your games." />
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@SIBR_XVI">
</head>
<body>
<div id="header">
<div id="link_div">
<a href="https://www.patreon.com/sixteen" class="link" target="_blank" rel="noopener noreferrer">Patreon</a><br />
<a href="https://github.com/Sakimori/matteo-the-prestige" class="link" target="_blank" rel="noopener noreferrer">Github</a><br />
<a href="https://twitter.com/intent/follow?screen_name=SIBR_XVI" class="link" target="_blank" rel="noopener noreferrer">Twitter</a>
</div>
<h2 class="page_header" style="font-size: 50px;">THE SIMMADOME</h2>
<h2 class="page_header">Join SIBR on <a href="https://discord.gg/UhAajY2NCW" class="link"><img src="static/discord.png" height="30"></a> to start your own games!</h2>
<div id="filters"> <div id="filters">
<div>Filter:</div> <div>Filter:</div>
<button class="filter" {% if not league %}id="selected_filter"{% endif %}>All</button> <button class="filter" {% if not league %}id="selected_filter"{% endif %}>All</button>
{% if league %}<button class="filter" id="selected_filter">{{ league }}</button>{% endif %} {% if league %}<button class="filter" id="selected_filter">{{ league }}</button>{% endif %}
</div> </div>
</div>
<section class="container" id="container"> <section class="container" id="container">
<div class="emptyslot"></div> <div class="emptyslot"></div>
<div class="emptyslot"></div> <div class="emptyslot"></div>
@ -35,5 +18,4 @@
<div id="footer"> <div id="footer">
<div></div> <div></div>
</div> </div>
</body> {% endblock %}
</html>