mirror of
				https://github.com/TitanEmbeds/Titan.git
				synced 2025-11-04 07:47:10 +01:00 
			
		
		
		
	Add user cards and badges, Closes #25
This commit is contained in:
		@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					"""Added badges column to cosmetics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Revision ID: 66971a97040e
 | 
				
			||||||
 | 
					Revises: 16b4fdbbe155
 | 
				
			||||||
 | 
					Create Date: 2017-12-07 04:30:25.639794
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# revision identifiers, used by Alembic.
 | 
				
			||||||
 | 
					revision = '66971a97040e'
 | 
				
			||||||
 | 
					down_revision = '16b4fdbbe155'
 | 
				
			||||||
 | 
					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('badges', sa.String(length=255), server_default='[]', nullable=False))
 | 
				
			||||||
 | 
					    # ### end Alembic commands ###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def downgrade():
 | 
				
			||||||
 | 
					    # ### commands auto generated by Alembic - please adjust! ###
 | 
				
			||||||
 | 
					    op.drop_column('cosmetics', 'badges')
 | 
				
			||||||
 | 
					    # ### end Alembic commands ###
 | 
				
			||||||
@@ -8,6 +8,9 @@ def init_debug():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' # Testing oauthlib
 | 
					    os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' # Testing oauthlib
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    app.jinja_env.auto_reload = True
 | 
				
			||||||
 | 
					    app.config['TEMPLATES_AUTO_RELOAD'] = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Session viewer https://gist.github.com/babldev/502364a3f7c9bafaa6db
 | 
					    # Session viewer https://gist.github.com/babldev/502364a3f7c9bafaa6db
 | 
				
			||||||
    def decode_flask_cookie(secret_key, cookie_str):
 | 
					    def decode_flask_cookie(secret_key, cookie_str):
 | 
				
			||||||
        import hashlib
 | 
					        import hashlib
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ from functools import wraps
 | 
				
			|||||||
from titanembeds.database import db, get_administrators_list, Cosmetics, Guilds, UnauthenticatedUsers, UnauthenticatedBans, TitanTokens, TokenTransactions, get_titan_token, set_titan_token
 | 
					from titanembeds.database import db, get_administrators_list, Cosmetics, Guilds, UnauthenticatedUsers, UnauthenticatedBans, TitanTokens, TokenTransactions, get_titan_token, set_titan_token
 | 
				
			||||||
from titanembeds.oauth import generate_guild_icon_url
 | 
					from titanembeds.oauth import generate_guild_icon_url
 | 
				
			||||||
import datetime
 | 
					import datetime
 | 
				
			||||||
 | 
					import json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
admin = Blueprint("admin", __name__)
 | 
					admin = Blueprint("admin", __name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -39,6 +40,7 @@ def cosmetics_post():
 | 
				
			|||||||
    css = request.form.get("css", None)
 | 
					    css = request.form.get("css", None)
 | 
				
			||||||
    css_limit = int(request.form.get("css_limit", 0))
 | 
					    css_limit = int(request.form.get("css_limit", 0))
 | 
				
			||||||
    guest_icon = request.form.get("guest_icon", None)
 | 
					    guest_icon = request.form.get("guest_icon", None)
 | 
				
			||||||
 | 
					    badges = request.form.get("badges", 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)
 | 
				
			||||||
@@ -51,6 +53,11 @@ def cosmetics_post():
 | 
				
			|||||||
    if guest_icon is not None:
 | 
					    if guest_icon is not None:
 | 
				
			||||||
        guest_icon = guest_icon.lower() == "true"
 | 
					        guest_icon = guest_icon.lower() == "true"
 | 
				
			||||||
        user.guest_icon = guest_icon
 | 
					        user.guest_icon = guest_icon
 | 
				
			||||||
 | 
					    if badges is not None:
 | 
				
			||||||
 | 
					        badges = badges.split(",")
 | 
				
			||||||
 | 
					        if badges == [""]:
 | 
				
			||||||
 | 
					            badges = []
 | 
				
			||||||
 | 
					        user.badges = json.dumps(badges)
 | 
				
			||||||
    db.session.add(user)
 | 
					    db.session.add(user)
 | 
				
			||||||
    db.session.commit()
 | 
					    db.session.commit()
 | 
				
			||||||
    return ('', 204)
 | 
					    return ('', 204)
 | 
				
			||||||
@@ -77,6 +84,7 @@ def cosmetics_patch():
 | 
				
			|||||||
    css = request.form.get("css", None)
 | 
					    css = request.form.get("css", None)
 | 
				
			||||||
    css_limit = request.form.get("css_limit", None)
 | 
					    css_limit = request.form.get("css_limit", None)
 | 
				
			||||||
    guest_icon = request.form.get("guest_icon", None)
 | 
					    guest_icon = request.form.get("guest_icon", None)
 | 
				
			||||||
 | 
					    badges = request.form.get("badges", 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)
 | 
				
			||||||
@@ -88,8 +96,14 @@ def cosmetics_patch():
 | 
				
			|||||||
    if guest_icon:
 | 
					    if guest_icon:
 | 
				
			||||||
        guest_icon = guest_icon.lower() == "true"
 | 
					        guest_icon = guest_icon.lower() == "true"
 | 
				
			||||||
        entry.guest_icon = guest_icon
 | 
					        entry.guest_icon = guest_icon
 | 
				
			||||||
 | 
					    if badges is not None:
 | 
				
			||||||
 | 
					        badges = badges.split(",")
 | 
				
			||||||
 | 
					        if badges == [""]:
 | 
				
			||||||
 | 
					            badges = []
 | 
				
			||||||
 | 
					        entry.badges = json.dumps(badges)
 | 
				
			||||||
    db.session.commit()
 | 
					    db.session.commit()
 | 
				
			||||||
    return ('', 204)
 | 
					    return ('', 204)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
def prepare_guild_members_list(members, bans):
 | 
					def prepare_guild_members_list(members, bans):
 | 
				
			||||||
    all_users = []
 | 
					    all_users = []
 | 
				
			||||||
    ip_pool = []
 | 
					    ip_pool = []
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
from titanembeds.database import db, Guilds, UnauthenticatedUsers, UnauthenticatedBans, AuthenticatedUsers, KeyValueProperties, GuildMembers, Messages, get_channel_messages, list_all_guild_members, get_guild_member, get_administrators_list
 | 
					from titanembeds.database import db, Guilds, UnauthenticatedUsers, UnauthenticatedBans, AuthenticatedUsers, KeyValueProperties, GuildMembers, Messages, get_channel_messages, list_all_guild_members, get_guild_member, get_administrators_list, get_badges
 | 
				
			||||||
from titanembeds.decorators import valid_session_required, discord_users_only
 | 
					from titanembeds.decorators import valid_session_required, discord_users_only
 | 
				
			||||||
from titanembeds.utils import check_guild_existance, guild_accepts_visitors, guild_query_unauth_users_bool, get_client_ipaddr, discord_api, rate_limiter, channel_ratelimit_key, guild_ratelimit_key, user_unauthenticated, checkUserRevoke, checkUserBanned, update_user_status, check_user_in_guild, get_guild_channels, guild_webhooks_enabled, guild_unauthcaptcha_enabled
 | 
					from titanembeds.utils import check_guild_existance, guild_accepts_visitors, guild_query_unauth_users_bool, get_client_ipaddr, discord_api, rate_limiter, channel_ratelimit_key, guild_ratelimit_key, user_unauthenticated, checkUserRevoke, checkUserBanned, update_user_status, check_user_in_guild, get_guild_channels, guild_webhooks_enabled, guild_unauthcaptcha_enabled
 | 
				
			||||||
from titanembeds.oauth import user_has_permission, generate_avatar_url, check_user_can_administrate_guild
 | 
					from titanembeds.oauth import user_has_permission, generate_avatar_url, check_user_can_administrate_guild
 | 
				
			||||||
@@ -429,6 +429,10 @@ def create_authenticated_user():
 | 
				
			|||||||
            response.status_code = 403
 | 
					            response.status_code = 403
 | 
				
			||||||
            return response
 | 
					            return response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@api.route("/badges/<user_id>")
 | 
				
			||||||
 | 
					def badges(user_id):
 | 
				
			||||||
 | 
					    return jsonify(get_badges(user_id))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def canCleanupDB():
 | 
					def canCleanupDB():
 | 
				
			||||||
    canclean = False
 | 
					    canclean = False
 | 
				
			||||||
    if request.form.get("secret", None) == config['app-secret']:
 | 
					    if request.form.get("secret", None) == config['app-secret']:
 | 
				
			||||||
@@ -437,6 +441,7 @@ def canCleanupDB():
 | 
				
			|||||||
        if session['user_id'] in get_administrators_list():
 | 
					        if session['user_id'] in get_administrators_list():
 | 
				
			||||||
            canclean = True
 | 
					            canclean = True
 | 
				
			||||||
    return canclean
 | 
					    return canclean
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
@api.route("/cleanup-db", methods=["DELETE"])
 | 
					@api.route("/cleanup-db", methods=["DELETE"])
 | 
				
			||||||
def cleanup_keyval_db():
 | 
					def cleanup_keyval_db():
 | 
				
			||||||
    if canCleanupDB():
 | 
					    if canCleanupDB():
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@ from flask import current_app as app
 | 
				
			|||||||
from flask_socketio import emit
 | 
					from flask_socketio import emit
 | 
				
			||||||
from config import config
 | 
					from config import config
 | 
				
			||||||
from titanembeds.decorators import discord_users_only
 | 
					from titanembeds.decorators import discord_users_only
 | 
				
			||||||
from titanembeds.database import db, Guilds, UnauthenticatedUsers, UnauthenticatedBans, Cosmetics, UserCSS, Patreon, set_titan_token, get_titan_token
 | 
					from titanembeds.database import db, Guilds, UnauthenticatedUsers, UnauthenticatedBans, Cosmetics, UserCSS, Patreon, set_titan_token, get_titan_token, add_badge
 | 
				
			||||||
from titanembeds.oauth import authorize_url, token_url, make_authenticated_session, get_current_authenticated_user, get_user_managed_servers, check_user_can_administrate_guild, check_user_permission, generate_avatar_url, generate_guild_icon_url, generate_bot_invite_url
 | 
					from titanembeds.oauth import authorize_url, token_url, make_authenticated_session, get_current_authenticated_user, get_user_managed_servers, check_user_can_administrate_guild, check_user_permission, generate_avatar_url, generate_guild_icon_url, generate_bot_invite_url
 | 
				
			||||||
import time
 | 
					import time
 | 
				
			||||||
import datetime
 | 
					import datetime
 | 
				
			||||||
@@ -431,6 +431,7 @@ def donate_confirm():
 | 
				
			|||||||
        action = "PAYPAL {}".format(trans_id)
 | 
					        action = "PAYPAL {}".format(trans_id)
 | 
				
			||||||
        set_titan_token(session["user_id"], tokens, action)
 | 
					        set_titan_token(session["user_id"], tokens, action)
 | 
				
			||||||
        session["tokens"] = get_titan_token(session["user_id"])
 | 
					        session["tokens"] = get_titan_token(session["user_id"])
 | 
				
			||||||
 | 
					        add_badge(session["user_id"], "supporter")
 | 
				
			||||||
        return redirect(url_for('user.donate_thanks', transaction=trans_id))
 | 
					        return redirect(url_for('user.donate_thanks', transaction=trans_id))
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        return redirect(url_for('index'))
 | 
					        return redirect(url_for('index'))
 | 
				
			||||||
@@ -555,6 +556,7 @@ def patreon_sync_post():
 | 
				
			|||||||
    db.session.add(dbpatreon)
 | 
					    db.session.add(dbpatreon)
 | 
				
			||||||
    db.session.commit()
 | 
					    db.session.commit()
 | 
				
			||||||
    set_titan_token(session["user_id"], usr["titan"]["eligible_tokens"], "PATREON {} [{}]".format(usr["attributes"]["full_name"], usr["id"]))
 | 
					    set_titan_token(session["user_id"], usr["titan"]["eligible_tokens"], "PATREON {} [{}]".format(usr["attributes"]["full_name"], usr["id"]))
 | 
				
			||||||
 | 
					    add_badge(session["user_id"], "supporter")
 | 
				
			||||||
    session["tokens"] = get_titan_token(session["user_id"])
 | 
					    session["tokens"] = get_titan_token(session["user_id"])
 | 
				
			||||||
    return ('', 204)
 | 
					    return ('', 204)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@ from .authenticated_users import AuthenticatedUsers
 | 
				
			|||||||
from .guild_members import GuildMembers, list_all_guild_members, get_guild_member
 | 
					from .guild_members import GuildMembers, list_all_guild_members, get_guild_member
 | 
				
			||||||
from .keyvalue_properties import KeyValueProperties, set_keyvalproperty, get_keyvalproperty, getexpir_keyvalproperty, setexpir_keyvalproperty, ifexists_keyvalproperty, delete_keyvalproperty
 | 
					from .keyvalue_properties import KeyValueProperties, set_keyvalproperty, get_keyvalproperty, getexpir_keyvalproperty, setexpir_keyvalproperty, ifexists_keyvalproperty, delete_keyvalproperty
 | 
				
			||||||
from .messages import Messages, get_channel_messages
 | 
					from .messages import Messages, get_channel_messages
 | 
				
			||||||
from .cosmetics import Cosmetics
 | 
					from .cosmetics import Cosmetics, set_badges, get_badges, add_badge, remove_badge
 | 
				
			||||||
from .user_css import UserCSS
 | 
					from .user_css import UserCSS
 | 
				
			||||||
from .administrators import Administrators, get_administrators_list
 | 
					from .administrators import Administrators, get_administrators_list
 | 
				
			||||||
from .titan_tokens import TitanTokens, get_titan_token
 | 
					from .titan_tokens import TitanTokens, get_titan_token
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
from titanembeds.database import db
 | 
					from titanembeds.database import db
 | 
				
			||||||
 | 
					import json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Cosmetics(db.Model):
 | 
					class Cosmetics(db.Model):
 | 
				
			||||||
    __tablename__ = "cosmetics"
 | 
					    __tablename__ = "cosmetics"
 | 
				
			||||||
@@ -7,6 +8,7 @@ class Cosmetics(db.Model):
 | 
				
			|||||||
    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
 | 
					    css_limit = db.Column(db.Integer, nullable=False, server_default="0") # Custom CSS Limit
 | 
				
			||||||
    guest_icon = db.Column(db.Boolean(), nullable=False, server_default=db.false()) # If they can set the guest icon for all guilds
 | 
					    guest_icon = db.Column(db.Boolean(), nullable=False, server_default=db.false()) # If they can set the guest icon for all guilds
 | 
				
			||||||
 | 
					    badges = db.Column(db.String(255), nullable=False, server_default="[]") # JSON list of all the badges the user has
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    def __init__(self, user_id, **kwargs):
 | 
					    def __init__(self, user_id, **kwargs):
 | 
				
			||||||
        self.user_id = user_id
 | 
					        self.user_id = user_id
 | 
				
			||||||
@@ -25,3 +27,34 @@ class Cosmetics(db.Model):
 | 
				
			|||||||
            self.guest_icon = kwargs["guest_icon"]
 | 
					            self.guest_icon = kwargs["guest_icon"]
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.guest_icon = False
 | 
					            self.guest_icon = False
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if "badges" in kwargs:
 | 
				
			||||||
 | 
					            self.badges = json.dumps(kwargs["badges"])
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self.badges = "[]"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def set_badges(user_id, badges):
 | 
				
			||||||
 | 
					    usr = db.session.query(Cosmetics).filter(Cosmetics.user_id == user_id).first()
 | 
				
			||||||
 | 
					    if not usr:
 | 
				
			||||||
 | 
					        usr = Cosmetics(user_id)
 | 
				
			||||||
 | 
					    usr.badges = json.dumps(badges)
 | 
				
			||||||
 | 
					    db.session.add(usr)
 | 
				
			||||||
 | 
					    db.session.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_badges(user_id):
 | 
				
			||||||
 | 
					    usr = db.session.query(Cosmetics).filter(Cosmetics.user_id == user_id).first()
 | 
				
			||||||
 | 
					    if usr:
 | 
				
			||||||
 | 
					        return json.loads(usr.badges)
 | 
				
			||||||
 | 
					    return []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def add_badge(user_id, name):
 | 
				
			||||||
 | 
					    bgs = get_badges(user_id)
 | 
				
			||||||
 | 
					    if name not in bgs:
 | 
				
			||||||
 | 
					        bgs.append(name)
 | 
				
			||||||
 | 
					        set_badges(user_id, bgs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def remove_badge(user_id, name):
 | 
				
			||||||
 | 
					    bgs = get_badges(user_id)
 | 
				
			||||||
 | 
					    if name in bgs:
 | 
				
			||||||
 | 
					        bgs.remove(name)
 | 
				
			||||||
 | 
					        set_badges(user_id, bgs)
 | 
				
			||||||
@@ -679,6 +679,73 @@ p.mentioned span.chatmessage {
 | 
				
			|||||||
  top: -5px;
 | 
					  top: -5px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#usercard .identity {
 | 
				
			||||||
 | 
					  display: inline;
 | 
				
			||||||
 | 
					  vertical-align: sub;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#usercard .identity .hash, #usercard .identity .discriminator {
 | 
				
			||||||
 | 
					  font-size: 1.30rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#usercard .bottag {
 | 
				
			||||||
 | 
					  background-color: #5DADE2;
 | 
				
			||||||
 | 
					  padding: 5px;
 | 
				
			||||||
 | 
					  border-radius: 10px;
 | 
				
			||||||
 | 
					  font-weight: bold;
 | 
				
			||||||
 | 
					  margin-left: 7px;
 | 
				
			||||||
 | 
					  font-size: 10pt;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#usercard .role .bubble {
 | 
				
			||||||
 | 
					  color: #cacbce;
 | 
				
			||||||
 | 
					  border: 1px solid;
 | 
				
			||||||
 | 
					  border-color: inherit;
 | 
				
			||||||
 | 
					  border-radius: 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#usercard .role .text, #usercard .role .color {
 | 
				
			||||||
 | 
					  margin-left: 5px;
 | 
				
			||||||
 | 
					  margin-right: 5px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#usercard .role .color {
 | 
				
			||||||
 | 
					  display: inline-block;
 | 
				
			||||||
 | 
					  width: 10px;
 | 
				
			||||||
 | 
					  height: 10px;
 | 
				
			||||||
 | 
					  background-color: #cacbce;
 | 
				
			||||||
 | 
					  margin-right: 0;
 | 
				
			||||||
 | 
					  border-radius: 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#usercard .role .text {
 | 
				
			||||||
 | 
					  color: lightgray;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#usercard .game {
 | 
				
			||||||
 | 
					  font-weight: bold;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#usercard .game .text {
 | 
				
			||||||
 | 
					  font-weight: normal;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#usercard .badges .star {
 | 
				
			||||||
 | 
					  color: yellow;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#usercard .badges .supporter {
 | 
				
			||||||
 | 
					  color: limegreen;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#usercard .badges .administrator {
 | 
				
			||||||
 | 
					  color: hotpink;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#usercard .badges .partner {
 | 
				
			||||||
 | 
					  color: orange;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#google-recaptcha {
 | 
					#google-recaptcha {
 | 
				
			||||||
  margin: 0 auto;
 | 
					  margin: 0 auto;
 | 
				
			||||||
  width: 302px;
 | 
					  width: 302px;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,13 @@
 | 
				
			|||||||
/* global $, Materialize, location */
 | 
					/* global $, Materialize, location */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function postForm(user_id, css, css_limit, guest_icon) {
 | 
					function postForm(user_id, css, css_limit, guest_icon, badges) {
 | 
				
			||||||
    if (css_limit == "") {
 | 
					    if (css_limit == "") {
 | 
				
			||||||
        css_limit = 0;
 | 
					        css_limit = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    var funct = $.ajax({
 | 
					    var funct = $.ajax({
 | 
				
			||||||
        dataType: "json",
 | 
					        dataType: "json",
 | 
				
			||||||
        method: "POST",
 | 
					        method: "POST",
 | 
				
			||||||
        data: {"user_id": user_id, "css": css, "css_limit": css_limit, "guest_icon": guest_icon}
 | 
					        data: {"user_id": user_id, "css": css, "css_limit": css_limit, "guest_icon": guest_icon, "badges": badges}
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    return funct.promise();
 | 
					    return funct.promise();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -32,6 +32,7 @@ function patchForm(user_id, param) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(function() {
 | 
					$(function() {
 | 
				
			||||||
 | 
					    $('select').material_select();
 | 
				
			||||||
    $("#new_submit").click(function () {
 | 
					    $("#new_submit").click(function () {
 | 
				
			||||||
        var user_id = $("#new_user_id").val();
 | 
					        var user_id = $("#new_user_id").val();
 | 
				
			||||||
        if (user_id.length < 1) {
 | 
					        if (user_id.length < 1) {
 | 
				
			||||||
@@ -41,7 +42,8 @@ $(function() {
 | 
				
			|||||||
        var css_checked = $("#new_css_switch").is(':checked');
 | 
					        var css_checked = $("#new_css_switch").is(':checked');
 | 
				
			||||||
        var css_limit = $("#new_css_limit").val();
 | 
					        var css_limit = $("#new_css_limit").val();
 | 
				
			||||||
        var guest_icon_checked = $("#new_guest_icon_switch").is(':checked');
 | 
					        var guest_icon_checked = $("#new_guest_icon_switch").is(':checked');
 | 
				
			||||||
        var formPost = postForm(user_id, css_checked, css_limit, guest_icon_checked);
 | 
					        var badges = $("#new_badges > option:selected").map(function(){ return this.value }).get().join();
 | 
				
			||||||
 | 
					        var formPost = postForm(user_id, css_checked, css_limit, guest_icon_checked, badges);
 | 
				
			||||||
        formPost.done(function (data) {
 | 
					        formPost.done(function (data) {
 | 
				
			||||||
            location.reload();
 | 
					            location.reload();
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
@@ -115,3 +117,18 @@ function update_guest_icon_switch(user_id, element) {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function update_badges(user_id, element) {
 | 
				
			||||||
 | 
					    var badges = $(element).val().join();
 | 
				
			||||||
 | 
					    var formPatch = patchForm(user_id, {"badges": badges});
 | 
				
			||||||
 | 
					    formPatch.done(function (data) {
 | 
				
			||||||
 | 
					        Materialize.toast('Badges 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 badges!', 10000);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -19,6 +19,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
(function () {
 | 
					(function () {
 | 
				
			||||||
    const theme_options = ["DiscordDark", "BetterTitan"]; // All the avaliable theming names
 | 
					    const theme_options = ["DiscordDark", "BetterTitan"]; // All the avaliable theming names
 | 
				
			||||||
 | 
					    const badges_options = ["administrator", "partner", "supporter", "star"]; // All badges avaliable
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    var user_def_css; // Saves the user defined css
 | 
					    var user_def_css; // Saves the user defined css
 | 
				
			||||||
    var has_already_been_initially_resized = false; // keep track if the embed initially been resized
 | 
					    var has_already_been_initially_resized = false; // keep track if the embed initially been resized
 | 
				
			||||||
@@ -134,6 +135,14 @@
 | 
				
			|||||||
        return funct.promise();
 | 
					        return funct.promise();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    function api_badges(user_id) {
 | 
				
			||||||
 | 
					        var funct = $.ajax({
 | 
				
			||||||
 | 
					            dataType: "json",
 | 
				
			||||||
 | 
					            url: "/api/badges/" + user_id,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        return funct.promise();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    $(function() {
 | 
					    $(function() {
 | 
				
			||||||
        if ($("#user-defined-css").length > 0) {
 | 
					        if ($("#user-defined-css").length > 0) {
 | 
				
			||||||
            user_def_css = $("#user-defined-css").text();
 | 
					            user_def_css = $("#user-defined-css").text();
 | 
				
			||||||
@@ -165,6 +174,9 @@
 | 
				
			|||||||
            inDuration: 400,
 | 
					            inDuration: 400,
 | 
				
			||||||
            outDuration: 400,
 | 
					            outDuration: 400,
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					        $("#usercard").modal({
 | 
				
			||||||
 | 
					            opacity: .5,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        $("#nameplate").click(function () {
 | 
					        $("#nameplate").click(function () {
 | 
				
			||||||
            $("#userembedmodal").modal("open");
 | 
					            $("#userembedmodal").modal("open");
 | 
				
			||||||
@@ -607,7 +619,7 @@
 | 
				
			|||||||
            var rendered_user = Mustache.render(template_user, {"id": member.id.toString() + "d", "username": member_name, "avatar": member.avatar_url});
 | 
					            var rendered_user = Mustache.render(template_user, {"id": member.id.toString() + "d", "username": member_name, "avatar": member.avatar_url});
 | 
				
			||||||
            $("#discord-members").append(rendered_user);
 | 
					            $("#discord-members").append(rendered_user);
 | 
				
			||||||
            $( "#discorduser-" + member.id.toString() + "d").click({"member_id": member.id.toString()}, function(event) {
 | 
					            $( "#discorduser-" + member.id.toString() + "d").click({"member_id": member.id.toString()}, function(event) {
 | 
				
			||||||
              mention_member(event.data.member_id);
 | 
					              openUserCard(event.data.member_id);
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            if (member.color) {
 | 
					            if (member.color) {
 | 
				
			||||||
              $( "#discorduser-" + member.id.toString() + "d").css("color", "#" + member.color);
 | 
					              $( "#discorduser-" + member.id.toString() + "d").css("color", "#" + member.color);
 | 
				
			||||||
@@ -631,7 +643,7 @@
 | 
				
			|||||||
            var rendered = Mustache.render(template, {"id": member.id.toString() + "a", "username": username, "avatar": member.avatar_url});
 | 
					            var rendered = Mustache.render(template, {"id": member.id.toString() + "a", "username": username, "avatar": member.avatar_url});
 | 
				
			||||||
            $("#embed-discord-members").append(rendered);
 | 
					            $("#embed-discord-members").append(rendered);
 | 
				
			||||||
            $( "#discorduser-" + member.id.toString() + "a").click({"member_id": member.id.toString()}, function(event) {
 | 
					            $( "#discorduser-" + member.id.toString() + "a").click({"member_id": member.id.toString()}, function(event) {
 | 
				
			||||||
              mention_member(event.data.member_id);
 | 
					              openUserCard(event.data.member_id);
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        authenticated_users_list = users;
 | 
					        authenticated_users_list = users;
 | 
				
			||||||
@@ -679,6 +691,60 @@
 | 
				
			|||||||
        }, 5000);
 | 
					        }, 5000);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    function openUserCard(user_id) {
 | 
				
			||||||
 | 
					        var bgs = api_badges(user_id);
 | 
				
			||||||
 | 
					        bgs.done(function (data) {
 | 
				
			||||||
 | 
					            for (var i = 0; i < badges_options.length; i++) {
 | 
				
			||||||
 | 
					                var badge = badges_options[i];
 | 
				
			||||||
 | 
					                if (data.indexOf(badge) != -1) {
 | 
				
			||||||
 | 
					                    $(`#usercard .badges .${badge}`).show();
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    $(`#usercard .badges .${badge}`).hide();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        for (var i = 0; i < discord_users_list.length; i++) {
 | 
				
			||||||
 | 
					            var usr = discord_users_list[i];
 | 
				
			||||||
 | 
					            if (usr.id == user_id) {
 | 
				
			||||||
 | 
					                $("#usercard .avatar").attr("src", usr.avatar_url);
 | 
				
			||||||
 | 
					                $("#usercard .identity .username").text(usr.username);
 | 
				
			||||||
 | 
					                $("#usercard .identity .discriminator").text(usr.discriminator);
 | 
				
			||||||
 | 
					                if (usr.bot) {
 | 
				
			||||||
 | 
					                    $("#usercard .bottag").show();
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    $("#usercard .bottag").hide();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (usr.status == "offline") {
 | 
				
			||||||
 | 
					                    $("#usercard .offline-text").show();
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    $("#usercard .offline-text").hide();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (usr["hoist-role"]) {
 | 
				
			||||||
 | 
					                    $("#usercard .role").show();
 | 
				
			||||||
 | 
					                    $("#usercard .role .text").text(usr["hoist-role"].name);
 | 
				
			||||||
 | 
					                    if (usr.color) {
 | 
				
			||||||
 | 
					                        $("#usercard .role .bubble").css("color", "#" + usr.color);
 | 
				
			||||||
 | 
					                        $("#usercard .role .color").css("background-color", "#" + usr.color);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    $("#usercard .role").hide();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (usr.game) {
 | 
				
			||||||
 | 
					                    $("#usercard .game").show();
 | 
				
			||||||
 | 
					                    $("#usercard .game .text").text(usr.game.name);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    $("#usercard .game").hide();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                $("#usercard-mention-btn").off("click");
 | 
				
			||||||
 | 
					                $("#usercard-mention-btn").click(function () {
 | 
				
			||||||
 | 
					                    mention_member(user_id);
 | 
				
			||||||
 | 
					                    $("#usercard").modal('close');
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $("#usercard").modal('open');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    function flashElement(element) {
 | 
					    function flashElement(element) {
 | 
				
			||||||
        var opacity = element.css("opacity");
 | 
					        var opacity = element.css("opacity");
 | 
				
			||||||
        for (var i = 0; i < 3; i++) {
 | 
					        for (var i = 0; i < 3; i++) {
 | 
				
			||||||
@@ -966,7 +1032,7 @@
 | 
				
			|||||||
                $("#chatcontent .chatusername").last().click(function () {
 | 
					                $("#chatcontent .chatusername").last().click(function () {
 | 
				
			||||||
                    var discordid = $(this).parent().attr("discord_userid");
 | 
					                    var discordid = $(this).parent().attr("discord_userid");
 | 
				
			||||||
                    if (discordid) {
 | 
					                    if (discordid) {
 | 
				
			||||||
                        mention_member(discordid);
 | 
					                        openUserCard(discordid);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
                $("#chatcontent p:last-child").find(".channellink").click(function () {
 | 
					                $("#chatcontent p:last-child").find(".channellink").click(function () {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,6 +15,7 @@
 | 
				
			|||||||
              <th>CSS</th>
 | 
					              <th>CSS</th>
 | 
				
			||||||
              <th>CSS Limit</th>
 | 
					              <th>CSS Limit</th>
 | 
				
			||||||
              <th>Guest Icon</th>
 | 
					              <th>Guest Icon</th>
 | 
				
			||||||
 | 
					              <th>Badges</th>
 | 
				
			||||||
              <th>Submit</th>
 | 
					              <th>Submit</th>
 | 
				
			||||||
          </tr>
 | 
					          </tr>
 | 
				
			||||||
        </thead>
 | 
					        </thead>
 | 
				
			||||||
@@ -50,6 +51,17 @@
 | 
				
			|||||||
                    </label>
 | 
					                    </label>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </td>
 | 
					            </td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					              <div class="input-field col s12">
 | 
				
			||||||
 | 
					                <select multiple id="new_badges">
 | 
				
			||||||
 | 
					                  <option value="" disabled>Choose your option</option>
 | 
				
			||||||
 | 
					                  <option value="administrator">TitanEmbeds Administrators</option>
 | 
				
			||||||
 | 
					                  <option value="partner">TitanEmbeds Partner</option>
 | 
				
			||||||
 | 
					                  <option value="supporter">TitanEmbeds Supporter</option>
 | 
				
			||||||
 | 
					                  <option value="star">GitHub Stargazer</option>
 | 
				
			||||||
 | 
					                </select>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
            <td>
 | 
					            <td>
 | 
				
			||||||
                <a class="waves-effect waves-light btn" id="new_submit">Submit</a>
 | 
					                <a class="waves-effect waves-light btn" id="new_submit">Submit</a>
 | 
				
			||||||
            </td>
 | 
					            </td>
 | 
				
			||||||
@@ -69,6 +81,7 @@
 | 
				
			|||||||
              <th>CSS</th>
 | 
					              <th>CSS</th>
 | 
				
			||||||
              <th>CSS Limit</th>
 | 
					              <th>CSS Limit</th>
 | 
				
			||||||
              <th>Guest Icon</th>
 | 
					              <th>Guest Icon</th>
 | 
				
			||||||
 | 
					              <th>Badges</th>
 | 
				
			||||||
          </tr>
 | 
					          </tr>
 | 
				
			||||||
        </thead>
 | 
					        </thead>
 | 
				
			||||||
        <tbody>
 | 
					        <tbody>
 | 
				
			||||||
@@ -101,6 +114,17 @@
 | 
				
			|||||||
                    </label>
 | 
					                    </label>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </td>
 | 
					            </td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					              <div class="input-field col s12">
 | 
				
			||||||
 | 
					                <select multiple id="new_badges" onchange="update_badges('{{ cosmetic.user_id }}', this)">
 | 
				
			||||||
 | 
					                  <option value="" disabled>Choose your option</option>
 | 
				
			||||||
 | 
					                  <option value="administrator" {% if "administrator" in cosmetic.badges %}selected{% endif %}>TitanEmbeds Administrators</option>
 | 
				
			||||||
 | 
					                  <option value="partner" {% if "partner" in cosmetic.badges %}selected{% endif %}>TitanEmbeds Partner</option>
 | 
				
			||||||
 | 
					                  <option value="supporter" {% if "supporter" in cosmetic.badges %}selected{% endif %}>TitanEmbeds Supporter</option>
 | 
				
			||||||
 | 
					                  <option value="star" {% if "star" in cosmetic.badges %}selected{% endif %}>GitHub Stargazer</option>
 | 
				
			||||||
 | 
					                </select>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
          </tr>
 | 
					          </tr>
 | 
				
			||||||
          {% endfor %}
 | 
					          {% endfor %}
 | 
				
			||||||
        </tbody>
 | 
					        </tbody>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -175,6 +175,30 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    <div id="usercard" class="modal bottom-sheet">
 | 
				
			||||||
 | 
					      <div class="modal-content">
 | 
				
			||||||
 | 
					        <div class="row">
 | 
				
			||||||
 | 
					          <div class="col s12 m1">
 | 
				
			||||||
 | 
					            <img class="circle avatar" src="">
 | 
				
			||||||
 | 
					            <br>
 | 
				
			||||||
 | 
					            <a class="waves-effect waves-light btn" id="usercard-mention-btn">Mention</a>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          <div class="col s12 m11">
 | 
				
			||||||
 | 
					            <h4 class="identity"><span class="username"></span><span class="hash">#</span><span class="discriminator"></span></h4> <span class="bottag">BOT</span>
 | 
				
			||||||
 | 
					            <div class="badges">
 | 
				
			||||||
 | 
					              <a class="administrator tooltipped" data-tooltip="TitanEmbeds Administrator" data-position="top" href="https://titanembeds.com/" target="_blank"><i class="material-icons">gavel</i></a>
 | 
				
			||||||
 | 
					              <a class="partner tooltipped" data-tooltip="TitanEmbeds Partner" data-position="top" href="https://titanembeds.com/about" target="_blank"><i class="material-icons">person_pin</i></a>
 | 
				
			||||||
 | 
					              <a class="supporter tooltipped" data-tooltip="TitanEmbeds Supporter" data-position="top" href="https://titanembeds.com/user/donate" target="_blank"><i class="material-icons">attach_money</i></a>
 | 
				
			||||||
 | 
					              <a class="star tooltipped" data-tooltip="GitHub Stargazer" data-position="top" href="https://github.com/TitanEmbeds/Titan" target="_blank"><i class="material-icons">star</i></a>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <p class="offline-text">User is Offline.</p>
 | 
				
			||||||
 | 
					            <p class="game">Playing <span class="text"></span></p>
 | 
				
			||||||
 | 
					            <p class="role">Highest Role: <span class="bubble"><span class="color"></span> <span class="text"></span></span></p>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    <div id="emoji-picker">
 | 
					    <div id="emoji-picker">
 | 
				
			||||||
      <div id="emoji-picker-content">
 | 
					      <div id="emoji-picker-content">
 | 
				
			||||||
        <div class="row">
 | 
					        <div class="row">
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user