Add custom css slots to prepare for donators feature

This commit is contained in:
Jeremy Zhang 2017-09-11 07:52:13 +00:00
parent 214bbfa162
commit 10b5deffe4
10 changed files with 121 additions and 17 deletions

View File

@ -0,0 +1,28 @@
"""Add css_limit column to cosmetics
Revision ID: d1b89c41bf16
Revises: f65629d470c6
Create Date: 2017-09-11 01:38:07.771715
"""
# revision identifiers, used by Alembic.
revision = 'd1b89c41bf16'
down_revision = 'f65629d470c6'
branch_labels = None
depends_on = None
from alembic import op
import sqlalchemy as sa
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('cosmetics', sa.Column('css_limit', sa.Integer(), server_default='0', nullable=False))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('cosmetics', 'css_limit')
# ### end Alembic commands ###

View File

@ -36,6 +36,7 @@ def cosmetics_post():
if not user_id: if not user_id:
abort(400) abort(400)
css = request.form.get("css", None) css = request.form.get("css", None)
css_limit = request.form.get("css_limit", None)
entry = db.session.query(Cosmetics).filter(Cosmetics.user_id == user_id).first() entry = db.session.query(Cosmetics).filter(Cosmetics.user_id == user_id).first()
if entry: if entry:
abort(409) abort(409)
@ -43,6 +44,8 @@ def cosmetics_post():
if css: if css:
css = css.lower() == "true" css = css.lower() == "true"
user.css = css user.css = css
if css_limit is not None:
user.css_limit = css_limit
db.session.add(user) db.session.add(user)
db.session.commit() db.session.commit()
return ('', 204) return ('', 204)
@ -67,12 +70,15 @@ def cosmetics_patch():
if not user_id: if not user_id:
abort(400) abort(400)
css = request.form.get("css", None) css = request.form.get("css", None)
css_limit = request.form.get("css_limit", None)
entry = db.session.query(Cosmetics).filter(Cosmetics.user_id == user_id).first() entry = db.session.query(Cosmetics).filter(Cosmetics.user_id == user_id).first()
if not entry: if not entry:
abort(409) abort(409)
if css: if css:
css = css.lower() == "true" css = css.lower() == "true"
entry.css = css entry.css = css
if css_limit is not None:
entry.css_limit = css_limit
db.session.commit() db.session.commit()
return ('', 204) return ('', 204)
def prepare_guild_members_list(members, bans): def prepare_guild_members_list(members, bans):

View File

@ -60,6 +60,14 @@ def logout():
return redirect(session['redirect']) return redirect(session['redirect'])
return redirect(url_for("index")) return redirect(url_for("index"))
def count_user_premium_css():
count = 0
css_list = db.session.query(UserCSS).filter(UserCSS.user_id == session['user_id']).all()
for css in css_list:
if css.css is not None:
count += 1
return count
@user.route("/dashboard") @user.route("/dashboard")
@discord_users_only() @discord_users_only()
def dashboard(): def dashboard():
@ -73,7 +81,8 @@ def dashboard():
css_list = None css_list = None
if cosmetics and cosmetics.css: if cosmetics and cosmetics.css:
css_list = db.session.query(UserCSS).filter(UserCSS.user_id == session['user_id']).all() css_list = db.session.query(UserCSS).filter(UserCSS.user_id == session['user_id']).all()
return render_template("dashboard.html.j2", servers=guilds, icon_generate=generate_guild_icon_url, cosmetics=cosmetics, css_list=css_list) premium_css_count = count_user_premium_css()
return render_template("dashboard.html.j2", servers=guilds, icon_generate=generate_guild_icon_url, cosmetics=cosmetics, css_list=css_list, premium_css_count=premium_css_count)
@user.route("/custom_css/new", methods=["GET"]) @user.route("/custom_css/new", methods=["GET"])
@discord_users_only() @discord_users_only()
@ -81,7 +90,8 @@ def new_custom_css_get():
cosmetics = db.session.query(Cosmetics).filter(Cosmetics.user_id == session['user_id']).first() cosmetics = db.session.query(Cosmetics).filter(Cosmetics.user_id == session['user_id']).first()
if not cosmetics or not cosmetics.css: if not cosmetics or not cosmetics.css:
abort(403) abort(403)
return render_template("usercss.html.j2", new=True) premium_css_count = count_user_premium_css()
return render_template("usercss.html.j2", new=True, cosmetics=cosmetics, premium_css_count=premium_css_count)
@user.route("/custom_css/new", methods=["POST"]) @user.route("/custom_css/new", methods=["POST"])
@discord_users_only() @discord_users_only()
@ -92,7 +102,7 @@ def new_custom_css_post():
name = request.form.get("name", None) name = request.form.get("name", None)
user_id = session["user_id"] user_id = session["user_id"]
css = request.form.get("css","") css = request.form.get("css",None)
variables = request.form.get("variables", None) variables = request.form.get("variables", None)
variables_enabled = request.form.get("variables_enabled", False) in ["true", True] variables_enabled = request.form.get("variables_enabled", False) in ["true", True]
if not name: if not name:
@ -100,6 +110,8 @@ def new_custom_css_post():
else: else:
name = name.strip() name = name.strip()
css = css.strip() css = css.strip()
if (len(css) == 0):
css = None
css = UserCSS(name, user_id, variables_enabled, variables, css) css = UserCSS(name, user_id, variables_enabled, variables, css)
db.session.add(css) db.session.add(css)
db.session.commit() db.session.commit()
@ -120,7 +132,8 @@ def edit_custom_css_get(css_id):
print(variables) print(variables)
if variables: if variables:
variables = json.loads(variables) variables = json.loads(variables)
return render_template("usercss.html.j2", new=False, css=css, variables=variables) premium_css_count = count_user_premium_css()
return render_template("usercss.html.j2", new=False, css=css, variables=variables, cosmetics=cosmetics, premium_css_count=premium_css_count)
@user.route("/custom_css/edit/<css_id>", methods=["POST"]) @user.route("/custom_css/edit/<css_id>", methods=["POST"])
@discord_users_only() @discord_users_only()
@ -134,7 +147,7 @@ def edit_custom_css_post(css_id):
if dbcss.user_id != session['user_id']: if dbcss.user_id != session['user_id']:
abort(403) abort(403)
name = request.form.get("name", None) name = request.form.get("name", None)
css = request.form.get("css", "") css = request.form.get("css", None)
variables = request.form.get("variables", None) variables = request.form.get("variables", None)
variables_enabled = request.form.get("variables_enabled", False) in ["true", True] variables_enabled = request.form.get("variables_enabled", False) in ["true", True]
if not name: if not name:
@ -142,6 +155,8 @@ def edit_custom_css_post(css_id):
else: else:
name = name.strip() name = name.strip()
css = css.strip() css = css.strip()
if (len(css) == 0):
css = None
dbcss.name = name dbcss.name = name
dbcss.css = css dbcss.css = css
dbcss.css_variables = variables dbcss.css_variables = variables

View File

@ -5,6 +5,7 @@ class Cosmetics(db.Model):
id = db.Column(db.Integer, primary_key=True) # Auto increment id id = db.Column(db.Integer, primary_key=True) # Auto increment id
user_id = db.Column(db.String(255), nullable=False) # Discord user id of user of cosmetics user_id = db.Column(db.String(255), nullable=False) # Discord user id of user of cosmetics
css = db.Column(db.Boolean(), nullable=False) # If they can create/edit custom CSS css = db.Column(db.Boolean(), nullable=False) # If they can create/edit custom CSS
css_limit = db.Column(db.Integer, nullable=False, server_default="0") # Custom CSS Limit
def __init__(self, user_id, **kwargs): def __init__(self, user_id, **kwargs):
self.user_id = user_id self.user_id = user_id
@ -13,3 +14,8 @@ class Cosmetics(db.Model):
self.css = kwargs["css"] self.css = kwargs["css"]
else: else:
self.css = False self.css = False
if "css_limit" in kwargs:
self.css_limit = kwargs["css_limit"]
else:
self.css_limit = 0

View File

