1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-07-02 00:58: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) {
jQuery.ajax(constants.SERVER + "script/bots.txt", {cache: false, context: this})
.done(function(data) {
this._legacy_parse_badges(data, 0, 2);
this._legacy_parse_badges(data, 0, 2, "Bot (By: {})");
}).fail(function(data) {
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,
count = 0;
ds = null;
title_template = title_template || '{}';
if ( data != null ) {
var lines = data.trim().split(/\W+/);
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] || {},
badges = user.badges = user.badges || {},
sets = user.sets = user.sets || [];
@ -414,6 +417,8 @@ FFZ.prototype._legacy_parse_badges = function(data, slot, badge_id) {
continue;
badges[slot] = {id:badge_id};
if ( line_data.length > 1 )
badges[slot].title = title_template.replace('{}', line_data[1]);
count += 1;
}
}

View file

@ -45,7 +45,6 @@ FFZ.settings_info.fix_color = {
},
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'));
if ( ! this.has_bttv && val !== '-1' )
@ -115,15 +114,22 @@ FFZ.settings_info.color_blind = {
// --------------------
FFZ.prototype.setup_colors = function() {
this.log("Preparing color-alteration style element.");
this._colors = {};
this._rebuild_contrast();
var s = this._color_style = document.createElement('style');
s.id = 'ffz-style-username-colors';
s.type = 'text/css';
document.head.appendChild(s);
this._update_colors();
// Events for rebuilding colors.
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.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() {
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.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.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(); }
@ -537,38 +549,56 @@ FFZ.prototype._rebuild_contrast = function() {
}
FFZ.prototype._rebuild_colors = function() {
if ( ! this._color_style || this.has_bttv )
if ( this.has_bttv )
return;
this._color_style.innerHTML = '';
var colors = Object.keys(this._colors);
// With update colors, we'll automatically process the colors we care about.
this._colors = {};
for(var i=0, l=colors.length; i<l; i++)
this._handle_color(colors[i]);
this._update_colors();
}
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) {
if ( ! color || this._colors.hasOwnProperty(color) )
return;
return this._colors[color];
this._colors[color] = true;
var rgb = RGBColor.fromHex(color),
clr = color,
light_color = color,
dark_color = color,
matched = false,
rule = 'span[style="color:' + color + '"]';
dark_color = color;
// Color Blindness Handling
if ( this.settings.color_blind !== '0' ) {
var new_color = rgb.daltonize(this.settings.color_blind);
if ( ! rgb.eq(new_color) ) {
rgb = new_color;
clr = light_color = dark_color = rgb.toCSS();
matched = true;
light_color = dark_color = rgb.toHex();
}
}
@ -585,8 +615,7 @@ FFZ.prototype._handle_color = function(color) {
break;
}
matched = true;
light_color = nc.toCSS();
light_color = nc.toHex();
}
if ( lum < 0.15 ) {
@ -597,8 +626,7 @@ FFZ.prototype._handle_color = function(color) {
break;
}
matched = true;
dark_color = nc.toCSS();
dark_color = nc.toHex();
}
}
@ -607,25 +635,23 @@ FFZ.prototype._handle_color = function(color) {
if ( this.settings.fix_color === '2' ) {
var hsl = rgb.toHSL();
matched = true;
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)).toCSS();
light_color = hsl._l(Math.min(Math.max(0, 0.7 * hsl.l), 1)).toHex();
dark_color = hsl._l(Math.min(Math.max(0, 0.3 + (0.7 * hsl.l)), 1)).toHex();
}
// Color Processing - HSV
if ( this.settings.fix_color === '3' ) {
var hsv = rgb.toHSV();
matched = true;
if ( hsv.s === 0 ) {
// Black and White
light_color = hsv._v(Math.min(Math.max(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().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().toHex();
} 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();
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();
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)).toHex();
}
}
@ -633,33 +659,13 @@ FFZ.prototype._handle_color = function(color) {
if ( this.settings.fix_color === '1' ) {
var luv = rgb.toLUV();
if ( luv.l > this._luv_required_dark ) {
matched = true;
light_color = luv._l(this._luv_required_dark).toRGB().toCSS();
if ( luv.l > this._luv_required_dark )
light_color = luv._l(this._luv_required_dark).toRGB().toHex();
if ( luv.l < this._luv_required_bright )
dark_color = luv._l(this._luv_required_bright).toRGB().toHex();
}
if ( luv.l < this._luv_required_bright ) {
matched = true;
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;
var out = this._colors[color] = [light_color, dark_color];
return out;
}

View file

@ -231,6 +231,12 @@ FFZ.prototype._modify_cindex = function(view) {
if ( f.settings.srl_races )
f.rebuild_race_ui();
if ( f.settings.auto_theater ) {
var Layout = App.__container__.lookup('controller:layout');
if ( Layout )
Layout.set('isTheatreMode', true);
}
},
ffzFixTitle: function() {
@ -280,7 +286,10 @@ FFZ.prototype._modify_cindex = function(view) {
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 )
container.insertBefore(btn, before);
else
@ -315,7 +324,10 @@ FFZ.prototype._modify_cindex = function(view) {
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 )
container.insertBefore(btn, before);
else
@ -592,6 +604,19 @@ FFZ.prototype._modify_cindex = function(view) {
// 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 = {
type: "boolean",
value: false,

View file

@ -7,25 +7,6 @@ var FFZ = window.FrankerFaceZ,
// 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 = {
type: "boolean",
value: false,
@ -97,7 +78,7 @@ FFZ.settings_info.remove_deleted = {
if ( msg.ffz_deleted || msg.deleted ) {
if ( alternate === undefined )
alternate = msg.ffz_alternate;
msgs.removeAt(i--);
msgs.removeAt(i);
continue;
}
@ -195,10 +176,6 @@ FFZ.settings_info.visible_rooms = {
FFZ.prototype.setup_chatview = function() {
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.");
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...");
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 = {
type: "boolean",
value: true,
@ -308,8 +322,18 @@ FFZ.settings_info.chat_padding = {
FFZ.settings_info.high_contrast_chat = {
type: "boolean",
value: false,
type: "select",
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",
no_bttv: true,
@ -317,7 +341,19 @@ FFZ.settings_info.high_contrast_chat = {
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.",
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;
var parsed = parseInt(new_val);
if ( parsed === NaN || parsed < 1 )
if ( ! parsed || parsed === NaN || parsed < 1 )
parsed = 12;
this.settings.set("chat_font_size", parsed);
@ -388,7 +424,7 @@ FFZ.settings_info.chat_ts_size = {
return;
var parsed = parseInt(new_val);
if ( parsed === NaN || parsed < 1 )
if ( ! parsed || parsed === NaN || parsed < 1 )
parsed = null;
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-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-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 = {};
@ -485,7 +524,10 @@ FFZ.prototype.save_aliases = function() {
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({
@ -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);
},
@ -592,7 +644,11 @@ FFZ.prototype._modify_line = function(component) {
this_ul = this.get('ffzUserLevel'),
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 ) {
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>');
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 )
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
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 ) {
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);
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
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> ');
if ( this.get('msgObject.style') !== 'action' ) {
style = '';
colored = '';
}
if ( deleted )
e.push('<span class="deleted"><a class="undelete" href="#">&lt;message deleted&gt;</a></span>');
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));
var old_messages = this.get('msgObject.ffz_old_messages');

View file

@ -581,6 +581,8 @@ FFZ.prototype.setup_mod_card = function() {
f.save_aliases();
// Update UI
f._update_alias(user);
Ember.propertyDidChange(controller, 'userName');
var name = el.querySelector('h3.name'),
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
// ----------------

View file

@ -1030,7 +1030,7 @@ FFZ.prototype._modify_room = function(room) {
this.set('ffz_banned', false);
// 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)
else if ( this.get('slowMode') )
this.updateWait(this.get('slow'));

View file

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

View file

@ -34,6 +34,11 @@ FFZ.prototype.setup_bttv = function(delay) {
this._dark_style = undefined;
}
if ( this._layout_style ) {
this._layout_style.parentElement.removeChild(this._layout_style);
this._layout_style = undefined;
}
if ( this._chat_style ) {
utils.update_css(this._chat_style, 'chat_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-sidebar-swap");
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
if ( this.settings.following_count ) {

View file

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

View file

@ -723,7 +723,7 @@ FFZ.prototype.tokenize_emotes = function(user, room, tokens, do_report) {
_.each(emotes, function(emote) {
var eo = {
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,
ffzEmoteSet: emote.set_id,
altText: (emote.hidden ? "???" : emote.name)

View file

@ -6,12 +6,39 @@ var FFZ = window.FrankerFaceZ,
// 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 = {
name: "About",
icon: constants.HEART,
sort_order: 100000,
render: function(view, container) {
render: function(view, container, inner, menu) {
var room = this.rooms[view.get("context.currentRoom.id")],
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>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.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.
var getting_logs = false;
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.id = 'ffz-ui-following';
var before = container.querySelector(':scope > span');
var before;
try { before = container.querySelector(':scope > span'); }
catch(err) { before = undefined; }
if ( before )
container.insertBefore(cont, before);
else
@ -247,7 +250,10 @@ FFZ.prototype.rebuild_following_ui = function() {
cont = document.createElement('span');
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 )
container.insertBefore(cont, before);
else
@ -344,7 +350,7 @@ FFZ.prototype._build_following_button = function(container, channel_id) {
noti_c.appendChild(noti);
// Event Listeners!
btn.addEventListener('click', function() {
btn.addEventListener('click', function(e) {
var user = f.get_user();
if ( ! user || ! user.login )
// Show the login dialog~!
@ -367,6 +373,14 @@ FFZ.prototype._build_following_button = function(container, channel_id) {
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() {
var sw = f._build_following_popup(noti_c, channel_id, notifications);
if ( sw )

View file

@ -2,7 +2,18 @@ var FFZ = window.FrankerFaceZ,
constants = require('../constants'),
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) {
var popup = f._popup, parent;
if ( ! popup ) return;
if ( popup.id === 'ffz-chat-menu' && popup.style && popup.style.left )
return;
popup = jQuery(popup);
parent = popup.parent();
@ -164,6 +178,12 @@ FFZ.menu_pages = {};
// 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) {
var popup = this._popup;
if ( popup ) {
@ -182,11 +202,13 @@ FFZ.prototype.build_ui_popup = function(view) {
dark = (this.has_bttv ? BetterTTV.settings.get('darkenedMode') : false);
container.className = 'emoticon-selector chat-menu ffz-ui-popup';
container.id = 'ffz-chat-menu';
inner.className = 'emoticon-selector-box dropmenu';
container.appendChild(inner);
container.classList.toggle('dark', dark);
// Menu Container
var sub_container = document.createElement('div');
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>";
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 = [];
for(var key in FFZ.menu_pages) {
if ( ! FFZ.menu_pages.hasOwnProperty(key) )
@ -255,7 +286,7 @@ FFZ.prototype.build_ui_popup = function(view) {
// Add the menu to the DOM.
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);
}
@ -279,7 +310,11 @@ FFZ.prototype._ui_change_page = function(view, inner, menu, container, page) {
else
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');
var sanitize_cache = {},
sanitize_el = document.createElement('span'),
var 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) {
plural = plural || 's';
@ -206,24 +220,8 @@ module.exports = {
return "";
},
sanitize: function(msg) {
var m = sanitize_cache[msg];
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;");
},
sanitize: sanitize,
quote_attr: quote_attr,
date_string: function(date) {
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 {
-ms-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 */
.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,
.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;
}
#ffz-chat-menu { pointer-events: none; }
.ffz-ui-popup ul.menu {
list-style-type: none;
border-top: 1px solid rgba(0,0,0,0.2);
background-color: #eee;
cursor: ew-resize;
}
.ffz-ui-popup .emoticon-selector-box {
width: 10000px !important; /* Max-width has our back */
max-width: 300px;
pointer-events: auto;
}
.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 */
.ffz-high-contrast-chat .chat-container,
.ffz-high-contrast-chat .ember-chat-container {
background-color: #fff;
color: #000;
.ffz-high-contrast-chat-text .chat-container,
.ffz-high-contrast-chat-text .ember-chat-container {
color: "#000";
}
.ffz-high-contrast-chat .ember-chat .chat-messages .chat-line .from,
.ffz-high-contrast-chat .ember-chat .chat-messages .chat-line .colon,
.ffz-high-contrast-chat .ember-chat .chat-messages .chat-line .message {
.ffz-high-contrast-chat-bg .chat-container,
.ffz-high-contrast-chat-bg .ember-chat-container {
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;
}
.ffz-high-contrast-chat .chat-line:before {
/*.ffz-high-contrast-chat .chat-line:before {
background-color: transparent !important;
border: none !important;
}
}*/
.ffz-high-contrast-chat .chat-container.dark,
.ffz-high-contrast-chat .chat-container.force-dark,
.ffz-high-contrast-chat .ember-chat-container.dark,
.ffz-high-contrast-chat .ember-chat-container.force-dark,
.ffz-high-contrast-chat .app-main.theatre .chat-container,
.ffz-high-contrast-chat.ffz-dark .ember-chat-container.dark .chat-line,
.ffz-high-contrast-chat.ffz-dark .chat-container.dark .chat-line {
background-color: #000;
.ffz-high-contrast-chat-text .chat-container.dark,
.ffz-high-contrast-chat-text .chat-container.force-dark,
.ffz-high-contrast-chat-text .ember-chat-container.dark,
.ffz-high-contrast-chat-text .ember-chat-container.force-dark,
.ffz-high-contrast-chat-text .app-main.theatre .chat-container,
.ffz-high-contrast-chat-text.ffz-dark .ember-chat-container.dark .chat-line,
.ffz-high-contrast-chat-text.ffz-dark .chat-container.dark .chat-line {
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;
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 {
color: #000 !important;
background-color: #fff !important;
}
}*/
.ffz-image-hover {
border:none;