From 3558a41860e8ea875273e9b067b982f25c69ecec Mon Sep 17 00:00:00 2001 From: top Date: Wed, 9 Aug 2023 08:33:14 +0000 Subject: [PATCH] Adds marseycide! (#182) Fun modifier for emotes that some people had asked about here: https://rdrama.net/post/194966/ricecop-gets-5-years-for-watching/4753853#context -Doesn't work with reverse due to the way transform works. Might come up with a solution to that later but doesn't matter much for this one since it's hard to tell it's turned with the animation anyways -This breaks current emotes just like talking did since they have the same ending unfortunately. Mostly did this to clean up the ending logic for emotes since it was not extensible, this should scale better (could still be improved). Let me know if you don't like it and I will keep just those changes. Co-authored-by: Chuck Reviewed-on: https://fsdfsd.net/rDrama/rDrama/pulls/182 Co-authored-by: top Co-committed-by: top --- files/assets/css/main.css | 11 ++++++ files/assets/js/markdown.js | 66 +++++++++++++++++++++++++------ files/helpers/sanitize.py | 60 +++++++++++++++++++++++----- files/templates/modals/emoji.html | 4 ++ 4 files changed, 118 insertions(+), 23 deletions(-) diff --git a/files/assets/css/main.css b/files/assets/css/main.css index 8fcbd3f2a..4f22b86b5 100644 --- a/files/assets/css/main.css +++ b/files/assets/css/main.css @@ -5594,6 +5594,17 @@ img[src$="/i/hand.webp"]+img[src^="/pp/"], img[src$="/i/hand.webp"]+img[src$="/p 100% { transform: scale(1, 0.8) } } +@keyframes cide-anim { + 0% { transform: scale(1,1) rotate(0deg) } + 100% { transform: scale(0, 0) rotate(360deg) } +} + +.cide, span[cide] { + display: inline-block; + animation: cide-anim 2s infinite; + animation-timing-function: linear; +} + /* Fix for
    being populated with
  1. in many contexts. */ .post-body li > p:first-child, .comment-text li > p:first-child, diff --git a/files/assets/js/markdown.js b/files/assets/js/markdown.js index 90b938597..b34d37811 100644 --- a/files/assets/js/markdown.js +++ b/files/assets/js/markdown.js @@ -72,8 +72,51 @@ const MODIFIERS = { REVERSED: 4, USER: 5, REVERSED_MODIFIER: 6, + GENOCIDE: 7, }; +const findAllEmoteEndings = (word) => { + let hasReachedNonModifer = false; + let currWord = word; + const currEndings = []; + while(!hasReachedNonModifer) { + if(currWord.endsWith('pat')) { + if(currEndings.indexOf(MODIFIERS.PAT) !== -1) { + hasReachedNonModifer = true; + continue; + } + currWord = currWord.slice(0, -3); + currEndings.push(MODIFIERS.PAT); + continue; + } + + if(currWord.endsWith('talking')) { + if(currEndings.indexOf(MODIFIERS.TALKING) !== -1) { + hasReachedNonModifer = true; + continue; + } + currWord = currWord.slice(0, -7); + currEndings.push(MODIFIERS.TALKING); + continue; + } + + if(currWord.endsWith('genocide')) { + if(currEndings.indexOf(MODIFIERS.GENOCIDE) !== -1) { + hasReachedNonModifer = true; + continue; + } + currWord = currWord.slice(0, -8); + currEndings.push(MODIFIERS.GENOCIDE); + continue; + } + + hasReachedNonModifer = true; + } + + + return [currEndings, currWord]; +} + function markdown(t) { let input = t.value; @@ -110,8 +153,8 @@ function markdown(t) { const modifiers = new Set(); - let length = emoji.length - if (emoji.includes('!!')) modifiers.add(MODIFIERS.REVERSED_MODIFIER); + let length = emoji.length; + if(emoji.includes('!!')) modifiers.add(MODIFIERS.REVERSED_MODIFIER); emoji = emoji.replaceAll('!', ''); if (length !== emoji.length) { modifiers.add(MODIFIERS.REVERSED); @@ -121,15 +164,11 @@ function markdown(t) { if (length !== emoji.length) { modifiers.add(MODIFIERS.LARGE); } - const isTalkingFirst = !(emoji.endsWith('pat') && emoji.slice(0, -3).endsWith('talking')); - if (emoji.endsWith('talking') || (emoji.endsWith('pat') && emoji.slice(0, -3).endsWith('talking'))) { - modifiers.add(MODIFIERS.TALKING); - emoji = emoji.endsWith('pat') ? [emoji.slice(0, -10), emoji.slice(-3)].join('') : emoji.slice(0, -7); - } - if (emoji.endsWith('pat')) { - modifiers.add(MODIFIERS.PAT); - emoji = emoji.slice(0, -3); - } + let endingModifiers; + [endingModifiers, emoji] = findAllEmoteEndings(emoji); + const isTalkingFirst = endingModifiers.indexOf(MODIFIERS.PAT) > endingModifiers.indexOf(MODIFIERS.TALKING); + + endingModifiers.forEach(modifiers.add, modifiers) if (emoji.startsWith('@')) { emoji = emoji.slice(1); @@ -145,18 +184,19 @@ function markdown(t) { } const mirroredClass = 'mirrored'; + const genocideClass = modifiers.has(MODIFIERS.GENOCIDE) ? 'cide' : ''; const emojiClass = modifiers.has(MODIFIERS.LARGE) ? 'emoji-lg' : 'emoji'; // patted emotes cannot be flipped back easily so they don't support double flipping const spanClass = modifiers.has(MODIFIERS.REVERSED) && (modifiers.has(MODIFIERS.PAT) || !modifiers.has(MODIFIERS.REVERSED_MODIFIER)) ? mirroredClass : ''; const imgClass = modifiers.has(MODIFIERS.REVERSED) && modifiers.has(MODIFIERS.REVERSED_MODIFIER) ? mirroredClass : '' - if (modifiers.has(MODIFIERS.PAT) || modifiers.has(MODIFIERS.TALKING)) { + if (modifiers.has(MODIFIERS.PAT) || modifiers.has(MODIFIERS.TALKING) || modifiers.has(MODIFIERS.GENOCIDE)) { const talkingHtml = modifiers.has(MODIFIERS.TALKING) ? `` : ''; const patHtml = modifiers.has(MODIFIERS.PAT) ? `` : ''; const url = modifiers.has(MODIFIERS.USER) ? `/@${emoji}/pic` : `${SITE_FULL_IMAGES}/e/${emoji}.webp`; const modifierHtml = isTalkingFirst ? `${talkingHtml}${patHtml}` : `${patHtml}${talkingHtml}`; - input = input.replace(old, `${modifierHtml}`); + input = input.replace(old, `${modifierHtml}`); } else { input = input.replace(old, ``); } diff --git a/files/helpers/sanitize.py b/files/helpers/sanitize.py index a0daceac1..9389645d7 100644 --- a/files/helpers/sanitize.py +++ b/files/helpers/sanitize.py @@ -99,6 +99,7 @@ def allowed_attributes(tag, name, value): if name == 'data-bs-toggle' and value == 'tooltip': return True if name == 'title': return True if name == 'alt': return True + if name == 'cide' and not value: return True if tag == 'table': if name == 'class' and value == 'table': return True @@ -212,6 +213,42 @@ def execute_blackjack(v, target, body, kind): send_repeatable_notification_duplicated(id, f"Blackjack by @{v.username}: {extra_info}") return True +def find_all_emote_endings(word): + endings = list() + curr_word = word + + is_non_ending_found = False + while not is_non_ending_found: + print(curr_word) + if curr_word.endswith('pat'): + if 'pat' in endings: + is_non_ending_found = True + continue + endings.append('pat') + curr_word = curr_word[:-3] + continue + + if curr_word.endswith('talking'): + if 'talking' in endings: + is_non_ending_found = True + continue + endings.append('talking') + curr_word = curr_word[:-7] + continue + + if curr_word.endswith('genocide'): + if 'genocide' in endings: + is_non_ending_found = True + continue + endings.append('genocide') + curr_word = curr_word[:-8] + continue + + is_non_ending_found = True + + return endings, curr_word + + def render_emoji(html, regexp, golden, emojis_used, b=False, is_title=False): emojis = list(regexp.finditer(html)) captured = set() @@ -245,12 +282,13 @@ def render_emoji(html, regexp, golden, emojis_used, b=False, is_title=False): emoji_partial = ':{0}:' emoji_html = None - is_talking = emoji.endswith('talking') or (emoji[:-3].endswith('talking') and emoji.endswith('pat')) - is_talking_first = emoji.endswith('talking') - emoji = emoji[:-7] if emoji.endswith('talking') else emoji - emoji = f'{emoji[:-10]}pat' if emoji[:-3].endswith('talking') and emoji.endswith('pat') else emoji - is_patted = emoji.endswith('pat') - emoji = emoji[:-3] if is_patted else emoji + ending_modifiers, emoji = find_all_emote_endings(emoji) + + is_talking = 'talking' in ending_modifiers + is_patted = 'pat' in ending_modifiers + is_talking_first = ending_modifiers.index('pat') > ending_modifiers.index('talking') if is_talking and is_patted else False + + is_genocided = 'genocide' in ending_modifiers is_user = emoji.startswith('@') end_modifier_length = 3 if is_patted else 0 @@ -258,8 +296,9 @@ def render_emoji(html, regexp, golden, emojis_used, b=False, is_title=False): hand_html = f'' if is_patted and emoji != 'marseyunpettable' else '' talking_html = f'' if is_talking else '' + genocide_attr = ' cide' if is_genocided else '' - modifier_html = None + modifier_html = '' if (is_talking and is_patted): modifier_html = f'{talking_html}{hand_html}' if is_talking_first else f'{hand_html}{talking_html}' elif (is_patted): @@ -267,12 +306,12 @@ def render_emoji(html, regexp, golden, emojis_used, b=False, is_title=False): elif (is_talking): modifier_html = talking_html - if (is_patted and emoji != 'marseyunpettable') or is_talking: + if (is_patted and emoji != 'marseyunpettable') or is_talking or is_genocided: if path.isfile(f"files/assets/images/emojis/{emoji}.webp"): - emoji_html = f'{modifier_html}{emoji_partial_pat.format(old, f"{SITE_FULL_IMAGES}/e/{emoji}.webp", attrs)}' + emoji_html = f'{modifier_html}{emoji_partial_pat.format(old, f"{SITE_FULL_IMAGES}/e/{emoji}.webp", attrs)}' elif is_user: if u := get_user(emoji[1:], graceful=True): - emoji_html = f'{modifier_html}{emoji_partial_pat.format(old, f"/pp/{u.id}", attrs)}' + emoji_html = f'{modifier_html}{emoji_partial_pat.format(old, f"/pp/{u.id}", attrs)}' elif path.isfile(f'files/assets/images/emojis/{emoji}.webp'): emoji_html = emoji_partial.format(old, f'{SITE_FULL_IMAGES}/e/{emoji}.webp', attrs) @@ -634,6 +673,7 @@ def allowed_attributes_emojis(tag, name, value): if name == 'data-bs-toggle' and value == 'tooltip': return True if name == 'title': return True if name == 'alt': return True + if name == 'cide' and not value: return True return False diff --git a/files/templates/modals/emoji.html b/files/templates/modals/emoji.html index dd2fd3aeb..a907885bb 100644 --- a/files/templates/modals/emoji.html +++ b/files/templates/modals/emoji.html @@ -38,6 +38,10 @@ +
    + + +