@ -18,11 +18,12 @@ function deleteForm(user_id) {
return funct.promise(); return funct.promise();
} }
function patchForm(user_id, css) { function patchForm(user_id, param) {
var data = Object.assign({"user_id": user_id}, param);
var funct = $.ajax({ var funct = $.ajax({
dataType: "json", dataType: "json",
method: "PATCH", method: "PATCH",
data: {"user_id": user_id, "css": css} data: data,
}); });
return funct.promise(); return funct.promise();
} }
@ -68,7 +69,7 @@ function delete_user(user_id) {
function update_css_switch(user_id, element) { function update_css_switch(user_id, element) {
var css_checked = $(element).is(':checked'); var css_checked = $(element).is(':checked');
var formPatch = patchForm(user_id, css_checked); var formPatch = patchForm(user_id, {"css": css_checked});
formPatch.done(function (data) { formPatch.done(function (data) {
Materialize.toast('CSS updated!', 10000); Materialize.toast('CSS updated!', 10000);
}); });
@ -80,3 +81,17 @@ function update_css_switch(user_id, element) {
} }
}); });
} }
function update_css_limit(user_id, value) {
var formPatch = patchForm(user_id, {"css_limit": value});
formPatch.done(function (data) {
Materialize.toast('CSS value updated!', 10000);
});
formPatch.fail(function (data) {
if (data.status == 409) {
Materialize.toast('This user id does not exists!', 10000);
} else {
Materialize.toast('Oh no! Something has failed changing the css limit field!', 10000);
}
});
}

View File

