mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-07-24 19:48:30 +00:00
4.0.0-rc21.7
* Added: Option to open viewer cards when clicking a mention in chat. * Fixed: Mention matching in chat. (Now using the same regular expression as vanilla Twitch.)
This commit is contained in:
parent
f754b7fce7
commit
b73234453b
6 changed files with 101 additions and 27 deletions
|
@ -7,7 +7,7 @@
|
|||
import Parser from '@ffz/icu-msgparser';
|
||||
|
||||
import {SERVER} from 'utilities/constants';
|
||||
import {get, pick_random, has, timeout} from 'utilities/object';
|
||||
import {get, pick_random, timeout} from 'utilities/object';
|
||||
import Module from 'utilities/module';
|
||||
|
||||
import NewTransCore from 'utilities/translation-core';
|
||||
|
@ -45,7 +45,7 @@ const FACES = ['(・`ω´・)', ';;w;;', 'owo', 'ono', 'oAo', 'oxo', 'ovo;', 'Uw
|
|||
upper: (key, ast) => transformText(ast, n => n.toUpperCase()),
|
||||
lower: (key, ast) => transformText(ast, n => n.toLowerCase()),
|
||||
append_key: (key, ast) => [...ast, ` (${key})`],
|
||||
set_key: (key, ast) => [key],
|
||||
set_key: key => [key],
|
||||
owo: (key, ast) => transformText(ast, owo)
|
||||
};
|
||||
|
||||
|
|
|
@ -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: '-rc21.6',
|
||||
major: 4, minor: 0, revision: 0, extra: '-rc21.7',
|
||||
commit: __git_commit__,
|
||||
build: __webpack_hash__,
|
||||
toString: () =>
|
||||
|
|
|
@ -45,6 +45,7 @@ export default class Chat extends Module {
|
|||
|
||||
// Bind for JSX stuff
|
||||
this.clickToReveal = this.clickToReveal.bind(this);
|
||||
this.handleMentionClick = this.handleMentionClick.bind(this);
|
||||
|
||||
this.style = new ManagedStyle;
|
||||
|
||||
|
@ -582,6 +583,16 @@ export default class Chat extends Module {
|
|||
});
|
||||
|
||||
|
||||
this.settings.add('chat.filtering.clickable-mentions', {
|
||||
default: false,
|
||||
ui: {
|
||||
component: 'setting-check-box',
|
||||
path: 'Chat > Filtering >> Appearance',
|
||||
title: 'Enable opening viewer cards by clicking mentions in chat.'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
this.settings.add('chat.filtering.highlight-mentions', {
|
||||
default: false,
|
||||
ui: {
|
||||
|
@ -950,6 +961,32 @@ export default class Chat extends Module {
|
|||
}
|
||||
|
||||
|
||||
handleMentionClick(event) {
|
||||
if ( ! this.context.get('chat.filtering.clickable-mentions') )
|
||||
return;
|
||||
|
||||
const target = event.target,
|
||||
ds = target && target.dataset;
|
||||
|
||||
if ( ! ds || ! ds.login )
|
||||
return;
|
||||
|
||||
const fine = this.resolve('site.fine');
|
||||
if ( ! fine )
|
||||
return;
|
||||
|
||||
const chat = fine.searchParent(event.target, n => n.props && n.props.onUsernameClick);
|
||||
if ( ! chat )
|
||||
return;
|
||||
|
||||
chat.props.onUsernameClick(
|
||||
ds.login,
|
||||
undefined, undefined,
|
||||
event.currentTarget.getBoundingClientRect().bottom
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
clickToReveal(event) {
|
||||
const target = event.target;
|
||||
if ( target ) {
|
||||
|
|
|
@ -12,7 +12,8 @@ import {TWITCH_EMOTE_BASE, REPLACEMENT_BASE, REPLACEMENTS} from 'utilities/const
|
|||
|
||||
const EMOTE_CLASS = 'chat-image chat-line__message--emote',
|
||||
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
|
||||
|
||||
|
||||
// ============================================================================
|
||||
|
@ -201,16 +202,29 @@ export const Mentions = {
|
|||
|
||||
component: () => import(/* webpackChunkName: 'vue-chat' */ './components/chat-mention.vue'),
|
||||
|
||||
render(token, createElement) {
|
||||
oldRender(token, createElement) {
|
||||
return (<strong class={`chat-line__message-mention${token.me ? ' ffz--mention-me' : ''}`}>
|
||||
{token.text}
|
||||
</strong>);
|
||||
},
|
||||
|
||||
render(token, createElement) {
|
||||
return (<span
|
||||
class={`chat-line__message-mention${token.me ? ' ffz--mention-me' : ''}`}
|
||||
data-login={token.recipient}
|
||||
onClick={this.handleMentionClick}
|
||||
>
|
||||
{token.text}
|
||||
</span>)
|
||||
},
|
||||
|
||||
process(tokens, msg, user) {
|
||||
if ( ! tokens || ! tokens.length )
|
||||
return tokens;
|
||||
|
||||
if ( user && user.login && user.login == msg.user.login && ! this.context.get('chat.filtering.process-own') )
|
||||
return tokens;
|
||||
|
||||
let regex, login, display;
|
||||
if ( user && user.login ) {
|
||||
login = user.login.toLowerCase();
|
||||
|
@ -218,7 +232,8 @@ export const Mentions = {
|
|||
if ( display === login )
|
||||
display = null;
|
||||
|
||||
regex = new RegExp(`([^\\w@#%\\-+=:~]|\\b)?(@?(${user.login.toLowerCase()}${display ? `|${display}` : ''})|@([^\\u0000-\\u007F]+|\\w+)+)([^\\w.\\/@#%&()\\-+=:?~]|\\s|\\b|$)`, 'gi');
|
||||
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
|
||||
regex = MENTION_REGEX;
|
||||
|
||||
|
@ -229,34 +244,52 @@ export const Mentions = {
|
|||
continue;
|
||||
}
|
||||
|
||||
regex.lastIndex = 0;
|
||||
const text = token.text;
|
||||
let idx = 0, match;
|
||||
let text = [];
|
||||
|
||||
while((match = regex.exec(text))) {
|
||||
const nix = match.index + (match[1] ? match[1].length : 0),
|
||||
m = match[3] || match[4],
|
||||
ml = m.toLowerCase(),
|
||||
me = ml === login || ml === display;
|
||||
for(const segment of token.text.split(/ +/)) {
|
||||
const match = regex.exec(segment);
|
||||
if ( match ) {
|
||||
// If we have pending text, join it together.
|
||||
if ( text.length || match[1]) {
|
||||
out.push({
|
||||
type: 'text',
|
||||
text: `${text.join(' ')} ${match[1] || ''}`
|
||||
});
|
||||
text = [];
|
||||
}
|
||||
|
||||
if ( idx !== nix )
|
||||
out.push({type: 'text', text: text.slice(idx, nix)});
|
||||
let recipient,
|
||||
mentioned = false,
|
||||
at = match[2];
|
||||
|
||||
if ( me )
|
||||
msg.mentioned = true;
|
||||
if ( match[4] ) {
|
||||
recipient = match[4];
|
||||
at = '@';
|
||||
|
||||
} else {
|
||||
recipient = match[3];
|
||||
mentioned = true;
|
||||
}
|
||||
|
||||
out.push({
|
||||
type: 'mention',
|
||||
text: match[2],
|
||||
me,
|
||||
recipient: m
|
||||
text: `${at}${recipient}`,
|
||||
me: mentioned,
|
||||
recipient
|
||||
});
|
||||
|
||||
idx = nix + match[2].length;
|
||||
if ( mentioned )
|
||||
msg.mentioned = true;
|
||||
|
||||
// Push the remaining text from the token.
|
||||
text.push(segment.substr(match[0].length));
|
||||
|
||||
} else
|
||||
text.push(segment);
|
||||
}
|
||||
|
||||
if ( idx < text.length )
|
||||
out.push({type: 'text', text: text.slice(idx)});
|
||||
if ( text.length > 1 || (text.length === 1 && text[0] !== '') )
|
||||
out.push({type: 'text', text: text.join(' ')})
|
||||
}
|
||||
|
||||
return out;
|
||||
|
|
|
@ -452,6 +452,7 @@ export default class ChatHook extends Module {
|
|||
this.chat.context.on('changed:chat.fix-bad-emotes', this.updateChatLines, this);
|
||||
this.chat.context.on('changed:chat.filtering.display-deleted', this.updateChatLines, this);
|
||||
this.chat.context.on('changed:chat.filtering.display-mod-action', this.updateChatLines, this);
|
||||
this.chat.context.on('changed:chat.filtering.clickable-mentions', val => this.css_tweaks.toggle('clickable-mentions', val));
|
||||
|
||||
this.chat.context.on('changed:chat.lines.alternate', val => {
|
||||
this.css_tweaks.toggle('chat-rows', val);
|
||||
|
@ -475,6 +476,8 @@ export default class ChatHook extends Module {
|
|||
this.css_tweaks.toggle('chat-deleted-strike', val === 1 || val === 2);
|
||||
this.css_tweaks.toggle('chat-deleted-fade', val < 2);
|
||||
|
||||
this.css_tweaks.toggle('clickable-mentions', this.chat.context.get('chat.filtering.clickable-mentions'));
|
||||
|
||||
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('chat-rows', this.chat.context.get('chat.lines.alternate'));
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
.ffz--highlight,
|
||||
.mention-fragment--recipient,
|
||||
.ffz--mention-me {
|
||||
border-radius: .5rem;
|
||||
padding: .3rem;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue