1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-09-16 18:06:55 +00:00
* Added: High-DPI badge support for Firefox using `@media` queries since they still don't support `image-set()` after 5+ years.
* Added: Display the date videos were uploaded in a tool-tip when hovering over the human readable duration (such as '3 months ago').
* Added: Setting to hide all the Community Highlight pop-ups at the top of chat. They are the latest pop-up style Twitch is trying. As usual, they fail to include a way to dismiss them and they obscure chat. Unfortunately, this also hides polls which have some value.
* Fixed: Inverted Portrait Mode.
This commit is contained in:
SirStendec 2019-12-10 20:46:33 -05:00
parent 3616027441
commit 5f8ebc9085
7 changed files with 123 additions and 18 deletions

View file

@ -1,7 +1,7 @@
{
"name": "frankerfacez",
"author": "Dan Salvato LLC",
"version": "4.17.2",
"version": "4.17.3",
"description": "FrankerFaceZ is a Twitch enhancement suite.",
"license": "Apache-2.0",
"scripts": {

View file

@ -4,7 +4,7 @@
// Badge Handling
// ============================================================================
import {NEW_API, SERVER, API_SERVER, IS_WEBKIT, WEBKIT_CSS as WEBKIT} from 'utilities/constants';
import {NEW_API, SERVER, API_SERVER, IS_WEBKIT, IS_FIREFOX, WEBKIT_CSS as WEBKIT} from 'utilities/constants';
import {createElement, ManagedStyle} from 'utilities/dom';
import {has} from 'utilities/object';
@ -126,11 +126,11 @@ export function generateBadgeCSS(badge, version, data, style, is_dark, badge_ver
if ( style !== 3 && style !== 4 ) {
svg = base_image.endsWith('.svg');
if ( data.urls )
image = `url("${data.urls[1]}")`;
image = `url("${data.urls[scale]}")`;
else
image = `url("${svg ? base_image : `${base_image}${scale}${trans ? '_trans' : ''}.png`}")`;
if ( data.urls ) {
if ( data.urls && scale === 1 ) {
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 ) {
@ -141,7 +141,7 @@ export function generateBadgeCSS(badge, version, data, style, is_dark, badge_ver
image_set = `${WEBKIT}image-set(${image} 1x, url("${base_image}4${trans ? '_trans' : ''}.png") 2x)`;
} else
image_set = svg;
image_set = image;
}
if ( color_fixer && color && color !== 'transparent' )
@ -149,7 +149,7 @@ export function generateBadgeCSS(badge, version, data, style, is_dark, badge_ver
// 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,
scale: 1,
color,
image,
image_set,
@ -172,6 +172,17 @@ export default class Badges extends Module {
this.badges = {};
this.twitch_badges = {};
if ( IS_FIREFOX )
this.settings.add('chat.badges.media-queries', {
default: true,
ui: {
path: 'Chat > Badges >> tabs ~> Appearance',
title: 'Use @media queries to support High-DPI Badge images in Mozilla Firefox.',
description: 'This is required to see high-DPI badges on Firefox because Firefox still has yet to support `image-set()` after more than five years. It may be less reliable.',
component: 'setting-check-box'
}
});
this.settings.add('chat.badges.version', {
default: 2,
ui: {
@ -304,6 +315,7 @@ export default class Badges extends Module {
this.parent.context.on('changed:theme.is-dark', this.rebuildAllCSS, this);
this.parent.context.on('changed:theme.tooltips-dark', this.rebuildAllCSS, this);
this.parent.context.on('changed:chat.badges.version', this.rebuildAllCSS, this);
this.parent.context.on('changed:chat.badges.media-queries', this.rebuildAllCSS, this);
this.parent.context.on('changed:chat.badges.fix-colors', this.rebuildColoredBadges, this);
this.rebuildAllCSS();
@ -684,7 +696,8 @@ 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');
is_dark = this.parent.context.get('theme.is-dark'),
use_media = IS_FIREFOX && this.parent.context.get('chat.badges.media-queries');
const out = [];
for(const key in this.badges)
@ -692,8 +705,14 @@ export default class Badges extends Module {
const data = this.badges[key],
selector = `.ffz-badge[data-badge="${key}"]`;
out.push(`${selector}{${generateBadgeCSS(key, 0, data, style, is_dark, 0, this.color_fixer)}}`);
out.push(`.ffz-badge[data-replaced="${key}"]{${generateOverrideCSS(data, style, is_dark)}}`);
if ( use_media ) {
out.push(`@media (max-resolution: 99dpi) {${selector}{${generateBadgeCSS(key, 0, data, style, is_dark, 0, this.color_fixer, 1)}}}`);
out.push(`@media (min-resolution: 100dpi) and (max-resolution:199dpi) {${selector}{${generateBadgeCSS(key, 0, data, style, is_dark, 0, this.color_fixer, 2)}}}`);
out.push(`@media (min-resolution: 200dpi) {${selector}{${generateBadgeCSS(key, 0, data, style, is_dark, 0, this.color_fixer, 4)}}}`);
} else
out.push(`${selector}{${generateBadgeCSS(key, 0, data, style, is_dark, 0, this.color_fixer)}}`);
}
this.style.set('ext-badges', out.join('\n'));
@ -758,6 +777,7 @@ export default class Badges extends Module {
buildTwitchCSSBadgeCSS() {
const style = this.parent.context.get('chat.badges.style'),
is_dark = this.parent.context.get('theme.is-dark'),
use_media = IS_FIREFOX && this.parent.context.get('chat.badges.media-queries'),
badge_version = this.parent.context.get('chat.badges.version'),
versioned = CSS_BADGES[badge_version] || {};
@ -771,6 +791,11 @@ export default class Badges extends Module {
const d = data[version],
selector = `.ffz-badge[data-badge="${key}"][data-version="${version}"]`;
if ( use_media ) {
out.push(`@media (max-resolution: 99dpi) {${selector}{${generateBadgeCSS(key, version, d, style, is_dark, badge_version, this.color_fixer, 1)}}}`);
out.push(`@media (min-resolution: 100dpi) and (max-resolution:199dpi) {${selector}{${generateBadgeCSS(key, version, d, style, is_dark, badge_version, this.color_fixer, 2)}}}`);
out.push(`@media (min-resolution: 200dpi) {${selector}{${generateBadgeCSS(key, version, d, style, is_dark, badge_version, this.color_fixer, 4)}}}`);
} else
out.push(`${selector}{${generateBadgeCSS(key, version, d, style, is_dark, badge_version, this.color_fixer)}}`);
}
}
@ -784,6 +809,7 @@ export default class Badges extends Module {
this.style.delete('twitch-badges');
const badge_version = this.parent.context.get('chat.badges.version'),
use_media = IS_FIREFOX && this.parent.context.get('chat.badges.media-queries'),
versioned = CSS_BADGES[badge_version] || {};
const out = [];
@ -795,9 +821,10 @@ export default class Badges extends Module {
const versions = this.twitch_badges[key];
for(const version in versions)
if ( has(versions, version) ) {
const data = versions[version];
const data = versions[version],
selector = `.ffz-badge[data-badge="${key}"][data-version="${version}"]`;
out.push(`.ffz-badge[data-badge="${key}"][data-version="${version}"] {
out.push(`${selector} {
background-color: transparent;
filter: none;
${WEBKIT}mask-image: none;
@ -808,7 +835,16 @@ export default class Badges extends Module {
url("${data.image2x}") 2x,
url("${data.image4x}") 4x
);
}`)
}`);
if ( use_media ) {
out.push(`@media (min-resolution: 100dpi) and (max-resolution:199dpi) { ${selector} {
background-image: url("${data.image2x});
}}`);
out.push(`@media (min-resolution: 200dpi) { ${selector} {
background-image: url("${data.image4x});
}}`);
}
}
}

View file

@ -6,7 +6,7 @@
import User from './user';
import {NEW_API, API_SERVER, WEBKIT_CSS as WEBKIT} from 'utilities/constants';
import {NEW_API, API_SERVER, WEBKIT_CSS as WEBKIT, IS_FIREFOX} from 'utilities/constants';
import {ManagedStyle} from 'utilities/dom';
import {has, SourcedSet, set_equals} from 'utilities/object';
@ -445,7 +445,8 @@ export default class Room {
if ( ! this.badges )
return this.style.delete('badges');
const out = [],
const use_media = IS_FIREFOX && this.manager.context.get('chat.badges.media-queries'),
out = [],
id = this.id;
for(const key in this.badges)
@ -454,9 +455,9 @@ export default class Room {
for(const version in versions)
if ( has(versions, version) ) {
const data = versions[version],
rule = `.ffz-badge[data-badge="${key}"][data-version="${version}"]`;
selector = `[data-room-id="${id}"] .ffz-badge[data-badge="${key}"][data-version="${version}"]`;
out.push(`[data-room-id="${id}"] ${rule} {
out.push(`${selector} {
background-color: transparent;
filter: none;
${WEBKIT}mask-image: none;
@ -470,6 +471,15 @@ export default class Room {
url("${data.image4x}") 4x
);
}`);
if ( use_media ) {
out.push(`@media (min-resolution: 100dpi) and (max-resolution:199dpi) { ${selector} {
background-image: url("${data.image2x}");
}}`);
out.push(`@media (min-resolution: 200dpi) { ${selector} {
background-image: url("${data.image4x}");
}}`);
}
}
}

View file

@ -16,6 +16,7 @@ export default class ChannelBar extends Module {
this.should_enable = true;
this.inject('i18n');
this.inject('settings');
this.inject('site.css_tweaks');
this.inject('site.fine');
@ -45,6 +46,11 @@ export default class ChannelBar extends Module {
changed: val => this.css_tweaks.toggle('channel-metadata-top', val)
});
this.VideoBar = this.fine.define(
'video-bar',
n => n.props && n.props.getLastVideoOffset && n.renderTrackedHighlightButton,
['video', 'user-video']
);
this.ChannelBar = this.fine.define(
'channel-bar',
@ -56,6 +62,11 @@ export default class ChannelBar extends Module {
onEnable() {
this.css_tweaks.toggle('channel-metadata-top', this.settings.get('channel.metadata.force-above'));
this.on('i18n:update', () => {
for(const bar of this.VideoBar.instances)
this.updateVideoBar(bar);
});
this.ChannelBar.on('unmount', this.unmountChannelBar, this);
this.ChannelBar.on('mount', this.updateChannelBar, this);
this.ChannelBar.on('update', this.updateChannelBar, this);
@ -64,6 +75,35 @@ export default class ChannelBar extends Module {
for(const inst of instances)
this.updateChannelBar(inst);
});
//this.VideoBar.on('unmount', this.unmountVideoBar, this);
this.VideoBar.on('mount', this.updateVideoBar, this);
this.VideoBar.on('update', this.updateVideoBar, this);
this.VideoBar.ready((cls, instances) => {
for(const inst of instances)
this.updateVideoBar(inst);
});
}
updateVideoBar(inst) {
const container = this.fine.getChildNode(inst),
timestamp = container && container.querySelector('[data-test-selector="date"]');
if ( ! timestamp )
return;
const published = get('props.video.publishedAt', inst);
if ( ! published )
timestamp.classList.toggle('ffz-tooltip', false);
else {
timestamp.classList.toggle('ffz-tooltip', true);
timestamp.dataset.title = this.i18n.t('video.published-on', 'Published on: {date,date}', {date: published});
}
}

View file

@ -252,10 +252,20 @@ export default class ChatHook extends Module {
// Settings
this.settings.add('chat.hide-community-highlights', {
default: false,
ui: {
path: 'Chat > Appearance >> Community',
title: 'Hide all Community Highlights from the top of chat.',
component: 'setting-check-box',
description: 'Community Highlights are polls, community gift subs, etc. that float over the top of chat temporarily with no way to close them.'
}
});
this.settings.add('chat.subs.gift-banner', {
default: true,
ui: {
path: 'Chat > Appearance >> Subscriptions',
path: 'Chat > Appearance >> Community',
title: 'Display a banner at the top of chat when a mass gift sub happens.',
component: 'setting-check-box'
}
@ -264,7 +274,7 @@ export default class ChatHook extends Module {
this.settings.add('chat.community-chest.show', {
default: true,
ui: {
path: 'Chat > Appearance >> Community Chest',
path: 'Chat > Appearance >> Community',
title: 'Display the Community Gift Chest banner.',
component: 'setting-check-box'
}
@ -684,6 +694,9 @@ export default class ChatHook extends Module {
this.css_tweaks.toggle('clickable-mentions', this.chat.context.get('chat.filtering.clickable-mentions'));
this.chat.context.on('changed:chat.hide-community-highlights', val => this.css_tweaks.toggleHide('community-highlights', val));
this.css_tweaks.toggleHide('community-highlights', this.chat.context.get('chat.hide-community-highlights'));
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'));

View file

@ -21,6 +21,8 @@ const CLASSES = {
'side-offline-channels': '.side-nav-card__link[href*="/videos/"],.side-nav-card[href*="/videos/"]',
'side-rerun-channels': '.side-nav .ffz--side-nav-card-rerun',
'community-highlights': '.community-highlight-stack__card',
'prime-offers': '.top-nav__prime',
'player-ext': '.video-player .extension-taskbar,.video-player .extension-container,.video-player .extensions-dock__layout,.video-player .extensions-notifications,.video-player .extensions-video-overlay-size-container,.video-player .extensions-dock__layout',

View file

@ -6,6 +6,10 @@
& > .tw-flex-column > .tw-full-height {
.ffz--portrait-invert & {
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: var(--ffz-chat-height) !important;
}