mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-27 21:05:53 +00:00
4.31.5
* Fixed: Reduce the amount of re-rendering that happens when a mass gift sub happens in chat. * Fixed: Do not display stream latency metadata when watching non-live content. * Fixed: Add support for user name overrides to clips and video chat. * Fixed: Badge tooltips on the clips subdomain. * API Added: `ffz_user_class`, `ffz_user_props`, and `ffz_user_style` on chat messages for customizing the display of usernames on messages in chat.
This commit is contained in:
parent
425276ed08
commit
dfb16c8483
7 changed files with 108 additions and 26 deletions
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "frankerfacez",
|
||||
"author": "Dan Salvato LLC",
|
||||
"version": "4.31.4",
|
||||
"version": "4.31.5",
|
||||
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
||||
"private": true,
|
||||
"license": "Apache-2.0",
|
||||
|
|
|
@ -502,6 +502,12 @@ export default class Badges extends Module {
|
|||
message = container[fine.accessor]?.return?.stateNode?.props?.message;
|
||||
if ( ! message )
|
||||
message = fine.searchParent(container, n => n.props?.message)?.props?.message;
|
||||
if ( ! message && this.root.flavor === 'clips' ) {
|
||||
const lines = this.resolve('site.chat.line');
|
||||
const node = fine.searchParent(container, n => n.props?.node)?.props?.node;
|
||||
if ( lines && node )
|
||||
message = lines.messages.get(node);
|
||||
}
|
||||
if ( ! message )
|
||||
message = fine.searchParent(container, n => n.props?.node)?.props?.node?._ffz_message;
|
||||
if ( ! message )
|
||||
|
|
|
@ -287,8 +287,14 @@ export default class Metadata extends Module {
|
|||
icon: 'ffz-i-download',
|
||||
|
||||
click(src) {
|
||||
const link = createElement('a', {target: '_blank', href: src});
|
||||
const title = this.settings.get('context.title');
|
||||
const name = title.replace(/[\\/:"*?<>|]+/, '_') + '.mp4';
|
||||
|
||||
const link = createElement('a', {target: '_blank', download: name, href: src, style: {display: 'none'}});
|
||||
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
link.remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -398,6 +404,9 @@ export default class Metadata extends Module {
|
|||
if ( ! this.settings.get('metadata.player-stats') || ! data.delay )
|
||||
return null;
|
||||
|
||||
if ( data.old )
|
||||
return null;
|
||||
|
||||
const delayed = data.drift > 5000 ? '(!) ' : '';
|
||||
|
||||
if ( data.old )
|
||||
|
|
|
@ -18,6 +18,7 @@ export default class Line extends Module {
|
|||
this.inject('i18n');
|
||||
|
||||
this.inject('chat');
|
||||
this.inject('chat.overrides');
|
||||
this.inject('site.fine');
|
||||
|
||||
this.ChatLine = this.fine.define(
|
||||
|
@ -75,12 +76,37 @@ export default class Line extends Module {
|
|||
action_italic = action_style >= 2,
|
||||
action_color = action_style === 1 || action_style === 3,
|
||||
user = msg.user,
|
||||
color = t.parent.colors.process(user.color),
|
||||
raw_color = t.overrides.getColor(user.id) || user.color,
|
||||
color = t.parent.colors.process(raw_color),
|
||||
|
||||
u = t.site.getUser();
|
||||
|
||||
const tokens = msg.ffz_tokens = msg.ffz_tokens || t.chat.tokenizeMessage(msg, u);
|
||||
|
||||
const user_block = t.chat.formatUser(user, createElement);
|
||||
const override_name = t.overrides.getName(user.id);
|
||||
|
||||
const user_props = {
|
||||
className: `clip-chat__message-author tw-font-size-5 ffz-link notranslate tw-strong${override_name ? ' ffz--name-override tw-relative ffz-il-tooltip__container' : ''} ${msg.ffz_user_class ?? ''}`,
|
||||
href: `https://www.twitch.tv/${user.login}/clips`,
|
||||
style: { color }
|
||||
};
|
||||
|
||||
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 = createElement('a', user_props, override_name ? [
|
||||
createElement('span', {
|
||||
className: 'chat-author__display-name'
|
||||
}, override_name),
|
||||
createElement('div', {
|
||||
className: 'ffz-il-tooltip ffz-il-tooltip--down ffz-il-tooltip--align-center'
|
||||
}, user_block)
|
||||
] : user_block);
|
||||
|
||||
return (<div class="tw-mg-b-1" style={{marginBottom:'0 !important'}}>
|
||||
<div
|
||||
data-a-target="tw-animation-target"
|
||||
|
@ -95,11 +121,7 @@ export default class Line extends Module {
|
|||
<span class="chat-line__message--badges">{
|
||||
t.chat.badges.render(msg, createElement)
|
||||
}</span>
|
||||
<a
|
||||
class="clip-chat__message-author tw-font-size-5 ffz-link notranslate tw-strong"
|
||||
href={`https://www.twitch.tv/${user.login}/clips`}
|
||||
style={{color}}
|
||||
>{ t.chat.formatUser(user, createElement) }</a>
|
||||
{user_bits}
|
||||
<div class="tw-inline-block tw-mg-r-05">{
|
||||
is_action ? '' : ':'
|
||||
}</div>
|
||||
|
|
|
@ -2010,6 +2010,21 @@ export default class ChatHook extends Module {
|
|||
}
|
||||
|
||||
|
||||
scheduleMystery(mystery) { // eslint-disable-line class-methods-use-this
|
||||
if ( ! mystery.line )
|
||||
return;
|
||||
|
||||
if ( mystery._timer )
|
||||
return;
|
||||
|
||||
mystery._timer = setTimeout(() => requestAnimationFrame(() => {
|
||||
mystery._timer = null;
|
||||
if ( mystery.line )
|
||||
mystery.line.forceUpdate();
|
||||
}), 250);
|
||||
}
|
||||
|
||||
|
||||
wrapChatService(cls) {
|
||||
const t = this,
|
||||
old_mount = cls.prototype.componentDidMount,
|
||||
|
@ -2213,7 +2228,7 @@ export default class ChatHook extends Module {
|
|||
mysteries[key] = null;
|
||||
|
||||
if ( mystery.line )
|
||||
mystery.line.forceUpdate();
|
||||
t.scheduleMystery(mystery);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -2265,7 +2280,7 @@ export default class ChatHook extends Module {
|
|||
mysteries[key] = null;
|
||||
|
||||
if ( mystery.line )
|
||||
mystery.line.forceUpdate();
|
||||
t.scheduleMystery(mystery);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -485,18 +485,26 @@ other {# messages were deleted by a moderator.}
|
|||
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),
|
||||
e('span', {
|
||||
className: 'chat-line__message--badges'
|
||||
}, t.chat.badges.render(msg, e)),
|
||||
e('span', {
|
||||
className: `chat-line__username notranslate${override_name ? ' ffz--name-override tw-relative ffz-il-tooltip__container' : ''}`,
|
||||
role: 'button',
|
||||
style: { color },
|
||||
onClick: this.ffz_user_click_handler,
|
||||
onContextMenu: t.actions.handleUserContext
|
||||
}, override_name ? [
|
||||
e('span', user_props, override_name ? [
|
||||
e('span', {
|
||||
className: 'chat-author__display-name'
|
||||
}, override_name),
|
||||
|
|
|
@ -47,6 +47,7 @@ export default class VideoChatHook extends Module {
|
|||
this.inject('site.web_munch');
|
||||
|
||||
this.inject('chat');
|
||||
this.inject('chat.overrides');
|
||||
this.injectAs('site_chat', 'site.chat');
|
||||
this.inject('site.chat.chat_line.rich_content');
|
||||
|
||||
|
@ -248,7 +249,8 @@ export default class VideoChatHook extends Module {
|
|||
action_italic = action_style >= 2,
|
||||
action_color = action_style === 1 || action_style === 3,
|
||||
user = msg.user,
|
||||
color = t.site_chat.colors.process(user.color),
|
||||
raw_color = t.overrides.getColor(user.id) || user.color,
|
||||
color = t.site_chat.colors.process(raw_color),
|
||||
|
||||
u = t.site.getUser();
|
||||
|
||||
|
@ -313,18 +315,38 @@ export default class VideoChatHook extends Module {
|
|||
const tokens = msg.ffz_tokens = msg.ffz_tokens || t.chat.tokenizeMessage(msg, u),
|
||||
rich_content = FFZRichContent && t.chat.pluckRichContent(tokens, msg);
|
||||
|
||||
const user_block = t.chat.formatUser(user, createElement);
|
||||
const override_name = t.overrides.getName(user.id);
|
||||
|
||||
const user_props = {
|
||||
className: `video-chat__message-author notranslate${override_name ? ' ffz--name-override tw-relative ffz-il-tooltip__container' : ''} ${msg.ffz_user_class ?? ''}`,
|
||||
'data-test-selector': 'comment-author-selector',
|
||||
href: `/${user.login}`,
|
||||
rel: 'noopener noreferrer',
|
||||
target: '_blank',
|
||||
style: { color }
|
||||
};
|
||||
|
||||
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 = createElement('a', user_props, override_name ? [
|
||||
createElement('span', {
|
||||
className: 'chat-author__display-name'
|
||||
}, override_name),
|
||||
createElement('div', {
|
||||
className: 'ffz-il-tooltip ffz-il-tooltip--down ffz-il-tooltip--align-center'
|
||||
}, user_block)
|
||||
] : user_block);
|
||||
|
||||
let out = (<div class="tw-flex-grow-1" data-room-id={msg.roomID} data-room={msg.roomLogin} data-user-id={user.id} data-user={user.login}>
|
||||
<span class="chat-line__message--badges">{
|
||||
t.chat.badges.render(msg, createElement)
|
||||
}</span>
|
||||
<a
|
||||
class="video-chat__message-author notranslate"
|
||||
data-test-selector="comment-author-selector"
|
||||
href={`/${user.login}`}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
style={{color}}
|
||||
>{t.chat.formatUser(user, createElement)}</a>
|
||||
{user_bits}
|
||||
<div data-test-selector="comment-message-selector" class="tw-inline video-chat__message">
|
||||
<span>{is_action ? ' ' : ': '}</span>
|
||||
<span
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue