mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-09-01 10:50:56 +00:00
4.0.0-rc16.2
* Fixed: Add initial support for Twitch's new message moderation display styles. * Fixed: Tooltips in pop-out chat not appearing correctly. * Fixed: Opening the FFZ Control Center from pop-out chat. * Fixed: Chat not appearing if a window is too thin with Portrait Mode enabled.
This commit is contained in:
parent
00859ac966
commit
6941a85ff6
9 changed files with 100 additions and 36 deletions
|
@ -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: '-rc16.1',
|
major: 4, minor: 0, revision: 0, extra: '-rc16.2',
|
||||||
commit: __git_commit__,
|
commit: __git_commit__,
|
||||||
build: __webpack_hash__,
|
build: __webpack_hash__,
|
||||||
toString: () =>
|
toString: () =>
|
||||||
|
|
|
@ -181,16 +181,6 @@ export default class Chat extends Module {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.settings.add('chat.filtering.show-deleted', {
|
|
||||||
default: false,
|
|
||||||
ui: {
|
|
||||||
path: 'Chat > Behavior >> Deleted Messages',
|
|
||||||
title: 'Always display deleted messages.',
|
|
||||||
description: 'Deleted messages will be displayed differently for differentiation, but never hidden behind <message deleted>.',
|
|
||||||
component: 'setting-check-box'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.settings.add('chat.filtering.deleted-style', {
|
this.settings.add('chat.filtering.deleted-style', {
|
||||||
default: 1,
|
default: 1,
|
||||||
ui: {
|
ui: {
|
||||||
|
@ -199,7 +189,9 @@ export default class Chat extends Module {
|
||||||
component: 'setting-select-box',
|
component: 'setting-select-box',
|
||||||
data: [
|
data: [
|
||||||
{value: 0, title: 'Faded'},
|
{value: 0, title: 'Faded'},
|
||||||
{value: 1, title: 'Faded, Line Through'}
|
{value: 1, title: 'Faded, Line Through'},
|
||||||
|
{value: 2, title: 'Line Through'},
|
||||||
|
{value: 3, title: 'No Change'}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -36,10 +36,10 @@ export default class TooltipProvider extends Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
onEnable() {
|
onEnable() {
|
||||||
const container = document.querySelector('#root>div,#root,.clips-root') || document.body,
|
const container = document.querySelector('#root>div') || document.querySelector('#root') || document.querySelector('.clips-root') || document.body,
|
||||||
is_minimal = false; //container && container.classList.contains('twilight-minimal-root');
|
is_minimal = false; //container && container.classList.contains('twilight-minimal-root');
|
||||||
|
|
||||||
this.tips = new Tooltip(is_minimal ? '.twilight-minimal-root,body' : '#root>div,#root,body', 'ffz-tooltip', {
|
this.tips = new Tooltip(container, 'ffz-tooltip', {
|
||||||
html: true,
|
html: true,
|
||||||
delayHide: this.checkDelayHide.bind(this),
|
delayHide: this.checkDelayHide.bind(this),
|
||||||
delayShow: this.checkDelayShow.bind(this),
|
delayShow: this.checkDelayShow.bind(this),
|
||||||
|
|
|
@ -108,7 +108,8 @@ const CHAT_TYPES = make_enum(
|
||||||
'SubMysteryGift',
|
'SubMysteryGift',
|
||||||
'AnonSubMysteryGift',
|
'AnonSubMysteryGift',
|
||||||
'FirstCheerMessage',
|
'FirstCheerMessage',
|
||||||
'BitsBadgeTierMessage'
|
'BitsBadgeTierMessage',
|
||||||
|
'InlinePrivateCallout'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -444,10 +445,14 @@ export default class ChatHook extends Module {
|
||||||
this.chat.context.on('changed:chat.bits.show-pinned', val =>
|
this.chat.context.on('changed:chat.bits.show-pinned', val =>
|
||||||
this.css_tweaks.toggleHide('pinned-cheer', !val));
|
this.css_tweaks.toggleHide('pinned-cheer', !val));
|
||||||
|
|
||||||
this.chat.context.on('changed:chat.filtering.deleted-style', val =>
|
this.chat.context.on('changed:chat.filtering.deleted-style', val => {
|
||||||
this.css_tweaks.toggle('chat-deleted-strike', val === 1))
|
this.css_tweaks.toggle('chat-deleted-strike', val === 1 || val === 2);
|
||||||
|
this.css_tweaks.toggle('chat-deleted-fade', val < 2);
|
||||||
|
});
|
||||||
|
|
||||||
this.css_tweaks.toggle('chat-deleted-strike', this.chat.context.get('chat.filtering.deleted-style') === 1);
|
const val = this.chat.context.get('chat.filtering.deleted-style');
|
||||||
|
this.css_tweaks.toggle('chat-deleted-strike', val === 1 || val === 2);
|
||||||
|
this.css_tweaks.toggle('chat-deleted-fade', val < 2);
|
||||||
|
|
||||||
this.css_tweaks.toggleHide('pinned-cheer', !this.chat.context.get('chat.bits.show-pinned'));
|
this.css_tweaks.toggleHide('pinned-cheer', !this.chat.context.get('chat.bits.show-pinned'));
|
||||||
this.css_tweaks.toggle('hide-bits', !this.chat.context.get('chat.bits.show'));
|
this.css_tweaks.toggle('hide-bits', !this.chat.context.get('chat.bits.show'));
|
||||||
|
@ -664,7 +669,12 @@ export default class ChatHook extends Module {
|
||||||
if ( event.defaultPrevented || m.ffz_removed )
|
if ( event.defaultPrevented || m.ffz_removed )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/*} else if ( msg.type === types.ModerationAction ) {
|
||||||
|
t.log.info('Moderation Action', msg);
|
||||||
|
|
||||||
} else if ( msg.type === types.Moderation ) {
|
} else if ( msg.type === types.Moderation ) {
|
||||||
|
t.log.info('Moderation', msg);
|
||||||
|
|
||||||
const login = msg.userLogin;
|
const login = msg.userLogin;
|
||||||
if ( inst.moderatedUsers.has(login) )
|
if ( inst.moderatedUsers.has(login) )
|
||||||
return;
|
return;
|
||||||
|
@ -704,14 +714,13 @@ export default class ChatHook extends Module {
|
||||||
inst.delayedMessageBuffer.forEach(do_update);
|
inst.delayedMessageBuffer.forEach(do_update);
|
||||||
|
|
||||||
inst.moderatedUsers.add(login);
|
inst.moderatedUsers.add(login);
|
||||||
setTimeout(inst.unmoderateUser(login), 1000);
|
setTimeout(inst.unsetModeratedUser(login), 1000);*/
|
||||||
return;
|
|
||||||
|
|
||||||
} else if ( msg.type === types.Clear ) {
|
} else if ( msg.type === types.Clear ) {
|
||||||
if ( t.chat.context.get('chat.filtering.ignore-clear') )
|
if ( t.chat.context.get('chat.filtering.ignore-clear') )
|
||||||
msg = {
|
msg = {
|
||||||
types: types.Notice,
|
type: types.Info,
|
||||||
message: t.i18n.t('chat.ignore-clear', 'An attempt to clear chat was ignored.')
|
message: t.i18n.t('chat.ignore-clear', 'An attempt by a moderator to clear chat was ignored.')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import Module from 'utilities/module';
|
||||||
import RichContent from './rich_content';
|
import RichContent from './rich_content';
|
||||||
import { has } from 'utilities/object';
|
import { has } from 'utilities/object';
|
||||||
import { KEYS } from 'utilities/constants';
|
import { KEYS } from 'utilities/constants';
|
||||||
|
import { print_duration } from 'src/utilities/time';
|
||||||
|
|
||||||
const SUB_TIERS = {
|
const SUB_TIERS = {
|
||||||
1000: 1,
|
1000: 1,
|
||||||
|
@ -256,6 +257,8 @@ export default class ChatLine extends Module {
|
||||||
return show !== old_show ||
|
return show !== old_show ||
|
||||||
(state && this.state && (state.ffz_expanded !== this.state.ffz_expanded)) ||
|
(state && this.state && (state.ffz_expanded !== this.state.ffz_expanded)) ||
|
||||||
//state.renderDebug !== this.state.renderDebug ||
|
//state.renderDebug !== this.state.renderDebug ||
|
||||||
|
props.deletedMessageDisplay !== this.props.deletedMessageDisplay ||
|
||||||
|
props.deletedCount !== this.props.deletedCount ||
|
||||||
props.message !== this.props.message ||
|
props.message !== this.props.message ||
|
||||||
props.isCurrentUserModerator !== this.props.isCurrentUserModerator ||
|
props.isCurrentUserModerator !== this.props.isCurrentUserModerator ||
|
||||||
props.showModerationIcons !== this.props.showModerationIcons ||
|
props.showModerationIcons !== this.props.showModerationIcons ||
|
||||||
|
@ -265,22 +268,70 @@ export default class ChatLine extends Module {
|
||||||
cls.prototype.render = function() { try {
|
cls.prototype.render = function() { try {
|
||||||
|
|
||||||
const types = t.parent.message_types || {},
|
const types = t.parent.message_types || {},
|
||||||
|
mod_mode = this.props.deletedMessageDisplay,
|
||||||
|
deleted_count = this.props.deletedCount,
|
||||||
|
|
||||||
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,
|
||||||
|
|
||||||
user = msg.user,
|
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');
|
|
||||||
|
|
||||||
let show, show_class;
|
let show, show_class, mod_action;
|
||||||
|
|
||||||
if ( show_deleted ) {
|
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} message was deleted by a moderator.',
|
||||||
|
'%{count} messages were deleted by a moderator.'
|
||||||
|
], {
|
||||||
|
count: deleted_count
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
show = true;
|
||||||
|
show_class = false;
|
||||||
|
mod_action = null;
|
||||||
|
|
||||||
|
} else if ( mod_mode === 'DETAILED' ) {
|
||||||
show = true;
|
show = true;
|
||||||
show_class = msg.deleted;
|
show_class = msg.deleted;
|
||||||
|
|
||||||
|
if ( msg.deleted ) {
|
||||||
|
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})`);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
show = this.state && this.state.alwaysShowMessage || ! msg.deleted;
|
show = this.state && this.state.alwaysShowMessage || ! msg.deleted;
|
||||||
show_class = false;
|
show_class = false;
|
||||||
|
mod_action = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let room = msg.roomLogin ? msg.roomLogin : msg.channel ? msg.channel.slice(1) : undefined;
|
let room = msg.roomLogin ? msg.roomLogin : msg.channel ? msg.channel.slice(1) : undefined;
|
||||||
|
@ -368,6 +419,8 @@ export default class ChatLine extends Module {
|
||||||
|
|
||||||
show && rich_content && e(FFZRichContent, rich_content),
|
show && rich_content && e(FFZRichContent, rich_content),
|
||||||
|
|
||||||
|
show && mod_action,
|
||||||
|
|
||||||
/*this.state.renderDebug === 2 && e('div', {
|
/*this.state.renderDebug === 2 && e('div', {
|
||||||
className: 'border mg-t-05'
|
className: 'border mg-t-05'
|
||||||
}, old_render.call(this)),
|
}, old_render.call(this)),
|
||||||
|
|
|
@ -72,8 +72,8 @@ export default class SettingsMenu extends Module {
|
||||||
click(inst, event) {
|
click(inst, event) {
|
||||||
// If we're on a page with minimal root, we want to open settings
|
// If we're on a page with minimal root, we want to open settings
|
||||||
// in a popout as we're almost certainly within Popout Chat.
|
// in a popout as we're almost certainly within Popout Chat.
|
||||||
const minimal_root = document.querySelector('.twilight-minimal-root');
|
const layout = this.resolve('site.layout');
|
||||||
if ( minimal_root || (event && (event.ctrlKey || event.shiftKey)) ) {
|
if ( (layout && layout.is_minimal) || (event && (event.ctrlKey || event.shiftKey)) ) {
|
||||||
const win = window.open(
|
const win = window.open(
|
||||||
'https://twitch.tv/popout/frankerfacez/chat?ffz-settings',
|
'https://twitch.tv/popout/frankerfacez/chat?ffz-settings',
|
||||||
'_blank',
|
'_blank',
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
.ffz--deleted-message {
|
||||||
|
&:not(:hover) > * {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@
|
||||||
import Module from 'utilities/module';
|
import Module from 'utilities/module';
|
||||||
|
|
||||||
const PORTRAIT_ROUTES = ['user', 'video', 'user-video', 'user-clip', 'user-videos', 'user-clips', 'user-collections', 'user-events', 'user-followers', 'user-following'];
|
const PORTRAIT_ROUTES = ['user', 'video', 'user-video', 'user-clip', 'user-videos', 'user-clips', 'user-collections', 'user-events', 'user-followers', 'user-following'];
|
||||||
|
const MINIMAL_ROUTES = ['popout', 'embed-chat'];
|
||||||
|
|
||||||
export default class Layout extends Module {
|
export default class Layout extends Module {
|
||||||
constructor(...args) {
|
constructor(...args) {
|
||||||
|
@ -20,7 +21,7 @@ export default class Layout extends Module {
|
||||||
|
|
||||||
this.RightColumn = this.fine.define(
|
this.RightColumn = this.fine.define(
|
||||||
'tw-rightcolumn',
|
'tw-rightcolumn',
|
||||||
n => n.hideOnBreakpoint && n.onTheatreMouseMove
|
n => n.hideOnBreakpoint && n.handleToggleVisibility
|
||||||
);
|
);
|
||||||
|
|
||||||
this.settings.add('layout.portrait', {
|
this.settings.add('layout.portrait', {
|
||||||
|
@ -129,6 +130,13 @@ export default class Layout extends Module {
|
||||||
|
|
||||||
changed: val => this.css_tweaks.setVariable('portrait-extra-width', `${val}rem`)
|
changed: val => this.css_tweaks.setVariable('portrait-extra-width', `${val}rem`)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.settings.add('layout.is-minimal', {
|
||||||
|
require: ['context.route.name'],
|
||||||
|
process(ctx) {
|
||||||
|
return MINIMAL_ROUTES.includes(ctx.get('context.route.name'));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onEnable() {
|
onEnable() {
|
||||||
|
@ -183,6 +191,10 @@ export default class Layout extends Module {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get is_minimal() {
|
||||||
|
return this.settings.get('layout.is-minimal')
|
||||||
|
}
|
||||||
|
|
||||||
updatePortraitMode() {
|
updatePortraitMode() {
|
||||||
for(const inst of this.RightColumn.instances)
|
for(const inst of this.RightColumn.instances)
|
||||||
inst.hideOnBreakpoint();
|
inst.hideOnBreakpoint();
|
||||||
|
|
|
@ -19,13 +19,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.ffz--deleted-message {
|
|
||||||
&:not(:hover) > * {
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.ffz-badge {
|
.ffz-badge {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
min-width: 1.8rem;
|
min-width: 1.8rem;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue