mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-07-05 10:38:30 +00:00
4.0.0-rc22
* Added: Option to highlight messages from a user when their viewer card is open. * Fixed: Every word in whisper messages being highlighted as a mention.
This commit is contained in:
parent
e0b71aa2dd
commit
d9f252ee4e
6 changed files with 171 additions and 10 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: '-rc21.8',
|
major: 4, minor: 0, revision: 0, extra: '-rc22',
|
||||||
commit: __git_commit__,
|
commit: __git_commit__,
|
||||||
build: __webpack_hash__,
|
build: __webpack_hash__,
|
||||||
toString: () =>
|
toString: () =>
|
||||||
|
|
|
@ -587,12 +587,11 @@ export default class Chat extends Module {
|
||||||
default: false,
|
default: false,
|
||||||
ui: {
|
ui: {
|
||||||
component: 'setting-check-box',
|
component: 'setting-check-box',
|
||||||
path: 'Chat > Filtering >> Appearance',
|
path: 'Chat > Viewer Cards >> Behavior',
|
||||||
title: 'Enable opening viewer cards by clicking mentions in chat.'
|
title: 'Enable opening viewer cards by clicking mentions in chat.'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
this.settings.add('chat.filtering.highlight-mentions', {
|
this.settings.add('chat.filtering.highlight-mentions', {
|
||||||
default: false,
|
default: false,
|
||||||
ui: {
|
ui: {
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {TWITCH_EMOTE_BASE, REPLACEMENT_BASE, REPLACEMENTS} from 'utilities/const
|
||||||
const EMOTE_CLASS = 'chat-image chat-line__message--emote',
|
const EMOTE_CLASS = 'chat-image chat-line__message--emote',
|
||||||
LINK_REGEX = /([^\w@#%\-+=:~])?((?:(https?:\/\/)?(?:[\w@#%\-+=:~]+\.)+[a-z]{2,6}(?:\/[\w./@#%&()\-+=:?~]*)?))([^\w./@#%&()\-+=:?~]|\s|$)/g,
|
LINK_REGEX = /([^\w@#%\-+=:~])?((?:(https?:\/\/)?(?:[\w@#%\-+=:~]+\.)+[a-z]{2,6}(?:\/[\w./@#%&()\-+=:?~]*)?))([^\w./@#%&()\-+=:?~]|\s|$)/g,
|
||||||
//MENTION_REGEX = /([^\w@#%\-+=:~])?(@([^\u0000-\u007F]+|\w+)+)([^\w./@#%&()\-+=:?~]|\s|$)/g; // eslint-disable-line no-control-regex
|
//MENTION_REGEX = /([^\w@#%\-+=:~])?(@([^\u0000-\u007F]+|\w+)+)([^\w./@#%&()\-+=:?~]|\s|$)/g; // eslint-disable-line no-control-regex
|
||||||
MENTION_REGEX = /^(['"*([{<\\/]*)(@?)((?:[^\u0000-\u007F]|[\w-])+)/; // eslint-disable-line no-control-regex
|
MENTION_REGEX = /^(['"*([{<\\/]*)(@)((?:[^\u0000-\u007F]|[\w-])+)/; // eslint-disable-line no-control-regex
|
||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
@ -222,18 +222,17 @@ export const Mentions = {
|
||||||
if ( ! tokens || ! tokens.length )
|
if ( ! tokens || ! tokens.length )
|
||||||
return tokens;
|
return tokens;
|
||||||
|
|
||||||
if ( user && user.login && user.login == msg.user.login && ! this.context.get('chat.filtering.process-own') )
|
const can_highlight_user = user && user.login && user.login == msg.user.login && ! this.context.get('chat.filtering.process-own');
|
||||||
return tokens;
|
|
||||||
|
|
||||||
let regex, login, display;
|
let regex, login, display, mentionable = false;
|
||||||
if ( user && user.login ) {
|
if ( user && user.login && ! can_highlight_user ) {
|
||||||
login = user.login.toLowerCase();
|
login = user.login.toLowerCase();
|
||||||
display = user.displayName && user.displayName.toLowerCase();
|
display = user.displayName && user.displayName.toLowerCase();
|
||||||
if ( display === login )
|
if ( display === login )
|
||||||
display = null;
|
display = null;
|
||||||
|
|
||||||
|
mentionable = true;
|
||||||
regex = new RegExp(`^(['"*([{<\\/]*)(?:(@?)(${user.login.toLowerCase()}${display ? `|${display}` : ''})|@((?:[^\u0000-\u007F]|[\\w-])+))`, 'i');
|
regex = new RegExp(`^(['"*([{<\\/]*)(?:(@?)(${user.login.toLowerCase()}${display ? `|${display}` : ''})|@((?:[^\u0000-\u007F]|[\\w-])+))`, 'i');
|
||||||
//regex = new RegExp(`([^\\w@#%\\-+=:~]|\\b)?(@?(${user.login.toLowerCase()}${display ? `|${display}` : ''})|@([^\\u0000-\\u007F]+|\\w+)+)([^\\w.\\/@#%&()\\-+=:?~]|\\s|\\b|$)`, 'gi');
|
|
||||||
} else
|
} else
|
||||||
regex = MENTION_REGEX;
|
regex = MENTION_REGEX;
|
||||||
|
|
||||||
|
@ -268,7 +267,7 @@ export const Mentions = {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
recipient = match[3];
|
recipient = match[3];
|
||||||
mentioned = true;
|
mentioned = mentionable;
|
||||||
}
|
}
|
||||||
|
|
||||||
out.push({
|
out.push({
|
||||||
|
|
69
src/modules/main_menu/components/setting-color-box.vue
Normal file
69
src/modules/main_menu/components/setting-color-box.vue
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
<template lang="html">
|
||||||
|
<div
|
||||||
|
:class="{inherits: isInherited, default: isDefault}"
|
||||||
|
class="ffz--widget ffz--color-box"
|
||||||
|
>
|
||||||
|
<div class="tw-flex tw-align-items-center">
|
||||||
|
<label :for="item.full_key">
|
||||||
|
{{ t(item.i18n_key, item.title, item) }}
|
||||||
|
<span v-if="unseen" class="tw-pill">{{ t('setting.new', 'New') }}</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<color-picker
|
||||||
|
ref="control"
|
||||||
|
:id="item.full_key"
|
||||||
|
:nullable="true"
|
||||||
|
:value="color"
|
||||||
|
@input="onInput"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<button
|
||||||
|
v-if="source && source !== profile"
|
||||||
|
class="tw-mg-l-05 tw-button tw-button--text"
|
||||||
|
@click="context.currentProfile = source"
|
||||||
|
>
|
||||||
|
<span class="tw-button__text ffz-i-right-dir">
|
||||||
|
{{ sourceDisplay }}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button v-if="has_value" class="tw-mg-l-05 tw-button tw-button--text tw-tooltip-wrapper" @click="clear">
|
||||||
|
<span class="tw-button__text ffz-i-cancel" />
|
||||||
|
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
|
||||||
|
{{ t('setting.reset', 'Reset to Default') }}
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section
|
||||||
|
v-if="item.description"
|
||||||
|
class="tw-c-text-alt-2"
|
||||||
|
>
|
||||||
|
<markdown :source="t(item.desc_i18n_key || `${item.i18n_key}.description`, item.description, item)" />
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import SettingMixin from '../setting-mixin';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [SettingMixin],
|
||||||
|
props: ['item', 'context'],
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
color() {
|
||||||
|
if ( ! this.value )
|
||||||
|
return '';
|
||||||
|
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
onInput(value) {
|
||||||
|
this.set(value || '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -18,6 +18,7 @@ import ChatLine from './line';
|
||||||
import SettingsMenu from './settings_menu';
|
import SettingsMenu from './settings_menu';
|
||||||
import EmoteMenu from './emote_menu';
|
import EmoteMenu from './emote_menu';
|
||||||
import Input from './input';
|
import Input from './input';
|
||||||
|
import ViewerCards from './viewer_card';
|
||||||
|
|
||||||
|
|
||||||
const REGEX_EMOTES = {
|
const REGEX_EMOTES = {
|
||||||
|
@ -151,6 +152,7 @@ export default class ChatHook extends Module {
|
||||||
this.inject(SettingsMenu);
|
this.inject(SettingsMenu);
|
||||||
this.inject(EmoteMenu);
|
this.inject(EmoteMenu);
|
||||||
this.inject(Input);
|
this.inject(Input);
|
||||||
|
this.inject(ViewerCards);
|
||||||
|
|
||||||
this.ChatService = this.fine.define(
|
this.ChatService = this.fine.define(
|
||||||
'chat-service',
|
'chat-service',
|
||||||
|
@ -355,6 +357,7 @@ export default class ChatHook extends Module {
|
||||||
ic.contrast = contrast;
|
ic.contrast = contrast;
|
||||||
|
|
||||||
this.updateChatLines();
|
this.updateChatLines();
|
||||||
|
this.emit(':update-colors');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
91
src/sites/twitch-twilight/modules/chat/viewer_card.jsx
Normal file
91
src/sites/twitch-twilight/modules/chat/viewer_card.jsx
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import Module from 'utilities/module';
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Vanilla Viewer Cards
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
export default class ViewerCards extends Module {
|
||||||
|
constructor(...args) {
|
||||||
|
super(...args);
|
||||||
|
|
||||||
|
this.inject('chat');
|
||||||
|
this.inject('settings');
|
||||||
|
this.inject('site.css_tweaks');
|
||||||
|
this.inject('site.fine');
|
||||||
|
|
||||||
|
this.last_login = null;
|
||||||
|
|
||||||
|
this.settings.add('chat.viewer-cards.highlight-chat', {
|
||||||
|
default: false,
|
||||||
|
ui: {
|
||||||
|
path: 'Chat > Viewer Cards >> Appearance',
|
||||||
|
title: 'Highlight messages from users with open viewer cards.',
|
||||||
|
component: 'setting-check-box'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.settings.add('chat.viewer-cards.color', {
|
||||||
|
default: '',
|
||||||
|
ui: {
|
||||||
|
path: 'Chat > Viewer Cards >> Appearance',
|
||||||
|
title: 'Highlight Color',
|
||||||
|
component: 'setting-color-box'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.settings.add('chat.viewer-cards.use-color', {
|
||||||
|
requires: ['chat.viewer-cards.highlight-chat', 'chat.viewer-cards.color'],
|
||||||
|
process(ctx) {
|
||||||
|
if ( ctx.get('chat.viewer-cards.highlight-chat') )
|
||||||
|
return ctx.get('chat.viewer-cards.color');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.ViewerCard = this.fine.define(
|
||||||
|
'chat-viewer-card',
|
||||||
|
n => n.toggleGiftPage && n.onWhisperButtonClick
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onEnable() {
|
||||||
|
this.chat.context.on('changed:chat.viewer-cards.highlight-chat', this.refreshStyle, this);
|
||||||
|
this.chat.context.on('changed:chat.viewer-cards.color', this.refreshStyle, this);
|
||||||
|
this.on('..:update-colors', this.refreshStyle, this);
|
||||||
|
|
||||||
|
this.ViewerCard.on('mount', this.updateCard, this);
|
||||||
|
this.ViewerCard.on('update', this.updateCard, this);
|
||||||
|
this.ViewerCard.on('unmount', this.unmountCard, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshStyle() {
|
||||||
|
this.updateStyle(this.last_login);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateStyle(login) {
|
||||||
|
this.last_login = login;
|
||||||
|
if ( login && this.chat.context.get('chat.viewer-cards.highlight-chat') ) {
|
||||||
|
let color = this.chat.context.get('chat.viewer-cards.color');
|
||||||
|
if ( color && color.length )
|
||||||
|
color = this.parent.inverse_colors.process(color);
|
||||||
|
else if ( this.chat.context.get('theme.is-dark') )
|
||||||
|
color = 'rgba(0,80,255,0.2)';
|
||||||
|
else
|
||||||
|
color = 'rgba(128,170,255,0.2)';
|
||||||
|
|
||||||
|
this.css_tweaks.set('viewer-card-highlight', `body .chat-list .chat-line__message:not(.chat-line--inline):nth-child(1n+0)[data-user="${login}"] {
|
||||||
|
background-color: ${color} !important;
|
||||||
|
}`);
|
||||||
|
} else
|
||||||
|
this.css_tweaks.delete('viewer-card-highlight');
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCard(inst) {
|
||||||
|
this.updateStyle(inst.props && inst.props.targetLogin);
|
||||||
|
}
|
||||||
|
|
||||||
|
unmountCard() {
|
||||||
|
this.updateStyle();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue