mirror of
https://github.com/Fluffy-Bean/GameExpo23.git
synced 2025-05-14 14:22:16 +00:00
Remake nav bar to work with more filters
Add new background work on fixing tables
This commit is contained in:
parent
1027361601
commit
459aefb124
15 changed files with 248 additions and 191 deletions
2
.env
2
.env
|
@ -5,5 +5,5 @@ POSTGRES_USER = leggy
|
|||
POSTGRES_PASSWORD = leggy
|
||||
POSTGRES_DB = leggy
|
||||
|
||||
THE_FRONT_ROOMS_DOMAIN = tfr.leggy.dev
|
||||
THE_FRONT_ROOMS_DOMAIN = thefrontroomsga.me
|
||||
THE_FRONT_ROOMS_SECRETE_KEY = leggy
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
Gunicorn
|
||||
psycopg2-binary
|
||||
shortuuid
|
||||
Flask
|
||||
Flask-SQLAlchemy
|
||||
Flask-Migrate
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import uuid
|
||||
import shortuuid
|
||||
|
||||
from flask import Blueprint, request, jsonify
|
||||
from flask_login import login_required, current_user
|
||||
|
||||
from server.models import Tokens, Scores
|
||||
from server.extensions import db
|
||||
from server.config import GAME_VERSION, GAME_VERSIONS, GAME_DIFFICULTIES, USER_MAX_TOKENS
|
||||
|
||||
|
||||
blueprint = Blueprint("api", __name__, url_prefix="/api")
|
||||
|
@ -21,7 +22,7 @@ def tokens():
|
|||
token = Tokens.query.filter_by(id=token_id).first()
|
||||
if not token:
|
||||
return jsonify({"error": "Token not found!"}), 404
|
||||
if token.holder != current_user.id:
|
||||
if token.user_id != current_user.id:
|
||||
return jsonify({"error": "You do not own this token!"}), 403
|
||||
|
||||
db.session.delete(token)
|
||||
|
@ -29,58 +30,56 @@ def tokens():
|
|||
|
||||
return jsonify({"success": "Token deleted!"}), 200
|
||||
elif request.method == "POST":
|
||||
if len(Tokens.query.filter_by(holder=current_user.id).all()) >= 5:
|
||||
return jsonify({"error": "You already have 5 tokens!"}), 403
|
||||
if len(Tokens.query.filter_by(user_id=current_user.id).all()) >= USER_MAX_TOKENS:
|
||||
return jsonify({"error": f"You already have {USER_MAX_TOKENS} tokens!"}), 403
|
||||
|
||||
token = Tokens(token=str(uuid.uuid4()), holder=current_user.id)
|
||||
new_string = str(shortuuid.ShortUUID().random(length=20))
|
||||
token = Tokens(token=new_string, user_id=current_user.id)
|
||||
db.session.add(token)
|
||||
db.session.commit()
|
||||
|
||||
return jsonify({"success": "Token added!"}), 200
|
||||
|
||||
|
||||
@blueprint.route("/post", methods=["GET", "POST"])
|
||||
@blueprint.route("/post", methods=["POST"])
|
||||
def post():
|
||||
if request.method == "GET":
|
||||
return """
|
||||
<form method="POST">
|
||||
<input name="score">
|
||||
<input name="difficulty">
|
||||
<input name="token">
|
||||
<button type="submit">Sub</button>
|
||||
</form>
|
||||
"""
|
||||
|
||||
form = request.form
|
||||
errors = []
|
||||
|
||||
if not form:
|
||||
return "Invalid form", 400
|
||||
errors += "No form data provided!"
|
||||
if not form["token"]:
|
||||
return "Invalid authentication", 401
|
||||
errors += "No token provided!"
|
||||
if not form["version"]:
|
||||
errors += "No version provided!"
|
||||
|
||||
# if not isinstance(form["score"], int):
|
||||
# return "Score must be an integer", 400
|
||||
if int(form["score"]) < 0:
|
||||
return "Score must be greater than 0", 400
|
||||
if int(form["difficulty"]) not in [0, 1, 2, 3, 4]:
|
||||
# 0 = Easy, Level 1
|
||||
# 1 = Easy, Level 2
|
||||
# 2 = Easy, Level 3
|
||||
# 3 = Normal
|
||||
# 4 = Hard
|
||||
return "Invalid difficulty", 400
|
||||
if errors:
|
||||
return jsonify(errors), 400
|
||||
|
||||
if token := Tokens.query.filter_by(token=form["token"]).first():
|
||||
# Yupeee, authenticated
|
||||
score = Scores(
|
||||
score=int(form["score"]),
|
||||
difficulty=int(form["difficulty"]),
|
||||
scorer=token.holder,
|
||||
)
|
||||
db.session.add(score)
|
||||
db.session.commit()
|
||||
try:
|
||||
int(form["score"])
|
||||
int(form["difficulty"])
|
||||
except TypeError:
|
||||
errors += "Invalid score and difficulty must be valid numbers!"
|
||||
|
||||
return "Success!", 200
|
||||
if int(form["difficulty"]) not in GAME_DIFFICULTIES:
|
||||
errors += "Invalid difficulty!"
|
||||
|
||||
# L no authentication :3
|
||||
return "Authentication failed", 401
|
||||
token_data = Tokens.query.filter_by(token=form["token"]).first()
|
||||
if not token_data:
|
||||
errors += "Authentication failed!"
|
||||
|
||||
if errors:
|
||||
return jsonify(errors), 400
|
||||
|
||||
score = Scores(
|
||||
score=int(form["score"]),
|
||||
difficulty=int(form["difficulty"]),
|
||||
version=form["version"],
|
||||
user_id=token_data.user_id,
|
||||
)
|
||||
|
||||
db.session.add(score)
|
||||
db.session.commit()
|
||||
|
||||
return "Success!", 200
|
||||
|
|
|
@ -31,7 +31,7 @@ def account():
|
|||
if action == "password":
|
||||
flash("Insert password change function", "error")
|
||||
|
||||
token_list = Tokens.query.filter_by(holder=current_user.id).all()
|
||||
token_list = Tokens.query.filter_by(user_id=current_user.id).all()
|
||||
return render_template("account.html", token_list=token_list)
|
||||
|
||||
|
||||
|
|
|
@ -13,3 +13,9 @@ SQLALCHEMY_POOL_RECYCLE = 621
|
|||
|
||||
MIGRATION_DIR = "/data/storage/migrations"
|
||||
INSTANCE_DIR = "/data/storage/instance"
|
||||
|
||||
GAME_VERSION = "alpha"
|
||||
GAME_VERSIONS = ["alpha"]
|
||||
GAME_DIFFICULTIES = [0, 1, 2, 3, 4]
|
||||
|
||||
USER_MAX_TOKENS = 3
|
||||
|
|
|
@ -4,17 +4,16 @@ Database models for the server
|
|||
import uuid
|
||||
from flask_login import UserMixin
|
||||
from server.extensions import db
|
||||
from server.config import GAME_VERSION
|
||||
|
||||
|
||||
class Scores(db.Model):
|
||||
"""
|
||||
Post table
|
||||
Scores supports anonymous posting, and instead just wants to post a score,
|
||||
then the username must be provided.Otherwise, it's grabbed from the user table
|
||||
then the username must be provided. Otherwise, it's grabbed from the user
|
||||
table
|
||||
"""
|
||||
|
||||
__tablename__ = "scores"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
|
||||
score = db.Column(db.Float, nullable=False)
|
||||
|
@ -24,17 +23,34 @@ class Scores(db.Model):
|
|||
nullable=False,
|
||||
server_default=db.func.now(),
|
||||
)
|
||||
posted_at = db.Column(
|
||||
db.DateTime,
|
||||
nullable=False,
|
||||
server_default=db.func.now(),
|
||||
)
|
||||
|
||||
scorer = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
|
||||
version = db.Column(db.String, default=GAME_VERSION)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey("users.id", use_alter=True))
|
||||
|
||||
|
||||
class Tokens(db.Model):
|
||||
"""
|
||||
Token table
|
||||
"""
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey("users.id", use_alter=True))
|
||||
token = db.Column(db.String, nullable=False, unique=True)
|
||||
created_at = db.Column(
|
||||
db.DateTime,
|
||||
nullable=False,
|
||||
server_default=db.func.now(),
|
||||
)
|
||||
|
||||
|
||||
class Users(db.Model, UserMixin):
|
||||
"""
|
||||
User table
|
||||
"""
|
||||
|
||||
__tablename__ = "users"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
alt_id = db.Column(db.String, nullable=False, unique=True)
|
||||
|
||||
|
@ -46,25 +62,9 @@ class Users(db.Model, UserMixin):
|
|||
server_default=db.func.now(),
|
||||
)
|
||||
|
||||
scores = db.relationship("Scores", backref="user", lazy=True)
|
||||
tokens = db.relationship("Tokens", backref="user", lazy=True)
|
||||
|
||||
scores = db.relationship("Scores", backref=db.backref('users', lazy=True))
|
||||
tokens = db.relationship("Tokens", backref=db.backref('users', lazy=True))
|
||||
|
||||
def get_id(self):
|
||||
return str(self.alt_id)
|
||||
|
||||
|
||||
class Tokens(db.Model):
|
||||
"""
|
||||
Token table
|
||||
"""
|
||||
|
||||
__tablename__ = "tokens"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
holder = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
|
||||
token = db.Column(db.String, nullable=False, unique=True)
|
||||
created_at = db.Column(
|
||||
db.DateTime,
|
||||
nullable=False,
|
||||
server_default=db.func.now(),
|
||||
)
|
||||
|
|
Before Width: | Height: | Size: 570 KiB After Width: | Height: | Size: 570 KiB |
BIN
TFR/server/static/background.webp
Normal file
BIN
TFR/server/static/background.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
82
TFR/server/static/sass/button.sass
Normal file
82
TFR/server/static/sass/button.sass
Normal file
|
@ -0,0 +1,82 @@
|
|||
.button
|
||||
margin: auto 0.15rem
|
||||
padding: 0.5rem 0.7rem
|
||||
|
||||
display: flex
|
||||
align-items: center
|
||||
gap: 0.5rem
|
||||
|
||||
text-decoration: none
|
||||
white-space: nowrap
|
||||
font-size: 0.9em
|
||||
|
||||
background-color: RGBA($white, 0.02)
|
||||
color: RGB($white)
|
||||
|
||||
border-radius: 2px
|
||||
border: 0 solid transparent
|
||||
|
||||
transition: background-color 0.1s ease-in-out
|
||||
|
||||
&:hover
|
||||
background-color: RGBA($white, 0.3)
|
||||
|
||||
&.primary
|
||||
background-color: RGBA($primary, 0.02)
|
||||
color: RGB($primary)
|
||||
|
||||
&:hover
|
||||
background-color: RGBA($primary, 0.3)
|
||||
|
||||
&.secondary
|
||||
background-color: RGBA($secondary, 0.02)
|
||||
color: RGB($secondary)
|
||||
|
||||
&:hover
|
||||
background-color: RGBA($secondary, 0.3)
|
||||
|
||||
> i
|
||||
font-size: 1.25em
|
||||
display: block
|
||||
|
||||
.search
|
||||
margin: auto 0.15rem
|
||||
width: 100%
|
||||
|
||||
position: relative
|
||||
display: flex
|
||||
flex-direction: row
|
||||
|
||||
> label
|
||||
padding: 0.5rem 0.7rem
|
||||
|
||||
text-decoration: none
|
||||
white-space: nowrap
|
||||
font-size: 0.9em
|
||||
|
||||
background-color: RGBA($white, 0.02)
|
||||
color: RGB($white)
|
||||
border-radius: 2px 0 0 2px
|
||||
|
||||
> input
|
||||
margin: 0
|
||||
padding: 0.5rem 0.7rem
|
||||
|
||||
width: 100%
|
||||
|
||||
text-decoration: none
|
||||
white-space: nowrap
|
||||
font-size: 0.9em
|
||||
|
||||
background-color: RGBA($white, 0.02)
|
||||
color: RGB($white)
|
||||
|
||||
border: 0 solid transparent
|
||||
border-left: 1px solid RGBA($white, 0.1)
|
||||
border-radius: 0 2px 2px 0
|
||||
|
||||
transition: background-color 0.1s ease-in-out
|
||||
|
||||
&:focus-visible, &:focus
|
||||
background-color: RGBA($white, 0.1)
|
||||
outline: 0 solid transparent
|
|
@ -5,23 +5,6 @@ $secondary: var(--secondary)
|
|||
$gold: var(--gold)
|
||||
$silver: var(--silver)
|
||||
$bronze: var(--bronze)
|
||||
$darkBlue: var(--darkBlue)
|
||||
|
||||
@mixin button($color)
|
||||
text-decoration: none
|
||||
text-align: center
|
||||
white-space: nowrap
|
||||
background-color: RGBA($color, 0.02)
|
||||
color: RGB($color)
|
||||
border-radius: 2px
|
||||
border: 0 solid transparent
|
||||
transition: background-color 0.2s ease-in-out, transform 0.1s ease-in-out
|
||||
|
||||
&:hover
|
||||
background-color: RGBA($color, 0.3)
|
||||
transform: translateY(-0.1rem)
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Merriweather:ital,wght@0,300;0,400;0,700;0,900;1,300;1,400;1,700&display=swap')
|
||||
|
||||
\:root
|
||||
--black: 21, 21, 21
|
||||
|
@ -31,7 +14,9 @@ $darkBlue: var(--darkBlue)
|
|||
--gold: 255, 222, 70
|
||||
--silver: 229, 220, 206
|
||||
--bronze: 193, 145, 69
|
||||
--darkBlue: 9, 9, 39
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Merriweather:ital,wght@0,300;0,400;0,700;0,900;1,300;1,400;1,700&display=swap')
|
||||
@import "button"
|
||||
|
||||
*
|
||||
box-sizing: border-box
|
||||
|
@ -46,17 +31,20 @@ body
|
|||
padding: 0
|
||||
display: flex
|
||||
flex-direction: row
|
||||
background-color: RGB($darkBlue)
|
||||
background-color: RGB($black)
|
||||
color: RGB($white)
|
||||
|
||||
.background
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
object-fit: cover
|
||||
position: absolute
|
||||
position: fixed
|
||||
inset: 0
|
||||
overflow: hidden
|
||||
z-index: 1
|
||||
|
||||
> img
|
||||
width: 100%
|
||||
height: 100%
|
||||
object-fit: cover
|
||||
|
||||
.app
|
||||
margin: 0 auto
|
||||
padding: 0
|
||||
|
@ -68,7 +56,7 @@ body
|
|||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
background-color: rgba($darkBlue, 0.7)
|
||||
background-color: rgba($black, 0.4)
|
||||
backdrop-filter: blur(5px)
|
||||
z-index: 2
|
||||
|
||||
|
@ -77,14 +65,15 @@ body
|
|||
|
||||
header
|
||||
padding: 1rem
|
||||
background-image: linear-gradient(to bottom, RGB(var(--black)), transparent)
|
||||
|
||||
background-color: RGBA($darkBlue, 0.7)
|
||||
|
||||
.title
|
||||
margin-bottom: 1rem
|
||||
height: auto
|
||||
> img
|
||||
margin-bottom: 1rem
|
||||
width: 100%
|
||||
height: auto
|
||||
text-align: center
|
||||
height: auto
|
||||
max-width: 100%
|
||||
|
||||
nav
|
||||
margin-top: 0.3rem
|
||||
|
@ -94,31 +83,14 @@ nav
|
|||
flex-direction: row
|
||||
justify-content: center
|
||||
|
||||
> span
|
||||
> form
|
||||
width: 100%
|
||||
display: flex
|
||||
flex-direction: row
|
||||
justify-content: center
|
||||
|
||||
> a
|
||||
margin: auto 0.15rem
|
||||
padding: 0.5rem 0.7rem
|
||||
|
||||
text-decoration: none
|
||||
white-space: nowrap
|
||||
font-size: 0.9em
|
||||
|
||||
color: RGB($primary)
|
||||
|
||||
&.button
|
||||
@include button($white)
|
||||
|
||||
&.primary
|
||||
@include button($primary)
|
||||
|
||||
&.secondary
|
||||
@include button($secondary)
|
||||
|
||||
> i
|
||||
font-size: 1.25em
|
||||
display: block
|
||||
.spacer
|
||||
width: 100%
|
||||
|
||||
.flash
|
||||
display: flex
|
||||
|
@ -133,7 +105,7 @@ nav
|
|||
width: 100%
|
||||
position: relative
|
||||
|
||||
background-color: RGB($darkBlue)
|
||||
background-color: RGB($black)
|
||||
color: RGB($primary)
|
||||
|
||||
transition: background-color 0.2s ease-in-out, padding 0.2s ease-in-out
|
||||
|
@ -230,7 +202,7 @@ main
|
|||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
background-color: rgba($darkBlue, 0.7)
|
||||
background-color: rgba($black, 0.7)
|
||||
border-radius: 2px
|
||||
|
||||
> h2
|
||||
|
@ -242,28 +214,6 @@ main
|
|||
margin: 0 0 1rem 0
|
||||
font-size: 1em
|
||||
|
||||
.button
|
||||
margin: 0
|
||||
padding: 0.5rem 0.7rem
|
||||
|
||||
text-decoration: none
|
||||
white-space: nowrap
|
||||
font-size: 0.9em
|
||||
|
||||
color: RGB($primary)
|
||||
|
||||
> i
|
||||
font-size: 1.25em
|
||||
display: block
|
||||
|
||||
@include button($white)
|
||||
|
||||
&.primary
|
||||
@include button($primary)
|
||||
|
||||
&.secondary
|
||||
@include button($secondary)
|
||||
|
||||
> table
|
||||
width: 100%
|
||||
border-collapse: collapse
|
||||
|
@ -300,7 +250,7 @@ main
|
|||
border: 1px solid RGB($white)
|
||||
border-radius: 2px
|
||||
|
||||
background-color: RGB($darkBlue)
|
||||
background-color: RGB($black)
|
||||
color: RGB($white)
|
||||
|
||||
&:focus
|
||||
|
@ -344,7 +294,7 @@ footer
|
|||
width: 100%
|
||||
display: flex
|
||||
flex-direction: row
|
||||
background-color: RGBA($darkBlue, 0.7)
|
||||
background-image: linear-gradient(to top, RGB(var(--black)), transparent)
|
||||
|
||||
> p
|
||||
margin: 0
|
||||
|
|
BIN
TFR/server/static/title.webp
Normal file
BIN
TFR/server/static/title.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
|
@ -2,8 +2,7 @@
|
|||
{% block nav %}
|
||||
<nav>
|
||||
<a href="{{ url_for('auth.account', action='logout') }}" class="button">Your Profile</a>
|
||||
<!-- This is a spacer -->
|
||||
<span></span>
|
||||
<span class="spacer"></span>
|
||||
<a href="{{ url_for('auth.account', action='logout') }}" class="button secondary">Logout</a>
|
||||
</nav>
|
||||
{% endblock %}
|
||||
|
|
|
@ -7,42 +7,39 @@
|
|||
<title>Front Rooms Highscores</title>
|
||||
|
||||
<script src="https://unpkg.com/@phosphor-icons/web"></script>
|
||||
|
||||
{% assets "scripts" %}
|
||||
<script src="{{ ASSET_URL }}"></script>
|
||||
{% endassets %}
|
||||
|
||||
{% assets "styles" %}
|
||||
<link rel="stylesheet" href="{{ ASSET_URL }}" type="text/css">
|
||||
{% endassets %}
|
||||
{% assets "scripts" %}<script src="{{ ASSET_URL }}"></script>{% endassets %}
|
||||
{% assets "styles" %}<link rel="stylesheet" href="{{ ASSET_URL }}" type="text/css">{% endassets %}
|
||||
</head>
|
||||
<body>
|
||||
<img src="{{ url_for('static', filename='bg.png') }}" alt="The Front Rooms pause menu" class="background">
|
||||
<picture class="background">
|
||||
<source srcset="{{ url_for('static', filename='background.webp') }}">
|
||||
<img src="{{ url_for('static', filename='background.png') }}" alt="The Front Rooms Level select render">
|
||||
</picture>
|
||||
<div class="app">
|
||||
<!-- Get flashed lol -->
|
||||
<div class="flash">
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<p class="{{ category }}" onclick="this.remove()">
|
||||
<span><i class="ph-bold ph-x"></i></span>
|
||||
{{ message }}
|
||||
</p>
|
||||
<p class="{{ category }}" onclick="this.remove()"><span><i class="ph-bold ph-x"></i></span>{{ message }}</p>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
|
||||
<header>
|
||||
<img src="{{ url_for('static', filename='title.png') }}" alt="The Front Rooms logo" class="title" height="82px">
|
||||
<picture class="title">
|
||||
<source srcset="{{ url_for('static', filename='title.webp') }}">
|
||||
<img src="{{ url_for('static', filename='title.png') }}" alt="The Front Rooms logo">
|
||||
</picture>
|
||||
<nav>
|
||||
<a href="{{ url_for('views.index') }}" class="button">Scores</a>
|
||||
<a href="{{ url_for('views.about') }}" class="button"><i class="ph ph-info"></i></a>
|
||||
<a href="{{ url_for('views.about') }}" class="button">About</a>
|
||||
<a href="{{ url_for('views.about') }}" class="button">Updates</a>
|
||||
|
||||
<span class="spacer"></span>
|
||||
|
||||
<a href="#" class="button"><i class="ph ph-download-simple"></i></a>
|
||||
|
||||
<!-- This is a spacer -->
|
||||
<span></span>
|
||||
|
||||
{% if current_user.is_authenticated %}
|
||||
<a href="{{ url_for('auth.account') }}" class="button primary">{{ current_user.username }}</a>
|
||||
{% else %}
|
||||
|
|
|
@ -1,14 +1,29 @@
|
|||
{% extends "base.html" %}
|
||||
{% block nav %}
|
||||
<nav>
|
||||
<a href="{{ url_for('views.index', diff=0) }}" class="button">Level 1</a>
|
||||
<a href="{{ url_for('views.index', diff=1) }}" class="button">Level 2</a>
|
||||
<a href="{{ url_for('views.index', diff=2) }}" class="button">Level 3</a>
|
||||
<a href="{{ url_for('views.index', diff=3) }}" class="button">Normal</a>
|
||||
<a href="{{ url_for('views.index', diff=4) }}" class="button">Hard</a>
|
||||
<form method="GET" action="{{ url_for('views.index') }}">
|
||||
<select name="diff" class="button">
|
||||
<option value="0" {% if diff==0 %}selected{% endif %}>Level 1</option>
|
||||
<option value="1" {% if diff==1 %}selected{% endif %}>Level 2</option>
|
||||
<option value="2" {% if diff==2 %}selected{% endif %}>Level 3</option>
|
||||
<option value="3" {% if diff==3 %}selected{% endif %}>Normal</option>
|
||||
<option value="4" {% if diff==4 %}selected{% endif %}>Hard</option>
|
||||
</select>
|
||||
|
||||
<!-- This is a spacer -->
|
||||
<span></span>
|
||||
<select name="ver" class="button">
|
||||
<option value="alpha" {% if ver=="alpha" %}selected{% endif %}>Alpha</option>
|
||||
<option value="beta" {% if ver=="beta" %}selected{% endif %}>Beta</option>
|
||||
<option value="1.0" {% if ver=="1.0" %}selected{% endif %}>1.0</option>
|
||||
<option value="1.1" {% if ver=="1.1" %}selected{% endif %}>1.1</option>
|
||||
</select>
|
||||
|
||||
<span class="search">
|
||||
<label for="user">Username</label>
|
||||
<input type="text" name="user" {% if user %}value="{{ user }}"{% endif %}/>
|
||||
</span>
|
||||
|
||||
<button class="button"><i class="ph ph-binoculars"></i></button>
|
||||
</form>
|
||||
</nav>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
|
@ -23,7 +38,7 @@
|
|||
{% for score in scores %}
|
||||
<tr>
|
||||
<td>{{ loop.index }}</td>
|
||||
<td>{{ score.scorer.username }}</td>
|
||||
<td>{{ score.user_id. }}</td>
|
||||
<td>{{ score.difficulty }}</td>
|
||||
<td>{{ score.score }}</td>
|
||||
</tr>
|
||||
|
@ -31,8 +46,8 @@
|
|||
</table>
|
||||
{% else %}
|
||||
<div class="center-text">
|
||||
<h2>No scores yet</h2>
|
||||
<p>Set some!</p>
|
||||
<h2>No scores</h2>
|
||||
<p>Set go some!</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -1,22 +1,30 @@
|
|||
from flask import Blueprint, request, render_template
|
||||
from server.models import Scores
|
||||
from flask import Blueprint, request, render_template, abort
|
||||
from server.models import Scores, Users
|
||||
from server.config import GAME_VERSION
|
||||
|
||||
|
||||
blueprint = Blueprint("views", __name__)
|
||||
|
||||
|
||||
@blueprint.route("/")
|
||||
# @cache.cached(timeout=60)
|
||||
def index():
|
||||
difficulty = request.args.get("diff", 0)
|
||||
diff_arg = request.args.get("diff", 0)
|
||||
ver_arg = request.args.get("ver", GAME_VERSION)
|
||||
user_arg = request.args.get("user", "")
|
||||
|
||||
scores = (
|
||||
Scores.query.filter_by(difficulty=difficulty)
|
||||
.order_by(Scores.score.desc())
|
||||
.limit(10)
|
||||
.all()
|
||||
)
|
||||
return render_template("scores.html", scores=scores)
|
||||
scores = Scores.query.filter_by(difficulty=diff_arg)
|
||||
|
||||
if ver_arg:
|
||||
scores.filter_by(version=ver_arg)
|
||||
if user_arg:
|
||||
if user := Users.query.filter_by(username=user_arg).first():
|
||||
scores.filter_by(user_id=user.id)
|
||||
else:
|
||||
abort(404, "User not found")
|
||||
|
||||
scores.order_by(Scores.score.desc()).limit(10).all()
|
||||
|
||||
return render_template("scores.html", scores=scores, diff=int(diff_arg), ver=ver_arg, user=user_arg)
|
||||
|
||||
|
||||
@blueprint.route("/about")
|
||||
|
|
Loading…
Add table
Reference in a new issue