make it possible to equip multiple hats

remotes/1693045480750635534/spooky-22
Aevann1 2022-09-05 05:44:24 +02:00
parent 82237ca585
commit 1816ce09f7
4 changed files with 71 additions and 49 deletions

View File

@ -30,5 +30,16 @@ class Hat(Base):
user_id = Column(Integer, ForeignKey('users.id'), primary_key=True)
hat_id = Column(Integer, ForeignKey('hat_defs.id'), primary_key=True)
equipped = Column(Boolean, default=False)
owners = relationship("User", back_populates="owned_hats")
hat_def = relationship("HatDef")
owners = relationship("User", back_populates="owned_hats")
@property
@lazy
def name(self):
return self.hat_def.name
@lazy
def censored_description(self, v):
return self.hat_def.censored_description(v)

View File

@ -139,7 +139,6 @@ class User(Base):
earlylife = Column(Integer)
owoify = Column(Integer)
marsify = Column(Integer)
equipped_hat_id = Column(Integer, ForeignKey("hat_defs.id"))
badges = relationship("Badge", order_by="Badge.created_utc", back_populates="user")
subscriptions = relationship("Subscription", back_populates="user")
@ -152,7 +151,6 @@ class User(Base):
apps = relationship("OauthApp", back_populates="author")
awards = relationship("AwardRelationship", primaryjoin="User.id==AwardRelationship.user_id", back_populates="user")
referrals = relationship("User")
equipped_hat = relationship("HatDef", primaryjoin="User.equipped_hat_id==HatDef.id")
designed_hats = relationship("HatDef", primaryjoin="User.id==HatDef.author_id", back_populates="author")
owned_hats = relationship("Hat", back_populates="owners")
@ -184,6 +182,43 @@ class User(Base):
def num_of_designed_hats(self):
return len(self.designed_hats)
@property
@lazy
def equipped_hats(self):
return g.db.query(Hat).filter_by(user_id=self.id, equipped=True).all()
@property
@lazy
def equipped_hat_ids(self):
return [x.hat_id for x in self.equipped_hats]
@property
@lazy
def hat_active(self):
if not FEATURES['HATS']:
return ''
if self.is_cakeday:
return 'Cakeday.webp'
if self.equipped_hats:
return random.choice(self.equipped_hats).name + '.webp'
return ''
@lazy
def hat_tooltip(self, v):
if not FEATURES['HATS']:
return ''
if self.is_cakeday:
return "I've spent another year rotting my brain with dramaposting, please ridicule me 🤓"
if self.equipped_hats:
return random.choice(self.equipped_hats).censored_description(v)
return ''
@property
@lazy
def name_color(self):
@ -652,33 +687,6 @@ class User(Base):
return self.profileurl
return f"{SITE_FULL}/assets/images/default-profile-pic.webp?v=1008"
@property
@lazy
def hat_active(self):
if not FEATURES['HATS']:
return ''
if self.is_cakeday:
return 'Cakeday.webp'
if self.equipped_hat_id:
return self.equipped_hat.name + '.webp'
return ''
@lazy
def hat_tooltip(self, v):
if not FEATURES['HATS']:
return ''
if self.is_cakeday:
return "I've spent another year rotting my brain with dramaposting, please ridicule me 🤓"
if self.equipped_hat_id:
return self.equipped_hat.censored_description(v)
return ''
@lazy
def json_popover(self, v):
data = {'username': self.username,

View File

@ -13,8 +13,10 @@ def hats(v):
owned_hat_ids = [x.hat_id for x in v.owned_hats]
if v.equipped_hat_id:
owned = [(v.equipped_hat, v.equipped_hat.author)] + g.db.query(HatDef, User).join(HatDef.author).filter(HatDef.id.in_(owned_hat_ids), HatDef.id != v.equipped_hat_id).order_by(HatDef.price, HatDef.name).all()
if v.equipped_hat_ids:
equipped = g.db.query(HatDef, User).join(HatDef.author).filter(HatDef.id.in_(owned_hat_ids), HatDef.id.in_(v.equipped_hat_ids)).order_by(HatDef.price, HatDef.name).all()
not_equipped = g.db.query(HatDef, User).join(HatDef.author).filter(HatDef.id.in_(owned_hat_ids), HatDef.id.notin_(v.equipped_hat_ids)).order_by(HatDef.price, HatDef.name).all()
owned = equipped + not_equipped
else:
owned = g.db.query(HatDef, User).join(HatDef.author).filter(HatDef.id.in_(owned_hat_ids)).order_by(HatDef.price, HatDef.name).all()
@ -83,18 +85,24 @@ def equip_hat(v, hat_id):
hat = g.db.query(Hat).filter_by(hat_id=hat_id, user_id=v.id).one_or_none()
if not hat: return {"error": "You don't own this hat!"}
v.equipped_hat_id = hat_id
g.db.add(v)
hat.equipped = True
g.db.add(hat)
return {"message": "Hat equipped!"}
@app.post("/unequip_hat")
@app.post("/unequip_hat/<hat_id>")
@auth_required
def unequip_hat(v):
def unequip_hat(v, hat_id):
if not FEATURES['HATS']: abort(404)
v.equipped_hat_id = None
g.db.add(v)
try: hat_id = int(hat_id)
except: return {"error": "Hat not found!"}
hat = g.db.query(Hat).filter_by(hat_id=hat_id, user_id=v.id).one_or_none()
if not hat: return {"error": "You don't own this hat!"}
hat.equipped = False
g.db.add(hat)
return {"message": "Hat unequipped!"}

View File

@ -19,17 +19,12 @@
{% block content %}
<script>
function equip_hat(t, hat_id, hat_name) {
const old_unequip_btn = document.querySelector(".unequip:not(.d-none)");
const profile_img = document.getElementById("profile-pic-35-hat");
const profile_pic_hat = document.getElementById("profile-pic-35-hat");
function extra_actions(xhr) {
if(xhr.status != 200) return
if (old_unequip_btn) {
old_unequip_btn.classList.add('d-none');
old_unequip_btn.nextElementSibling.classList.remove('d-none');
if(xhr.status == 200) {
profile_pic_hat.src = `/i/hats/${hat_name}.webp?v=1`
profile_pic_hat.classList.remove('d-none')
}
profile_img.src = `/i/hats/${hat_name}.webp?v=1`
profile_img.classList.remove('d-none')
}
post_toast(t, `/equip_hat/${hat_id}`, `equip-${hat_id}`, `unequip-${hat_id}`, `d-none`, extra_actions)
@ -84,9 +79,9 @@
{% endif %}
<div id="if-owned-{{hat.id}}" {% if hat.id not in owned_hat_ids %}class="d-none"{% endif %}>
<a id="unequip-{{hat.id}}" class="unequip {% if hat.id != v.equipped_hat.id %}d-none{% endif %} btn btn-success" role="button" onclick="post_toast(this, '/unequip_hat', 'equip-{{hat.id}}', 'unequip-{{hat.id}}', 'd-none');document.getElementById('profile-pic-35-hat').classList.add('d-none')"><span class="m-auto">Unequip</span></a>
<a id="unequip-{{hat.id}}" class="unequip {% if hat.id not in v.equipped_hat_ids %}d-none{% endif %} btn btn-success" role="button" onclick="post_toast(this, '/unequip_hat/{{hat.id}}', 'equip-{{hat.id}}', 'unequip-{{hat.id}}', 'd-none')"><span class="m-auto">Unequip</span></a>
<a id="equip-{{hat.id}}" class="equip {% if hat.id == v.equipped_hat.id %}d-none{% endif %} btn btn-success" role="button" onclick="equip_hat(this, '{{hat.id}}', '{{hat.name}}')"><span class="m-auto">Equip</span></a>
<a id="equip-{{hat.id}}" class="equip {% if hat.id in v.equipped_hat_ids %}d-none{% endif %} btn btn-success" role="button" onclick="equip_hat(this, '{{hat.id}}', '{{hat.name}}')"><span class="m-auto">Equip</span></a>
</div>
</td>
</tr>