1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-07-05 18:48:31 +00:00

4.0.0-rc13.23

* Added: Override chat line rendering for viewer cards (and also Rooms, as a side effect. Rooms are still a thing and people use them, right? Right? ... right.....?)
* Fixed: With Swap Sidebars enabled in Firefox, the button to expand and close chat not appearing correctly.
* Fixed: Messages being removed for moderators when they shouldn't be due to FFZ settings.
This commit is contained in:
SirStendec 2019-01-31 19:58:21 -05:00
parent 9697962313
commit a8886167a3
4 changed files with 116 additions and 81 deletions

View file

@ -149,7 +149,7 @@ ${typeof x[1] === 'string' ? x[1] : JSON.stringify(x[1], null, 4)}`
FrankerFaceZ.Logger = Logger; FrankerFaceZ.Logger = Logger;
const VER = FrankerFaceZ.version_info = { const VER = FrankerFaceZ.version_info = {
major: 4, minor: 0, revision: 0, extra: '-rc13.22', major: 4, minor: 0, revision: 0, extra: '-rc13.23',
commit: __git_commit__, commit: __git_commit__,
build: __webpack_hash__, build: __webpack_hash__,
toString: () => toString: () =>

View file

@ -713,13 +713,14 @@ export default class ChatHook extends Module {
raw_delay = t.chat.context.get('chat.delay'), raw_delay = t.chat.context.get('chat.delay'),
delay = raw_delay === -1 ? this.delayDuration : raw_delay, delay = raw_delay === -1 ? this.delayDuration : raw_delay,
first = now - delay, first = now - delay,
see_deleted = this.shouldSeeBlockedAndDeletedMessages || this.props && this.props.shouldSeeBlockedAndDeletedMessages,
do_remove = t.chat.context.get('chat.filtering.remove-deleted'); do_remove = t.chat.context.get('chat.filtering.remove-deleted');
let changed = false; let changed = false;
for(const msg of this.delayedMessageBuffer) { for(const msg of this.delayedMessageBuffer) {
if ( msg.time <= first || ! msg.shouldDelay ) { if ( msg.time <= first || ! msg.shouldDelay ) {
if ( do_remove !== 0 && (do_remove > 1 || ! this.shouldSeeBlockedAndDeletedMessages) && this.isDeletable(msg.event) && msg.event.deleted ) if ( do_remove !== 0 && (do_remove > 1 || ! see_deleted) && this.isDeletable(msg.event) && msg.event.deleted )
continue; continue;
this.buffer.push(msg.event); this.buffer.push(msg.event);
@ -886,9 +887,14 @@ export default class ChatHook extends Module {
try { try {
const out = i.convertMessage({message: e}); const out = i.convertMessage({message: e});
out.ffz_type = 'resub'; out.ffz_type = 'resub';
out.sub_cumulative = e.cumulativeMonths || 0;
out.sub_streak = e.streakMonths || 0;
out.sub_share_streak = e.shouldShareStreakTenure;
out.sub_months = e.months; out.sub_months = e.months;
out.sub_plan = e.methods; out.sub_plan = e.methods;
//t.log.info('Resub Event', e, out);
return i.postMessageToCurrentChannel(e, out); return i.postMessageToCurrentChannel(e, out);
} catch(err) { } catch(err) {

View file

@ -8,6 +8,7 @@ import Twilight from 'site';
import Module from 'utilities/module'; import Module from 'utilities/module';
import RichContent from './rich_content'; import RichContent from './rich_content';
import { has } from 'src/utilities/object';
const SUB_TIERS = { const SUB_TIERS = {
1000: 1, 1000: 1,
@ -33,16 +34,22 @@ export default class ChatLine extends Module {
this.ChatLine = this.fine.define( this.ChatLine = this.fine.define(
'chat-line', 'chat-line',
n => n.renderMessageBody && n.props && ! n.props.roomID, n => n.renderMessageBody && n.props && !has(n.props, 'hasModPermissions'),
Twilight.CHAT_ROUTES Twilight.CHAT_ROUTES
); );
this.ChatRoomLine = this.fine.define( this.ChatRoomLine = this.fine.define(
'chat-room-line', 'chat-room-line',
n => n.renderMessageBody && n.props && n.props.roomID, n => n.renderMessageBody && n.props && has(n.props, 'hasModPermissions'),
Twilight.CHAT_ROUTES Twilight.CHAT_ROUTES
); );
/*this.ChatRoomContainer = this.fine.define(
'chat-room-container',
n => n.renderPlaceholders && n.sendRoomMessage && n.props && n.props.channel,
Twilight.CHAT_ROUTES
);*/
this.WhisperLine = this.fine.define( this.WhisperLine = this.fine.define(
'whisper-line', 'whisper-line',
n => n.props && n.props.message && n.props.reportOutgoingWhisperRendered n => n.props && n.props.message && n.props.reportOutgoingWhisperRendered
@ -78,55 +85,69 @@ export default class ChatLine extends Module {
FFZRichContent = this.rich_content && this.rich_content.RichContent; FFZRichContent = this.rich_content && this.rich_content.RichContent;
/*this.ChatRoomLine.ready(cls => { this.ChatRoomLine.ready(cls => {
cls.prototype.render = function() { const old_render = cls.prototype.render;
cls.prototype.render = function() { try {
const msg = t.chat.standardizeMessage(this.props.message), const msg = t.chat.standardizeMessage(this.props.message),
is_action = msg.is_action, is_action = msg.is_action,
user = msg.user, user = msg.user,
color = t.parent.colors.process(user.color), color = t.parent.colors.process(user.color),
bg_css = null, show_deleted = t.chat.context.get('chat.filtering.show-deleted');
show = this._ffz_show = this.state.shouldShowDeletedBody || ! msg.deletedAt;
let room = msg.roomLogin ? msg.roomLogin : msg.channel ? msg.channel.slice(1) : null; let show, show_class;
if ( ! room && this.props.channelID ) { if ( show_deleted ) {
const r = t.chat.getRoom(this.props.channelID, null, true); show = true;
if ( r && r.login ) show_class = msg.deleted;
room = msg.roomLogin = r.login; } else {
show = this.state && this.state.shouldShowDeletedBody || ! msg.deleted;
show_class = false;
} }
const u = t.site.getUser(), const u = t.site.getUser(),
r = {id: this.props.channelID, login: room}; r = {id: null, login: null};
if ( u ) { if ( u ) {
u.moderator = this.props.isCurrentUserModerator; u.moderator = this.props.hasModPermissions;
u.staff = this.props.isCurrentUserStaff;
} }
const tokens = msg.ffz_tokens = msg.ffz_tokens || t.chat.tokenizeMessage(msg, u), // Find the parent element.
rich_content = FFZRichContent && t.chat.pluckRichContent(tokens, msg); const parent = this._ffz_parent = this._ffz_parent || t.fine.searchParent(this,
n => (n.props && n.props.banStatusData && n.props.channelID) ||
(n.renderPlaceholders && n.sendRoomMessage && n.props && n.props.channel), 50);
if ( parent != null ) {
r.id = parent.props.channelID;
r.login = parent.props.channelLogin;
}
const tokens = msg.ffz_tokens = msg.ffz_tokens || t.chat.tokenizeMessage(msg, u, r),
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_user_click_handler ) if ( ! this.ffz_user_click_handler )
this.ffz_user_click_handler = event => this.ffz_user_click_handler = this.props.onUsernameClick;
event.ctrlKey ?
this.props.onUsernameClick(user.login, null, msg.id, event.currentTarget.getBoundingClientRect().bottom) :
t.viewer_cards.openCard(r, user, event);
let cls = 'chat-line__message', let cls = `chat-line__message${show_class ? ' ffz--deleted-message' : ''}`,
out = (tokens.length || ! msg.ffz_type) ? [ out = (tokens.length || ! msg.ffz_type) ? [
this.props.showTimestamps && e('span', { this.props.showTimestamps && e('span', {
className: 'chat-line__timestamp' className: 'chat-line__timestamp'
}, t.chat.formatTime(msg.timestamp)), }, t.chat.formatTime(msg.timestamp)),
t.actions.renderInline(msg, this.props.showModerationIcons, u, r, e), this.renderModerationIcons(),
//t.actions.renderInline(msg, this.props.showModerationIcons, u, r, e),
e('span', { e('span', {
className: 'chat-line__message--badges' className: 'chat-line__message--badges'
}, t.chat.badges.render(msg, e)), }, t.chat.badges.render(msg, e)),
e('a', { e('button', {
className: 'chat-author__display-name notranslate', className: 'chat-line__username notranslate',
style: { color }, style: { color },
onClick: this.ffz_user_click_handler onClick: this.ffz_user_click_handler
}, [ }, [
user.displayName, e('span', {
className: 'chat-author__display-name'
}, user.displayName),
user.isIntl && e('span', { user.isIntl && e('span', {
className: 'chat-author__intl-login' className: 'chat-author__intl-login'
}, ` (${user.login})`) }, ` (${user.login})`)
@ -152,20 +173,28 @@ export default class ChatLine extends Module {
return null; return null;
return e('div', { return e('div', {
className: `${cls}${msg.mentioned ? ' ffz-mentioned' : ''}`, className: `${cls}${msg.mentioned ? ' ffz-mentioned' : ''}${bg_css ? ' ffz-custom-color' : ''}`,
style: {backgroundColor: bg_css}, style: {backgroundColor: bg_css},
id: msg.id, 'data-room-id': r.id,
'data-room-id': this.props.channelID, 'data-room': r.login,
'data-room': room,
'data-user-id': user.id, 'data-user-id': user.id,
'data-user': user.login && user.login.toLowerCase() 'data-user': user.login && user.login.toLowerCase()
}, out); }, out);
}
} catch(err) {
t.log.capture(err, {
extra: {
props: this.props
}
});
return old_render.call(this);
} };
// Do this after a short delay to hopefully reduce the chance of React // Do this after a short delay to hopefully reduce the chance of React
// freaking out on us. // freaking out on us.
setTimeout(() => this.ChatRoomLine.forceUpdate()); setTimeout(() => this.ChatRoomLine.forceUpdate());
});*/ });
this.WhisperLine.ready(cls => { this.WhisperLine.ready(cls => {
@ -234,23 +263,9 @@ export default class ChatLine extends Module {
const types = t.parent.message_types || {}, const types = t.parent.message_types || {},
msg = t.chat.standardizeMessage(this.props.message), msg = t.chat.standardizeMessage(this.props.message),
is_action = msg.messageType === types.Action; is_action = msg.messageType === types.Action,
/*if ( msg.content && ! msg.message ) user = msg.user,
msg.message = msg.content.text;
if ( msg.sender && ! msg.user ) {
msg.user = msg.sender;
msg.user.color = msg.user.color || msg.user.chatColor;
}
if ( ! msg.badges && msg.user.displayBadges ) {
const b = msg.badges = {};
for(const item of msg.user.displayBadges)
b[item.setID] = item.version;
}*/
const user = msg.user,
color = t.parent.colors.process(user.color), color = t.parent.colors.process(user.color),
show_deleted = t.chat.context.get('chat.filtering.show-deleted'); show_deleted = t.chat.context.get('chat.filtering.show-deleted');
@ -323,7 +338,7 @@ export default class ChatLine extends Module {
}, e('a', { }, e('a', {
href: '', href: '',
onClick: this.alwaysShowMessage onClick: this.alwaysShowMessage
}, `<message deleted>`)), }, t.i18n.t('chat.message-deleted', '<message deleted>'))),
show && rich_content && e(FFZRichContent, rich_content), show && rich_content && e(FFZRichContent, rich_content),
@ -343,32 +358,45 @@ export default class ChatLine extends Module {
if ( msg.ffz_type === 'resub' ) { if ( msg.ffz_type === 'resub' ) {
const plan = msg.sub_plan || {}, const plan = msg.sub_plan || {},
months = msg.sub_months || 1, months = msg.sub_cumulative || msg.sub_months,
tier = SUB_TIERS[plan.plan] || 1; tier = SUB_TIERS[plan.plan] || 1;
const sub_msg = t.i18n.tList('chat.sub.main', '%{user} subscribed %{plan}.', {
user: e('button', {
className: 'chatter-name',
onClick: this.ffz_user_click_handler
}, e('span', {
className: 'tw-c-text-base tw-strong'
}, user.userDisplayName)),
plan: plan.prime ?
t.i18n.t('chat.sub.twitch-prime', 'with Twitch Prime') :
t.i18n.t('chat.sub.plan', 'at Tier %{tier}', {tier})
});
if ( msg.sub_share_streak && msg.sub_streak ) {
sub_msg.push(t.i18n.t(
'chat.sub.cumulative-months',
"They've subscribed for %{cumulative} months, currently on a %{streak} month streak!",
{
cumulative: msg.sub_cumulative,
streak: msg.sub_streak
}
));
} else if ( months ) {
sub_msg.push(t.i18n.t(
'chat.sub.months',
"They've subscribed for %{count} months!",
{
count: months
}
));
}
cls = 'user-notice-line tw-pd-y-05 tw-pd-r-2 ffz--subscribe-line'; cls = 'user-notice-line tw-pd-y-05 tw-pd-r-2 ffz--subscribe-line';
out = [ out = [
e('div', {className: 'tw-c-text-alt-2'}, [ e('div', {className: 'tw-c-text-alt-2'}, sub_msg),
t.i18n.tList('chat.sub.main', '%{user} just subscribed with %{plan}!', {
user: e('button', {
className: 'chatter-name',
onClick: this.ffz_user_click_handler //e => this.props.onUsernameClick(user.login, null, msg.id, e.currentTarget.getBoundingClientRect().bottom)
}, e('span', {
className: 'tw-c-text-base tw-strong'
}, user.userDisplayName)),
plan: plan.prime ?
t.i18n.t('chat.sub.twitch-prime', 'Twitch Prime') :
t.i18n.t('chat.sub.plan', 'a Tier %{tier} sub', {tier})
}),
months > 1 ?
` ${t.i18n.t(
'chat.sub.months',
'%{user} subscribed for %{count} months in a row!',
{
user: user.userDisplayName,
count: months
})}` : null
]),
out && e('div', { out && e('div', {
className: 'chat-line--inline chat-line__message', className: 'chat-line--inline chat-line__message',
'data-room-id': this.props.channelID, 'data-room-id': this.props.channelID,
@ -419,16 +447,15 @@ export default class ChatLine extends Module {
'data-user': user.userLogin && user.userLogin.toLowerCase(), 'data-user': user.userLogin && user.userLogin.toLowerCase(),
}, out); }, out);
} catch(err) { } catch(err) {
t.log.capture(err, { t.log.capture(err, {
extra: { extra: {
props: this.props props: this.props
} }
}); });
return old_render.call(this); return old_render.call(this);
} } }
}
// Do this after a short delay to hopefully reduce the chance of React // Do this after a short delay to hopefully reduce the chance of React
// freaking out on us. // freaking out on us.

View file

@ -5,12 +5,14 @@
.side-nav__toggle-visibility { .side-nav__toggle-visibility {
right: unset !important; right: unset !important;
left: -2.5rem; left: -2.5rem;
z-index: 10 !important;
svg { transform: rotate(180deg) } svg { transform: rotate(180deg) }
} }
.right-column__toggle-visibility { .right-column__toggle-visibility {
left: unset !important; left: unset !important;
right: -2.5rem; right: -2.5rem;
z-index: 10 !important;
svg { transform: rotate(180deg) } svg { transform: rotate(180deg) }
} }