Add settings page and basic settings #20
|
@ -84,7 +84,11 @@ def password_check(db: DbContext, lexicon_id: int, password: str) -> bool:
|
|||
def password_set(db: DbContext, lexicon_id: int, new_password: Optional[str]) -> None:
|
||||
"""Set or clear a lexicon's password."""
|
||||
password_hash = generate_password_hash(new_password) if new_password else None
|
||||
db(update(Lexicon).where(Lexicon.id == lexicon_id).values(password=password_hash))
|
||||
db(
|
||||
update(Lexicon)
|
||||
.where(Lexicon.id == lexicon_id)
|
||||
.values(join_password=password_hash)
|
||||
)
|
||||
db.session.commit()
|
||||
|
||||
|
||||
|
|
|
@ -114,6 +114,10 @@ textarea.fullwidth {
|
|||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
input.fullwidth {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
input.smallnumber {
|
||||
width: 4em;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ def edit(lexicon_name, character_id: uuid.UUID):
|
|||
# Data is valid
|
||||
character.name = form.name.data
|
||||
character.signature = form.signature.data
|
||||
g.db.session.commit()
|
||||
g.db.session.commit() # TODO refactor into backend
|
||||
return redirect(
|
||||
url_for("lexicon.characters.list", lexicon_name=lexicon_name)
|
||||
)
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
from flask import Blueprint, render_template, url_for, redirect
|
||||
from flask import Blueprint, render_template, url_for, g, flash, redirect
|
||||
|
||||
from amanuensis.backend import *
|
||||
from amanuensis.db import *
|
||||
from amanuensis.server.helpers import editor_required, lexicon_param, player_required
|
||||
from amanuensis.server.helpers import (
|
||||
editor_required,
|
||||
lexicon_param,
|
||||
player_required,
|
||||
current_membership,
|
||||
current_lexicon,
|
||||
)
|
||||
|
||||
from .forms import PlayerSettingsForm, SetupSettingsForm
|
||||
|
||||
|
||||
bp = Blueprint("settings", __name__, url_prefix="/settings", template_folder=".")
|
||||
|
@ -15,27 +23,99 @@ def page(lexicon_name):
|
|||
return redirect(url_for("lexicon.settings.player", lexicon_name=lexicon_name))
|
||||
|
||||
|
||||
@bp.get("/player/")
|
||||
@bp.route("/player/", methods=["GET", "POST"])
|
||||
@lexicon_param
|
||||
@player_required
|
||||
def player(lexicon_name):
|
||||
return render_template("settings.jinja", lexicon_name=lexicon_name, page_name=player.__name__)
|
||||
form = PlayerSettingsForm()
|
||||
mem: Membership = current_membership
|
||||
|
||||
if not form.is_submitted():
|
||||
# GET
|
||||
form.notify_ready.data = mem.notify_ready
|
||||
form.notify_reject.data = mem.notify_reject
|
||||
form.notify_approve.data = mem.notify_approve
|
||||
return render_template(
|
||||
"settings.jinja",
|
||||
lexicon_name=lexicon_name,
|
||||
page_name=player.__name__,
|
||||
form=form,
|
||||
)
|
||||
|
||||
else:
|
||||
# POST
|
||||
if form.validate():
|
||||
# Data is valid
|
||||
mem.notify_ready = form.notify_ready.data
|
||||
mem.notify_reject = form.notify_reject.data
|
||||
mem.notify_approve = form.notify_approve.data
|
||||
g.db.session.commit() # TODO refactor into backend
|
||||
flash("Settings saved")
|
||||
return redirect(
|
||||
url_for("lexicon.settings.player", lexicon_name=lexicon_name)
|
||||
)
|
||||
|
||||
else:
|
||||
# Invalid POST data
|
||||
return render_template(
|
||||
"settings.jinja",
|
||||
lexicon_name=lexicon_name,
|
||||
page_name=player.__name__,
|
||||
form=form,
|
||||
)
|
||||
|
||||
|
||||
@bp.get("/general/")
|
||||
@bp.route("/setup/", methods=["GET", "POST"])
|
||||
@lexicon_param
|
||||
@editor_required
|
||||
def general(lexicon_name):
|
||||
return render_template(
|
||||
"settings.jinja", lexicon_name=lexicon_name, page_name=general.__name__
|
||||
)
|
||||
def setup(lexicon_name):
|
||||
form = SetupSettingsForm()
|
||||
lexicon: Lexicon = current_lexicon
|
||||
|
||||
if not form.is_submitted():
|
||||
# GET
|
||||
form.title.data = lexicon.title
|
||||
form.prompt.data = lexicon.prompt
|
||||
form.public.data = lexicon.public
|
||||
form.joinable.data = lexicon.joinable
|
||||
form.has_password.data = lexicon.join_password is not None
|
||||
form.turn_count.data = lexicon.turn_count
|
||||
form.player_limit.data = lexicon.player_limit
|
||||
form.character_limit.data = lexicon.character_limit
|
||||
return render_template(
|
||||
"settings.jinja",
|
||||
lexicon_name=lexicon_name,
|
||||
page_name=setup.__name__,
|
||||
form=form,
|
||||
)
|
||||
|
||||
@bp.get("/join/")
|
||||
@lexicon_param
|
||||
@editor_required
|
||||
def join(lexicon_name):
|
||||
return render_template("settings.jinja", lexicon_name=lexicon_name, page_name=join.__name__)
|
||||
else:
|
||||
# POST
|
||||
if form.validate():
|
||||
# Data is valid
|
||||
lexicon.title = form.title.data
|
||||
lexicon.prompt = form.prompt.data
|
||||
lexicon.public = form.public.data
|
||||
lexicon.joinable = form.joinable.data
|
||||
new_password = form.password.data if form.has_password.data else None
|
||||
lexiq.password_set(g.db, lexicon.id, new_password)
|
||||
lexicon.turn_count = form.turn_count.data
|
||||
lexicon.player_limit = form.player_limit.data
|
||||
lexicon.character_limit = form.character_limit.data
|
||||
g.db.session.commit() # TODO refactor into backend
|
||||
flash("Settings saved")
|
||||
return redirect(
|
||||
url_for("lexicon.settings.setup", lexicon_name=lexicon_name)
|
||||
)
|
||||
|
||||
else:
|
||||
# Invalid POST data
|
||||
return render_template(
|
||||
"settings.jinja",
|
||||
lexicon_name=lexicon_name,
|
||||
page_name=setup.__name__,
|
||||
form=form,
|
||||
)
|
||||
|
||||
|
||||
@bp.get("/progress/")
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
from flask_wtf import FlaskForm
|
||||
from wtforms import (
|
||||
BooleanField,
|
||||
IntegerField,
|
||||
PasswordField,
|
||||
StringField,
|
||||
SubmitField,
|
||||
TextAreaField,
|
||||
)
|
||||
from wtforms.validators import Optional, DataRequired
|
||||
from wtforms.widgets.html5 import NumberInput
|
||||
|
||||
|
||||
class PlayerSettingsForm(FlaskForm):
|
||||
"""/lexicon/<name>/settings/player/"""
|
||||
|
||||
notify_ready = BooleanField("Notify me when an article is submitted for review")
|
||||
notify_reject = BooleanField("Notify me when an editor rejects one of my articles")
|
||||
notify_approve = BooleanField(
|
||||
"Notify me when an editor approves one of my articles"
|
||||
)
|
||||
submit = SubmitField("Submit")
|
||||
|
||||
|
||||
class SetupSettingsForm(FlaskForm):
|
||||
"""/lexicon/<name>/settings/setup/"""
|
||||
|
||||
title = StringField("Title override")
|
||||
prompt = TextAreaField("Prompt", validators=[DataRequired()])
|
||||
public = BooleanField("Make game publicly visible")
|
||||
joinable = BooleanField("Allow players to join game")
|
||||
has_password = BooleanField("Require password to join the game")
|
||||
password = PasswordField("Game password")
|
||||
turn_count = IntegerField(
|
||||
"Number of turns", widget=NumberInput(), validators=[DataRequired()]
|
||||
)
|
||||
player_limit = IntegerField(
|
||||
"Maximum number of players", widget=NumberInput(), validators=[Optional()]
|
||||
)
|
||||
character_limit = IntegerField(
|
||||
"Maximum number of characters per player",
|
||||
widget=NumberInput(),
|
||||
validators=[Optional()],
|
||||
)
|
||||
submit = SubmitField("Submit")
|
|
@ -5,12 +5,24 @@
|
|||
<a{% if page_name != page %} href="{{ url_for('lexicon.settings.' + page, lexicon_name=lexicon_name) }}"{% endif %}>{{ text }}</a>
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro flag_setting(field) %}
|
||||
{{ field() }}
|
||||
{{ field.label }}<br>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro number_setting(field) %}
|
||||
{{ field(autocomplete="off", class_="smallnumber") }}
|
||||
{{ field.label }}<br>
|
||||
{% for error in field.errors %}
|
||||
<span style="color: #ff0000">{{ error }}</span><br>
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
|
||||
{% block main %}
|
||||
{% if current_membership.is_editor %}
|
||||
<ul class="unordered-tabs">
|
||||
<li>{{ settings_page_link("player", "Player") }}</li>
|
||||
<li>{{ settings_page_link("general", "General") }}</li>
|
||||
<li>{{ settings_page_link("join", "Visibility and Joining") }}</li>
|
||||
<li>{{ settings_page_link("setup", "Game Setup") }}</li>
|
||||
<li>{{ settings_page_link("progress", "Game Progress") }}</li>
|
||||
<li>{{ settings_page_link("publish", "Turn Publishing") }}</li>
|
||||
<li>{{ settings_page_link("article", "Article Requirements") }}</li>
|
||||
|
@ -19,14 +31,56 @@
|
|||
|
||||
{% if page_name == "player" %}
|
||||
<h3>Player Settings</h3>
|
||||
<form action="" method="post" novalidate>
|
||||
{{ form.hidden_tag() }}
|
||||
<p>
|
||||
{% if current_membership.is_editor %}{{ flag_setting(form.notify_ready) }}{% endif %}
|
||||
{{ flag_setting(form.notify_reject) }}
|
||||
{{ flag_setting(form.notify_approve) }}
|
||||
</p>
|
||||
<p>{{ form.submit() }}</p>
|
||||
</form>
|
||||
|
||||
{% for message in get_flashed_messages() %}
|
||||
<span style="color:#ff0000">{{ message }}</span><br>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if page_name == "general" %}
|
||||
<h3>General Settings</h3>
|
||||
{% endif %}
|
||||
|
||||
{% if page_name == "join" %}
|
||||
<h3>Visibility and Joining</h3>
|
||||
{% if page_name == "setup" %}
|
||||
<h3>Game Setup</h3>
|
||||
<form action="" method="post" novalidate>
|
||||
{{ form.hidden_tag() }}
|
||||
<p>
|
||||
{{ form.title.label }}:<br>
|
||||
{{ form.title(autocomplete="off", placeholder="Lexicon " + lexicon_name, class_="fullwidth") }}<br>
|
||||
</p>
|
||||
<p>
|
||||
{{ form.prompt.label }}: {{ form.prompt(class_="fullwidth") }}
|
||||
{% for error in form.prompt.errors %}
|
||||
<span style="color: #ff0000">{{ error }}</span><br>
|
||||
{% endfor %}
|
||||
</p>
|
||||
<p>
|
||||
{{ flag_setting(form.public) }}
|
||||
{{ flag_setting(form.joinable) }}
|
||||
{{ form.has_password() }}
|
||||
{{ form.has_password.label }}:<br>
|
||||
{{ form.password(autocomplete="off") }}
|
||||
</p>
|
||||
<p>
|
||||
{{ number_setting(form.turn_count) }}
|
||||
</p>
|
||||
<p>
|
||||
{{ number_setting(form.player_limit) }}
|
||||
</p>
|
||||
<p>
|
||||
{{ number_setting(form.character_limit) }}
|
||||
</p>
|
||||
<p>{{ form.submit() }}</p>
|
||||
</form>
|
||||
{% for message in get_flashed_messages() %}
|
||||
<span style="color:#ff0000">{{ message }}</span><br>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if page_name == "progress" %}
|
||||
|
|
Loading…
Reference in New Issue