diff --git a/src/main.js b/src/main.js index e409dd2b..8b996720 100644 --- a/src/main.js +++ b/src/main.js @@ -149,7 +149,7 @@ ${typeof x[1] === 'string' ? x[1] : JSON.stringify(x[1], null, 4)}` FrankerFaceZ.Logger = Logger; 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__, build: __webpack_hash__, toString: () => diff --git a/src/modules/chat/index.js b/src/modules/chat/index.js index f41dd127..745945b1 100644 --- a/src/modules/chat/index.js +++ b/src/modules/chat/index.js @@ -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 .', - component: 'setting-check-box' - } - }); - this.settings.add('chat.filtering.deleted-style', { default: 1, ui: { @@ -199,7 +189,9 @@ export default class Chat extends Module { component: 'setting-select-box', data: [ {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'} ] } }); diff --git a/src/modules/tooltips.js b/src/modules/tooltips.js index 576aa84f..3fa4f525 100644 --- a/src/modules/tooltips.js +++ b/src/modules/tooltips.js @@ -36,10 +36,10 @@ export default class TooltipProvider extends Module { } 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'); - 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, delayHide: this.checkDelayHide.bind(this), delayShow: this.checkDelayShow.bind(this), diff --git a/src/sites/twitch-twilight/modules/chat/index.js b/src/sites/twitch-twilight/modules/chat/index.js index 90923e83..687b6616 100644 --- a/src/sites/twitch-twilight/modules/chat/index.js +++ b/src/sites/twitch-twilight/modules/chat/index.js @@ -108,7 +108,8 @@ const CHAT_TYPES = make_enum( 'SubMysteryGift', 'AnonSubMysteryGift', '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.css_tweaks.toggleHide('pinned-cheer', !val)); - this.chat.context.on('changed:chat.filtering.deleted-style', val => - this.css_tweaks.toggle('chat-deleted-strike', val === 1)) + this.chat.context.on('changed:chat.filtering.deleted-style', val => { + 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.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 ) return; + /*} else if ( msg.type === types.ModerationAction ) { + t.log.info('Moderation Action', msg); + } else if ( msg.type === types.Moderation ) { + t.log.info('Moderation', msg); + const login = msg.userLogin; if ( inst.moderatedUsers.has(login) ) return; @@ -704,14 +714,13 @@ export default class ChatHook extends Module { inst.delayedMessageBuffer.forEach(do_update); inst.moderatedUsers.add(login); - setTimeout(inst.unmoderateUser(login), 1000); - return; + setTimeout(inst.unsetModeratedUser(login), 1000);*/ } else if ( msg.type === types.Clear ) { if ( t.chat.context.get('chat.filtering.ignore-clear') ) msg = { - types: types.Notice, - message: t.i18n.t('chat.ignore-clear', 'An attempt to clear chat was ignored.') + type: types.Info, + message: t.i18n.t('chat.ignore-clear', 'An attempt by a moderator to clear chat was ignored.') } } diff --git a/src/sites/twitch-twilight/modules/chat/line.js b/src/sites/twitch-twilight/modules/chat/line.js index 74bb469e..902797dd 100644 --- a/src/sites/twitch-twilight/modules/chat/line.js +++ b/src/sites/twitch-twilight/modules/chat/line.js @@ -10,6 +10,7 @@ import Module from 'utilities/module'; import RichContent from './rich_content'; import { has } from 'utilities/object'; import { KEYS } from 'utilities/constants'; +import { print_duration } from 'src/utilities/time'; const SUB_TIERS = { 1000: 1, @@ -256,6 +257,8 @@ export default class ChatLine extends Module { return show !== old_show || (state && this.state && (state.ffz_expanded !== this.state.ffz_expanded)) || //state.renderDebug !== this.state.renderDebug || + props.deletedMessageDisplay !== this.props.deletedMessageDisplay || + props.deletedCount !== this.props.deletedCount || props.message !== this.props.message || props.isCurrentUserModerator !== this.props.isCurrentUserModerator || props.showModerationIcons !== this.props.showModerationIcons || @@ -265,22 +268,70 @@ export default class ChatLine extends Module { cls.prototype.render = function() { try { const types = t.parent.message_types || {}, + mod_mode = this.props.deletedMessageDisplay, + deleted_count = this.props.deletedCount, msg = t.chat.standardizeMessage(this.props.message), is_action = msg.messageType === types.Action, user = msg.user, - color = t.parent.colors.process(user.color), - show_deleted = t.chat.context.get('chat.filtering.show-deleted'); + color = t.parent.colors.process(user.color); - 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_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 { show = this.state && this.state.alwaysShowMessage || ! msg.deleted; show_class = false; + mod_action = null; } 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 && mod_action, + /*this.state.renderDebug === 2 && e('div', { className: 'border mg-t-05' }, old_render.call(this)), diff --git a/src/sites/twitch-twilight/modules/chat/settings_menu.jsx b/src/sites/twitch-twilight/modules/chat/settings_menu.jsx index a8af8ec1..103b0d2e 100644 --- a/src/sites/twitch-twilight/modules/chat/settings_menu.jsx +++ b/src/sites/twitch-twilight/modules/chat/settings_menu.jsx @@ -72,8 +72,8 @@ export default class SettingsMenu extends Module { click(inst, event) { // 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. - const minimal_root = document.querySelector('.twilight-minimal-root'); - if ( minimal_root || (event && (event.ctrlKey || event.shiftKey)) ) { + const layout = this.resolve('site.layout'); + if ( (layout && layout.is_minimal) || (event && (event.ctrlKey || event.shiftKey)) ) { const win = window.open( 'https://twitch.tv/popout/frankerfacez/chat?ffz-settings', '_blank', diff --git a/src/sites/twitch-twilight/modules/css_tweaks/styles/chat-deleted-fade.scss b/src/sites/twitch-twilight/modules/css_tweaks/styles/chat-deleted-fade.scss new file mode 100644 index 00000000..f64b3cfd --- /dev/null +++ b/src/sites/twitch-twilight/modules/css_tweaks/styles/chat-deleted-fade.scss @@ -0,0 +1,5 @@ +.ffz--deleted-message { + &:not(:hover) > * { + opacity: 0.5; + } +} \ No newline at end of file diff --git a/src/sites/twitch-twilight/modules/layout.js b/src/sites/twitch-twilight/modules/layout.js index a38e906c..6e8f5d6c 100644 --- a/src/sites/twitch-twilight/modules/layout.js +++ b/src/sites/twitch-twilight/modules/layout.js @@ -7,6 +7,7 @@ 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 MINIMAL_ROUTES = ['popout', 'embed-chat']; export default class Layout extends Module { constructor(...args) { @@ -20,7 +21,7 @@ export default class Layout extends Module { this.RightColumn = this.fine.define( 'tw-rightcolumn', - n => n.hideOnBreakpoint && n.onTheatreMouseMove + n => n.hideOnBreakpoint && n.handleToggleVisibility ); 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`) }); + + this.settings.add('layout.is-minimal', { + require: ['context.route.name'], + process(ctx) { + return MINIMAL_ROUTES.includes(ctx.get('context.route.name')); + } + }); } onEnable() { @@ -183,6 +191,10 @@ export default class Layout extends Module { }); } + get is_minimal() { + return this.settings.get('layout.is-minimal') + } + updatePortraitMode() { for(const inst of this.RightColumn.instances) inst.hideOnBreakpoint(); diff --git a/styles/chat.scss b/styles/chat.scss index b46dfb62..de49eb36 100644 --- a/styles/chat.scss +++ b/styles/chat.scss @@ -19,13 +19,6 @@ } -.ffz--deleted-message { - &:not(:hover) > * { - opacity: 0.5; - } -} - - .ffz-badge { display: inline-block; min-width: 1.8rem;