mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-27 21:05:53 +00:00
4.67.0
* Fixed: Bug displaying rich content errors when no data is returned from the link information service. * API Changed: The `site.chat.addNotice()` method now supports rich content and localization.
This commit is contained in:
parent
44e30e985d
commit
8688d1a41b
4 changed files with 143 additions and 52 deletions
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "frankerfacez",
|
||||
"author": "Dan Salvato LLC",
|
||||
"version": "4.66.0",
|
||||
"version": "4.67.0",
|
||||
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
||||
"private": true,
|
||||
"license": "Apache-2.0",
|
||||
|
|
|
@ -2644,12 +2644,14 @@ export default class Chat extends Module {
|
|||
|
||||
|
||||
handleLinkToS(data) {
|
||||
if ( ! Array.isArray(data?.urls) )
|
||||
return data;
|
||||
|
||||
// Check for YouTube
|
||||
const agreed = this.settings.provider.get('agreed-tos', []),
|
||||
rejected = this.settings.provider.get('declined-tos', []);
|
||||
|
||||
const resolvers = data.urls ? new Set(data.urls.map(x => x.resolver).filter(x => x)) : null;
|
||||
if ( resolvers ) {
|
||||
const resolvers = new Set(data.urls.map(x => x.resolver).filter(x => x));
|
||||
for(const [key, info] of Object.entries(RESOLVERS_REQUIRE_TOS)) {
|
||||
if ( resolvers.has(key) && ! agreed.includes(key) ) {
|
||||
const declined = rejected.includes(key);
|
||||
|
@ -2698,7 +2700,6 @@ export default class Chat extends Module {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
// ============================================================================
|
||||
|
||||
import {Color, ColorAdjuster} from 'utilities/color';
|
||||
import {get, has, make_enum, shallow_object_equals, set_equals, deep_equals, glob_to_regex, escape_regex} from 'utilities/object';
|
||||
import {get, has, make_enum, shallow_object_equals, set_equals, deep_equals, glob_to_regex, escape_regex, generateUUID} from 'utilities/object';
|
||||
import {WEBKIT_CSS as WEBKIT} from 'utilities/constants';
|
||||
|
||||
import {useFont} from 'utilities/fonts';
|
||||
|
||||
import awaitMD, { getMD } from 'utilities/markdown';
|
||||
import Module from 'utilities/module';
|
||||
|
||||
import Twilight from 'site';
|
||||
|
@ -2389,10 +2389,40 @@ export default class ChatHook extends Module {
|
|||
|
||||
for(const inst of this.ChatService.instances) {
|
||||
if ( room === '*' || inst.props.channelLogin.toLowerCase() === room ) {
|
||||
if ( typeof message === 'string' )
|
||||
inst.addMessage({
|
||||
type: this.chat_types.Notice,
|
||||
message
|
||||
});
|
||||
else {
|
||||
const props = inst.props,
|
||||
login = props.channelLogin,
|
||||
id = props.channelID;
|
||||
|
||||
if ( message.markdown ) {
|
||||
const md = getMD();
|
||||
if ( ! md )
|
||||
awaitMD();
|
||||
}
|
||||
|
||||
inst.addMessage({
|
||||
type: this.chat_types.Message,
|
||||
channel: `#${login}`,
|
||||
roomID: id,
|
||||
roomLogin: login,
|
||||
id: `ffz_notice_${generateUUID()}`,
|
||||
ffz_type: 'notice',
|
||||
ffz_no_actions: true,
|
||||
ffz_data: message,
|
||||
message: null,
|
||||
messageParts: [],
|
||||
timestamp: Date.now(),
|
||||
user: {
|
||||
userID: id,
|
||||
userLogin: login
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import { KEYS, RERENDER_SETTINGS, UPDATE_BADGE_SETTINGS, UPDATE_TOKEN_SETTINGS }
|
|||
import { print_duration } from 'utilities/time';
|
||||
|
||||
import { getRewardTitle, getRewardCost } from './points';
|
||||
import awaitMD, {getMD} from 'utilities/markdown';
|
||||
|
||||
const SUB_TIERS = {
|
||||
1000: 1,
|
||||
|
@ -45,6 +46,65 @@ export default class ChatLine extends Module {
|
|||
}
|
||||
};
|
||||
|
||||
this.line_types.notice = {
|
||||
renderNotice: (msg, current_user, room, inst, e) => {
|
||||
const data = msg.ffz_data;
|
||||
let content = this.line_types.notice.renderContent(msg, current_user, room, inst, e);
|
||||
|
||||
if ( ! data.icon )
|
||||
return content;
|
||||
|
||||
if ( typeof content === 'string' )
|
||||
content = e('span', {}, content);
|
||||
|
||||
content.ffz_icon = e('span', {
|
||||
className: `${data.icon} tw-mg-r-05`
|
||||
});
|
||||
|
||||
return content;
|
||||
},
|
||||
|
||||
renderContent: (msg, current_user, room, inst, e) => {
|
||||
const data = msg.ffz_data;
|
||||
if ( data.renderer )
|
||||
try {
|
||||
return data.renderer(data, inst, e);
|
||||
} catch(err) {
|
||||
this.log.capture(err);
|
||||
this.log.error('Error using custom renderer for notice:', err);
|
||||
return `Error rendering notice.`
|
||||
}
|
||||
|
||||
const text = data.i18n ? this.i18n.t(data.i18n, data.messgae, data) : data.message;
|
||||
|
||||
if ( data.markdown ) {
|
||||
const md = getMD();
|
||||
if ( ! md ) {
|
||||
awaitMD().then(() => inst.forceUpdate());
|
||||
return 'Loading...';
|
||||
}
|
||||
|
||||
return e('span', {
|
||||
dangerouslySetInnerHTML: {
|
||||
__html: getMD().renderInline(text)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if ( data.tokenize ) {
|
||||
const tokens = data.ffz_tokens = data.ffz_tokens || this.chat.tokenizeMessage({
|
||||
message: text,
|
||||
id: msg.id,
|
||||
user: msg.user
|
||||
}, current_user);
|
||||
|
||||
return this.chat.renderTokens(tokens, e);
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
};
|
||||
|
||||
this.line_types.hype = {
|
||||
renderNotice: (msg, current_user, room, inst, e) => {
|
||||
const setting = this.chat.context.get('chat.hype.message-style');
|
||||
|
@ -1058,7 +1118,7 @@ other {# messages were deleted by a moderator.}
|
|||
|
||||
// The preamble
|
||||
timestamp,
|
||||
t.actions.renderInline(msg, this.props.showModerationIcons, current_user, current_room, e, this),
|
||||
msg.ffz_no_actions ? null : t.actions.renderInline(msg, this.props.showModerationIcons, current_user, current_room, e, this),
|
||||
this.renderInlineHighlight ? this.renderInlineHighlight() : null,
|
||||
hl_position === 2 ? highlight_tags : null,
|
||||
|
||||
|
@ -1121,7 +1181,7 @@ other {# messages were deleted by a moderator.}
|
|||
? e('span', { className: 'chat-line__timestamp' }, t.chat.formatTime(msg.timestamp))
|
||||
: null;
|
||||
|
||||
const actions = t.actions.renderInline(msg, this.props.showModerationIcons, current_user, current_room, e, this);
|
||||
const actions = msg.ffz_no_actions ? null : t.actions.renderInline(msg, this.props.showModerationIcons, current_user, current_room, e, this);
|
||||
|
||||
if ( is_raw ) {
|
||||
notice.ffz_target.unshift(
|
||||
|
@ -1187,7 +1247,7 @@ other {# messages were deleted by a moderator.}
|
|||
}
|
||||
|
||||
// Check for hover actions, as those require we wrap the output in a few extra elements.
|
||||
const hover_actions = (user && msg.id)
|
||||
const hover_actions = (user && msg.id && ! msg.ffz_no_actions)
|
||||
? t.actions.renderHover(msg, this.props.showModerationIcons, current_user, current_room, e, this)
|
||||
: null;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue