1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-30 08:08:32 +00:00

Added change log. Refactored how modified colors are applied for performance. Added option for automatically entering theater-mode when navigating to a channel. Split High Contrast option for more configurability. Added option to shift-click emoticons to open info pages. Made new aliases update in existing chat lines immediately. Disabled slow mode countdown for subscribers. Made menu draggable from side to side.

This commit is contained in:
SirStendec 2015-07-31 17:44:20 -04:00
parent c5f55bd6b8
commit c73158202e
18 changed files with 890 additions and 487 deletions

806
script.js

File diff suppressed because it is too large Load diff

14
script.min.js vendored

File diff suppressed because one or more lines are too long

View file

@ -366,7 +366,7 @@ FFZ.prototype._legacy_add_donors = function() {
FFZ.prototype._legacy_load_bots = function(tries) { FFZ.prototype._legacy_load_bots = function(tries) {
jQuery.ajax(constants.SERVER + "script/bots.txt", {cache: false, context: this}) jQuery.ajax(constants.SERVER + "script/bots.txt", {cache: false, context: this})
.done(function(data) { .done(function(data) {
this._legacy_parse_badges(data, 0, 2); this._legacy_parse_badges(data, 0, 2, "Bot (By: {})");
}).fail(function(data) { }).fail(function(data) {
if ( data.status == 404 ) if ( data.status == 404 )
@ -394,15 +394,18 @@ FFZ.prototype._legacy_load_donors = function(tries) {
} }
FFZ.prototype._legacy_parse_badges = function(data, slot, badge_id) { FFZ.prototype._legacy_parse_badges = function(data, slot, badge_id, title_template) {
var title = this.badges[badge_id].title, var title = this.badges[badge_id].title,
count = 0; count = 0;
ds = null; ds = null;
title_template = title_template || '{}';
if ( data != null ) { if ( data != null ) {
var lines = data.trim().split(/\W+/); var lines = data.trim().split(/\W+/);
for(var i=0; i < lines.length; i++) { for(var i=0; i < lines.length; i++) {
var user_id = lines[i], var line_data = lines[i].split(";"),
user_id = line_data[0],
user = this.users[user_id] = this.users[user_id] || {}, user = this.users[user_id] = this.users[user_id] || {},
badges = user.badges = user.badges || {}, badges = user.badges = user.badges || {},
sets = user.sets = user.sets || []; sets = user.sets = user.sets || [];
@ -414,6 +417,8 @@ FFZ.prototype._legacy_parse_badges = function(data, slot, badge_id) {
continue; continue;
badges[slot] = {id:badge_id}; badges[slot] = {id:badge_id};
if ( line_data.length > 1 )
badges[slot].title = title_template.replace('{}', line_data[1]);
count += 1; count += 1;
} }
} }

View file

@ -45,7 +45,6 @@ FFZ.settings_info.fix_color = {
}, },
on_update: function(val) { on_update: function(val) {
document.body.classList.toggle("ffz-chat-colors", !this.has_bttv && val !== '-1');
document.body.classList.toggle("ffz-chat-colors-gray", !this.has_bttv && (val === '-1')); document.body.classList.toggle("ffz-chat-colors-gray", !this.has_bttv && (val === '-1'));
if ( ! this.has_bttv && val !== '-1' ) if ( ! this.has_bttv && val !== '-1' )
@ -115,15 +114,22 @@ FFZ.settings_info.color_blind = {
// -------------------- // --------------------
FFZ.prototype.setup_colors = function() { FFZ.prototype.setup_colors = function() {
this.log("Preparing color-alteration style element.");
this._colors = {}; this._colors = {};
this._rebuild_contrast(); this._rebuild_contrast();
var s = this._color_style = document.createElement('style'); this._update_colors();
s.id = 'ffz-style-username-colors';
s.type = 'text/css'; // Events for rebuilding colors.
document.head.appendChild(s); var Layout = App.__container__.lookup('controller:layout'),
Settings = App.__container__.lookup('controller:settings');
if ( Layout )
Layout.addObserver("isTheatreMode", this._update_colors.bind(this, true));
if ( Settings )
Settings.addObserver("model.darkMode", this._update_colors.bind(this, true))
this._color_old_darkness = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('model.darkMode'));
} }
@ -248,6 +254,11 @@ RGBColor.prototype.toCSS = function() { return "rgb(" + Math.round(this.r) + ","
RGBColor.prototype.toXYZ = function() { return XYZColor.fromRGB(this.r, this.g, this.b); } RGBColor.prototype.toXYZ = function() { return XYZColor.fromRGB(this.r, this.g, this.b); }
RGBColor.prototype.toLUV = function() { return this.toXYZ().toLUV(); } RGBColor.prototype.toLUV = function() { return this.toXYZ().toLUV(); }
RGBColor.prototype.toHex = function() {
var rgb = this.b | (this.g << 8) | (this.r << 16);
return '#' + (0x1000000 + rgb).toString(16).slice(1);
}
RGBColor.prototype.luminance = function() { RGBColor.prototype.luminance = function() {
var rgb = [this.r / 255, this.g / 255, this.b / 255]; var rgb = [this.r / 255, this.g / 255, this.b / 255];
@ -361,6 +372,7 @@ HSLColor.fromRGB = function(r, g, b) {
HSLColor.prototype.toRGB = function() { return RGBColor.fromHSL(this.h, this.s, this.l); } HSLColor.prototype.toRGB = function() { return RGBColor.fromHSL(this.h, this.s, this.l); }
HSLColor.prototype.toCSS = function() { return "hsl(" + Math.round(this.h*360) + "," + Math.round(this.s*100) + "%," + Math.round(this.l*100) + "%)"; } HSLColor.prototype.toCSS = function() { return "hsl(" + Math.round(this.h*360) + "," + Math.round(this.s*100) + "%," + Math.round(this.l*100) + "%)"; }
HSLColor.prototype.toHex = function() { return RGBColor.fromHSL(this.h, this.s, this.l).toHex(); }
HSLColor.prototype.toHSV = function() { return RGBColor.fromHSL(this.h, this.s, this.l).toHSV(); } HSLColor.prototype.toHSV = function() { return RGBColor.fromHSL(this.h, this.s, this.l).toHSV(); }
HSLColor.prototype.toXYZ = function() { return RGBColor.fromHSL(this.h, this.s, this.l).toXYZ(); } HSLColor.prototype.toXYZ = function() { return RGBColor.fromHSL(this.h, this.s, this.l).toXYZ(); }
HSLColor.prototype.toLUV = function() { return RGBColor.fromHSL(this.h, this.s, this.l).toLUV(); } HSLColor.prototype.toLUV = function() { return RGBColor.fromHSL(this.h, this.s, this.l).toLUV(); }
@ -537,38 +549,56 @@ FFZ.prototype._rebuild_contrast = function() {
} }
FFZ.prototype._rebuild_colors = function() { FFZ.prototype._rebuild_colors = function() {
if ( ! this._color_style || this.has_bttv ) if ( this.has_bttv )
return; return;
this._color_style.innerHTML = ''; // With update colors, we'll automatically process the colors we care about.
var colors = Object.keys(this._colors);
this._colors = {}; this._colors = {};
for(var i=0, l=colors.length; i<l; i++) this._update_colors();
this._handle_color(colors[i]); }
FFZ.prototype._update_colors = function(darkness_only) {
// Update the lines. ALL of them.
var Layout = App.__container__.lookup('controller:layout'),
Settings = App.__container__.lookup('controller:settings'),
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('model.darkMode'));
if ( darkness_only && this._color_old_darkness === is_dark )
return;
this._color_old_darkness = is_dark;
var colored_bits = document.querySelectorAll('.chat-line .has-color');
for(var i=0, l=colored_bits.length; i < l; i++) {
var bit = colored_bits[i],
color = bit.getAttribute('data-color'),
colors = color && this._handle_color(color);
if ( ! colors )
continue;
bit.style.color = is_dark ? colors[1] : colors[0];
}
} }
FFZ.prototype._handle_color = function(color) { FFZ.prototype._handle_color = function(color) {
if ( ! color || this._colors.hasOwnProperty(color) ) if ( ! color || this._colors.hasOwnProperty(color) )
return; return this._colors[color];
this._colors[color] = true;
var rgb = RGBColor.fromHex(color), var rgb = RGBColor.fromHex(color),
clr = color,
light_color = color, light_color = color,
dark_color = color, dark_color = color;
matched = false,
rule = 'span[style="color:' + color + '"]';
// Color Blindness Handling // Color Blindness Handling
if ( this.settings.color_blind !== '0' ) { if ( this.settings.color_blind !== '0' ) {
var new_color = rgb.daltonize(this.settings.color_blind); var new_color = rgb.daltonize(this.settings.color_blind);
if ( ! rgb.eq(new_color) ) { if ( ! rgb.eq(new_color) ) {
rgb = new_color; rgb = new_color;
clr = light_color = dark_color = rgb.toCSS(); light_color = dark_color = rgb.toHex();
matched = true;
} }
} }
@ -585,8 +615,7 @@ FFZ.prototype._handle_color = function(color) {
break; break;
} }
matched = true; light_color = nc.toHex();
light_color = nc.toCSS();
} }
if ( lum < 0.15 ) { if ( lum < 0.15 ) {
@ -597,8 +626,7 @@ FFZ.prototype._handle_color = function(color) {
break; break;
} }
matched = true; dark_color = nc.toHex();
dark_color = nc.toCSS();
} }
} }
@ -607,25 +635,23 @@ FFZ.prototype._handle_color = function(color) {
if ( this.settings.fix_color === '2' ) { if ( this.settings.fix_color === '2' ) {
var hsl = rgb.toHSL(); var hsl = rgb.toHSL();
matched = true; light_color = hsl._l(Math.min(Math.max(0, 0.7 * hsl.l), 1)).toHex();
light_color = hsl._l(Math.min(Math.max(0, 0.7 * hsl.l), 1)).toCSS(); dark_color = hsl._l(Math.min(Math.max(0, 0.3 + (0.7 * hsl.l)), 1)).toHex();
dark_color = hsl._l(Math.min(Math.max(0, 0.3 + (0.7 * hsl.l)), 1)).toCSS();
} }
// Color Processing - HSV // Color Processing - HSV
if ( this.settings.fix_color === '3' ) { if ( this.settings.fix_color === '3' ) {
var hsv = rgb.toHSV(); var hsv = rgb.toHSV();
matched = true;
if ( hsv.s === 0 ) { if ( hsv.s === 0 ) {
// Black and White // Black and White
light_color = hsv._v(Math.min(Math.max(0.5, 0.5 * hsv.v), 1)).toRGB().toCSS(); light_color = hsv._v(Math.min(Math.max(0.5, 0.5 * hsv.v), 1)).toRGB().toHex();
dark_color = hsv._v(Math.min(Math.max(0.5, 0.5 + (0.5 * hsv.v)), 1)).toRGB().toCSS(); dark_color = hsv._v(Math.min(Math.max(0.5, 0.5 + (0.5 * hsv.v)), 1)).toRGB().toHex();
} else { } else {
light_color = RGBColor.fromHSV(hsv.h, Math.min(Math.max(0.7, 0.7 + (0.3 * hsv.s)), 1), Math.min(0.7, hsv.v)).toCSS(); light_color = RGBColor.fromHSV(hsv.h, Math.min(Math.max(0.7, 0.7 + (0.3 * hsv.s)), 1), Math.min(0.7, hsv.v)).toHex();
dark_color = RGBColor.fromHSV(hsv.h, Math.min(0.7, hsv.s), Math.min(Math.max(0.7, 0.7 + (0.3 * hsv.v)), 1)).toCSS(); dark_color = RGBColor.fromHSV(hsv.h, Math.min(0.7, hsv.s), Math.min(Math.max(0.7, 0.7 + (0.3 * hsv.v)), 1)).toHex();
} }
} }
@ -633,33 +659,13 @@ FFZ.prototype._handle_color = function(color) {
if ( this.settings.fix_color === '1' ) { if ( this.settings.fix_color === '1' ) {
var luv = rgb.toLUV(); var luv = rgb.toLUV();
if ( luv.l > this._luv_required_dark ) { if ( luv.l > this._luv_required_dark )
matched = true; light_color = luv._l(this._luv_required_dark).toRGB().toHex();
light_color = luv._l(this._luv_required_dark).toRGB().toCSS();
if ( luv.l < this._luv_required_bright )
dark_color = luv._l(this._luv_required_bright).toRGB().toHex();
} }
if ( luv.l < this._luv_required_bright ) { var out = this._colors[color] = [light_color, dark_color];
matched = true; return out;
dark_color = luv._l(this._luv_required_bright).toRGB().toCSS();
}
}
// Output
if ( ! matched )
return;
var output = '';
if ( light_color !== clr )
output += 'body.ffz-chat-colors .chat-line ' + rule + ' { color: ' + light_color + ' !important; }';
if ( dark_color !== light_color ) {
output += 'body.ffz-chat-colors .theatre .chat-container .chat-line ' + rule +
', body.ffz-chat-colors .ember-chat-container.dark .chat-line ' + rule +
', body.ffz-chat-colors .ember-chat-container.force-dark .chat-line ' + rule +
', body.ffz-chat-colors .chat-container.dark .chat-line ' + rule +
', body.ffz-chat-colors .chat-container.force-dark .chat-line ' + rule + ' { color: ' + dark_color + ' !important; }';
}
this._color_style.innerHTML += output;
} }

View file

@ -231,6 +231,12 @@ FFZ.prototype._modify_cindex = function(view) {
if ( f.settings.srl_races ) if ( f.settings.srl_races )
f.rebuild_race_ui(); f.rebuild_race_ui();
if ( f.settings.auto_theater ) {
var Layout = App.__container__.lookup('controller:layout');
if ( Layout )
Layout.set('isTheatreMode', true);
}
}, },
ffzFixTitle: function() { ffzFixTitle: function() {
@ -280,7 +286,10 @@ FFZ.prototype._modify_cindex = function(view) {
btn.addEventListener('click', this.ffzClickHost.bind(btn, this, false)); btn.addEventListener('click', this.ffzClickHost.bind(btn, this, false));
var before = container.querySelector(':scope > .theatre-button'); var before;
try { before = container.querySelector(':scope > .theatre-button'); }
catch(err) { before = undefined; }
if ( before ) if ( before )
container.insertBefore(btn, before); container.insertBefore(btn, before);
else else
@ -315,7 +324,10 @@ FFZ.prototype._modify_cindex = function(view) {
btn.addEventListener('click', this.ffzClickHost.bind(btn, this, true)); btn.addEventListener('click', this.ffzClickHost.bind(btn, this, true));
var before = container.querySelector(':scope > .theatre-button'); var before;
try { before = container.querySelector(':scope > .theatre-button'); }
catch(err) { before = undefined; }
if ( before ) if ( before )
container.insertBefore(btn, before); container.insertBefore(btn, before);
else else
@ -592,6 +604,19 @@ FFZ.prototype._modify_cindex = function(view) {
// Settings // Settings
// --------------- // ---------------
FFZ.settings_info.auto_theater = {
type: "boolean",
value: false,
category: "Appearance",
no_mobile: true,
no_bttv: true,
name: "Automatic Theater Mode",
help: "Automatically enter theater mode when opening a channel."
};
FFZ.settings_info.chatter_count = { FFZ.settings_info.chatter_count = {
type: "boolean", type: "boolean",
value: false, value: false,

View file

@ -7,25 +7,6 @@ var FFZ = window.FrankerFaceZ,
// Settings // Settings
// -------------------- // --------------------
FFZ.settings_info.swap_sidebars = {
type: "boolean",
value: false,
category: "Appearance",
no_mobile: true,
no_bttv: true,
name: "Swap Sidebar Positions",
help: "Swap the positions of the left and right sidebars, placing chat on the left.",
on_update: function(val) {
if ( ! this.has_bttv )
document.body.classList.toggle("ffz-sidebar-swap", val);
}
};
FFZ.settings_info.minimal_chat = { FFZ.settings_info.minimal_chat = {
type: "boolean", type: "boolean",
value: false, value: false,
@ -97,7 +78,7 @@ FFZ.settings_info.remove_deleted = {
if ( msg.ffz_deleted || msg.deleted ) { if ( msg.ffz_deleted || msg.deleted ) {
if ( alternate === undefined ) if ( alternate === undefined )
alternate = msg.ffz_alternate; alternate = msg.ffz_alternate;
msgs.removeAt(i--); msgs.removeAt(i);
continue; continue;
} }
@ -195,10 +176,6 @@ FFZ.settings_info.visible_rooms = {
FFZ.prototype.setup_chatview = function() { FFZ.prototype.setup_chatview = function() {
document.body.classList.toggle("ffz-minimal-chat", this.settings.minimal_chat); document.body.classList.toggle("ffz-minimal-chat", this.settings.minimal_chat);
if ( ! this.has_bttv )
document.body.classList.toggle("ffz-sidebar-swap", this.settings.swap_sidebars);
this.log("Hooking the Ember Chat controller."); this.log("Hooking the Ember Chat controller.");
var Chat = App.__container__.lookup('controller:chat'), var Chat = App.__container__.lookup('controller:chat'),
@ -267,21 +244,6 @@ FFZ.prototype.setup_chatview = function() {
} }
} }
this.log("Hooking the Ember Layout controller.");
var Layout = App.__container__.lookup('controller:layout');
if ( ! Layout )
return;
Layout.reopen({
ffzFixTabs: function() {
if ( f.settings.group_tabs && f._chatv && f._chatv._ffz_tabs ) {
setTimeout(function() {
f._chatv && f._chatv.$('.chat-room').css('top', f._chatv._ffz_tabs.offsetHeight + "px");
},0);
}
}.observes("isRightColumnClosed")
});
this.log("Hooking the Ember 'Right Column' controller. Seriously..."); this.log("Hooking the Ember 'Right Column' controller. Seriously...");
var Column = App.__container__.lookup('controller:right-column'); var Column = App.__container__.lookup('controller:right-column');

View file

@ -198,6 +198,20 @@ FFZ.settings_info.keywords = {
}; };
FFZ.settings_info.clickable_emoticons = {
type: "boolean",
value: false,
category: "Chat Tooltips",
no_bttv: true,
no_mobile: true,
name: "Emoticon Information Pages",
help: "When enabled, holding shift and clicking on an emoticon will open it on the FrankerFaceZ website or Twitch Emotes."
};
FFZ.settings_info.link_info = { FFZ.settings_info.link_info = {
type: "boolean", type: "boolean",
value: true, value: true,
@ -308,8 +322,18 @@ FFZ.settings_info.chat_padding = {
FFZ.settings_info.high_contrast_chat = { FFZ.settings_info.high_contrast_chat = {
type: "boolean", type: "select",
value: false, options: {
'222': "Disabled",
'212': "Bold",
'221': "Text",
'211': "Text + Bold",
'122': "Background",
'121': "Background + Text",
'112': "Background + Bold",
'111': 'All'
},
value: '000',
category: "Chat Appearance", category: "Chat Appearance",
no_bttv: true, no_bttv: true,
@ -317,7 +341,19 @@ FFZ.settings_info.high_contrast_chat = {
name: "High Contrast", name: "High Contrast",
help: "Display chat using white and black for maximum contrast. This is suitable for capturing and chroma keying chat to display on stream.", help: "Display chat using white and black for maximum contrast. This is suitable for capturing and chroma keying chat to display on stream.",
on_update: function(val) { document.body.classList.toggle("ffz-high-contrast-chat", !this.has_bttv && val); } process_value: function(val) {
if ( val === false )
return '000';
else if ( val === true )
return '111';
return val;
},
on_update: function(val) {
document.body.classList.toggle("ffz-high-contrast-chat-text", !this.has_bttv && val[2] === '1');
document.body.classList.toggle("ffz-high-contrast-chat-bold", !this.has_bttv && val[1] === '1');
document.body.classList.toggle("ffz-high-contrast-chat-bg", !this.has_bttv && val[0] === '1');
}
}; };
@ -339,7 +375,7 @@ FFZ.settings_info.chat_font_size = {
return; return;
var parsed = parseInt(new_val); var parsed = parseInt(new_val);
if ( parsed === NaN || parsed < 1 ) if ( ! parsed || parsed === NaN || parsed < 1 )
parsed = 12; parsed = 12;
this.settings.set("chat_font_size", parsed); this.settings.set("chat_font_size", parsed);
@ -388,7 +424,7 @@ FFZ.settings_info.chat_ts_size = {
return; return;
var parsed = parseInt(new_val); var parsed = parseInt(new_val);
if ( parsed === NaN || parsed < 1 ) if ( ! parsed || parsed === NaN || parsed < 1 )
parsed = null; parsed = null;
this.settings.set("chat_ts_size", parsed); this.settings.set("chat_ts_size", parsed);
@ -450,7 +486,10 @@ FFZ.prototype.setup_line = function() {
document.body.classList.toggle("ffz-chat-separator-3d", !this.has_bttv && this.settings.chat_separators === '2'); document.body.classList.toggle("ffz-chat-separator-3d", !this.has_bttv && this.settings.chat_separators === '2');
document.body.classList.toggle("ffz-chat-padding", !this.has_bttv && this.settings.chat_padding); document.body.classList.toggle("ffz-chat-padding", !this.has_bttv && this.settings.chat_padding);
document.body.classList.toggle("ffz-chat-purge-icon", !this.has_bttv && this.settings.line_purge_icon); document.body.classList.toggle("ffz-chat-purge-icon", !this.has_bttv && this.settings.line_purge_icon);
document.body.classList.toggle("ffz-high-contrast-chat", !this.has_bttv && this.settings.high_contrast_chat);
document.body.classList.toggle("ffz-high-contrast-chat-text", !this.has_bttv && this.settings.high_contrast_chat[2] === '1');
document.body.classList.toggle("ffz-high-contrast-chat-bold", !this.has_bttv && this.settings.high_contrast_chat[1] === '1');
document.body.classList.toggle("ffz-high-contrast-chat-bg", !this.has_bttv && this.settings.high_contrast_chat[0] === '1');
this._last_row = {}; this._last_row = {};
@ -485,7 +524,10 @@ FFZ.prototype.save_aliases = function() {
FFZ.prototype._modify_line = function(component) { FFZ.prototype._modify_line = function(component) {
var f = this; var f = this,
Layout = App.__container__.lookup('controller:layout'),
Settings = App.__container__.lookup('controller:settings');
component.reopen({ component.reopen({
@ -559,6 +601,16 @@ FFZ.prototype._modify_line = function(component) {
} }
} }
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons && e.target && e.target.classList.contains('emoticon') ) {
var eid = e.target.getAttribute('data-emote');
if ( eid )
window.open("https://twitchemotes.com/emote/" + eid);
else {
eid = e.target.getAttribute("data-ffz-emote");
window.open("https://www.frankerfacez.com/emoticons/" + eid);
}
}
return this._super(e); return this._super(e);
}, },
@ -592,7 +644,11 @@ FFZ.prototype._modify_line = function(component) {
this_ul = this.get('ffzUserLevel'), this_ul = this.get('ffzUserLevel'),
other_ul = room && room.room && room.room.get('ffzUserLevel') || 0, other_ul = room && room.room && room.room.get('ffzUserLevel') || 0,
row_type = this.get('msgObject.ffz_alternate'); row_type = this.get('msgObject.ffz_alternate'),
raw_color = this.get('msgObject.color'),
colors = raw_color && f._handle_color(raw_color),
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('model.darkMode'));
if ( row_type === undefined ) { if ( row_type === undefined ) {
row_type = f._last_row[room_id] = f._last_row.hasOwnProperty(room_id) ? !f._last_row[room_id] : false; row_type = f._last_row[room_id] = f._last_row.hasOwnProperty(room_id) ? !f._last_row[room_id] : false;
@ -653,31 +709,43 @@ FFZ.prototype._modify_line = function(component) {
e.push('</span>'); e.push('</span>');
var alias = f.aliases[user], var alias = f.aliases[user],
name = this.get('msgObject.tags.display-name') || (user && user.capitalize()) || "unknown user"; name = this.get('msgObject.tags.display-name') || (user && user.capitalize()) || "unknown user",
style = colors && 'color:' + (is_dark ? colors[1] : colors[0]),
colored = style ? ' has-color' : '';
if ( alias ) if ( alias )
e.push('<span class="from ffz-alias tooltip" style="' + this.get('fromStyle') + '" title="' + utils.sanitize(name) + '">' + utils.sanitize(alias) + '</span>'); e.push('<span class="from ffz-alias tooltip' + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '') + '" title="' + utils.sanitize(name) + '">' + utils.sanitize(alias) + '</span>');
else else
e.push('<span class="from" style="' + this.get('fromStyle') + '">' + utils.sanitize(name) + '</span>'); e.push('<span class="from' + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '') + '">' + utils.sanitize(name) + '</span>');
if ( is_whisper ) { if ( is_whisper ) {
var to_alias = f.aliases[recipient], var to_alias = f.aliases[recipient],
to_name = this.get('msgObject.tags.recipient-display-name') || (recipient && recipient.capitalize()) || "unknown user"; to_name = this.get('msgObject.tags.recipient-display-name') || (recipient && recipient.capitalize()) || "unknown user",
to_color = this.get('msgObject.toColor'),
to_colors = to_color && f._handle_color(to_color),
to_style = to_color && 'color:' + (is_dark ? colors[1] : colors[0]),
to_colored = to_style ? ' has-color' : '';
this._renderWhisperArrow(e); this._renderWhisperArrow(e);
if ( to_alias ) if ( to_alias )
e.push('<span class="to ffz-alias tooltip" style="' + this.get('toStyle') + '" title="' + utils.sanitize(to_name) + '">' + utils.sanitize(to_alias) + '</span>'); e.push('<span class="to ffz-alias tooltip' + to_colored + '" style="' + to_style + (to_color ? '" data-color="' + to_color : '') + '" title="' + utils.sanitize(to_name) + '">' + utils.sanitize(to_alias) + '</span>');
else else
e.push('<span class="to" style="' + this.get('toStyle') + '">' + utils.sanitize(to_name) + '</span>'); e.push('<span class="to' + to_colored + '" style="' + to_style + (to_colors ? '" data-color="' + to_color : '') + '">' + utils.sanitize(to_name) + '</span>');
} }
e.push('<span class="colon">:</span> '); e.push('<span class="colon">:</span> ');
if ( this.get('msgObject.style') !== 'action' ) {
style = '';
colored = '';
}
if ( deleted ) if ( deleted )
e.push('<span class="deleted"><a class="undelete" href="#">&lt;message deleted&gt;</a></span>'); e.push('<span class="deleted"><a class="undelete" href="#">&lt;message deleted&gt;</a></span>');
else { else {
e.push('<span class="message" style="' + this.get('messageStyle') + '">'); e.push('<span class="message' + colored + '" style="' + style + '">');
e.push(f.render_tokens(this.get('tokenizedMessage'), true)); e.push(f.render_tokens(this.get('tokenizedMessage'), true));
var old_messages = this.get('msgObject.ffz_old_messages'); var old_messages = this.get('msgObject.ffz_old_messages');

View file

@ -581,6 +581,8 @@ FFZ.prototype.setup_mod_card = function() {
f.save_aliases(); f.save_aliases();
// Update UI // Update UI
f._update_alias(user);
Ember.propertyDidChange(controller, 'userName'); Ember.propertyDidChange(controller, 'userName');
var name = el.querySelector('h3.name'), var name = el.querySelector('h3.name'),
link = name && name.querySelector('a'); link = name && name.querySelector('a');
@ -668,6 +670,32 @@ FFZ.prototype.setup_mod_card = function() {
} }
// ----------------
// Aliases
// ----------------
FFZ.prototype._update_alias = function(user) {
var alias = this.aliases && this.aliases[user],
display_name = alias,
el = this._roomv && this._roomv.get('element'),
lines = el && el.querySelectorAll('.chat-line[data-sender="' + user + '"]');
if ( ! lines )
return;
if ( ! display_name )
display_name = FFZ.get_capitalization(user);
for(var i=0, l = lines.length; i < l; i++) {
var line = lines[i],
el_from = line.querySelector('.from');
el_from.classList.toggle('ffz-alias', alias);
el_from.textContent = display_name;
}
}
// ---------------- // ----------------
// Chat Commands // Chat Commands
// ---------------- // ----------------

View file

@ -1030,7 +1030,7 @@ FFZ.prototype._modify_room = function(room) {
this.set('ffz_banned', false); this.set('ffz_banned', false);
// Update the wait time. // Update the wait time.
if ( this.get('isModeratorOrHigher') || ! this.get('slowMode') ) if ( this.get('isSubscriber') || this.get('isModeratorOrHigher') || ! this.get('slowMode') )
this.updateWait(0, was_banned) this.updateWait(0, was_banned)
else if ( this.get('slowMode') ) else if ( this.get('slowMode') )
this.updateWait(this.get('slow')); this.updateWait(this.get('slow'));

View file

@ -237,7 +237,7 @@ FFZ.prototype.load_emoji_data = function(callback, tries) {
emoji.token = { emoji.token = {
srcSet: emoji.srcSet, srcSet: emoji.srcSet,
emoticonSrc: emoji.src + '" data-ffz-emoji="' + eid + '" height="18px', emoticonSrc: emoji.src,
ffzEmoji: eid, ffzEmoji: eid,
altText: emoji.raw altText: emoji.raw
}; };

View file

@ -34,6 +34,11 @@ FFZ.prototype.setup_bttv = function(delay) {
this._dark_style = undefined; this._dark_style = undefined;
} }
if ( this._layout_style ) {
this._layout_style.parentElement.removeChild(this._layout_style);
this._layout_style = undefined;
}
if ( this._chat_style ) { if ( this._chat_style ) {
utils.update_css(this._chat_style, 'chat_font_size', ''); utils.update_css(this._chat_style, 'chat_font_size', '');
utils.update_css(this._chat_style, 'chat_ts_font_size', ''); utils.update_css(this._chat_style, 'chat_ts_font_size', '');
@ -63,7 +68,9 @@ FFZ.prototype.setup_bttv = function(delay) {
document.body.classList.remove("ffz-chat-separator-3d"); document.body.classList.remove("ffz-chat-separator-3d");
document.body.classList.remove("ffz-sidebar-swap"); document.body.classList.remove("ffz-sidebar-swap");
document.body.classList.remove("ffz-transparent-badges"); document.body.classList.remove("ffz-transparent-badges");
document.body.classList.remove("ffz-high-contrast-chat"); document.body.classList.remove("ffz-high-contrast-chat-text");
document.body.classList.remove("ffz-high-contrast-chat-bg");
document.body.classList.remove("ffz-high-contrast-chat-bold");
// Remove Following Count // Remove Following Count
if ( this.settings.following_count ) { if ( this.settings.following_count ) {

View file

@ -21,7 +21,7 @@ FFZ.get = function() { return FFZ.instance; }
// Version // Version
var VER = FFZ.version_info = { var VER = FFZ.version_info = {
major: 3, minor: 5, revision: 2, major: 3, minor: 5, revision: 7,
toString: function() { toString: function() {
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || ""); return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
} }
@ -115,8 +115,9 @@ require('./tokenize');
// Analytics: require('./ember/router'); // Analytics: require('./ember/router');
require('./ember/channel'); require('./ember/channel');
require('./ember/player'); //require('./ember/player');
require('./ember/room'); require('./ember/room');
require('./ember/layout');
require('./ember/line'); require('./ember/line');
require('./ember/chatview'); require('./ember/chatview');
require('./ember/viewers'); require('./ember/viewers');
@ -159,7 +160,7 @@ FFZ.prototype.initialize = function(increment, delay) {
// Check for the player // Check for the player
if ( location.hostname === 'player.twitch.tv' ) { if ( location.hostname === 'player.twitch.tv' ) {
this.init_player(delay); //this.init_player(delay);
return; return;
} }
@ -321,10 +322,11 @@ FFZ.prototype.init_ember = function(delay) {
//this.setup_router(); //this.setup_router();
this.setup_colors(); this.setup_colors();
this.setup_tokenization(); this.setup_tokenization();
this.setup_player(); //this.setup_player();
this.setup_channel(); this.setup_channel();
this.setup_room(); this.setup_room();
this.setup_line(); this.setup_line();
this.setup_layout();
this.setup_chatview(); this.setup_chatview();
this.setup_viewers(); this.setup_viewers();
this.setup_mod_card(); this.setup_mod_card();

View file

@ -723,7 +723,7 @@ FFZ.prototype.tokenize_emotes = function(user, room, tokens, do_report) {
_.each(emotes, function(emote) { _.each(emotes, function(emote) {
var eo = { var eo = {
srcSet: emote.srcSet, srcSet: emote.srcSet,
emoticonSrc: emote.urls[1] + '" data-ffz-emote="' + encodeURIComponent(JSON.stringify([emote.id, emote.set_id])), emoticonSrc: emote.urls[1],
ffzEmote: emote.id, ffzEmote: emote.id,
ffzEmoteSet: emote.set_id, ffzEmoteSet: emote.set_id,
altText: (emote.hidden ? "???" : emote.name) altText: (emote.hidden ? "???" : emote.name)

View file

@ -6,12 +6,39 @@ var FFZ = window.FrankerFaceZ,
// About Page // About Page
// ------------------- // -------------------
FFZ.menu_pages.changelog = {
name: "Changelog",
visible: false,
render: function(view, container) {
var heading = document.createElement('div');
heading.className = 'chat-menu-content center';
heading.innerHTML = '<h1>FrankerFaceZ</h1><div class="ffz-about-subheading">change log</div>';
jQuery.ajax(constants.SERVER + "script/changelog.html", {cache: false, context: this})
.done(function(data) {
container.appendChild(heading);
container.innerHTML += data;
}).fail(function(data) {
var content = document.createElement('div');
content.className = 'chat-menu-content menu-side-padding';
content.textContent = 'There was an error loading the change log from the server.';
container.appendChild(heading);
container.appendChild(content);
});
}
};
FFZ.menu_pages.about = { FFZ.menu_pages.about = {
name: "About", name: "About",
icon: constants.HEART, icon: constants.HEART,
sort_order: 100000, sort_order: 100000,
render: function(view, container) { render: function(view, container, inner, menu) {
var room = this.rooms[view.get("context.currentRoom.id")], var room = this.rooms[view.get("context.currentRoom.id")],
has_emotes = false, f = this; has_emotes = false, f = this;
@ -77,11 +104,16 @@ FFZ.menu_pages.about = {
content += '<tr><td>Dan Salvato</td><td><a class="twitch" href="http://www.twitch.tv/dansalvato" title="Twitch" target="_new">&nbsp;</a></td><td><a class="twitter" href="https://twitter.com/dansalvato1" title="Twitter" target="_new">&nbsp;</a></td><td><a class="youtube" href="https://www.youtube.com/user/dansalvato1" title="YouTube" target="_new">&nbsp;</a></td></tr>'; content += '<tr><td>Dan Salvato</td><td><a class="twitch" href="http://www.twitch.tv/dansalvato" title="Twitch" target="_new">&nbsp;</a></td><td><a class="twitter" href="https://twitter.com/dansalvato1" title="Twitter" target="_new">&nbsp;</a></td><td><a class="youtube" href="https://www.youtube.com/user/dansalvato1" title="YouTube" target="_new">&nbsp;</a></td></tr>';
content += '<tr><td>Stendec</td><td><a class="twitch" href="http://www.twitch.tv/sirstendec" title="Twitch" target="_new">&nbsp;</a></td><td><a class="twitter" href="https://twitter.com/SirStendec" title="Twitter" target="_new">&nbsp;</a></td><td><a class="youtube" href="https://www.youtube.com/channel/UCnxuvmK1DCPCXSJ-mXIh4KQ" title="YouTube" target="_new">&nbsp;</a></td></tr>'; content += '<tr><td>Stendec</td><td><a class="twitch" href="http://www.twitch.tv/sirstendec" title="Twitch" target="_new">&nbsp;</a></td><td><a class="twitter" href="https://twitter.com/SirStendec" title="Twitter" target="_new">&nbsp;</a></td><td><a class="youtube" href="https://www.youtube.com/channel/UCnxuvmK1DCPCXSJ-mXIh4KQ" title="YouTube" target="_new">&nbsp;</a></td></tr>';
content += '<tr class="debug"><td>Version ' + FFZ.version_info + '</td><td colspan="3"><a href="#" id="ffz-debug-logs">Logs</a></td></tr>'; content += '<tr class="debug"><td><a href="#" id="ffz-changelog">Version ' + FFZ.version_info + '</a></td><td colspan="3"><a href="#" id="ffz-debug-logs">Logs</a></td></tr>';
credits.className = 'chat-menu-content center'; credits.className = 'chat-menu-content center';
credits.innerHTML = content; credits.innerHTML = content;
// Functional Changelog
credits.querySelector('#ffz-changelog').addEventListener('click', function() {
f._ui_change_page(view, inner, menu, container, 'changelog');
});
// Make the Logs button functional. // Make the Logs button functional.
var getting_logs = false; var getting_logs = false;
credits.querySelector('#ffz-debug-logs').addEventListener('click', function() { credits.querySelector('#ffz-debug-logs').addEventListener('click', function() {

View file

@ -211,7 +211,10 @@ FFZ.prototype.rebuild_following_ui = function() {
cont = document.createElement('span'); cont = document.createElement('span');
cont.id = 'ffz-ui-following'; cont.id = 'ffz-ui-following';
var before = container.querySelector(':scope > span'); var before;
try { before = container.querySelector(':scope > span'); }
catch(err) { before = undefined; }
if ( before ) if ( before )
container.insertBefore(cont, before); container.insertBefore(cont, before);
else else
@ -247,7 +250,10 @@ FFZ.prototype.rebuild_following_ui = function() {
cont = document.createElement('span'); cont = document.createElement('span');
cont.id = 'ffz-ui-following'; cont.id = 'ffz-ui-following';
var before = container.querySelector(':scope > span'); var before;
try { before = container.querySelector(':scope > span'); }
catch(err) { before = undefined; }
if ( before ) if ( before )
container.insertBefore(cont, before); container.insertBefore(cont, before);
else else
@ -344,7 +350,7 @@ FFZ.prototype._build_following_button = function(container, channel_id) {
noti_c.appendChild(noti); noti_c.appendChild(noti);
// Event Listeners! // Event Listeners!
btn.addEventListener('click', function() { btn.addEventListener('click', function(e) {
var user = f.get_user(); var user = f.get_user();
if ( ! user || ! user.login ) if ( ! user || ! user.login )
// Show the login dialog~! // Show the login dialog~!
@ -367,6 +373,14 @@ FFZ.prototype._build_following_button = function(container, channel_id) {
return false; return false;
}); });
btn.addEventListener('mousedown', function(e) {
if ( e.button !== 1 )
return;
e.preventDefault();
window.open(Twitch.uri.profile(channel_id));
});
noti.addEventListener('click', function() { noti.addEventListener('click', function() {
var sw = f._build_following_popup(noti_c, channel_id, notifications); var sw = f._build_following_popup(noti_c, channel_id, notifications);
if ( sw ) if ( sw )

View file

@ -2,7 +2,18 @@ var FFZ = window.FrankerFaceZ,
constants = require('../constants'), constants = require('../constants'),
utils = require('../utils'), utils = require('../utils'),
TWITCH_BASE = "http://static-cdn.jtvnw.net/emoticons/v1/"; TWITCH_BASE = "http://static-cdn.jtvnw.net/emoticons/v1/",
fix_menu_position = function(container) {
var bounds = container.getBoundingClientRect(),
left = parseInt(container.style.left || '0'),
right = bounds.left + container.scrollWidth;
if ( bounds.left < 0 )
container.style.left = (left - bounds.left) + 'px';
else if ( right > document.body.clientWidth )
container.style.left = (left - (right - document.body.clientWidth)) + 'px';
};
// -------------------- // --------------------
@ -16,6 +27,9 @@ FFZ.prototype.setup_menu = function() {
jQuery(document).mouseup(function(e) { jQuery(document).mouseup(function(e) {
var popup = f._popup, parent; var popup = f._popup, parent;
if ( ! popup ) return; if ( ! popup ) return;
if ( popup.id === 'ffz-chat-menu' && popup.style && popup.style.left )
return;
popup = jQuery(popup); popup = jQuery(popup);
parent = popup.parent(); parent = popup.parent();
@ -164,6 +178,12 @@ FFZ.menu_pages = {};
// Create Menu // Create Menu
// -------------------- // --------------------
FFZ.prototype._fix_menu_position = function() {
var container = document.querySelector('#ffz-chat-menu');
if ( container )
fix_menu_position(container);
}
FFZ.prototype.build_ui_popup = function(view) { FFZ.prototype.build_ui_popup = function(view) {
var popup = this._popup; var popup = this._popup;
if ( popup ) { if ( popup ) {
@ -182,11 +202,13 @@ FFZ.prototype.build_ui_popup = function(view) {
dark = (this.has_bttv ? BetterTTV.settings.get('darkenedMode') : false); dark = (this.has_bttv ? BetterTTV.settings.get('darkenedMode') : false);
container.className = 'emoticon-selector chat-menu ffz-ui-popup'; container.className = 'emoticon-selector chat-menu ffz-ui-popup';
container.id = 'ffz-chat-menu';
inner.className = 'emoticon-selector-box dropmenu'; inner.className = 'emoticon-selector-box dropmenu';
container.appendChild(inner); container.appendChild(inner);
container.classList.toggle('dark', dark); container.classList.toggle('dark', dark);
// Menu Container // Menu Container
var sub_container = document.createElement('div'); var sub_container = document.createElement('div');
sub_container.className = 'ffz-ui-menu-page'; sub_container.className = 'ffz-ui-menu-page';
@ -202,6 +224,15 @@ FFZ.prototype.build_ui_popup = function(view) {
heading.innerHTML = "<span>" + (constants.DEBUG ? "[DEV] " : "") + "FrankerFaceZ</span>"; heading.innerHTML = "<span>" + (constants.DEBUG ? "[DEV] " : "") + "FrankerFaceZ</span>";
menu.appendChild(heading); menu.appendChild(heading);
// Draggable
jQuery(container).draggable({
handle: menu, cancel: 'li.item', axis:"x",
stop: function(e) { fix_menu_position(this); }
});
// Get rid of the position: relative that draggable adds.
container.style.position = '';
var menu_pages = []; var menu_pages = [];
for(var key in FFZ.menu_pages) { for(var key in FFZ.menu_pages) {
if ( ! FFZ.menu_pages.hasOwnProperty(key) ) if ( ! FFZ.menu_pages.hasOwnProperty(key) )
@ -255,7 +286,7 @@ FFZ.prototype.build_ui_popup = function(view) {
// Add the menu to the DOM. // Add the menu to the DOM.
this._popup = container; this._popup = container;
sub_container.style.maxHeight = Math.max(200, view.$().height() - 472) + "px"; sub_container.style.maxHeight = Math.max(200, view.$().height() - 172) + "px";
view.$('.chat-interface').append(container); view.$('.chat-interface').append(container);
} }
@ -279,7 +310,11 @@ FFZ.prototype._ui_change_page = function(view, inner, menu, container, page) {
else else
this.log("No matching page: " + page); this.log("No matching page: " + page);
FFZ.menu_pages[page].render.bind(this)(view, container); FFZ.menu_pages[page].render.bind(this)(view, container, inner, menu);
// Re-position if necessary.
var f = this;
setTimeout(function(){f._fix_menu_position();});
} }

View file

@ -2,8 +2,22 @@ var FFZ = window.FrankerFaceZ,
constants = require('./constants'); constants = require('./constants');
var sanitize_cache = {}, var sanitize_el = document.createElement('span'),
sanitize_el = document.createElement('span'),
sanitize = function(msg) {
sanitize_el.textContent = msg;
return sanitize_el.innerHTML;
},
R_QUOTE = /"/g,
R_SQUOTE = /'/g,
R_AMP = /&/g,
R_LT = /</g,
R_GT = />/g,
quote_attr = function(msg) {
return msg.replace(R_AMP, "&amp;").replace(R_QUOTE, "&quot;").replace(R_SQUOTE, "&apos;").replace(R_LT, "&lt;").replace(R_GT, "&gt;");
},
pluralize = function(value, singular, plural) { pluralize = function(value, singular, plural) {
plural = plural || 's'; plural = plural || 's';
@ -206,24 +220,8 @@ module.exports = {
return ""; return "";
}, },
sanitize: function(msg) { sanitize: sanitize,
var m = sanitize_cache[msg]; quote_attr: quote_attr,
if ( ! m ) {
sanitize_el.textContent = msg;
m = sanitize_cache[msg] = sanitize_el.innerHTML;
sanitize_el.innerHTML = "";
}
return m;
},
quote_attr: function(attr) {
return (attr + '')
.replace(/&/g, "&amp;")
.replace(/'/g, "&apos;")
.replace(/"/g, "&quot;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;");
},
date_string: function(date) { date_string: function(date) {
return date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate(); return date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate();

View file

@ -1,3 +1,10 @@
/* Fix Tooltip Opacity */
body > div.tipsy { opacity: 1 !important; }
body > div.tipsy .tipsy-inner { background-color: rgba(0,0,0,0.8); }
body > div.tipsy .tipsy-arrow { opacity: 0.8; }
.ffz-flip { .ffz-flip {
-ms-transform: rotate(180deg); -ms-transform: rotate(180deg);
-webkit-transform: rotate(180deg); -webkit-transform: rotate(180deg);
@ -415,6 +422,8 @@ body:not(.ffz-minimal-chat):not(.ffz-menu-replace) .emoticon-selector-toggle + s
/* Menu Options */ /* Menu Options */
.chat-menu.ffz-ui-popup .ffz-ui-menu-page .chat-menu-content.menu-side-padding { padding-left: 20px; padding-right: 20px; }
.emoticon-grid.collapsed span, .emoticon-grid.collapsed span,
.chat-menu-content.collapsed p { display: none; } .chat-menu-content.collapsed p { display: none; }
@ -535,15 +544,19 @@ body:not(.ffz-minimal-chat):not(.ffz-menu-replace) .emoticon-selector-toggle + s
margin: 0 10px 5px; margin: 0 10px 5px;
} }
#ffz-chat-menu { pointer-events: none; }
.ffz-ui-popup ul.menu { .ffz-ui-popup ul.menu {
list-style-type: none; list-style-type: none;
border-top: 1px solid rgba(0,0,0,0.2); border-top: 1px solid rgba(0,0,0,0.2);
background-color: #eee; background-color: #eee;
cursor: ew-resize;
} }
.ffz-ui-popup .emoticon-selector-box { .ffz-ui-popup .emoticon-selector-box {
width: 10000px !important; /* Max-width has our back */ width: 10000px !important; /* Max-width has our back */
max-width: 300px; max-width: 300px;
pointer-events: auto;
} }
.ember-chat .chat-interface .ffz-ui-popup.emoticon-selector .emoticon-selector-box .emoticon-grid { background-color: transparent; } .ember-chat .chat-interface .ffz-ui-popup.emoticon-selector .emoticon-selector-box .emoticon-grid { background-color: transparent; }
@ -1683,35 +1696,49 @@ li[data-name="following"] a {
/* High Contrast Chat */ /* High Contrast Chat */
.ffz-high-contrast-chat .chat-container, .ffz-high-contrast-chat-text .chat-container,
.ffz-high-contrast-chat .ember-chat-container { .ffz-high-contrast-chat-text .ember-chat-container {
background-color: #fff; color: "#000";
color: #000;
} }
.ffz-high-contrast-chat .ember-chat .chat-messages .chat-line .from, .ffz-high-contrast-chat-bg .chat-container,
.ffz-high-contrast-chat .ember-chat .chat-messages .chat-line .colon, .ffz-high-contrast-chat-bg .ember-chat-container {
.ffz-high-contrast-chat .ember-chat .chat-messages .chat-line .message { background-color: #fff;
}
.ffz-high-contrast-chat-bold .ember-chat .chat-messages .chat-line .from,
.ffz-high-contrast-chat-bold .ember-chat .chat-messages .chat-line .colon,
.ffz-high-contrast-chat-bold .ember-chat .chat-messages .chat-line .message {
font-weight: bold; font-weight: bold;
} }
.ffz-high-contrast-chat .chat-line:before { /*.ffz-high-contrast-chat .chat-line:before {
background-color: transparent !important; background-color: transparent !important;
border: none !important; border: none !important;
} }*/
.ffz-high-contrast-chat .chat-container.dark, .ffz-high-contrast-chat-text .chat-container.dark,
.ffz-high-contrast-chat .chat-container.force-dark, .ffz-high-contrast-chat-text .chat-container.force-dark,
.ffz-high-contrast-chat .ember-chat-container.dark, .ffz-high-contrast-chat-text .ember-chat-container.dark,
.ffz-high-contrast-chat .ember-chat-container.force-dark, .ffz-high-contrast-chat-text .ember-chat-container.force-dark,
.ffz-high-contrast-chat .app-main.theatre .chat-container, .ffz-high-contrast-chat-text .app-main.theatre .chat-container,
.ffz-high-contrast-chat.ffz-dark .ember-chat-container.dark .chat-line, .ffz-high-contrast-chat-text.ffz-dark .ember-chat-container.dark .chat-line,
.ffz-high-contrast-chat.ffz-dark .chat-container.dark .chat-line { .ffz-high-contrast-chat-text.ffz-dark .chat-container.dark .chat-line {
background-color: #000;
color: #fff; color: #fff;
} }
.ffz-high-contrast-chat .chat-line .mentioned { .ffz-high-contrast-chat-bg .chat-container.dark,
.ffz-high-contrast-chat-bg .chat-container.force-dark,
.ffz-high-contrast-chat-bg .ember-chat-container.dark,
.ffz-high-contrast-chat-bg .ember-chat-container.force-dark,
.ffz-high-contrast-chat-bg .app-main.theatre .chat-container,
.ffz-high-contrast-chat-bg.ffz-dark .ember-chat-container.dark .chat-line,
.ffz-high-contrast-chat-bg.ffz-dark .chat-container.dark .chat-line {
background-color: #000;
}
/*.ffz-high-contrast-chat .chat-line .mentioned {
color: #fff !important; color: #fff !important;
background-color: #000 !important; background-color: #000 !important;
} }
@ -1725,7 +1752,7 @@ li[data-name="following"] a {
.ffz-high-contrast-chat.ffz-dark .chat-container.dark .chat-line .chat-line .mentioned { .ffz-high-contrast-chat.ffz-dark .chat-container.dark .chat-line .chat-line .mentioned {
color: #000 !important; color: #000 !important;
background-color: #fff !important; background-color: #fff !important;
} }*/
.ffz-image-hover { .ffz-image-hover {
border:none; border:none;