1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-08-24 23:10:54 +00:00
* Added: The FFZ Subwoofer badge now displays a user's number of subscribed months in its tool-tip.
* Added: Setting to set the default sorting mode of the directory. (Have you tried the Deck add-on?)
* Fixed: The location of certain player action buttons was incorrect after Twitch made changes to the player.
* Changed: Badges added by add-on are now grouped by add-on in badge visibility settings. This allows users to disable all badges from a given add-on at once, and is just generally nicer to look at.
* API Added: `iterateMessages()` method on the `chat` module as an easy way to iterate over all live chat messages, in case existing messages need to be modified without the overhead of tokenization.
* API Added: Badges can now be stacked together for visibility purposes, similar to Twitch's native badge versions, by setting a `base_id` on each badge.
* API Added: Badges can now display dynamic data on their tool-tip by using a `tooltipExtra` method. This was used to display Subwoofer subscription lengths.
* API Added: New setting UI type `setting-text` that can be used to insert arbitrary markdown into settings pages.
* API Changed: The `ffz_user_class` special property on messages can be an array instead of a string.
* API Fixed: Add-on proxy modules are now correctly used for an add-on's sub-modules.
This commit is contained in:
SirStendec 2023-11-02 21:39:52 -04:00
parent 0eaf1a55be
commit 21ae0059a5
22 changed files with 499 additions and 688 deletions

View file

@ -30,7 +30,6 @@ export default class ChatLine extends Module {
this.inject('chat');
this.inject('site');
this.inject('site.fine');
this.inject('site.web_munch');
this.inject(RichContent);
this.inject('experiments');
@ -459,6 +458,41 @@ export default class ChatLine extends Module {
this.chat.context.on('changed:tooltip.link-images', this.maybeUpdateLines, this);
this.chat.context.on('changed:tooltip.link-nsfw-images', this.maybeUpdateLines, this);
this.on('chat:get-messages', (include_chat, include_whisper, include_video, messages) => {
if ( include_chat ) {
for(const inst of this.ChatLine.instances) {
const msg = inst.props.message;
if ( msg )
messages.push({
message: msg,
_instance: inst,
update: () => inst.forceUpdate()
});
}
for(const inst of this.ExtensionLine.instances) {
const msg = inst.props.message;
if ( msg )
messages.push({
message: msg,
_instance: inst,
update: () => inst.forceUpdate()
});
}
}
if ( include_whisper )
for(const inst of this.WhisperLine.instances) {
const msg = inst.props.message;
if ( msg && msg._ffz_message )
messages.push({
message: msg._ffz_message,
_instance: inst,
update: () => inst.forceUpdate()
});
}
});
this.on('chat:get-tab-commands', e => {
if ( this.experiments.getTwitchAssignmentByName('chat_replies') === 'control' )
return;
@ -539,7 +573,7 @@ export default class ChatLine extends Module {
});
const t = this,
React = await this.web_munch.findModule('react');
React = await this.site.findReact();
if ( ! React )
return;
@ -934,8 +968,12 @@ other {# messages were deleted by a moderator.}
const username = t.chat.formatUser(user, e),
override_name = t.overrides.getName(user.id);
let user_class = msg.ffz_user_class;
if ( Array.isArray(user_class) )
user_class = user_class.join(' ');
const user_props = {
className: `chat-line__username notranslate${override_name ? ' ffz--name-override tw-relative ffz-il-tooltip__container' : ''} ${msg.ffz_user_class ?? ''}`,
className: `chat-line__username notranslate${override_name ? ' ffz--name-override tw-relative ffz-il-tooltip__container' : ''} ${user_class ?? ''}`,
role: 'button',
style: { color },
onClick: this.ffz_user_click_handler,
@ -1161,608 +1199,6 @@ other {# messages were deleted by a moderator.}
}
} };
/*cls.prototype.ffzOldRender = function() { try {
this._ffz_no_scan = true;
const types = t.parent.message_types || {},
deleted_count = this.props.deletedCount,
reply_mode = t.chat.context.get('chat.replies.style'),
anim_hover = t.chat.context.get('chat.emotes.animated') === 2,
override_mode = t.chat.context.get('chat.filtering.display-deleted'),
msg = t.chat.standardizeMessage(this.props.message),
reply_tokens = (reply_mode === 2 || (reply_mode === 1 && this.props.repliesAppearancePreference && this.props.repliesAppearancePreference !== 'expanded')) ? ( msg.ffz_reply = msg.ffz_reply || t.chat.tokenizeReply(this.props.reply) ) : null,
is_action = msg.messageType === types.Action,
action_style = is_action ? t.chat.context.get('chat.me-style') : 0,
action_italic = action_style >= 2,
action_color = action_style === 1 || action_style === 3,
user = msg.user,
raw_color = t.overrides.getColor(user.id) || user.color,
color = t.parent.colors.process(raw_color);
let mod_mode = this.props.deletedMessageDisplay;
let show, show_class, mod_action = null;
const highlight_mode = t.chat.context.get('chat.points.allow-highlight'),
highlight = highlight_mode > 0 && msg.ffz_type === 'points' && msg.ffz_reward && isHighlightedReward(msg.ffz_reward),
twitch_highlight = highlight && highlight_mode == 1,
ffz_highlight = highlight && highlight_mode == 2;
if ( ! this.props.isCurrentUserModerator && mod_mode == 'DETAILED' )
mod_mode = 'LEGACY';
if ( override_mode )
mod_mode = override_mode;
if ( mod_mode === 'BRIEF' ) {
if ( msg.deleted ) {
if ( deleted_count == null )
return null;
return e('div', {
className: 'chat-line__status'
}, t.i18n.t('chat.deleted-messages', `{count,plural,
one {One message was deleted by a moderator.}
other {# messages were deleted by a moderator.}
}`, {
count: deleted_count
}));
}
show = true;
show_class = false;
} else if ( mod_mode === 'DETAILED' ) {
show = true;
show_class = msg.deleted;
} else {
show = this.state && this.state.alwaysShowMessage || ! msg.deleted;
show_class = false;
}
if ( msg.deleted ) {
const show_mode = t.chat.context.get('chat.filtering.display-mod-action');
if ( show_mode === 2 || (show_mode === 1 && mod_mode === 'DETAILED') ) {
const action = msg.modActionType;
if ( action === 'timeout' )
mod_action = t.i18n.t('chat.mod-action.timeout',
'{duration} Timeout'
, {
duration: print_duration(msg.duration || 1)
});
else if ( action === 'ban' )
mod_action = t.i18n.t('chat.mod-action.ban', 'Banned');
else if ( action === 'delete' || ! action )
mod_action = t.i18n.t('chat.mod-action.delete', 'Deleted');
if ( mod_action && msg.modLogin )
mod_action = t.i18n.t('chat.mod-action.by', '{action} by {login}', {
login: msg.modLogin,
action: mod_action
});
if ( mod_action )
mod_action = e('span', {
className: 'tw-pd-l-05',
'data-test-selector': 'chat-deleted-message-attribution'
}, `(${mod_action})`);
}
}
let room = msg.roomLogin ? msg.roomLogin : msg.channel ? msg.channel.slice(1) : undefined,
room_id = msg.roomId ? msg.roomId : this.props.channelID;
if ( ! room && room_id ) {
const r = t.chat.getRoom(room_id, null, true);
if ( r && r.login )
room = msg.roomLogin = r.login;
}
if ( ! room_id && room ) {
const r = t.chat.getRoom(null, room, true);
if ( r && r.id )
room_id = msg.roomId = r.id;
}
const u = t.site.getUser(),
r = {id: room_id, login: room};
const has_replies = this.props && !!(this.props.hasReply || this.props.reply || ! this.props.replyRestrictedReason),
can_replies = has_replies && msg.message && ! msg.deleted && ! this.props.disableReplyClick,
can_reply = can_replies && (has_replies || (u && u.login !== msg.user?.login));
if ( u ) {
u.moderator = this.props.isCurrentUserModerator;
u.staff = this.props.isCurrentUserStaff;
u.reply_mode = reply_mode;
u.can_reply = can_reply;
}
const hover_actions = t.actions.renderHover(msg, this.props.showModerationIcons, u, r, e, this),
twitch_clickable = hover_actions != null;
const tokens = msg.ffz_tokens = msg.ffz_tokens || t.chat.tokenizeMessage(msg, u),
rich_content = FFZRichContent && t.chat.pluckRichContent(tokens, msg),
bg_css = msg.mentioned && msg.mention_color ? t.parent.inverse_colors.process(msg.mention_color) : null;
if ( ! this.ffz_open_reply )
this.ffz_open_reply = this.ffzOpenReply.bind(this);
if ( ! this.ffz_user_click_handler ) {
if ( this.props.onUsernameClick )
this.ffz_user_click_handler = event => {
if ( this.isKeyboardEvent(event) && event.keyCode !== KEYS.Space && event.keyCode !== KEYS.Enter )
return;
const target = event.currentTarget,
ds = target && target.dataset;
let target_user = user;
if ( ds && ds.user ) {
try {
target_user = JSON.parse(ds.user);
} catch(err) { /* nothing~! * / }
}
const fe = new FFZEvent({
inst: this,
event,
message: msg,
user: target_user,
room: r
});
t.emit('chat:user-click', fe);
if ( fe.defaultPrevented )
return;
this.props.onUsernameClick(target_user.login, 'chat_message', msg.id, target.getBoundingClientRect().bottom);
}
else
this.ffz_user_click_handler = this.openViewerCard || this.usernameClickHandler; //event => event.ctrlKey ? this.usernameClickHandler(event) : t.viewer_cards.openCard(r, user, event);
}
const user_block = t.chat.formatUser(user, e);
const override_name = t.overrides.getName(user.id);
const user_props = {
className: `chat-line__username notranslate${override_name ? ' ffz--name-override tw-relative ffz-il-tooltip__container' : ''} ${msg.ffz_user_class ?? ''}`,
role: 'button',
style: { color },
onClick: this.ffz_user_click_handler,
onContextMenu: t.actions.handleUserContext
};
if ( msg.ffz_user_props )
Object.assign(user_props, msg.ffz_user_props);
if ( msg.ffz_user_style )
Object.assign(user_props.style, msg.ffz_user_style);
const user_bits = [
t.actions.renderInline(msg, this.props.showModerationIcons, u, r, e, this),
this.renderInlineHighlight ? this.renderInlineHighlight() : null,
e('span', {
className: 'chat-line__message--badges'
}, t.chat.badges.render(msg, e)),
e('span', user_props, override_name ? [
e('span', {
className: 'chat-author__display-name'
}, override_name),
e('div', {
className: 'ffz-il-tooltip ffz-il-tooltip--down ffz-il-tooltip--align-center'
}, user_block)
] : user_block)
];
let extra_ts,
cls = `chat-line__message${show_class ? ' ffz--deleted-message' : ''}${twitch_clickable ? ' tw-relative' : ''}`,
out = (tokens.length || ! msg.ffz_type) ? [
(this.props.showTimestamps || this.props.isHistorical) && e('span', {
className: 'chat-line__timestamp'
}, t.chat.formatTime(msg.timestamp)),
user_bits,
e('span', {'aria-hidden': true}, is_action ? ' ' : ': '),
show && has_replies && reply_tokens ?
t.chat.renderTokens(reply_tokens, e)
: null,
show ?
e('span', {
className:`message ${action_italic ? 'chat-line__message-body--italicized' : ''} ${twitch_highlight ? 'chat-line__message-body--highlighted' : ''}`,
style: action_color ? { color } : null
}, t.chat.renderTokens(tokens, e, (reply_mode !== 0 && has_replies) ? this.props.reply : null))
:
e('span', {
className: 'chat-line__message--deleted',
}, e('a', {
href: '',
onClick: this.alwaysShowMessage
}, t.i18n.t('chat.message-deleted', '<message deleted>'))),
show && rich_content && e(FFZRichContent, rich_content),
mod_action,
] : null;
if ( out == null )
extra_ts = t.chat.context.get('chat.extra-timestamps');
if ( msg.ffz_type === 'sub_mystery' ) {
const mystery = msg.mystery;
if ( mystery )
msg.mystery.line = this;
const sub_msg = t.i18n.tList('chat.sub.gift', "{user} is gifting {count, plural, one {# Tier {tier} Sub} other {# Tier {tier} Subs}} to {channel}'s community! ", {
user: (msg.sub_anon || user.username === 'ananonymousgifter') ?
t.i18n.t('chat.sub.anonymous-gifter', 'An anonymous gifter') :
e('span', {
role: 'button',
className: 'chatter-name',
onClick: this.ffz_user_click_handler
}, e('span', {
className: 'tw-c-text-base tw-strong'
}, user.displayName)),
count: msg.sub_count,
tier: SUB_TIERS[msg.sub_plan] || 1,
channel: msg.roomLogin
});
if ( msg.sub_total === 1 )
sub_msg.push(t.i18n.t('chat.sub.gift-first', "It's their first time gifting a Sub in the channel!"));
else if ( msg.sub_total > 1 )
sub_msg.push(t.i18n.t('chat.sub.gift-total', "They've gifted {count} Subs in the channel!", {
count: msg.sub_total
}));
if ( ! this.ffz_click_expand )
this.ffz_click_expand = () => {
this.setState({
ffz_expanded: ! this.state.ffz_expanded
});
}
const expanded = t.chat.context.get('chat.subs.merge-gifts-visibility') ?
! this.state.ffz_expanded : this.state.ffz_expanded;
let sub_list = null;
if( expanded && mystery && mystery.recipients && mystery.recipients.length > 0 ) {
const the_list = [];
for(const x of mystery.recipients) {
if ( the_list.length )
the_list.push(', ');
the_list.push(e('span', {
role: 'button',
className: 'ffz--giftee-name',
onClick: this.ffz_user_click_handler,
'data-user': JSON.stringify(x)
}, e('span', {
className: 'tw-c-text-base tw-strong'
}, x.displayName)));
}
sub_list = e('div', {
className: 'tw-mg-t-05 tw-border-t tw-pd-t-05 tw-c-text-alt-2'
}, the_list);
}
cls = `ffz-notice-line user-notice-line tw-pd-y-05 ffz--subscribe-line${show_class ? ' ffz--deleted-message' : ''}${twitch_clickable ? ' tw-relative' : ''}`;
out = [
e('div', {
className: 'tw-flex tw-c-text-alt-2',
onClick: this.ffz_click_expand
}, [
t.chat.context.get('chat.subs.compact') ? null :
e('figure', {
className: `ffz-i-star${msg.sub_anon ? '-empty' : ''} tw-mg-r-05`
}),
e('div', null, [
out ? null : extra_ts && (this.props.showTimestamps || this.props.isHistorical) && e('span', {
className: 'chat-line__timestamp'
}, t.chat.formatTime(msg.timestamp)),
(out || msg.sub_anon) ? null : t.actions.renderInline(msg, this.props.showModerationIcons, u, r, e, this),
sub_msg
]),
mystery ? e('div', {
className: 'tw-pd-l-05 tw-font-size-4'
}, e('figure', {
className: `ffz-i-${expanded ? 'down' : 'right'}-dir tw-pd-y-1`
})) : null
]),
sub_list,
out && e('div', {
className: 'chat-line--inline chat-line__message',
'data-room-id': room_id,
'data-room': room,
'data-user-id': user.userID,
'data-user': user.userLogin && user.userLogin.toLowerCase(),
}, out)
];
} else if ( msg.ffz_type === 'sub_gift' ) {
const plan = msg.sub_plan || {},
months = msg.sub_months || 1,
tier = SUB_TIERS[plan.plan] || 1;
let sub_msg;
const bits = {
months,
user: (msg.sub_anon || user.username === 'ananonymousgifter') ?
t.i18n.t('chat.sub.anonymous-gifter', 'An anonymous gifter') :
e('span', {
role: 'button',
className: 'chatter-name',
onClick: this.ffz_user_click_handler
}, e('span', {
className: 'tw-c-text-base tw-strong'
}, user.displayName)),
plan: plan.plan === 'custom' ? '' :
t.i18n.t('chat.sub.gift-plan', 'Tier {tier}', {tier}),
recipient: e('span', {
role: 'button',
className: 'chatter-name',
onClick: this.ffz_user_click_handler,
'data-user': JSON.stringify(msg.sub_recipient)
}, e('span', {
className: 'tw-c-text-base tw-strong'
}, msg.sub_recipient.displayName))
};
if ( months <= 1 )
sub_msg = t.i18n.tList('chat.sub.mystery', '{user} gifted a {plan} Sub to {recipient}! ', bits);
else
sub_msg = t.i18n.tList('chat.sub.gift-months', '{user} gifted {months, plural, one {# month} other {# months}} of {plan} Sub to {recipient}!', bits);
if ( msg.sub_total === 1 )
sub_msg.push(t.i18n.t('chat.sub.gift-first', "It's their first time gifting a Sub in the channel!"));
else if ( msg.sub_total > 1 )
sub_msg.push(t.i18n.t('chat.sub.gift-total', "They've gifted {count,number} Subs in the channel!", {
count: msg.sub_total
}));
cls = `ffz-notice-line user-notice-line tw-pd-y-05 tw-pd-r-2 ffz--subscribe-line${show_class ? ' ffz--deleted-message' : ''}${twitch_clickable ? ' tw-relative' : ''}`;
out = [
e('div', {className: 'tw-flex tw-c-text-alt-2'}, [
t.chat.context.get('chat.subs.compact') ? null :
e('figure', {
className: 'ffz-i-star tw-mg-r-05'
}),
e('div', null, [
out ? null : extra_ts && (this.props.showTimestamps || this.props.isHistorical) && e('span', {
className: 'chat-line__timestamp'
}, t.chat.formatTime(msg.timestamp)),
(out || msg.sub_anon) ? null : t.actions.renderInline(msg, this.props.showModerationIcons, u, r, e, this),
sub_msg
])
]),
out && e('div', {
className: 'chat-line--inline chat-line__message',
'data-room-id': room_id,
'data-room': room,
'data-user-id': user.userID,
'data-user': user.userLogin && user.userLogin.toLowerCase(),
}, out)
];
} else if ( msg.ffz_type === 'resub' ) {
const months = msg.sub_cumulative || msg.sub_months,
setting = t.chat.context.get('chat.subs.show');
if ( setting === 3 || (setting === 1 && out && months > 1) || (setting === 2 && months > 1) ) {
const plan = msg.sub_plan || {},
tier = SUB_TIERS[plan.plan] || 1;
const sub_msg = t.i18n.tList('chat.sub.main', '{user} subscribed {plan}. ', {
user: e('span', {
role: 'button',
className: 'chatter-name',
onClick: this.ffz_user_click_handler
}, e('span', {
className: 'tw-c-text-base tw-strong'
}, user.displayName)),
plan: plan.prime ?
t.i18n.t('chat.sub.twitch-prime', 'with Prime Gaming') :
t.i18n.t('chat.sub.plan', 'at Tier {tier}', {tier})
});
if ( msg.sub_share_streak && msg.sub_streak > 1 ) {
sub_msg.push(t.i18n.t(
'chat.sub.cumulative-months',
"They've subscribed for {cumulative,number} months, currently on a {streak,number} month streak!",
{
cumulative: msg.sub_cumulative,
streak: msg.sub_streak
}
));
} else if ( months > 1 ) {
sub_msg.push(t.i18n.t(
'chat.sub.months',
"They've subscribed for {count,number} months!",
{
count: months
}
));
}
cls = `ffz-notice-line user-notice-line tw-pd-y-05 tw-pd-r-2 ffz--subscribe-line${show_class ? ' ffz--deleted-message' : ''}${twitch_clickable ? ' tw-relative' : ''}`;
out = [
e('div', {className: 'tw-flex tw-c-text-alt-2'}, [
t.chat.context.get('chat.subs.compact') ? null :
e('figure', {
className: `ffz-i-${plan.prime ? 'crown' : 'star'} tw-mg-r-05`
}),
e('div', null, [
out ? null : extra_ts && (this.props.showTimestamps || this.props.isHistorical) && e('span', {
className: 'chat-line__timestamp'
}, t.chat.formatTime(msg.timestamp)),
out ? null : t.actions.renderInline(msg, this.props.showModerationIcons, u, r, e, this),
sub_msg
])
]),
out && e('div', {
className: 'chat-line--inline chat-line__message',
'data-room-id': room_id,
'data-room': room,
'data-user-id': user.userID,
'data-user': user.userLogin && user.userLogin.toLowerCase(),
}, out)
];
}
} else if ( msg.ffz_type === 'ritual' && t.chat.context.get('chat.rituals.show') ) {
let system_msg;
if ( msg.ritual === 'new_chatter' )
system_msg = e('div', {className: 'tw-c-text-alt-2'}, [
t.i18n.tList('chat.ritual', '{user} is new here. Say hello!', {
user: e('span', {
role: 'button',
className: 'chatter-name',
onClick: this.ffz_user_click_handler
}, e('span', {
className: 'tw-c-text-base tw-strong'
}, user.displayName))
})
]);
if ( system_msg ) {
cls = `ffz-notice-line user-notice-line tw-pd-y-05 tw-pd-r-2 ffz--ritual-line${show_class ? ' ffz--deleted-message' : ''}${twitch_clickable ? ' tw-relative' : ''}`;
out = [
out ? null : extra_ts && (this.props.showTimestamps || this.props.isHistorical) && e('span', {
className: 'chat-line__timestamp'
}, t.chat.formatTime(msg.timestamp)),
system_msg,
out && e('div', {
className: 'chat-line--inline chat-line__message',
'data-room-id': room_id,
'data-room': room,
'data-user-id': user.userID,
'data-user': user.userLogin && user.userLogin.toLowerCase(),
}, out)
];
}
} else if ( msg.ffz_type === 'points' && msg.ffz_reward ) {
const reward = e('span', {className: 'ffz--points-reward'}, getRewardTitle(msg.ffz_reward, t.i18n)),
cost = e('span', {className: 'ffz--points-cost'}, [
e('span', {className: 'ffz--points-icon'}),
t.i18n.formatNumber(getRewardCost(msg.ffz_reward))
]);
cls = `ffz-notice-line ffz--points-line tw-pd-l-1 tw-pd-y-05 tw-pd-r-2${ffz_highlight ? ' ffz-custom-color ffz--points-highlight' : ''}${show_class ? ' ffz--deleted-message' : ''}${twitch_clickable ? ' tw-relative' : ''}`;
out = [
e('div', {className: 'tw-c-text-alt-2'}, [
out ? null : extra_ts && (this.props.showTimestamps || this.props.isHistorical) && e('span', {
className: 'chat-line__timestamp'
}, t.chat.formatTime(msg.timestamp)),
out ? null : t.actions.renderInline(msg, this.props.showModerationIcons, u, r, e, this),
out ?
t.i18n.tList('chat.points.redeemed', 'Redeemed {reward} {cost}', {reward, cost}) :
t.i18n.tList('chat.points.user-redeemed', '{user} redeemed {reward} {cost}', {
reward, cost,
user: e('span', {
role: 'button',
className: 'chatter-name',
onClick: this.ffz_user_click_handler
}, e('span', {
className: 'tw-c-text-base tw-strong'
}, user.displayName))
})
]),
out && e('div', {
className: 'chat-line--inline chat-line__message',
'data-room-id': room_id,
'data-room': room,
'data-user-id': user.userID,
'data-user': user.userLogin && user.userLogin.toLowerCase()
}, out)
]
} else if ( msg.bits > 0 && t.chat.context.get('chat.bits.cheer-notice') ) {
cls = `ffz-notice-line user-notice-line tw-pd-y-05 tw-pd-r-2 ffz--ritual-line${show_class ? ' ffz--deleted-message' : ''}${twitch_clickable ? ' tw-relative' : ''}`;
out = [
e('div', {className: 'tw-c-text-alt-2'}, [
out ? null : extra_ts && (this.props.showTimestamps || this.props.isHistorical) && e('span', {
className: 'chat-line__timestamp'
}, t.chat.formatTime(msg.timestamp)),
out ? null : t.actions.renderInline(msg, this.props.showModerationIcons, u, r, e, this),
t.i18n.tList('chat.bits-message', 'Cheered {count, plural, one {# Bit} other {# Bits}}', {count: msg.bits || 0})
]),
out && e('div', {
className: 'chat-line--inline chat-line__message',
'data-room-id': room_id,
'data-room': room,
'data-user-id': user.userID,
'data-user': user.userLogin && user.userLogin.toLowerCase(),
}, out)
];
}
if ( ! out )
return null;
if ( twitch_clickable ) {
out = [
e('div', {
className: 'chat-line__message-highlight tw-absolute tw-border-radius-medium tw-top-0 tw-bottom-0 tw-right-0 tw-left-0',
'data-test-selector': 'chat-message-highlight'
}),
e('div', {
className: 'chat-line__message-container tw-relative'
}, reply_mode == 1 ? [
this.props.repliesAppearancePreference && this.props.repliesAppearancePreference === 'expanded' ? this.renderReplyLine() : null,
out
] : out),
hover_actions
];
}
return e('div', {
className: `${cls}${msg.mentioned ? ' ffz-mentioned' : ''}${bg_css ? ' ffz-custom-color' : ''}`,
style: {backgroundColor: bg_css},
'data-room-id': room_id,
'data-room': room,
'data-user-id': user.userID,
'data-user': user.userLogin && user.userLogin.toLowerCase(),
onMouseOver: anim_hover ? t.chat.emotes.animHover : null,
onMouseOut: anim_hover ? t.chat.emotes.animLeave : null
}, out);
} catch(err) {
t.log.info(err);
t.log.capture(err, {
extra: {
props: this.props
}
});
try {
return old_render.call(this);
} catch(e2) {
t.log.error('An error in Twitch rendering.', e2);
t.log.capture(e2, {
extra: {
props: this.props
}
});
return 'An error occurred rendering this chat line.';
}
} } */
/*cls.prototype.render = this.experiments.get('line_renderer')
? cls.prototype.ffzNewRender
: cls.prototype.ffzOldRender;*/
cls.prototype.render = cls.prototype.ffzNewRender;
// Do this after a short delay to hopefully reduce the chance of React