forked from MarseyWorld/MarseyWorld
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 <dude@bussy.com> Reviewed-on: rDrama/rDrama#182 Co-authored-by: top <top@noreply.fsdfsd.net> Co-committed-by: top <top@noreply.fsdfsd.net>master
parent
78c608b129
commit
3558a41860
|
@ -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) }
|
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 <ol> being populated with <li><p></p></li> in many contexts. */
|
/* Fix for <ol> being populated with <li><p></p></li> in many contexts. */
|
||||||
.post-body li > p:first-child,
|
.post-body li > p:first-child,
|
||||||
.comment-text li > p:first-child,
|
.comment-text li > p:first-child,
|
||||||
|
|
|
@ -72,8 +72,51 @@ const MODIFIERS = {
|
||||||
REVERSED: 4,
|
REVERSED: 4,
|
||||||
USER: 5,
|
USER: 5,
|
||||||
REVERSED_MODIFIER: 6,
|
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) {
|
function markdown(t) {
|
||||||
let input = t.value;
|
let input = t.value;
|
||||||
|
|
||||||
|
@ -110,7 +153,7 @@ function markdown(t) {
|
||||||
|
|
||||||
const modifiers = new Set();
|
const modifiers = new Set();
|
||||||
|
|
||||||
let length = emoji.length
|
let length = emoji.length;
|
||||||
if(emoji.includes('!!')) modifiers.add(MODIFIERS.REVERSED_MODIFIER);
|
if(emoji.includes('!!')) modifiers.add(MODIFIERS.REVERSED_MODIFIER);
|
||||||
emoji = emoji.replaceAll('!', '');
|
emoji = emoji.replaceAll('!', '');
|
||||||
if (length !== emoji.length) {
|
if (length !== emoji.length) {
|
||||||
|
@ -121,15 +164,11 @@ function markdown(t) {
|
||||||
if (length !== emoji.length) {
|
if (length !== emoji.length) {
|
||||||
modifiers.add(MODIFIERS.LARGE);
|
modifiers.add(MODIFIERS.LARGE);
|
||||||
}
|
}
|
||||||
const isTalkingFirst = !(emoji.endsWith('pat') && emoji.slice(0, -3).endsWith('talking'));
|
let endingModifiers;
|
||||||
if (emoji.endsWith('talking') || (emoji.endsWith('pat') && emoji.slice(0, -3).endsWith('talking'))) {
|
[endingModifiers, emoji] = findAllEmoteEndings(emoji);
|
||||||
modifiers.add(MODIFIERS.TALKING);
|
const isTalkingFirst = endingModifiers.indexOf(MODIFIERS.PAT) > endingModifiers.indexOf(MODIFIERS.TALKING);
|
||||||
emoji = emoji.endsWith('pat') ? [emoji.slice(0, -10), emoji.slice(-3)].join('') : emoji.slice(0, -7);
|
|
||||||
}
|
endingModifiers.forEach(modifiers.add, modifiers)
|
||||||
if (emoji.endsWith('pat')) {
|
|
||||||
modifiers.add(MODIFIERS.PAT);
|
|
||||||
emoji = emoji.slice(0, -3);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (emoji.startsWith('@')) {
|
if (emoji.startsWith('@')) {
|
||||||
emoji = emoji.slice(1);
|
emoji = emoji.slice(1);
|
||||||
|
@ -145,18 +184,19 @@ function markdown(t) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const mirroredClass = 'mirrored';
|
const mirroredClass = 'mirrored';
|
||||||
|
const genocideClass = modifiers.has(MODIFIERS.GENOCIDE) ? 'cide' : '';
|
||||||
const emojiClass = modifiers.has(MODIFIERS.LARGE) ? 'emoji-lg' : 'emoji';
|
const emojiClass = modifiers.has(MODIFIERS.LARGE) ? 'emoji-lg' : 'emoji';
|
||||||
|
|
||||||
// patted emotes cannot be flipped back easily so they don't support double flipping
|
// 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 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 : ''
|
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) ? `<img loading="lazy" src="${SITE_FULL_IMAGES}/i/talking.webp">` : '';
|
const talkingHtml = modifiers.has(MODIFIERS.TALKING) ? `<img loading="lazy" src="${SITE_FULL_IMAGES}/i/talking.webp">` : '';
|
||||||
const patHtml = modifiers.has(MODIFIERS.PAT) ? `<img loading="lazy" src="${SITE_FULL_IMAGES}/i/hand.webp">` : '';
|
const patHtml = modifiers.has(MODIFIERS.PAT) ? `<img loading="lazy" src="${SITE_FULL_IMAGES}/i/hand.webp">` : '';
|
||||||
const url = modifiers.has(MODIFIERS.USER) ? `/@${emoji}/pic` : `${SITE_FULL_IMAGES}/e/${emoji}.webp`;
|
const url = modifiers.has(MODIFIERS.USER) ? `/@${emoji}/pic` : `${SITE_FULL_IMAGES}/e/${emoji}.webp`;
|
||||||
const modifierHtml = isTalkingFirst ? `${talkingHtml}${patHtml}` : `${patHtml}${talkingHtml}`;
|
const modifierHtml = isTalkingFirst ? `${talkingHtml}${patHtml}` : `${patHtml}${talkingHtml}`;
|
||||||
input = input.replace(old, `<span class="pat-preview ${spanClass}" data-bs-toggle="tooltip">${modifierHtml}<img loading="lazy" class="${emojiClass} ${imgClass}" src="${url}"></span>`);
|
input = input.replace(old, `<span class="pat-preview ${spanClass} ${genocideClass}" data-bs-toggle="tooltip">${modifierHtml}<img loading="lazy" class="${emojiClass} ${imgClass} " src="${url}"></span>`);
|
||||||
} else {
|
} else {
|
||||||
input = input.replace(old, `<img loading="lazy" class="${emojiClass} ${modifiers.has(MODIFIERS.REVERSED) ? mirroredClass : ''}" src="${SITE_FULL_IMAGES}/e/${emoji}.webp">`);
|
input = input.replace(old, `<img loading="lazy" class="${emojiClass} ${modifiers.has(MODIFIERS.REVERSED) ? mirroredClass : ''}" src="${SITE_FULL_IMAGES}/e/${emoji}.webp">`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,7 @@ def allowed_attributes(tag, name, value):
|
||||||
if name == 'data-bs-toggle' and value == 'tooltip': return True
|
if name == 'data-bs-toggle' and value == 'tooltip': return True
|
||||||
if name == 'title': return True
|
if name == 'title': return True
|
||||||
if name == 'alt': return True
|
if name == 'alt': return True
|
||||||
|
if name == 'cide' and not value: return True
|
||||||
|
|
||||||
if tag == 'table':
|
if tag == 'table':
|
||||||
if name == 'class' and value == 'table': return True
|
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}")
|
send_repeatable_notification_duplicated(id, f"Blackjack by @{v.username}: {extra_info}")
|
||||||
return True
|
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):
|
def render_emoji(html, regexp, golden, emojis_used, b=False, is_title=False):
|
||||||
emojis = list(regexp.finditer(html))
|
emojis = list(regexp.finditer(html))
|
||||||
captured = set()
|
captured = set()
|
||||||
|
@ -245,12 +282,13 @@ def render_emoji(html, regexp, golden, emojis_used, b=False, is_title=False):
|
||||||
emoji_partial = '<img alt=":{0}:" data-bs-toggle="tooltip" loading="lazy" src="{1}" title=":{0}:"{2}>'
|
emoji_partial = '<img alt=":{0}:" data-bs-toggle="tooltip" loading="lazy" src="{1}" title=":{0}:"{2}>'
|
||||||
emoji_html = None
|
emoji_html = None
|
||||||
|
|
||||||
is_talking = emoji.endswith('talking') or (emoji[:-3].endswith('talking') and emoji.endswith('pat'))
|
ending_modifiers, emoji = find_all_emote_endings(emoji)
|
||||||
is_talking_first = emoji.endswith('talking')
|
|
||||||
emoji = emoji[:-7] if emoji.endswith('talking') else emoji
|
is_talking = 'talking' in ending_modifiers
|
||||||
emoji = f'{emoji[:-10]}pat' if emoji[:-3].endswith('talking') and emoji.endswith('pat') else emoji
|
is_patted = 'pat' in ending_modifiers
|
||||||
is_patted = emoji.endswith('pat')
|
is_talking_first = ending_modifiers.index('pat') > ending_modifiers.index('talking') if is_talking and is_patted else False
|
||||||
emoji = emoji[:-3] if is_patted else emoji
|
|
||||||
|
is_genocided = 'genocide' in ending_modifiers
|
||||||
is_user = emoji.startswith('@')
|
is_user = emoji.startswith('@')
|
||||||
|
|
||||||
end_modifier_length = 3 if is_patted else 0
|
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'<img loading="lazy" src="{SITE_FULL_IMAGES}/i/hand.webp">' if is_patted and emoji != 'marseyunpettable' else ''
|
hand_html = f'<img loading="lazy" src="{SITE_FULL_IMAGES}/i/hand.webp">' if is_patted and emoji != 'marseyunpettable' else ''
|
||||||
talking_html = f'<img loading="lazy" src="{SITE_FULL_IMAGES}/i/talking.webp">' if is_talking else ''
|
talking_html = f'<img loading="lazy" src="{SITE_FULL_IMAGES}/i/talking.webp">' if is_talking else ''
|
||||||
|
genocide_attr = ' cide' if is_genocided else ''
|
||||||
|
|
||||||
modifier_html = None
|
modifier_html = ''
|
||||||
if (is_talking and is_patted):
|
if (is_talking and is_patted):
|
||||||
modifier_html = f'{talking_html}{hand_html}' if is_talking_first else f'{hand_html}{talking_html}'
|
modifier_html = f'{talking_html}{hand_html}' if is_talking_first else f'{hand_html}{talking_html}'
|
||||||
elif (is_patted):
|
elif (is_patted):
|
||||||
|
@ -267,12 +306,12 @@ def render_emoji(html, regexp, golden, emojis_used, b=False, is_title=False):
|
||||||
elif (is_talking):
|
elif (is_talking):
|
||||||
modifier_html = talking_html
|
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"):
|
if path.isfile(f"files/assets/images/emojis/{emoji}.webp"):
|
||||||
emoji_html = f'<span alt=":{old}:" data-bs-toggle="tooltip" title=":{old}:">{modifier_html}{emoji_partial_pat.format(old, f"{SITE_FULL_IMAGES}/e/{emoji}.webp", attrs)}</span>'
|
emoji_html = f'<span alt=":{old}:" data-bs-toggle="tooltip" title=":{old}:"{genocide_attr}>{modifier_html}{emoji_partial_pat.format(old, f"{SITE_FULL_IMAGES}/e/{emoji}.webp", attrs)}</span>'
|
||||||
elif is_user:
|
elif is_user:
|
||||||
if u := get_user(emoji[1:], graceful=True):
|
if u := get_user(emoji[1:], graceful=True):
|
||||||
emoji_html = f'<span alt=":{old}:" data-bs-toggle="tooltip" title=":{old}:">{modifier_html}{emoji_partial_pat.format(old, f"/pp/{u.id}", attrs)}</span>'
|
emoji_html = f'<span alt=":{old}:" data-bs-toggle="tooltip" title=":{old}:"{genocide_attr}>{modifier_html}{emoji_partial_pat.format(old, f"/pp/{u.id}", attrs)}</span>'
|
||||||
elif path.isfile(f'files/assets/images/emojis/{emoji}.webp'):
|
elif path.isfile(f'files/assets/images/emojis/{emoji}.webp'):
|
||||||
emoji_html = emoji_partial.format(old, f'{SITE_FULL_IMAGES}/e/{emoji}.webp', attrs)
|
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 == 'data-bs-toggle' and value == 'tooltip': return True
|
||||||
if name == 'title': return True
|
if name == 'title': return True
|
||||||
if name == 'alt': return True
|
if name == 'alt': return True
|
||||||
|
if name == 'cide' and not value: return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,10 @@
|
||||||
<input type="checkbox" id="emoji-sel-3" value="talking" class="emoji-postfix">
|
<input type="checkbox" id="emoji-sel-3" value="talking" class="emoji-postfix">
|
||||||
<label class="emoji-option" for="emoji-sel-3">Talking</label>
|
<label class="emoji-option" for="emoji-sel-3">Talking</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="display: inline" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Sends the emoji away">
|
||||||
|
<input type="checkbox" id="emoji-sel-4" value="genocide" class="emoji-postfix">
|
||||||
|
<label class="emoji-option" for="emoji-sel-4">Genocide</label>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue