mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-09-15 17:46:55 +00:00
Render badges. Fix badges with weird font sizes. Add an option to show metadata in theatre mode. Fixes #364. Fixes #363.
This commit is contained in:
parent
95d0002b56
commit
0754144c36
8 changed files with 170 additions and 52 deletions
|
@ -25,20 +25,45 @@ export const CSS_BADGES = {
|
|||
subscriber: { 0: { color: '#6441a4' }, 1: { color: '#6441a4' }},
|
||||
}
|
||||
|
||||
export const BADGE_POSITIONS = {
|
||||
broadcaster: 0,
|
||||
staff: 0,
|
||||
admin: 0,
|
||||
global_mod: 0,
|
||||
mod: 1,
|
||||
moderator: 1,
|
||||
twitchbot: 1,
|
||||
subscriber: 25
|
||||
};
|
||||
|
||||
|
||||
const NO_REPEAT = 'background-repeat:no-repeat;background-position:center;',
|
||||
BASE_IMAGE = 'https://cdn.frankerfacez.com/badges/twitch/',
|
||||
CSS_TEMPLATES = {
|
||||
0: data => `background:${data.image} ${data.color};${data.svg ? `background-size:${data.scale*18}px;` : `background-image:${data.image_set};`}${NO_REPEAT}`,
|
||||
1: data => `${CSS_TEMPLATES[0](data)}border-radius:${data.scale*2}px;`,
|
||||
2: data => `${CSS_TEMPLATES[0](data)}border-radius:${data.scale*9}px;background-size:${data.scale*16}px;`,
|
||||
3: data => `background:${data.color};border-radius:${data.scale*9}px;`,
|
||||
4: data => `${CSS_TEMPLATES[3](data)}height:${data.scale*10}px;min-width:${data.scale*10}px;`,
|
||||
5: data => `background:${data.image};${data.svg ? `background-size:${data.scale*18}px;` : `background-image:${data.image_set};`}${NO_REPEAT}`,
|
||||
6: data => `background:linear-gradient(${data.color},${data.color});${WEBKIT}mask-image:${data.image};${data.svg ? `${WEBKIT}mask-size:${data.scale*18}px ${data.scale*18}px;` : `${WEBKIT}mask-image:${data.image_set};`}`
|
||||
0: data => `background:${data.image} ${data.color};background-size:${data.scale*1.8}rem;${data.svg ? '' : `background-image:${data.image_set};`}${NO_REPEAT}`,
|
||||
1: data => `${CSS_TEMPLATES[0](data)}border-radius:${data.scale*.2}rem;`,
|
||||
2: data => `${CSS_TEMPLATES[0](data)}border-radius:${data.scale*.9}rem;background-size:${data.scale*1.6}rem;`,
|
||||
3: data => `background:${data.color};border-radius:${data.scale*.9}rem;`,
|
||||
4: data => `${CSS_TEMPLATES[3](data)}height:${data.scale}rem;min-width:${data.scale}rem;`,
|
||||
5: data => `background:${data.image};background-size:${data.scale*1.8}rem;${data.svg ? `` : `background-image:${data.image_set};`}${NO_REPEAT}`,
|
||||
6: data => `background:linear-gradient(${data.color},${data.color});${WEBKIT}mask-image:${data.image};${WEBKIT}mask-size:${data.scale*1.8}rem ${data.scale*1.8}rem;${data.svg ? `` : `${WEBKIT}mask-image:${data.image_set};`}`
|
||||
};
|
||||
|
||||
|
||||
export function generateOverrideCSS(data, style, is_dark) {
|
||||
let image = `url("${data.urls[1]}")`,
|
||||
image_set = `${WEBKIT}image-set(${image} 1x${data.urls[2] ? `, url("${data.urls[2]}") 2x` : ''}${data.urls[4] ? `, url("${data.urls[4]}") 4x` : ''})`;
|
||||
|
||||
if ( style === 3 || style === 4 )
|
||||
return '';
|
||||
|
||||
if ( style === 6 )
|
||||
return `${WEBKIT}mask-image:${image} !important;${WEBKIT}mask-image:${image_set} !important;`;
|
||||
else
|
||||
return `background-image:${image} !important;background-image:${image_set} !important;`;
|
||||
}
|
||||
|
||||
|
||||
export function generateBadgeCSS(badge, version, data, style, is_dark, scale = 1) {
|
||||
let color = data.color || 'transparent',
|
||||
base_image = data.image || `${BASE_IMAGE}${badge}${data.svg ? '.svg' : `/${version}/`}`,
|
||||
|
@ -72,9 +97,15 @@ export function generateBadgeCSS(badge, version, data, style, is_dark, scale = 1
|
|||
style = 0;
|
||||
|
||||
svg = base_image.endsWith('.svg');
|
||||
image = `url("${svg ? base_image : `${base_image}${scale}${trans ? '_trans' : ''}.png`}")`;
|
||||
if ( data.urls )
|
||||
image = `url("${data.urls[1]}")`;
|
||||
else
|
||||
image = `url("${svg ? base_image : `${base_image}${scale}${trans ? '_trans' : ''}.png`}")`;
|
||||
|
||||
if ( svg && scale < 4 ) {
|
||||
if ( data.urls ) {
|
||||
image_set = `${WEBKIT}image-set(${image} 1x${data.urls[2] ? `, url("${data.urls[2]}") 2x` : ''}${data.urls[4] ? `url("${data.urls[4]}") 4x` : ''})`
|
||||
|
||||
} else if ( ! svg && scale < 4 ) {
|
||||
if ( scale === 1 )
|
||||
image_set = `${WEBKIT}image-set(${image} 1x, url("${base_image}2${trans ? '_trans' : ''}.png") 2x, url("${base_image}4${trans ? '_trans' : ''}.png") 4x)`;
|
||||
|
||||
|
@ -85,7 +116,8 @@ export function generateBadgeCSS(badge, version, data, style, is_dark, scale = 1
|
|||
image_set = svg;
|
||||
}
|
||||
|
||||
return `${invert ? 'filter:invert(100%);' : ''}${CSS_TEMPLATES[style]({
|
||||
// TODO: Fix the click_url name once we actually support badge clicking.
|
||||
return `${data.__click_url ? 'cursor:pointer;' : ''}${invert ? 'filter:invert(100%);' : ''}${CSS_TEMPLATES[style]({
|
||||
scale,
|
||||
color,
|
||||
image,
|
||||
|
@ -137,13 +169,19 @@ export default class Badges extends Module {
|
|||
this.rebuildAllCSS();
|
||||
this.loadGlobalBadges();
|
||||
|
||||
// TODO: Better tooltips. Especially support for custom colors, titles, etc. from
|
||||
// user-specific badges.
|
||||
|
||||
this.tooltips.types.badge = (target, tip) => {
|
||||
const container = target.parentElement.parentElement,
|
||||
provider = target.dataset.provider,
|
||||
replaced = target.dataset.replaced,
|
||||
badge = target.dataset.badge,
|
||||
version = target.dataset.version,
|
||||
room_id = container.dataset.roomId,
|
||||
room_login = container.dataset.room;
|
||||
room_login = container.dataset.room,
|
||||
|
||||
replaced_data = replaced && this.badges[replaced];
|
||||
|
||||
let preview, title;
|
||||
|
||||
|
@ -163,8 +201,8 @@ export default class Badges extends Module {
|
|||
preview = e('span', {
|
||||
className: 'preview-image ffz-badge',
|
||||
style: {
|
||||
height: '72px',
|
||||
width: '72px',
|
||||
height: '7.2rem',
|
||||
width: '7.2rem',
|
||||
backgroundColor: data.color,
|
||||
backgroundImage: `url("${data.urls[4]}")`
|
||||
}
|
||||
|
@ -195,33 +233,65 @@ export default class Badges extends Module {
|
|||
|
||||
|
||||
render(msg, e) { // eslint-disable-line class-methods-use-this
|
||||
const out = [],
|
||||
twitch_badges = msg.badges || {};
|
||||
const hidden_badges = this.parent.context.get('chat.badges.hidden') || [],
|
||||
out = [],
|
||||
slotted = {},
|
||||
twitch_badges = msg.badges || {},
|
||||
|
||||
/*user = msg.user || {},
|
||||
user = msg.user || {},
|
||||
user_id = user.userID,
|
||||
user_login = user.userLogin,
|
||||
room_id = msg.roomID,
|
||||
room_login = msg.roomLogin,
|
||||
|
||||
badges = this.getBadges(user_id, user_login, room_id, room_login);*/
|
||||
badges = this.getBadges(user_id, user_login, room_id, room_login);
|
||||
|
||||
let last_slot = 50, slot;
|
||||
|
||||
for(const badge_id in twitch_badges)
|
||||
if ( has(twitch_badges, badge_id) ) {
|
||||
const version = twitch_badges[badge_id];
|
||||
out.push(e('span', {
|
||||
className: 'ffz-tooltip ffz-badge',
|
||||
'data-tooltip-type': 'badge',
|
||||
'data-provider': 'twitch',
|
||||
'data-badge': badge_id,
|
||||
'data-version': version
|
||||
}));
|
||||
const version = twitch_badges[badge_id],
|
||||
is_game = badge_id.endsWith('_1');
|
||||
|
||||
if ( hidden_badges.includes(badge_id) || (is_game && hidden_badges.includes('game')) )
|
||||
continue;
|
||||
|
||||
if ( has(BADGE_POSITIONS, badge_id) )
|
||||
slot = BADGE_POSITIONS[badge_id];
|
||||
else
|
||||
slot = last_slot++;
|
||||
|
||||
slotted[slot] = {
|
||||
id: badge_id,
|
||||
props: {
|
||||
'data-provider': 'twitch',
|
||||
'data-badge': badge_id,
|
||||
'data-version': version
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/*for(const badge of badges)
|
||||
for(const badge of badges)
|
||||
if ( badge && badge.id ) {
|
||||
if ( hidden_badges.includes(badge.id) )
|
||||
continue;
|
||||
|
||||
const full_badge = this.badges[badge.id],
|
||||
style = {},
|
||||
slot = has(badge, 'slot') ? badge.slot : full_badge.slot,
|
||||
old_badge = slotted[slot];
|
||||
|
||||
if ( old_badge ) {
|
||||
const replaces = has(badge, 'replaces') ? badge.replaces : full_badge.replaces,
|
||||
replaces_type = badge.replaces_type || full_badge.replaces_type;
|
||||
if ( replaces && (!replaces_type || replaces_type === old_badge.id) )
|
||||
old_badge.replaced = badge.id;
|
||||
|
||||
continue;
|
||||
|
||||
} else if ( ! slot )
|
||||
continue;
|
||||
|
||||
const style = {},
|
||||
props = {
|
||||
className: 'ffz-tooltip ffz-badge',
|
||||
'data-tooltip-type': 'badge',
|
||||
|
@ -230,14 +300,22 @@ export default class Badges extends Module {
|
|||
style
|
||||
};
|
||||
|
||||
if ( full_badge.image )
|
||||
style.backgroundImage = `url("${full_badge.image}")`;
|
||||
slotted[slot] = { id: badge.id, props };
|
||||
}
|
||||
|
||||
if ( full_badge.color )
|
||||
style.backgroundColor = full_badge.color;
|
||||
for(const slot in slotted)
|
||||
if ( has(slotted, slot) ) {
|
||||
const data = slotted[slot],
|
||||
props = data.props;
|
||||
|
||||
props.className = 'ffz-tooltip ffz-badge';
|
||||
props['data-tooltip-type'] = 'badge';
|
||||
|
||||
if ( data.replaced )
|
||||
props['data-replaced'] = data.replaced;
|
||||
|
||||
out.push(e('span', props));
|
||||
}*/
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
@ -247,6 +325,7 @@ export default class Badges extends Module {
|
|||
for(const room of this.parent.iterateRooms())
|
||||
room.buildBadgeCSS();
|
||||
|
||||
this.buildBadgeCSS();
|
||||
this.buildTwitchBadgeCSS();
|
||||
this.buildTwitchCSSBadgeCSS();
|
||||
}
|
||||
|
@ -316,6 +395,7 @@ export default class Badges extends Module {
|
|||
}
|
||||
|
||||
this.log.info(`Loaded ${badges} badges and assigned them to ${users} users.`);
|
||||
this.buildBadgeCSS();
|
||||
}
|
||||
|
||||
|
||||
|
@ -332,6 +412,24 @@ export default class Badges extends Module {
|
|||
}
|
||||
|
||||
|
||||
buildBadgeCSS() {
|
||||
const style = this.parent.context.get('chat.badges.style'),
|
||||
is_dark = this.parent.context.get('theme.is-dark');
|
||||
|
||||
const out = [];
|
||||
for(const key in this.badges)
|
||||
if ( has(this.badges, key) ) {
|
||||
const data = this.badges[key],
|
||||
selector = `.ffz-badge[data-badge="${key}"]`;
|
||||
|
||||
out.push(`${selector}{${generateBadgeCSS(key, 0, data, style, is_dark)}}`);
|
||||
out.push(`.ffz-badge[data-replaced="${key}"]{${generateOverrideCSS(data, style, is_dark)}}`);
|
||||
}
|
||||
|
||||
this.style.set('ext-badges', out.join('\n'));
|
||||
}
|
||||
|
||||
|
||||
// ========================================================================
|
||||
// Twitch Badges
|
||||
// ========================================================================
|
||||
|
@ -394,6 +492,7 @@ export default class Badges extends Module {
|
|||
background-color: transparent;
|
||||
filter: none;
|
||||
${WEBKIT}mask-image: none;
|
||||
background-size: 1.8rem;
|
||||
background-image: url("${data.image1x}");
|
||||
background-image: ${WEBKIT}image-set(
|
||||
url("${data.image1x}") 1x,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue