mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-08 07:10:54 +00:00
4.20.20
* Changed: Show the verified badge on rich chat embeds for Twitch partner channels. * API Added: More flexible support for tokens when building chat embeds. * API Added: Experiment for using the API to look-up links, rather than the socket cluster.
This commit is contained in:
parent
a4fa1d1491
commit
05e8428a4a
7 changed files with 96 additions and 12 deletions
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "frankerfacez",
|
||||
"author": "Dan Salvato LLC",
|
||||
"version": "4.20.19",
|
||||
"version": "4.20.20",
|
||||
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
|
|
|
@ -7,12 +7,20 @@
|
|||
{"value": false, "weight": 100}
|
||||
]
|
||||
},
|
||||
"all_points": {
|
||||
"name": "Override Channel Points Rendering",
|
||||
"description": "Override rendering for all channel points messages, even when no message is present.",
|
||||
"api_links": {
|
||||
"name": "API-Based Link Lookups",
|
||||
"description": "Use the new API to look up links instead of the socket cluster.",
|
||||
"groups": [
|
||||
{"value": true, "weight": 50},
|
||||
{"value": false, "weight": 50}
|
||||
]
|
||||
},
|
||||
"all_points": {
|
||||
"name": "Override Channel Points Rendering",
|
||||
"description": "Override rendering for all channel points messages, even when no message is present.",
|
||||
"groups": [
|
||||
{"value": true, "weight": 100},
|
||||
{"value": false, "weight": 0}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
|
||||
import {has, timeout} from 'utilities/object';
|
||||
import {ALLOWED_ATTRIBUTES, ALLOWED_TAGS} from 'utilities/constants';
|
||||
|
||||
const ERROR_IMAGE = 'https://static-cdn.jtvnw.net/emoticons/v1/58765/2.0';
|
||||
|
||||
|
@ -95,9 +96,34 @@ export default {
|
|||
else if ( typeof token !== 'object' )
|
||||
out.push(token);
|
||||
|
||||
else {
|
||||
const el = h(token.tag || 'span', {
|
||||
else if ( token.type === 't') {
|
||||
const content = {};
|
||||
if ( token.content )
|
||||
for(const [key,val] of Object.entries(token.content))
|
||||
content[key] = this.renderTokens(val, h);
|
||||
|
||||
out = out.concat(this.tList(token.key, token.phrase, content));
|
||||
|
||||
} else {
|
||||
const tag = token.tag || 'span';
|
||||
if ( ! ALLOWED_TAGS.includes(tag) ) {
|
||||
console.log('Skipping disallowed tag', tag);
|
||||
continue;
|
||||
}
|
||||
|
||||
const attrs = {};
|
||||
if ( token.attrs ) {
|
||||
for(const [key,val] of Object.entries(token.attrs)) {
|
||||
if ( ! ALLOWED_ATTRIBUTES.includes(key) && ! key.startsWith('data-') )
|
||||
console.log('Skipping disallowed attribute', key);
|
||||
else
|
||||
attrs[key] = val;
|
||||
}
|
||||
}
|
||||
|
||||
const el = h(tag, {
|
||||
class: token.class,
|
||||
attrs
|
||||
}, this.renderTokens(token.content, h));
|
||||
|
||||
out.push(el);
|
||||
|
|
|
@ -1536,7 +1536,12 @@ export default class Chat extends Module {
|
|||
cbs[success ? 0 : 1](data);
|
||||
}
|
||||
|
||||
if ( this.experiments.getAssignment('api_links') )
|
||||
timeout(fetch(`https://api-test.frankerfacez.com/v2/link?url=${encodeURIComponent(url)}`).then(r => r.json()), 15000)
|
||||
.then(data => handle(true, data))
|
||||
.catch(err => handle(false, err));
|
||||
|
||||
else
|
||||
timeout(this.socket.call('get_link', url), 15000)
|
||||
.then(data => handle(true, data))
|
||||
.catch(err => handle(false, err));
|
||||
|
|
|
@ -143,6 +143,16 @@ export const Users = {
|
|||
];
|
||||
}
|
||||
|
||||
if ( user.roles?.isPartner ) {
|
||||
if ( ! title_tokens )
|
||||
title_tokens = [title];
|
||||
|
||||
title_tokens = {tag: 'div', class: 'tw-flex tw-align-items-center', content: [
|
||||
{tag: 'div', content: title_tokens},
|
||||
{tag: 'figure', class: 'tw-mg-l-05 ffz-i-verified tw-c-text-link', content: []}
|
||||
]};
|
||||
}
|
||||
|
||||
return {
|
||||
url: token.url,
|
||||
accent: user.primaryColorHex ? `#${user.primaryColorHex}` : null,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import Module from 'utilities/module';
|
||||
import {timeout, has} from 'utilities/object';
|
||||
import {ALLOWED_ATTRIBUTES, ALLOWED_TAGS} from 'utilities/constants';
|
||||
|
||||
const ERROR_IMAGE = 'https://static-cdn.jtvnw.net/emoticons/v1/58765/2.0';
|
||||
|
||||
|
@ -104,9 +105,34 @@ export default class RichContent extends Module {
|
|||
else if ( typeof token !== 'object' )
|
||||
out.push(token);
|
||||
|
||||
else {
|
||||
const el = createElement(token.tag || 'span', {
|
||||
className: token.class
|
||||
else if ( token.type === 't' ) {
|
||||
const content = {};
|
||||
if ( token.content )
|
||||
for(const [key,val] of Object.entries(token.content))
|
||||
content[key] = this.renderTokens(val);
|
||||
|
||||
out = out.concat(t.i18n.tList(token.key, token.phrase, content));
|
||||
|
||||
} else {
|
||||
const tag = token.tag || 'span';
|
||||
if ( ! ALLOWED_TAGS.includes(tag) ) {
|
||||
console.log('Skipping disallowed tag', tag);
|
||||
continue;
|
||||
}
|
||||
|
||||
const attrs = {};
|
||||
if ( token.attrs ) {
|
||||
for(const [key,val] of Object.entries(token.attrs)) {
|
||||
if ( ! ALLOWED_ATTRIBUTES.includes(key) && ! key.startsWith('data-') )
|
||||
console.log('Skipping disallowed attribute', key);
|
||||
else
|
||||
attrs[key] = val;
|
||||
}
|
||||
}
|
||||
|
||||
const el = createElement(tag, {
|
||||
className: token.class,
|
||||
...attrs
|
||||
}, this.renderTokens(token.content));
|
||||
|
||||
out.push(el);
|
||||
|
|
|
@ -18,6 +18,15 @@ export const LV_SERVER = 'https://cbenni.com/api';
|
|||
export const LV_SOCKET_SERVER = 'wss://cbenni.com/socket.io/';
|
||||
|
||||
|
||||
export const ALLOWED_TAGS = [
|
||||
'strong', 'em', 'i', 'b', 'time', 'br', 'hr', 'div', 'span', 'img', 'figure', 'p', 'a', 'video', 'audio', 'blockquote', 'heading', 'section', 'nav', 'footer', 'aside', 'article', 'source', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'
|
||||
];
|
||||
|
||||
export const ALLOWED_ATTRIBUTES = [
|
||||
'datetime', 'src', 'href', 'style', 'alt', 'title', 'height', 'width', 'srcset', 'autoplay', 'volume', 'muted', 'loop', 'poster', 'type'
|
||||
];
|
||||
|
||||
|
||||
export const KEYS = {
|
||||
Enter: 13,
|
||||
Escape: 27,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue