replace train and scooter award with a "horizontal" selection to "emoji" award

master
Aevann 2023-10-09 01:42:05 +03:00
parent e8b932431d
commit 19c352c8f0
10 changed files with 168 additions and 156 deletions

View File

@ -1,3 +1,5 @@
/*generic*/
#awards-container { #awards-container {
position: absolute; position: absolute;
overflow: hidden; overflow: hidden;
@ -14,58 +16,32 @@
animation-timing-function: linear !important; animation-timing-function: linear !important;
} }
.scooter img {
width: min(7vw, 50px) !important;
}
.emoji-award img { /*emoji*/
.emoji-award img, .emoji-hz-award img {
width: min(10vw, 60px) !important; width: min(10vw, 60px) !important;
} }
.train img { .emoji-award:nth-child(even) {
width: min(10vw, 80px) !important; animation-direction: alternate-reverse;
} }
.emoji-award:nth-child(2) img, .emoji-award:nth-child(3) img, .emoji-award:nth-child(6) img, .emoji-award:nth-child(7) img, .emoji-award:nth-child(10) img, .emoji-award:nth-child(11) img, .emoji-award:nth-child(14) img, .emoji-award:nth-child(15) img, .emoji-award:nth-child(18) img, .emoji-award:nth-child(19) img {
.emoji-award:nth-child(even), .emoji-award:nth-child(n+2):nth-child(n+3) img {
animation-direction: alternate-reverse; animation-direction: alternate-reverse;
} }
@keyframes emojiX { @keyframes emojiX {
0% {
opacity: 1;
}
100% { 100% {
opacity: 1;
transform: translateX(98vw); transform: translateX(98vw);
} }
} }
@keyframes emojiY { @keyframes emojiY {
0% {
opacity: 1;
}
100% { 100% {
opacity: 1;
transform: translateY(80vh); transform: translateY(80vh);
} }
} }
.train:nth-child(1), .scooter:nth-child(1) {top:2%}
.train:nth-child(2), .scooter:nth-child(2) {top:27%}
.train:nth-child(3), .scooter:nth-child(3) {top:52%}
.train:nth-child(4), .scooter:nth-child(4) {top:77%}
.train:nth-child(odd) {animation-direction: reverse;}
.train:nth-child(odd) img {transform: scaleX(-1);}
@keyframes train {
from {transform: translateX(-10vw)}
to {transform: translateX(110vw)}
}
.scooter:nth-child(even) {animation-direction: reverse;}
.scooter:nth-child(even) img {transform: scaleX(-1);}
.emoji-award { .emoji-award {
animation: emojiX 8s alternate; animation: emojiX 8s alternate;
} }
@ -73,10 +49,6 @@
animation: emojiY 9s alternate; animation: emojiY 9s alternate;
} }
.train, .scooter {
animation: train 12s;
}
@media (max-width: 768px) { @media (max-width: 768px) {
.emoji-award { .emoji-award {
animation: emojiX 6s alternate; animation: emojiX 6s alternate;
@ -84,9 +56,62 @@
.emoji-award img { .emoji-award img {
animation: emojiY 7s alternate; animation: emojiY 7s alternate;
} }
.train, .scooter { }
animation: train 6s;
.emoji-hz-award:nth-child(odd) {
animation-direction: reverse;
}
.emoji-hz-award:nth-child(odd) img {
transform: scaleX(-1);
}
.emoji-hz-award:nth-child(1), .emoji-hz-award:nth-child(5), .emoji-hz-award:nth-child(9), .emoji-hz-award:nth-child(13), .emoji-hz-award:nth-child(17) {
top: 2%;
}
.emoji-hz-award:nth-child(2), .emoji-hz-award:nth-child(6), .emoji-hz-award:nth-child(10), .emoji-hz-award:nth-child(14), .emoji-hz-award:nth-child(18) {
top: 27%;
}
.emoji-hz-award:nth-child(3), .emoji-hz-award:nth-child(7), .emoji-hz-award:nth-child(11), .emoji-hz-award:nth-child(15), .emoji-hz-award:nth-child(19) {
top: 52%;
}
.emoji-hz-award:nth-child(4), .emoji-hz-award:nth-child(8), .emoji-hz-award:nth-child(12), .emoji-hz-award:nth-child(16), .emoji-hz-award:nth-child(20) {
top: 77%;
}
@keyframes emoji-hz {
0% {
transform: translateX(-10vw);
} }
100% {
transform: translateX(110vw);
}
}
.emoji-hz-award {
animation: emoji-hz 12s;
}
@media (max-width: 768px) {
.emoji-hz-award {
animation: emoji-hz 6s;
}
}
.animation-delay-1 {
animation-delay: 1s !important;
}
.animation-delay-2 {
animation-delay: 2s !important;
}
.animation-delay-3 {
animation-delay: 3s !important;
}
.animation-delay-4 {
animation-delay: 4s !important;
}
.emoji-award, .emoji-hz-award {
transform: translateX(-10vw);
} }
/*confetti*/ /*confetti*/
@ -222,7 +247,7 @@
animation: 60s linear 0s infinite move-colors; animation: 60s linear 0s infinite move-colors;
} }
.queen:not(a):not(.ectoplasm), h1.queen.post-title a { .queen:not(a) img, .emoji-award:not(.ectoplasm), h1.queen.post-title a {
color: hotpink !important; color: hotpink !important;
font-weight: 700 !important; font-weight: 700 !important;
text-transform: lowercase !important; text-transform: lowercase !important;
@ -274,44 +299,6 @@
font-weight: 400; font-weight: 400;
} }
.animation-delay-1 {
opacity: 0;
animation-delay: 1s;
}
.animation-delay-2 {
opacity: 0;
animation-delay: 2s;
}
.animation-delay-3 {
opacity: 0;
animation-delay: 3s;
}
.animation-delay-4 {
opacity: 0;
animation-delay: 4s;
}
.animation-delay-5 {
opacity: 0;
animation-delay: 5s;
}
.animation-delay-6 {
opacity: 0;
animation-delay: 6s;
}
.animation-delay-7 {
opacity: 0;
animation-delay: 7s;
}
.animation-delay-8 {
opacity: 0;
animation-delay: 8s;
}
.animation-delay-9 {
opacity: 0;
animation-delay: 9s;
}
@keyframes move-colors { @keyframes move-colors {
from {background-position: 0px;} from {background-position: 0px;}
to {background-position: 1000px;} to {background-position: 1000px;}

View File

@ -7187,12 +7187,12 @@ input::-webkit-inner-spin-button {
min-height: 60px; min-height: 60px;
} }
#notelabel { #notelabel, #emoji_behavior_label {
font-size: 16px; font-size: 16px;
} }
@media (max-width: 768px) { @media (max-width: 768px) {
#note, #notelabel { #note, #notelabel, #emoji_behavior_label {
font-size: 14px !important; font-size: 14px !important;
} }
} }

View File

@ -92,6 +92,9 @@ function vote(type, id, dir) {
let global_price; let global_price;
const note_section = document.getElementById('note_section')
const gif_button = note_section.querySelector('[title="Add GIF"]')
function pick(kind, price, coins, marseybux) { function pick(kind, price, coins, marseybux) {
global_price = price; global_price = price;
@ -120,11 +123,22 @@ function pick(kind, price, coins, marseybux) {
if (kind == "chud") { if (kind == "chud") {
document.getElementById('phrase_section').classList.remove("d-none") document.getElementById('phrase_section').classList.remove("d-none")
document.getElementById('note_section').classList.add("d-none") note_section.classList.add("d-none")
} }
else { else {
document.getElementById('phrase_section').classList.add("d-none") document.getElementById('phrase_section').classList.add("d-none")
document.getElementById('note_section').classList.remove("d-none") note_section.classList.remove("d-none")
}
if (kind == "emoji") {
document.getElementById('emoji_behavior_section').classList.remove("d-none")
document.getElementById('note').setAttribute("style", "min-height:35px;max-height:35px;height:35px;min-width:min(300px,80vw)")
gif_button.classList.add('d-none')
}
else {
document.getElementById('emoji_behavior_section').classList.add("d-none")
document.getElementById('note').removeAttribute("style")
gif_button.classList.remove('d-none')
} }
if (kind == "flairlock") { if (kind == "flairlock") {
@ -185,7 +199,8 @@ function giveaward(t) {
postToast(t, t.dataset.action, postToast(t, t.dataset.action,
{ {
"kind": kind, "kind": kind,
"note": document.getElementById(note_id).value "note": document.getElementById(note_id).value,
"emoji_behavior": document.getElementById("emoji_behavior").value
}, },
() => { () => {
let owned = document.getElementById(`${kind}-owned`) let owned = document.getElementById(`${kind}-owned`)

View File

@ -20,6 +20,13 @@ from files.helpers.sorting_and_time import *
from .saves import CommentSaveRelationship from .saves import CommentSaveRelationship
def get_emoji_awards_emojis(obj, v, kind, OVER_18_EMOJIS):
if g.show_nsfw:
emojis = [x.note for x in obj.awards if x.kind == kind]
else:
emojis = [x.note for x in obj.awards if x.kind == kind and x.note not in OVER_18_EMOJIS]
return reversed(emojis[:20])
def get_award_classes(obj, v, title=False): def get_award_classes(obj, v, title=False):
classes = [] classes = []
@ -321,12 +328,6 @@ class Comment(Base):
return 0 return 0
return len([x for x in self.awards if x.kind == kind]) return len([x for x in self.awards if x.kind == kind])
@lazy
def emoji_award_emojis(self, v, OVER_18_EMOJIS):
if g.show_nsfw:
return [x.note for x in self.awards if x.kind == "emoji"][:10]
return [x.note for x in self.awards if x.kind == "emoji" and x.note not in OVER_18_EMOJIS][:10]
@property @property
@lazy @lazy
def json(self): def json(self):
@ -505,3 +506,7 @@ class Comment(Base):
@lazy @lazy
def award_classes(self, v): def award_classes(self, v):
return get_award_classes(self, v) return get_award_classes(self, v)
@lazy
def emoji_awards_emojis(self, v, kind, OVER_18_EMOJIS):
return get_emoji_awards_emojis(self, v, kind, OVER_18_EMOJIS)

View File

@ -15,7 +15,7 @@ from files.helpers.lazy import lazy
from files.helpers.regex import * from files.helpers.regex import *
from files.helpers.sorting_and_time import make_age_string from files.helpers.sorting_and_time import make_age_string
from .comment import normalize_urls_runtime, add_options, get_award_classes from .comment import *
from .polls import * from .polls import *
from .hole import * from .hole import *
from .subscriptions import * from .subscriptions import *
@ -262,12 +262,6 @@ class Post(Base):
return 4 return 4
return num return num
@lazy
def emoji_award_emojis(self, v, OVER_18_EMOJIS):
if g.show_nsfw:
return [x.note for x in self.awards if x.kind == "emoji"][:10]
return [x.note for x in self.awards if x.kind == "emoji" and x.note not in OVER_18_EMOJIS][:10]
@lazy @lazy
def realurl(self, v): def realurl(self, v):
url = self.url url = self.url
@ -383,3 +377,7 @@ class Post(Base):
@lazy @lazy
def award_classes(self, v, title=False): def award_classes(self, v, title=False):
return get_award_classes(self, v, title) return get_award_classes(self, v, title)
@lazy
def emoji_awards_emojis(self, v, kind, OVER_18_EMOJIS):
return get_emoji_awards_emojis(self, v, kind, OVER_18_EMOJIS)

View File

@ -463,36 +463,10 @@ AWARDS = {
"enabled": True, "enabled": True,
"positive": True, "positive": True,
}, },
"train": {
"kind": "train",
"title": "Train",
"description": "Summons a train on the post.",
"icon": "fas fa-train",
"color": "text-pink",
"price": 300,
"deflectable": False,
"cosmetic": True,
"ghost": True,
"enabled": True,
"positive": True,
},
"scooter": {
"kind": "scooter",
"title": "Scooter",
"description": "Summons a scooter on the post.",
"icon": "fas fa-flag-usa",
"color": "text-muted",
"price": 300,
"deflectable": False,
"cosmetic": True,
"ghost": True,
"enabled": True,
"positive": True,
},
"emoji": { "emoji": {
"kind": "emoji", "kind": "emoji",
"title": "Emoji", "title": "Emoji",
"description": "Summons a bouncing emoji on the post.", "description": "Summons a moving emoji on the post.",
"icon": "fas fa-smile-beam", "icon": "fas fa-smile-beam",
"color": "text-yellow", "color": "text-yellow",
"price": 300, "price": 300,
@ -502,6 +476,19 @@ AWARDS = {
"enabled": True, "enabled": True,
"positive": True, "positive": True,
}, },
"emoji-hz": {
"kind": "emoji-hz",
"title": "Emoji",
"description": "Summons a moving emoji on the post.",
"icon": "fas fa-smile-beam",
"color": "text-yellow",
"price": 300,
"deflectable": False,
"cosmetic": True,
"ghost": True,
"enabled": False,
"positive": True,
},
"firework": { "firework": {
"kind": "firework", "kind": "firework",
"title": "Fireworks", "title": "Fireworks",

View File

@ -158,6 +158,8 @@ def award_thing(v, thing_type, id):
if kind not in AWARDS: abort(404, "This award doesn't exist") if kind not in AWARDS: abort(404, "This award doesn't exist")
award_title = AWARDS[kind]['title']
award = g.db.query(AwardRelationship).filter( award = g.db.query(AwardRelationship).filter(
AwardRelationship.kind == kind, AwardRelationship.kind == kind,
AwardRelationship.user_id == v.id, AwardRelationship.user_id == v.id,
@ -189,15 +191,15 @@ def award_thing(v, thing_type, id):
if v.id != author.id: if v.id != author.id:
if author.deflector and v.deflector and AWARDS[kind]['deflectable']: if author.deflector and v.deflector and AWARDS[kind]['deflectable']:
msg = f"@{v.username} has tried to give your [{thing_type}]({thing.shortlink}) the {AWARDS[kind]['title']} Award but it was deflected on them, they also had a deflector up, so it bounced back and forth until it vaporized!" msg = f"@{v.username} has tried to give your [{thing_type}]({thing.shortlink}) the {award_title} Award but it was deflected on them, they also had a deflector up, so it bounced back and forth until it vaporized!"
send_repeatable_notification(author.id, msg) send_repeatable_notification(author.id, msg)
msg = f"{safe_username} under the effect of a deflector award; your {AWARDS[kind]['title']} Award has been deflected back to you but your deflector protected you, the award bounced back and forth until it vaporized!" msg = f"{safe_username} under the effect of a deflector award; your {award_title} Award has been deflected back to you but your deflector protected you, the award bounced back and forth until it vaporized!"
send_repeatable_notification(v.id, msg) send_repeatable_notification(v.id, msg)
g.db.delete(award) g.db.delete(award)
return {"message": f"{AWARDS[kind]['title']} award given to {thing_type} successfully!"} return {"message": f"{award_title} award given to {thing_type} successfully!"}
if author.deflector and AWARDS[kind]['deflectable']: if author.deflector and AWARDS[kind]['deflectable']:
author = v author = v
@ -586,12 +588,12 @@ def award_thing(v, thing_type, id):
if v.id != author.id: if v.id != author.id:
if author.deflector and AWARDS[kind]['deflectable']: if author.deflector and AWARDS[kind]['deflectable']:
msg = f"@{v.username} has tried to give your [{thing_type}]({thing.shortlink}) the {AWARDS[kind]['title']} Award but it was deflected and applied to them :marseytroll:" msg = f"@{v.username} has tried to give your [{thing_type}]({thing.shortlink}) the {award_title} Award but it was deflected and applied to them :marseytroll:"
send_repeatable_notification(author.id, msg) send_repeatable_notification(author.id, msg)
msg = f"{safe_username} under the effect of a deflector award; your {AWARDS[kind]['title']} Award has been deflected back to you :marseytroll:" msg = f"{safe_username} under the effect of a deflector award; your {award_title} Award has been deflected back to you :marseytroll:"
send_repeatable_notification(v.id, msg) send_repeatable_notification(v.id, msg)
elif kind != 'spider': elif kind != 'spider':
msg = f"@{v.username} has given [{link_text_in_notif}]({thing.shortlink}) the {AWARDS[kind]['title']} Award" msg = f"@{v.username} has given [{link_text_in_notif}]({thing.shortlink}) the {award_title} Award"
if kind == 'shit': if kind == 'shit':
msg += f" and has stolen from you {awarded_coins} coins as a result" msg += f" and has stolen from you {awarded_coins} coins as a result"
@ -613,7 +615,12 @@ def award_thing(v, thing_type, id):
g.db.add(thing) g.db.add(thing)
return {"message": f"{AWARDS[kind]['title']} award given to {thing_type} successfully!"} if award.kind == "emoji":
emoji_behavior = request.values.get("emoji_behavior").strip()
if emoji_behavior == "horizontal":
award.kind = "emoji-hz"
return {"message": f"{award_title} award given to {thing_type} successfully!"}
@app.post("/trick-or-treat") @app.post("/trick-or-treat")
@limiter.limit("1/hour", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @limiter.limit("1/hour", key_func=lambda:f'{SITE}-{session.get("lo_user")}')

View File

@ -9,25 +9,19 @@
</div> </div>
{% endmacro %} {% endmacro %}
{% if p.award_count("emoji", v) %} {% if p.award_count("emoji", v) or p.award_count("emoji-hz", v) %}
{% for kind in ["emoji", "emoji-hz"] %}
<div class="stackable-container"> <div class="stackable-container">
{% for emoji in p.emoji_award_emojis(v, OVER_18_EMOJIS) %} {% for emoji in p.emoji_awards_emojis(v, kind, OVER_18_EMOJIS) %}
{% set src = '/e/' + emoji + '.webp' %} {% set src = '/e/' + emoji + '.webp' %}
{% set alt = ':#' + emoji + ':' %} {% set alt = ':#' + emoji + ':' %}
{% set delay = 'animation-delay-' ~ (loop.index-1) %} {% set delay = 'animation-delay-' ~ ((loop.index-1)/4)|int %}
<div class="emoji-award {{delay}}"> <div class="{{kind}}-award {{delay}}">
<img class="{{delay}}" loading="lazy" alt="{{alt}}" src="{{src}}"> <img class="{{delay}}" loading="lazy" alt="{{alt}}" src="{{src}}">
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
{% endif %} {% endfor %}
{% if p.award_count("train", v) %}
{{stackable_award('train', '/e/marseytrain.webp', ':#marseytrain:')}}
{% endif %}
{% if p.award_count("scooter", v) %}
{{stackable_award('scooter', '/e/marseyscooter.webp', ':#marseyscooter:')}}
{% endif %} {% endif %}
{% if p.award_count("firework", v) %} {% if p.award_count("firework", v) %}

View File

@ -53,18 +53,35 @@
</div> </div>
</div> </div>
<div id="note_section"> <div class="row pt-4">
<label id="notelabel" for="note" class="pt-4">Note (optional):</label> <div id="note_section" class="col mb-3">
<label id="notelabel" for="note">Note (optional):</label>
<textarea autocomplete="off" id="note" maxlength="200" class="form-control" placeholder="Note to include in award notification..."></textarea> <textarea autocomplete="off" id="note" maxlength="200" class="form-control" placeholder="Note to include in award notification..."></textarea>
{{macros.emoji_btn('note', 'awardModal')}} {{macros.emoji_btn('note', 'awardModal')}}
{{macros.gif_btn('note', 'awardModal')}} {{macros.gif_btn('note', 'awardModal')}}
</div> </div>
<input autocomplete="off" id="giveaward" class="awardbtn btn btn-primary mt-3 fl-r" type="submit" data-nonce="{{g.nonce}}" data-onclick="giveaward(this)" value="Give Award" data-bs-dismiss="modal" disabled> <div id="emoji_behavior_section" class="col d-none mb-3 pb-3">
<label id="emoji_behavior_label" for="behavior">Emoji behavior:</label>
<button type="button" id="buy" class="awardbtn btn btn-primary mt-3 mr-3 fl-r" disabled data-areyousure="buy()" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)">Buy</button> <div class="input-group">
<select autocomplete="off" id='emoji_behavior' class="form-control pr-2" style="min-height:35px;min-width:min(300px,80vw)">
<option value="bouncing">
bouncing
</option>
<option value="horizontal">
horizontal
</option>
</select>
</div>
</div>
</div>
<div id="award_price_block" class="fl-r mt-4 mr-3 d-none text-small-sm"> <input autocomplete="off" id="giveaward" class="awardbtn btn btn-primary fl-r" type="submit" data-nonce="{{g.nonce}}" data-onclick="giveaward(this)" value="Give Award" data-bs-dismiss="modal" disabled>
<button type="button" id="buy" class="awardbtn btn btn-primary mr-3 fl-r" disabled data-areyousure="buy()" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)">Buy</button>
<div id="award_price_block" class="fl-r mt-2 mr-3 d-none text-small-sm">
Price: <span id="award_price"></span> coins/marseybux Price: <span id="award_price"></span> coins/marseybux
</div> </div>
</div> </div>

View File

@ -0,0 +1,2 @@
update award_relationships set kind='emoji-hz', note='marseytrain' where kind='train';
update award_relationships set kind='emoji-hz', note='marseyscooter' where kind='scooter';