diff --git a/files/assets/css/main.css b/files/assets/css/main.css index b1a435b61..881f8883d 100644 --- a/files/assets/css/main.css +++ b/files/assets/css/main.css @@ -5284,7 +5284,7 @@ textarea { } } .img, img[alt^="![]("], -.preview img:not(img[src^="/uid/"], img[src^="/pp/"], img[src$="/pic"], img[src$="/i/hand.webp"], img[src$="/i/talking.webp"], img[src*="/e/"]) { +.preview img:not(img[src^="/uid/"], img[src^="/pp/"], img[src$="/pic"], img[src$="/i/hand.webp"], img[src$="/i/talking.webp"], img[src$="/i/typing-hands.webp"], img[src*="/e/"]) { max-height: 150px !important; max-width: 100% !important; border-radius: 0.2rem !important; @@ -5446,6 +5446,12 @@ span > img[src$="/i/talking.webp"] { position: absolute; width: 70%; } +span > img[src$="/i/typing-hands.webp"] { + position: absolute; + width: 100%; + bottom: 0; + z-index: 1; +} span > img[src$="/i/hand.webp"] ~ img { animation: pat-pfp-anim 0.3s infinite; transform-origin: bottom center; @@ -5489,6 +5495,10 @@ span > img[src$="/i/talking.webp"]+img[src$="/i/hand.webp"]+img { bottom: calc(2px + 2%) !important; } +.typing-hands-preview { + bottom: calc(2px + 2%) !important; +} + span > img[src$="/i/love-foreground.webp"]+img[src$="/i/love-background.webp"]+img { position: absolute; z-index: 50; @@ -5499,6 +5509,26 @@ span > img[src$="/i/love-foreground.webp"]+img[src$="/i/love-background.webp"]+i transform: scaleX(-1) rotate(-10deg); } +span > img[src$="/i/love-foreground.webp"]+img[src$="/i/love-background.webp"]+img[src$="/i/typing-hands.webp"] { + position: absolute; + z-index: 51; + height: unset; + width: 50%; + bottom: -2%; + left: 33%; + transform: rotate(10deg); +} + +span > img[src$="/i/love-foreground.webp"]+img[src$="/i/love-background.webp"]+img+img { + position: absolute; + z-index: 50; + height: 60%; + width: 60%; + bottom: -2%; + left: 33%; + transform: scaleX(-1) rotate(-10deg); +} + span > img[src$="/i/love-foreground.webp"] { position: absolute; z-index: 100; diff --git a/files/assets/images/typing-hands.webp b/files/assets/images/typing-hands.webp new file mode 100644 index 000000000..6188577f5 Binary files /dev/null and b/files/assets/images/typing-hands.webp differ diff --git a/files/assets/js/markdown.js b/files/assets/js/markdown.js index 6e4039979..640949f30 100644 --- a/files/assets/js/markdown.js +++ b/files/assets/js/markdown.js @@ -74,6 +74,7 @@ const MODIFIERS = { REVERSED_MODIFIER: 6, GENOCIDE: 7, LOVE: 8, + TYPING: 9, }; const findAllEmojiEndings = (word) => { @@ -121,6 +122,16 @@ const findAllEmojiEndings = (word) => { continue; } + if(currWord.endsWith('typing')) { + if(currEndings.indexOf(MODIFIERS.TYPING) !== -1) { + hasReachedNonModifer = true; + continue; + } + currWord = currWord.slice(0, -6); + currEndings.push(MODIFIERS.TYPING); + continue; + } + hasReachedNonModifer = true; } @@ -204,12 +215,13 @@ function markdown(t) { const imgClass = modifiers.has(MODIFIERS.REVERSED) && modifiers.has(MODIFIERS.REVERSED_MODIFIER) ? mirroredClass : '' const lovedClass = modifiers.has(MODIFIERS.LOVE) ? 'love-preview' : ''; - if ([MODIFIERS.TALKING, MODIFIERS.GENOCIDE, MODIFIERS.PAT, MODIFIERS.LOVE].some((modifer) => modifiers.has(modifer))) { + if ([MODIFIERS.TALKING, MODIFIERS.GENOCIDE, MODIFIERS.PAT, MODIFIERS.LOVE, MODIFIERS.TYPING].some((modifer) => modifiers.has(modifer))) { + const typingHtml = modifiers.has(MODIFIERS.TYPING) ? `` : ''; const talkingHtml = modifiers.has(MODIFIERS.TALKING) ? `` : ''; const patHtml = modifiers.has(MODIFIERS.PAT) ? `` : ''; const loveHtml = modifiers.has(MODIFIERS.LOVE) ? `` : ''; const url = modifiers.has(MODIFIERS.USER) ? `/@${emoji}/pic` : `${SITE_FULL_IMAGES}/e/${emoji}.webp`; - const modifierHtml = isTalkingFirst ? `${talkingHtml}${patHtml}${loveHtml}` : `${patHtml}${talkingHtml}${loveHtml}`; + const modifierHtml = isTalkingFirst ? `${talkingHtml}${patHtml}${loveHtml}${typingHtml}` : `${patHtml}${talkingHtml}${loveHtml}${typingHtml}`; input = input.replace(old, `${modifierHtml}`); } else { input = input.replace(old, ``); diff --git a/files/helpers/sanitize.py b/files/helpers/sanitize.py index 345c1bb6d..ebf5c238e 100644 --- a/files/helpers/sanitize.py +++ b/files/helpers/sanitize.py @@ -210,6 +210,14 @@ def find_all_emoji_endings(emoji): emoji = emoji[:-4] continue + if emoji.endswith('typing'): + if 'typing' in endings: + is_non_ending_found = True + continue + endings.append('typing') + emoji = emoji[:-6] + continue + is_non_ending_found = True if emoji.endswith('random'): @@ -254,6 +262,7 @@ def render_emoji(html, regexp, golden, emojis_used, b=False, is_title=False): is_talking_first = ending_modifiers.index('pat') > ending_modifiers.index('talking') if is_talking and is_patted else False is_loved = 'love' in ending_modifiers is_genocided = 'genocide' in ending_modifiers + is_typing = 'typing' in ending_modifiers is_user = emoji.startswith('@') end_modifier_length = 3 if is_patted else 0 @@ -261,6 +270,7 @@ 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 '' + typing_html = f'' if is_typing else '' loved_html = f'' genocide_attr = ' cide' if is_genocided else '' @@ -275,7 +285,10 @@ def render_emoji(html, regexp, golden, emojis_used, b=False, is_title=False): if is_loved: modifier_html = f'{modifier_html}{loved_html}' - if (is_patted and emoji != 'marseyunpettable') or is_talking or is_genocided or is_loved: + if is_typing: + modifier_html = f'{modifier_html}{typing_html}' + + if (is_patted and emoji != 'marseyunpettable') or is_talking or is_genocided or is_loved or is_typing: 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)}' elif is_user: diff --git a/files/templates/formatting.html b/files/templates/formatting.html index 007f0de26..74ff353bd 100644 --- a/files/templates/formatting.html +++ b/files/templates/formatting.html @@ -152,11 +152,20 @@