From b3d99b93f8d3ea7c9558bdccabfcf8c1f6b84a73 Mon Sep 17 00:00:00 2001 From: Lephe Date: Thu, 8 Jul 2021 11:43:09 +0200 Subject: [PATCH] account: add a theme setting (#14) --- app/forms/account.py | 9 +++++- app/models/user.py | 5 ++++ app/routes/account/account.py | 5 +++- app/static/css/form.css | 4 +++ .../{theme.css => themes/default_theme.css} | 0 app/templates/account/account.html | 10 +++++++ app/utils/render.py | 7 ++++- ...1577f301_add_theme_settings_for_members.py | 28 +++++++++++++++++++ 8 files changed, 65 insertions(+), 3 deletions(-) rename app/static/css/{theme.css => themes/default_theme.css} (100%) create mode 100644 migrations/versions/adcd1577f301_add_theme_settings_for_members.py diff --git a/app/forms/account.py b/app/forms/account.py index 236547a..d1a7c25 100644 --- a/app/forms/account.py +++ b/app/forms/account.py @@ -1,5 +1,5 @@ from flask_wtf import FlaskForm -from wtforms import StringField, PasswordField, BooleanField, TextAreaField, SubmitField, DecimalField, SelectField +from wtforms import StringField, PasswordField, BooleanField, TextAreaField, SubmitField, DecimalField, SelectField, RadioField from wtforms.fields.html5 import DateField, EmailField from wtforms.validators import InputRequired, Optional, Email, EqualTo from flask_wtf.file import FileField # Cuz' wtforms' FileField is shitty @@ -122,6 +122,13 @@ class UpdateAccountForm(FlaskForm): 'Inscription à la newsletter', description='Un mail par trimestre environ, pour être prévenu des concours, évènements et nouveautés.', ) + theme = RadioField( + 'Thème du site', + choices=[ + ('default_theme', 'Thème par défaut (clair)'), + ('FK_dark_theme', 'Thème sombre de FlamingKite'), + ], + ) submit = SubmitField('Mettre à jour') diff --git a/app/models/user.py b/app/models/user.py index d4d5218..afedac5 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -108,6 +108,7 @@ class Member(User): # Settings newsletter = db.Column(db.Boolean, default=False) + theme = db.Column(db.Unicode(32)) # Relations trophies = db.relationship('Trophy', secondary=TrophyMember, @@ -131,6 +132,7 @@ class Member(User): # Workflow with LDAP enabled is User → Postgresql → LDAP → set password self.xp = 0 + self.theme = 'default_theme' self.bio = "" self.signature = "" self.birthday = None @@ -238,6 +240,7 @@ class Member(User): "newsletter" bool Newsletter setting "xp" int Experience points "avatar" File Avatar image + "theme" str Name of theme file For future compatibility, other attributes are silently ignored. None values can be specified and are ignored. @@ -271,6 +274,8 @@ class Member(User): self.set_avatar(data["avatar"]) if "title" in data: self.title = Title.query.get(data["title"]) + if "theme" in data: + self.theme = data["theme"] # For admins only if "email_confirmed" in data: diff --git a/app/routes/account/account.py b/app/routes/account/account.py index e15b00e..9dede19 100644 --- a/app/routes/account/account.py +++ b/app/routes/account/account.py @@ -30,7 +30,8 @@ def edit_account(): signature=form.signature.data, bio=form.biography.data, title=form.title.data, - newsletter=form.newsletter.data + newsletter=form.newsletter.data, + theme=form.theme.data ) db.session.merge(current_user) db.session.commit() @@ -39,6 +40,8 @@ def edit_account(): return redirect(request.url) else: flash('Erreur lors de la modification', 'error') + else: + form.theme.data = current_user.theme or 'default_theme' return render('account/account.html', scripts=["+scripts/entropy.js"], form=form) diff --git a/app/static/css/form.css b/app/static/css/form.css index fa11e42..1cb019a 100644 --- a/app/static/css/form.css +++ b/app/static/css/form.css @@ -46,6 +46,10 @@ box-shadow: 0 0 0 3px var(--shadow-focused); } +.form input[type='radio'] { + margin: 0 4px 0 0; +} + .form textarea { max-width: 100%; resize: vertical; diff --git a/app/static/css/theme.css b/app/static/css/themes/default_theme.css similarity index 100% rename from app/static/css/theme.css rename to app/static/css/themes/default_theme.css diff --git a/app/templates/account/account.html b/app/templates/account/account.html index 03981da..ee80383 100644 --- a/app/templates/account/account.html +++ b/app/templates/account/account.html @@ -89,6 +89,16 @@ {{ error }} {% endfor %} +
+ {{ form.theme.label }} + {% for subfield in form.theme %} +
{{ subfield }} {{ subfield.label }}
+ {% endfor %} +
{{ form.theme.description }}
+ {% for error in form.theme.errors %} + {{ error }} + {% endfor %} +
{{ form.submit(class_="bg-ok") }}
diff --git a/app/utils/render.py b/app/utils/render.py index 980687c..000fd37 100644 --- a/app/utils/render.py +++ b/app/utils/render.py @@ -1,11 +1,11 @@ from flask import render_template +from flask_login import current_user def render(*args, styles=[], scripts=[], **kwargs): # Pour jouer sur les feuilles de style ou les scripts : # render('page.html', styles=['-css/form.css', '+css/admin/forms.css']) styles_ = [ - 'css/theme.css', 'css/global.css', 'css/navbar.css', 'css/header.css', @@ -28,6 +28,11 @@ def render(*args, styles=[], scripts=[], **kwargs): 'scripts/filter.js' ] + # Apply theme from user settings + theme = current_user.theme if current_user.is_authenticated else '' + theme = theme if theme else 'default_theme' + styles_ = [f'css/themes/{theme}.css'] + styles_ + for s in styles: if s[0] == '-': styles_.remove(s[1:]) diff --git a/migrations/versions/adcd1577f301_add_theme_settings_for_members.py b/migrations/versions/adcd1577f301_add_theme_settings_for_members.py new file mode 100644 index 0000000..3e6b4cb --- /dev/null +++ b/migrations/versions/adcd1577f301_add_theme_settings_for_members.py @@ -0,0 +1,28 @@ +"""Add theme settings for Members + +Revision ID: adcd1577f301 +Revises: 0abd1c81e3aa +Create Date: 2021-07-08 11:25:19.535246 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'adcd1577f301' +down_revision = '0abd1c81e3aa' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('member', sa.Column('theme', sa.Unicode(length=32), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('member', 'theme') + # ### end Alembic commands ###