@ -1,12 +1,20 @@
/*global $, ace, Materialize, newCSS*/ /*global $, ace, Materialize, newCSS*/
(function () { (function () {
var editor = ace.edit("css_editor"); if($("#css_editor").length != 0) {
var editor = ace.edit("css_editor");
}
function postForm() { function postForm() {
var name = $('#css_name').val(); var name = $('#css_name').val();
var var_enabled = $("#toggleCSSVar").is(':checked'); var var_enabled = $("#toggleCSSVar").is(':checked');
var variables = JSON.stringify(formatCSSVars()); var variables = JSON.stringify(formatCSSVars());
var css = editor.getValue(); var css = null;
if($("#css_editor").length != 0) {
css = editor.getValue();
if (css.length == 0) {
css = null;
}
}
var funct = $.ajax({ var funct = $.ajax({
dataType: "json", dataType: "json",
method: "POST", method: "POST",
@ -16,8 +24,10 @@
} }
$(function(){ $(function(){
editor.getSession().setMode("ace/mode/css"); if($("#css_editor").length != 0) {
editor.setTheme("ace/theme/chrome"); editor.getSession().setMode("ace/mode/css");
editor.setTheme("ace/theme/chrome");
}
$("#submit-btn").click(submitForm); $("#submit-btn").click(submitForm);
if (!newCSS) { if (!newCSS) {

View File

@ -13,6 +13,7 @@
<tr> <tr>
<th>User ID</th> <th>User ID</th>
<th>CSS</th> <th>CSS</th>
<th>CSS Limit</th>
<th>Submit</th> <th>Submit</th>
</tr> </tr>
</thead> </thead>
@ -23,6 +24,11 @@
<input id="new_user_id" placeholder="User ID"> <input id="new_user_id" placeholder="User ID">
</div> </div>
</td> </td>
<td>
<div class="input-field inline">
<input id="new_css_limit" placeholder="CSS Limit" type="number">
</div>
</td>
<td> <td>
<div class="switch"> <div class="switch">
<label> <label>
@ -50,23 +56,29 @@
<th>Remove</th> <th>Remove</th>
<th>User ID</th> <th>User ID</th>
<th>CSS</th> <th>CSS</th>
<th>CSS Limit</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for cosmetic in cosmetics %} {% for cosmetic in cosmetics %}
<tr> <tr>
<td><a class="waves-effect waves-light btn red" id="new_submit" onclick="delete_user('{{ cosmetic.user_id }}');">Remove</a></td> <td><a class="waves-effect waves-light btn red" onclick="delete_user('{{ cosmetic.user_id }}');">Remove</a></td>
<td>{{ cosmetic.user_id }}</td> <td>{{ cosmetic.user_id }}</td>
<td> <td>
<div class="switch"> <div class="switch">
<label> <label>
Off Off
<input type="checkbox" id="new_css_switch" {% if cosmetic.css %}checked{% endif %} onchange="update_css_switch('{{ cosmetic.user_id }}', this)"> <input type="checkbox" {% if cosmetic.css %}checked{% endif %} onchange="update_css_switch('{{ cosmetic.user_id }}', this)">
<span class="lever"></span> <span class="lever"></span>
On On
</label> </label>
</div> </div>
</td> </td>
<td>
<div class="input-field inline">
<input placeholder="CSS Limit" type="number" value="{{ cosmetic.css_limit }}" onchange="update_css_limit('{{ cosmetic.user_id }}', $(this).val())">
</div>
</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>

View File

@ -46,9 +46,11 @@
{% if css_list is not none %} {% if css_list is not none %}
<p class="flow-text"> <p class="flow-text">
Create or modify your custom CSS. Create or modify your user defined CSS.
<a class="waves-effect waves-light btn" href="{{ url_for("user.new_custom_css_get") }}">New</a> <a class="waves-effect waves-light btn" href="{{ url_for("user.new_custom_css_get") }}">New</a>
</p> </p>
<p>You have used <strong>{{ premium_css_count }} out of {{ cosmetics.css_limit }}</strong> custom css slots. {% if premium_css_count >= cosmetics.css_limit %}<strong>Don't fret! You can still use CSS variables.</strong>{% endif %} Donate below to obtain more slots!</p>
{% if premium_css_count >= cosmetics.css_limit %}<p>Free up some slots by emptying your other custom CSS field and submitting it (Titan will automatically mark empty custom css editor fields as unused slots in the database) or delete the user defined css slot altogether.</p>{% endif %}
<div class="row"> <div class="row">
{% for css in css_list %} {% for css in css_list %}
<div class="col l4 m6 s12"> <div class="col l4 m6 s12">

View File

@ -20,7 +20,7 @@
{% include 'google_analytics.html.j2' %} {% include 'google_analytics.html.j2' %}
{% if css is not none %} {% if css is not none %}
<style id="user-defined-css">{% if cssvariables is not none and css.css_var_bool %}{{ cssvariables|e }}{% endif %} {{ css.css }}</style> <style id="user-defined-css">{% if cssvariables is not none and css.css_var_bool %}{{ cssvariables|e }}{% endif %} {% if css.css is not none %}{{ css.css }}{% endif %}</style>
{% endif %} {% endif %}
</head> </head>
<body> <body>

View File

@ -85,13 +85,23 @@ will have CSS cosmetic privilages removed, if caught. Please don't, we check the
</div> </div>
<p><strong>TIP!</strong> You can use the variables in your CSS below! Something like <code>color: var(--leftsidebar);</code> would work!</p> <p><strong>TIP!</strong> You can use the variables in your CSS below! Something like <code>color: var(--leftsidebar);</code> would work!</p>
</div> </div>
{% if (new and premium_css_count >= cosmetics.css_limit) or (not new and premium_css_count >= cosmetics.css_limit and css.css is none) %}
<div class="col s12">
<hr>
<p class="flow-text">All custom CSS slots are used. Donate to get more!</p>
<p>Free up some slots by emptying your other custom CSS field and submitting it (Titan will automatically mark empty custom css editor fields as unused slots in the database) or delete the user defined css slot altogether.</p>
<hr>
</div>
{% else %}
<div class="col s12"> <div class="col s12">
<p class="flow-text">Edit your CSS code here</p> <p class="flow-text">Edit your CSS code here</p>
<p><em>Remove any text and leave this box blank when submitting to not use up your custom css slots.</em></p>
<div style="position: relative; height: 40vh;"> <div style="position: relative; height: 40vh;">
<div id="css_editor">{% if new %}/* Enter your CSS code here! */{% else %}{{ css.css|e }}{% endif %}</div> <div id="css_editor">{% if new %}/* Enter your CSS code here! */{% else %}{% if css.css %}{{ css.css|e }}{% endif %}{% endif %}</div>
</div> </div>
<br> <br>
</div> </div>
{% endif %}
<div class="col s12"> <div class="col s12">
<a id="submit-btn" class="waves-effect waves-light btn">Submit</a> <a id="submit-btn" class="waves-effect waves-light btn">Submit</a>
{% if not new %}<a id="delete-btn" class="waves-effect waves-light btn red">Delete</a>{% endif %} {% if not new %}<a id="delete-btn" class="waves-effect waves-light btn red">Delete</a>{% endif %}