Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overlay Emote Modifier #6590

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
32 changes: 32 additions & 0 deletions src/modules/chat/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const EMOTE_MODIFIERS = {
'c!': 'bttv-emote-modifier-cursed',
'l!': 'bttv-emote-modifier-rotate-left',
'r!': 'bttv-emote-modifier-rotate-right',
'o!': 'bttv-emote-modifier-overlay',
'p!': 'bttv-emote-modifier-party',
's!': 'bttv-emote-modifier-shake',
ffzW: 'bttv-emote-modifier-wide',
Expand All @@ -40,6 +41,9 @@ const EMOTE_MODIFIERS = {
const PREFIX_EMOTE_MODIFIERS_LIST = Object.keys(EMOTE_MODIFIERS).filter((key) => key.endsWith('!'));
const SUFFIX_EMOTE_MODIFIERS_LIST = Object.keys(EMOTE_MODIFIERS).filter((key) => !key.endsWith('!'));

const overlayModifierPredicate = ({modifier}) => modifier === 'o!';
const negate = (pred) => (x) => !pred(x);

const badgeTemplate = (url, description) => {
const badgeContainer = document.createElement('div');
badgeContainer.classList.add('bttv-tooltip-wrapper', 'bttv-chat-badge-container');
Expand Down Expand Up @@ -290,6 +294,7 @@ class ChatModule {

const parts = data.split(' ');
const partMetadata = [];
const isOverlay = [];
let hasModifiers = false;
let modified = false;
for (let j = 0; j < parts.length; j++) {
Expand Down Expand Up @@ -327,6 +332,7 @@ class ChatModule {
let modifiers = [];
if (hasModifiers && isEmoteOrSuffixModifier) {
let detectedEmote = false;
let predecessor = null;
// we search backwards to find the emote and any modifiers
for (let k = j; k >= 0; k--) {
const partMetadataItem = partMetadata[k];
Expand All @@ -343,11 +349,37 @@ class ChatModule {
(!detectedEmote && partMetadataItem.type === 'prefix') ||
(detectedEmote && partMetadataItem.type === 'suffix')
) {
predecessor = k;
break;
}
modifiers.push(partMetadataItem);
parts[k] = null;
}

// An emote may be an overlay if it satisfies the following conditions:
// 1. It has a "predecessor" part.
// 2. That predecessor part is an emote.
// 3. That predecessor emote is not an overlay.
// 4. The user has applied the overlay modifier.
// This ensures that overlays do not stack and they only stack on another emote.
const hasOverlayModifier = modifiers.some(overlayModifierPredicate);
isOverlay[j] =
predecessor != null && partMetadata[predecessor]?.emote && !isOverlay[predecessor] && hasOverlayModifier;
if (!isOverlay[j] && hasOverlayModifier) {
// Strip the overlay modifier from the part.
modifiers = modifiers.filter(negate(overlayModifierPredicate));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stripping it works, but it also results in the modifier going missing from the output. for other modifiers, we do not show the modified emote but we show the modifier was sent when used incorrectly. is there a way to replicate this behavior here?

image

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as an aside, do you have an image asset for this modifier? if not, we can probably have one made

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a way to replicate this behavior here?

I've modified it so that if an overlay modifier is removed, it replaces the corresponding parts in the part array.
Screenshot 2024-02-17 094835

do you have an image asset for this modifier?

I'm no artist, so feel free to use or not use this.
overlay2

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dclstn any ideas on the icon for this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like so perhaps:

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's so much better 👏

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the image is small in emote form, it kind of just looks like 1 square. Maybe make it so that the top square doesn't overlap the bottom one quite so completely?

Copy link
Owner

@night night Mar 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed with Dallas' feedback. you can't tell what this is when smaller. it also resembles a copy button, which is not the intention.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How's this?

downsized for reference:


Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks better


// Find the locations to restore the modifier part.
const start = predecessor != null ? predecessor + 1 : 0;
const replacementEmote = emotes.getEligibleEmote('o!', user);
for (let location = start; location < j; ++location) {
if (overlayModifierPredicate(partMetadata[location])) {
// Restore the string or modifier emote in the parts array.
parts[location] = replacementEmote == null ? 'o!' : replacementEmote.render(null, null, null);
}
}
}

// if the emote is only a suffix modifier, render it without its effect
if (modifiers.length === 1 && modifiers[0].type === 'suffix' && emoteIndex === j) {
modifiers = [];
Expand Down
4 changes: 4 additions & 0 deletions src/modules/chat/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@
filter: grayscale(1) brightness(0.7) contrast(2.5);
}

.bttv-emote-modifier-overlay {
margin-left: -32px;
}

.bttv-emote-modifier-party img {
animation: bttv-emote-modifier-party 1.5s linear infinite;
}
Expand Down