forked from rDrama/rDrama
make it possible to equip multiple hats
parent
82237ca585
commit
1816ce09f7
|
@ -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)
|
||||
|
||||
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)
|
|
@ -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,
|
||||
|
|
|
@ -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!"}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue