mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-03 08:28:31 +00:00
Added nice following tooltips to the sidebar. Shift-clicking emotes in the menu works now. Fixed color code bugs on non-ember. Fixed DDoS prevention nonsense.
This commit is contained in:
parent
08ad23ec02
commit
9ece18ec0f
12 changed files with 737 additions and 421 deletions
16
script.min.js
vendored
16
script.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -46,7 +46,7 @@ FFZ.settings_info.fix_color = {
|
|||
|
||||
on_update: function(val) {
|
||||
document.body.classList.toggle("ffz-chat-colors-gray", !this.has_bttv && (val === '-1'));
|
||||
|
||||
|
||||
if ( ! this.has_bttv && val !== '-1' )
|
||||
this._rebuild_colors();
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ FFZ.settings_info.luv_contrast = {
|
|||
|
||||
name: "Username Colors - Luv Minimum Contrast",
|
||||
help: "Set the minimum contrast ratio used by Luv Adjustment to ensure colors are readable.",
|
||||
|
||||
|
||||
method: function() {
|
||||
var old_val = this.settings.luv_contrast,
|
||||
new_val = prompt("Luv Adjustment Minimum Contrast Ratio\n\nPlease enter a new value for the minimum contrast ratio required between username colors and the background. The default is: 4.5", old_val);
|
||||
|
@ -73,10 +73,10 @@ FFZ.settings_info.luv_contrast = {
|
|||
var parsed = parseFloat(new_val);
|
||||
if ( parsed === NaN || parsed < 1 )
|
||||
parsed = 4.5;
|
||||
|
||||
|
||||
this.settings.set("luv_contrast", parsed);
|
||||
},
|
||||
|
||||
|
||||
on_update: function(val) {
|
||||
this._rebuild_contrast();
|
||||
|
||||
|
@ -116,19 +116,19 @@ FFZ.settings_info.color_blind = {
|
|||
FFZ.prototype.setup_colors = function() {
|
||||
this._colors = {};
|
||||
this._rebuild_contrast();
|
||||
|
||||
|
||||
this._update_colors();
|
||||
|
||||
|
||||
// Events for rebuilding colors.
|
||||
var Layout = App.__container__.lookup('controller:layout'),
|
||||
Settings = App.__container__.lookup('controller:settings');
|
||||
var Layout = window.App && App.__container__.lookup('controller:layout'),
|
||||
Settings = window.App && 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'));
|
||||
}
|
||||
|
||||
|
@ -196,13 +196,13 @@ RGBColor.fromHex = function(code) {
|
|||
|
||||
RGBColor.fromHSV = function(h, s, v) {
|
||||
var r, g, b,
|
||||
|
||||
|
||||
i = Math.floor(h * 6),
|
||||
f = h * 6 - i,
|
||||
p = v * (1 - s),
|
||||
q = v * (1 - f * s),
|
||||
t = v * (1 - (1 - f) * s);
|
||||
|
||||
|
||||
switch(i % 6) {
|
||||
case 0: r = v, g = t, b = p; break;
|
||||
case 1: r = q, g = v, b = p; break;
|
||||
|
@ -211,7 +211,7 @@ RGBColor.fromHSV = function(h, s, v) {
|
|||
case 4: r = t, g = p, b = v; break;
|
||||
case 5: r = v, g = p, b = q;
|
||||
}
|
||||
|
||||
|
||||
return new RGBColor(
|
||||
Math.round(Math.min(Math.max(0, r*255), 255)),
|
||||
Math.round(Math.min(Math.max(0, g*255), 255)),
|
||||
|
@ -240,12 +240,12 @@ RGBColor.fromHSL = function(h, s, l) {
|
|||
|
||||
var q = l < 0.5 ? l * (1 + s) : l + s - l * s,
|
||||
p = 2 * l - q;
|
||||
|
||||
|
||||
return new RGBColor(
|
||||
Math.round(Math.min(Math.max(0, 255 * hue2rgb(p, q, h + 1/3)), 255)),
|
||||
Math.round(Math.min(Math.max(0, 255 * hue2rgb(p, q, h)), 255)),
|
||||
Math.round(Math.min(Math.max(0, 255 * hue2rgb(p, q, h - 1/3)), 255))
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
RGBColor.prototype.toHSV = function() { return HSVColor.fromRGB(this.r, this.g, this.b); }
|
||||
|
@ -254,7 +254,7 @@ 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() {
|
||||
RGBColor.prototype.toHex = function() {
|
||||
var rgb = this.b | (this.g << 8) | (this.r << 16);
|
||||
return '#' + (0x1000000 + rgb).toString(16).slice(1);
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ RGBColor.prototype.luminance = function() {
|
|||
RGBColor.prototype.brighten = function(amount) {
|
||||
amount = typeof amount === "number" ? amount : 1;
|
||||
amount = Math.round(255 * (amount / 100));
|
||||
|
||||
|
||||
return new RGBColor(
|
||||
Math.max(0, Math.min(255, this.r + amount)),
|
||||
Math.max(0, Math.min(255, this.g + amount)),
|
||||
|
@ -292,10 +292,10 @@ RGBColor.prototype.daltonize = function(type, amount) {
|
|||
if ( FFZ.Color.CVDMatrix.hasOwnProperty(type) )
|
||||
cvd = FFZ.Color.CVDMatrix[type];
|
||||
else
|
||||
throw "Invalid CVD matrix.";
|
||||
throw "Invalid CVD matrix.";
|
||||
} else
|
||||
cvd = type;
|
||||
|
||||
|
||||
var cvd_a = cvd[0], cvd_b = cvd[1], cvd_c = cvd[2],
|
||||
cvd_d = cvd[3], cvd_e = cvd[4], cvd_f = cvd[5],
|
||||
cvd_g = cvd[6], cvd_h = cvd[7], cvd_i = cvd[8],
|
||||
|
@ -343,7 +343,7 @@ HSLColor.prototype.eq = function(hsl) {
|
|||
|
||||
HSLColor.fromRGB = function(r, g, b) {
|
||||
r /= 255; g /= 255; b /= 255;
|
||||
|
||||
|
||||
var max = Math.max(r,g,b),
|
||||
min = Math.min(r,g,b),
|
||||
|
||||
|
@ -389,15 +389,15 @@ HSVColor.prototype.eq = function(hsv) { return hsv.h === this.h && hsv.s === thi
|
|||
|
||||
HSVColor.fromRGB = function(r, g, b) {
|
||||
r /= 255; g /= 255; b /= 255;
|
||||
|
||||
|
||||
var max = Math.max(r, g, b),
|
||||
min = Math.min(r, g, b),
|
||||
d = Math.min(Math.max(0, max - min), 1),
|
||||
|
||||
|
||||
h,
|
||||
s = max === 0 ? 0 : d / max,
|
||||
v = max;
|
||||
|
||||
|
||||
if ( d === 0 )
|
||||
h = 0;
|
||||
else {
|
||||
|
@ -413,7 +413,7 @@ HSVColor.fromRGB = function(r, g, b) {
|
|||
}
|
||||
h /= 6;
|
||||
}
|
||||
|
||||
|
||||
return new HSVColor(h, s, v);
|
||||
}
|
||||
|
||||
|
@ -560,25 +560,25 @@ FFZ.prototype._rebuild_colors = function() {
|
|||
|
||||
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'),
|
||||
var Layout = window.App && App.__container__.lookup('controller:layout'),
|
||||
Settings = window.App && 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];
|
||||
}
|
||||
}
|
||||
|
@ -589,7 +589,7 @@ FFZ.prototype._handle_color = function(color) {
|
|||
return this._colors[color];
|
||||
|
||||
var rgb = RGBColor.fromHex(color),
|
||||
|
||||
|
||||
light_color = color,
|
||||
dark_color = color;
|
||||
|
||||
|
@ -601,20 +601,20 @@ FFZ.prototype._handle_color = function(color) {
|
|||
light_color = dark_color = rgb.toHex();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Color Processing - RGB
|
||||
if ( this.settings.fix_color === '4' ) {
|
||||
var lum = rgb.luminance();
|
||||
|
||||
|
||||
if ( lum > 0.3 ) {
|
||||
var s = 127, nc = rgb;
|
||||
while(s--) {
|
||||
nc = nc.brighten(-1);
|
||||
if ( nc.luminance() <= 0.3 )
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
light_color = nc.toHex();
|
||||
}
|
||||
|
||||
|
@ -625,25 +625,25 @@ FFZ.prototype._handle_color = function(color) {
|
|||
if ( nc.luminance() >= 0.15 )
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
dark_color = nc.toHex();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Color Processing - HSL
|
||||
if ( this.settings.fix_color === '2' ) {
|
||||
var hsl = rgb.toHSL();
|
||||
|
||||
|
||||
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();
|
||||
|
||||
|
||||
if ( hsv.s === 0 ) {
|
||||
// Black and White
|
||||
light_color = hsv._v(Math.min(Math.max(0.5, 0.5 * hsv.v), 1)).toRGB().toHex();
|
||||
|
@ -651,21 +651,21 @@ FFZ.prototype._handle_color = function(color) {
|
|||
|
||||
} 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)).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();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Color Processing - LUV
|
||||
if ( this.settings.fix_color === '1' ) {
|
||||
var luv = rgb.toLUV();
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
var out = this._colors[color] = [light_color, dark_color];
|
||||
return out;
|
||||
}
|
|
@ -59,6 +59,8 @@ module.exports = {
|
|||
CAMERA: '<svg class="svg-camera" height="16px" version="1.1" viewBox="0 0 36 36" width="16px" x="0px" y="0px"><path fill-rule="evenodd" clip-rule="evenodd" d="M24,20v6H4V10h20v6l8-6v16L24,20z"/></svg>',
|
||||
INVITE: '<svg class="svg-plus" height="16px" version="1.1" viewBox="0 0 16 16" width="16px" x="0px" y="0px"><path clip-rule="evenodd" d="M15,9h-3v3h-2V9H7V7h3V4h2v3h3V9z M9,6H6v4h2h1v3h4l0,0l0,0v1h-3H4H1v-1l3-3h2L4,8V2h6v1H9V6z" fill-rule="evenodd"></path></svg>',
|
||||
|
||||
LIVE: '<svg class="svg-glyph_live_small" height="16px" version="1.1" viewbox="0 0 16 16" width="13px" x="0px" y="0px"><path clip-rule="evenodd" d="M11,14H5H2v-1l3-3h2L5,8V2h6v6l-2,2h2l3,3v1H11z" fill-rule="evenodd"></path></svg>',
|
||||
|
||||
EYE: '<svg class="svg-glyph_views ffz-svg svg-eye" height="16px" version="1.1" viewBox="0 0 16 16" width="16px" x="0px" y="0px"><path clip-rule="evenodd" d="M11,13H5L1,9V8V7l4-4h6l4,4v1v1L11,13z M8,5C6.344,5,5,6.343,5,8c0,1.656,1.344,3,3,3c1.657,0,3-1.344,3-3C11,6.343,9.657,5,8,5z M8,9C7.447,9,7,8.552,7,8s0.447-1,1-1s1,0.448,1,1S8.553,9,8,9z" fill-rule="evenodd"></path></svg>',
|
||||
CLOCK: '<svg class="svg-glyph_views ffz-svg svg-clock" height="16px" version="1.1" viewBox="0 0 16 16" width="16px" x="0px" y="0px"><path fill-rule="evenodd" clip-rule="evenodd" fill="#888888" d="M8,15c-3.866,0-7-3.134-7-7s3.134-7,7-7s7,3.134,7,7 S11.866,15,8,15z M8,3C5.238,3,3,5.238,3,8s2.238,5,5,5s5-2.238,5-5S10.762,3,8,3z M7.293,8.707L7,8l1-4l0.902,3.607L11,11 L7.293,8.707z"/></svg>',
|
||||
GEAR: '<svg class="svg-gear" height="16px" version="1.1" viewBox="0 0 16 16" width="16px" x="0px" y="0px"><path clip-rule="evenodd" d="M15,7v2h-2.115c-0.125,0.615-0.354,1.215-0.713,1.758l1.484,1.484l-1.414,1.414l-1.484-1.484C10.215,12.531,9.615,12.76,9,12.885V15H7v-2.12c-0.614-0.126-1.21-0.356-1.751-0.714l-1.491,1.49l-1.414-1.414l1.491-1.49C3.477,10.211,3.247,9.613,3.12,9H1V7h2.116C3.24,6.384,3.469,5.785,3.829,5.242L2.343,3.757l1.414-1.414l1.485,1.485C5.785,3.469,6.384,3.24,7,3.115V1h2v2.12c0.613,0.126,1.211,0.356,1.752,0.714l1.49-1.491l1.414,1.414l-1.49,1.492C12.523,5.79,12.754,6.387,12.88,7H15z M8,6C6.896,6,6,6.896,6,8s0.896,2,2,2s2-0.896,2-2S9.104,6,8,6z" fill-rule="evenodd"></path></svg>',
|
||||
|
|
|
@ -36,7 +36,7 @@ FFZ.settings_info.line_purge_icon = {
|
|||
|
||||
name: "Purge Icon in Mod Icons",
|
||||
help: "Display a Purge Icon in chat line Mod Icons for quickly purging users.",
|
||||
|
||||
|
||||
on_update: function(val) {
|
||||
if ( this.has_bttv )
|
||||
return;
|
||||
|
@ -49,10 +49,10 @@ FFZ.settings_info.line_purge_icon = {
|
|||
FFZ.settings_info.replace_bad_emotes = {
|
||||
type: "boolean",
|
||||
value: true,
|
||||
|
||||
|
||||
category: "Chat Appearance",
|
||||
no_bttv: true,
|
||||
|
||||
|
||||
name: "Fix Low Quality Twitch Global Emoticons",
|
||||
help: "Replace emoticons such as DansGame and RedCoat with cleaned up versions that don't have pixels around the edges or white backgrounds for nicer display on dark chat."
|
||||
}
|
||||
|
@ -240,11 +240,11 @@ FFZ.settings_info.link_image_hover = {
|
|||
FFZ.settings_info.image_hover_all_domains = {
|
||||
type: "boolean",
|
||||
value: false,
|
||||
|
||||
|
||||
category: "Chat Tooltips",
|
||||
no_bttv: true,
|
||||
no_mobile: true,
|
||||
|
||||
|
||||
name: "Image Preview - All Domains",
|
||||
help: "<i>Requires Image Preview.</i> Attempt to show an image preview for any URL ending in the appropriate extension. <b>Warning: This may be used to leak your IP address to malicious users.</b>"
|
||||
};
|
||||
|
@ -288,7 +288,7 @@ FFZ.settings_info.chat_separators = {
|
|||
|
||||
category: "Chat Appearance",
|
||||
no_bttv: true,
|
||||
|
||||
|
||||
process_value: function(val) {
|
||||
if ( val === false )
|
||||
return '0';
|
||||
|
@ -305,8 +305,8 @@ FFZ.settings_info.chat_separators = {
|
|||
document.body.classList.toggle("ffz-chat-separator-3d", !this.has_bttv && val === '2');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
FFZ.settings_info.chat_padding = {
|
||||
type: "boolean",
|
||||
value: false,
|
||||
|
@ -377,7 +377,7 @@ FFZ.settings_info.chat_font_size = {
|
|||
var parsed = parseInt(new_val);
|
||||
if ( ! parsed || parsed === NaN || parsed < 1 )
|
||||
parsed = 12;
|
||||
|
||||
|
||||
this.settings.set("chat_font_size", parsed);
|
||||
},
|
||||
|
||||
|
@ -414,10 +414,10 @@ FFZ.settings_info.chat_ts_size = {
|
|||
|
||||
method: function() {
|
||||
var old_val = this.settings.chat_ts_size;
|
||||
|
||||
|
||||
if ( ! old_val )
|
||||
old_val = this.settings.chat_font_size;
|
||||
|
||||
|
||||
var new_val = prompt("Chat Timestamp Font Size\n\nPlease enter a new size for the chat timestamp font. The default is to match the regular chat font size.", old_val);
|
||||
|
||||
if ( new_val === null || new_val === undefined )
|
||||
|
@ -426,7 +426,7 @@ FFZ.settings_info.chat_ts_size = {
|
|||
var parsed = parseInt(new_val);
|
||||
if ( ! parsed || parsed === NaN || parsed < 1 )
|
||||
parsed = null;
|
||||
|
||||
|
||||
this.settings.set("chat_ts_size", parsed);
|
||||
},
|
||||
|
||||
|
@ -456,7 +456,7 @@ FFZ.prototype.setup_line = function() {
|
|||
jQuery(document.body).on("mouseleave", ".tipsy", function() {
|
||||
this.parentElement.removeChild(this);
|
||||
});
|
||||
|
||||
|
||||
// Aliases
|
||||
try {
|
||||
this.aliases = JSON.parse(localStorage.ffz_aliases || '{}');
|
||||
|
@ -464,29 +464,29 @@ FFZ.prototype.setup_line = function() {
|
|||
this.log("Error Loading Aliases: " + err);
|
||||
this.aliases = {};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Chat Style
|
||||
var s = this._chat_style = document.createElement('style');
|
||||
s.id = "ffz-style-chat";
|
||||
s.type = 'text/css';
|
||||
document.head.appendChild(s);
|
||||
|
||||
document.head.appendChild(s);
|
||||
|
||||
// Initial calculation.
|
||||
FFZ.settings_info.chat_font_size.on_update.bind(this)(this.settings.chat_font_size);
|
||||
|
||||
|
||||
|
||||
// Chat Enhancements
|
||||
document.body.classList.toggle("ffz-chat-colors", !this.has_bttv && this.settings.fix_color !== '-1');
|
||||
document.body.classList.toggle("ffz-chat-colors-gray", !this.has_bttv && this.settings.fix_color === '-1');
|
||||
|
||||
|
||||
document.body.classList.toggle("ffz-legacy-badges", this.settings.legacy_badges);
|
||||
document.body.classList.toggle('ffz-chat-background', !this.has_bttv && this.settings.chat_rows);
|
||||
document.body.classList.toggle("ffz-chat-separator", !this.has_bttv && this.settings.chat_separators !== '0');
|
||||
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-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');
|
||||
|
@ -521,7 +521,7 @@ FFZ.prototype.save_aliases = function() {
|
|||
|
||||
FFZ.prototype._modify_line = function(component) {
|
||||
var f = this,
|
||||
|
||||
|
||||
Layout = App.__container__.lookup('controller:layout'),
|
||||
Settings = App.__container__.lookup('controller:settings');
|
||||
|
||||
|
@ -573,22 +573,22 @@ FFZ.prototype._modify_line = function(component) {
|
|||
ffzUpdated: Ember.observer("msgObject.ffz_deleted", "msgObject.ffz_old_messages", function() {
|
||||
this.rerender();
|
||||
}),
|
||||
|
||||
|
||||
click: function(e) {
|
||||
if ( e.target && e.target.classList.contains('ffz-old-messages') )
|
||||
return f._show_deleted(this.get('msgObject.room'));
|
||||
|
||||
|
||||
if ( e.target && e.target.classList.contains('deleted-link') )
|
||||
return f._deleted_link_click.bind(e.target)(e);
|
||||
|
||||
|
||||
if ( e.target && e.target.classList.contains('mod-icon') ) {
|
||||
jQuery(e.target).trigger('mouseout');
|
||||
|
||||
|
||||
if ( e.target.classList.contains('purge') ) {
|
||||
var i = this.get('msgObject.from'),
|
||||
room_id = this.get('msgObject.room'),
|
||||
room = room_id && f.rooms[room_id] && f.rooms[room_id].room;
|
||||
|
||||
|
||||
if ( room ) {
|
||||
room.send("/timeout " + i + " 1");
|
||||
room.clearMessages(i);
|
||||
|
@ -596,7 +596,7 @@ FFZ.prototype._modify_line = function(component) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 )
|
||||
|
@ -606,10 +606,10 @@ FFZ.prototype._modify_line = function(component) {
|
|||
window.open("https://www.frankerfacez.com/emoticons/" + eid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return this._super(e);
|
||||
},
|
||||
|
||||
|
||||
ffzUserLevel: function() {
|
||||
if ( this.get('isStaff') )
|
||||
return 5;
|
||||
|
@ -623,27 +623,27 @@ FFZ.prototype._modify_line = function(component) {
|
|||
return 1;
|
||||
return 0;
|
||||
}.property('msgObject.labels.[]'),
|
||||
|
||||
|
||||
render: function(e) {
|
||||
var deleted = this.get('msgObject.deleted'),
|
||||
r = this,
|
||||
|
||||
|
||||
badges = {},
|
||||
|
||||
|
||||
user = this.get('msgObject.from'),
|
||||
room_id = this.get('msgObject.room'),
|
||||
room = f.rooms && f.rooms[room_id],
|
||||
|
||||
|
||||
recipient = this.get('msgObject.to'),
|
||||
is_whisper = recipient && recipient.length,
|
||||
|
||||
|
||||
this_ul = this.get('ffzUserLevel'),
|
||||
other_ul = room && room.room && room.room.get('ffzUserLevel') || 0,
|
||||
|
||||
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 ) {
|
||||
|
@ -653,19 +653,19 @@ FFZ.prototype._modify_line = function(component) {
|
|||
|
||||
e.push('<div class="indicator"></div>');
|
||||
e.push('<span class="timestamp float-left">' + this.get("timestamp") + '</span> ');
|
||||
|
||||
|
||||
if ( ! is_whisper && this_ul < other_ul ) {
|
||||
e.push('<span class="mod-icons float-left">');
|
||||
if ( deleted )
|
||||
e.push('<a class="mod-icon float-left tooltip unban" title="Unban User" href="#">Unban</a>');
|
||||
else
|
||||
e.push('<a class="mod-icon float-left tooltip ban" title="Ban User" href="#">Ban</a>');
|
||||
|
||||
|
||||
e.push('<a class="mod-icon float-left tooltip timeout" title="Timeout User (10m)" href="#">Timeout</a>');
|
||||
e.push('<a class="mod-icon float-left tooltip purge" title="Purge User (Timeout 1s)" href="#">Purge</a>');
|
||||
e.push('</span>');
|
||||
}
|
||||
|
||||
|
||||
// Stock Badges
|
||||
if ( ! is_whisper && this.get('isBroadcaster') )
|
||||
badges[0] = {klass: 'broadcaster', title: 'Broadcaster'};
|
||||
|
@ -677,7 +677,7 @@ FFZ.prototype._modify_line = function(component) {
|
|||
badges[0] = {klass: 'global-moderator', title: 'Global Moderator'};
|
||||
else if ( ! is_whisper && this.get('isModerator') )
|
||||
badges[0] = {klass: 'moderator', title: 'Moderator'};
|
||||
|
||||
|
||||
if ( ! is_whisper && this.get('isSubscriber') )
|
||||
badges[10] = {klass: 'subscriber', title: 'Subscriber'};
|
||||
if ( this.get('hasTurbo') )
|
||||
|
@ -692,10 +692,10 @@ FFZ.prototype._modify_line = function(component) {
|
|||
for(var key in badges) {
|
||||
var badge = badges[key],
|
||||
css = badge.image ? 'background-image:url("' + badge.image + '");' : '';
|
||||
|
||||
|
||||
if ( badge.color )
|
||||
css += 'background-color:' + badge.color + ';';
|
||||
|
||||
|
||||
if ( badge.extra_css )
|
||||
css += badge.extra_css;
|
||||
|
||||
|
@ -703,11 +703,11 @@ 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",
|
||||
style = colors && 'color:' + (is_dark ? colors[1] : colors[0]),
|
||||
colored = style ? ' has-color' : '';
|
||||
colored = style ? ' has-color' : '';
|
||||
|
||||
if ( alias )
|
||||
e.push('<span class="from ffz-alias tooltip' + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '') + '" title="' + utils.sanitize(name) + '">' + utils.sanitize(alias) + '</span>');
|
||||
|
@ -717,14 +717,14 @@ FFZ.prototype._modify_line = function(component) {
|
|||
if ( is_whisper ) {
|
||||
var to_alias = f.aliases[recipient],
|
||||
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 ? to_colors[1] : to_colors[0]),
|
||||
to_colored = to_style ? ' has-color' : '';
|
||||
|
||||
|
||||
this._renderWhisperArrow(e);
|
||||
|
||||
|
||||
if ( to_alias )
|
||||
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
|
||||
|
@ -732,26 +732,26 @@ FFZ.prototype._modify_line = function(component) {
|
|||
}
|
||||
|
||||
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="#"><message deleted></a></span>');
|
||||
else {
|
||||
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');
|
||||
if ( old_messages && old_messages.length )
|
||||
e.push('<div class="button primary float-right ffz-old-messages">Show ' + utils.number_commas(old_messages.length) + ' Old</div>');
|
||||
|
||||
|
||||
e.push('</span>');
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
classNameBindings: [
|
||||
'msgObject.ffz_alternate:ffz-alternate',
|
||||
'msgObject.ffz_has_mention:ffz-mentioned',
|
||||
|
@ -759,12 +759,12 @@ FFZ.prototype._modify_line = function(component) {
|
|||
'ffzHasOldMessages:clearfix',
|
||||
'ffzHasOldMessages:ffz-has-deleted'
|
||||
],
|
||||
|
||||
|
||||
|
||||
ffzWasDeleted: function() {
|
||||
return f.settings.prevent_clear && this.get('msgObject.ffz_deleted');
|
||||
}.property('msgObject.ffz_deleted'),
|
||||
|
||||
|
||||
ffzHasOldMessages: function() {
|
||||
var old_messages = this.get('msgObject.ffz_old_messages');
|
||||
return old_messages && old_messages.length;
|
||||
|
@ -773,7 +773,7 @@ FFZ.prototype._modify_line = function(component) {
|
|||
|
||||
didInsertElement: function() {
|
||||
this._super();
|
||||
|
||||
|
||||
var el = this.get('element');
|
||||
|
||||
el.setAttribute('data-room', this.get('msgObject.room'));
|
||||
|
|
|
@ -49,22 +49,8 @@ FFZ.prototype._emote_menu_enumerator = function() {
|
|||
if ( emote.hidden )
|
||||
continue;
|
||||
|
||||
// TODO: Stop having to calculate this here.
|
||||
var title = set.title, badge = set.icon || null;
|
||||
if ( ! title ) {
|
||||
if ( set.id === "global" )
|
||||
title = "FrankerFaceZ Global Emotes";
|
||||
|
||||
else if ( set.id == "globalevent" )
|
||||
title = "FrankerFaceZ Event Emotes";
|
||||
|
||||
else if ( this.feature_friday && set.id == this.feature_friday.set )
|
||||
title = "FrankerFaceZ " + this.feature_friday.title + ": " + this.feature_friday.display_name;
|
||||
|
||||
else
|
||||
title = "FrankerFaceZ Set: " + FFZ.get_capitalization(set.id);
|
||||
} else
|
||||
title = "FrankerFaceZ: " + title;
|
||||
var title = "FrankerFaceZ " + set.title,
|
||||
badge = set.icon || '//cdn.frankerfacez.com/script/devicon.png';
|
||||
|
||||
emotes.push({text: emote.name, url: emote.urls[1],
|
||||
hidden: false, channel: title, badge: badge});
|
||||
|
|
|
@ -21,7 +21,7 @@ FFZ.get = function() { return FFZ.instance; }
|
|||
|
||||
// Version
|
||||
var VER = FFZ.version_info = {
|
||||
major: 3, minor: 5, revision: 8,
|
||||
major: 3, minor: 5, revision: 10,
|
||||
toString: function() {
|
||||
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ FFZ.prototype.initialize = function(increment, delay) {
|
|||
this.init_normal(delay);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ( location.hostname === 'passport' && /^\/(?:authorize)/.test(location.pathname) ) {
|
||||
this.log("Running on passport!");
|
||||
this.init_normal(delay, true);
|
||||
|
|
|
@ -2,6 +2,7 @@ var FFZ = window.FrankerFaceZ;
|
|||
|
||||
FFZ.prototype._ws_open = false;
|
||||
FFZ.prototype._ws_delay = 0;
|
||||
FFZ.prototype._ws_last_iframe = 0;
|
||||
|
||||
FFZ.ws_commands = {};
|
||||
FFZ.ws_on_close = [];
|
||||
|
@ -11,6 +12,22 @@ FFZ.ws_on_close = [];
|
|||
// Socket Creation
|
||||
// ----------------
|
||||
|
||||
FFZ.prototype.ws_iframe = function() {
|
||||
this._ws_last_iframe = Date.now();
|
||||
var ifr = document.createElement('iframe'),
|
||||
f = this;
|
||||
|
||||
ifr.src = 'http://catbag.frankerfacez.com';
|
||||
ifr.style.visibility = 'hidden';
|
||||
document.body.appendChild(ifr);
|
||||
setTimeout(function() {
|
||||
document.body.removeChild(ifr);
|
||||
if ( ! f._ws_open )
|
||||
f.ws_create();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
|
||||
FFZ.prototype.ws_create = function() {
|
||||
var f = this, ws;
|
||||
|
||||
|
@ -30,6 +47,7 @@ FFZ.prototype.ws_create = function() {
|
|||
ws.onopen = function(e) {
|
||||
f._ws_open = true;
|
||||
f._ws_delay = 0;
|
||||
f._ws_last_iframe = Date.now();
|
||||
f.log("Socket connected.");
|
||||
|
||||
// Check for incognito. We don't want to do a hello in incognito mode.
|
||||
|
@ -106,6 +124,12 @@ FFZ.prototype.ws_create = function() {
|
|||
}
|
||||
}
|
||||
|
||||
if ( f._ws_delay > 10000 ) {
|
||||
var ua = navigator.userAgent.toLowerCase();
|
||||
if ( Date.now() - f._ws_last_iframe > 1800000 && !(ua.indexOf('chrome') === -1 && ua.indexOf('safari') !== -1) )
|
||||
return f.ws_iframe();
|
||||
}
|
||||
|
||||
// We never ever want to not have a socket.
|
||||
if ( f._ws_delay < 60000 )
|
||||
f._ws_delay += (Math.floor(Math.random()*10) + 5) * 1000;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
var FFZ = window.FrankerFaceZ,
|
||||
utils = require('../utils');
|
||||
utils = require('../utils'),
|
||||
constants = require('../constants');
|
||||
|
||||
|
||||
|
||||
|
@ -16,7 +17,7 @@ FFZ.settings_info.following_count = {
|
|||
|
||||
on_update: function(val) {
|
||||
this._schedule_following_count();
|
||||
|
||||
|
||||
var Stream = window.App && App.__container__.resolve('model:stream'),
|
||||
Live = Stream && Stream.find("live");
|
||||
|
||||
|
@ -35,7 +36,7 @@ FFZ.prototype.setup_following_count = function(has_ember) {
|
|||
// Start it updating.
|
||||
if ( this.settings.following_count )
|
||||
this._schedule_following_count();
|
||||
|
||||
|
||||
// If we don't have Ember, no point in trying this stuff.
|
||||
if ( ! has_ember )
|
||||
return this._update_following_count();
|
||||
|
@ -52,11 +53,17 @@ FFZ.prototype.setup_following_count = function(has_ember) {
|
|||
return this.log("Unable to find Live Streams collection.");
|
||||
|
||||
Live.addObserver('total', function() { f._draw_following_count(this.get('total')); });
|
||||
Live.addObserver('content.length', function() { f._draw_following_channels(this.get('content'), this.get('total')); })
|
||||
|
||||
Live.load();
|
||||
|
||||
var total = Live.get('total');
|
||||
if ( typeof total === "number" )
|
||||
|
||||
var total = Live.get('total'),
|
||||
streams = Live.get('content');
|
||||
if ( typeof total === "number" ) {
|
||||
this._draw_following_count(total);
|
||||
if ( streams && streams.length )
|
||||
this._draw_following_channels(streams, total);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -84,7 +91,7 @@ FFZ.prototype._update_following_count = function() {
|
|||
}
|
||||
|
||||
this._following_count_timer = setTimeout(this._update_following_count.bind(this), 55000 + (10000*Math.random()));
|
||||
|
||||
|
||||
var Stream = window.App && App.__container__.resolve('model:stream'),
|
||||
Live = Stream && Stream.find("live"),
|
||||
f = this;
|
||||
|
@ -92,15 +99,84 @@ FFZ.prototype._update_following_count = function() {
|
|||
if ( Live )
|
||||
Live.load();
|
||||
else
|
||||
Twitch.api && Twitch.api.get("streams/followed", {limit:1, offset:0}, {version:3})
|
||||
Twitch.api && Twitch.api.get("streams/followed", {limit:5, offset:0}, {version:3})
|
||||
.done(function(data) {
|
||||
f._draw_following_count(data._total);
|
||||
f._draw_following_channels(data.streams, data._total);
|
||||
}).fail(function() {
|
||||
f._draw_following_count();
|
||||
f._draw_following_channels();
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
FFZ.prototype._draw_following_channels = function(streams, total) {
|
||||
// First, build the data.
|
||||
var tooltip = 'Following';
|
||||
|
||||
if ( streams && streams.length ) {
|
||||
var c = 0;
|
||||
for(var i=0, l = streams.length; i < l; i++) {
|
||||
var stream = streams[i];
|
||||
if ( ! stream || ! stream.channel )
|
||||
continue;
|
||||
|
||||
c += 1;
|
||||
if ( c > 5 ) {
|
||||
var ttl = total || streams.length;
|
||||
tooltip += '<hr><span>And ' + utils.number_commas(ttl - 5) + ' more...</span>';
|
||||
break;
|
||||
}
|
||||
|
||||
tooltip += (i > 0 ? '<br>' : '<hr>') + '<span class="viewers">' + constants.LIVE + ' ' + utils.number_commas(stream.viewers) + '</span><b>' + utils.sanitize(stream.channel.display_name || stream.channel.name) + '</b><br><span class="playing">' + (stream.channel.game ? 'Playing ' + utils.sanitize(stream.channel.game) : 'Not Playing') + '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Small
|
||||
var small_following = jQuery('#small_nav ul.game_filters li[data-name="following"] a');
|
||||
if ( small_following && small_following.length ) {
|
||||
var data = small_following.data('tipsy');
|
||||
if ( data && data.options ) {
|
||||
data.options.gravity = function() { return this.parentElement.getAttribute('data-name') === 'following' ? 'nw': 'w'; };
|
||||
data.options.html = true;
|
||||
data.options.className = 'ffz-wide-tip';
|
||||
} else
|
||||
small_following.tipsy({html: true, className: 'ffz-wide-tip', gravity: 'nw'});
|
||||
|
||||
small_following.attr('title', tooltip);
|
||||
}
|
||||
|
||||
|
||||
// Large
|
||||
var large_following = jQuery('#large_nav #nav_personal li[data-name="following"] a');
|
||||
if ( large_following && large_following.length ) {
|
||||
var data = large_following.data('tipsy');
|
||||
if ( data && data.options ) {
|
||||
data.options.html = true;
|
||||
data.options.className = 'ffz-wide-tip';
|
||||
} else
|
||||
large_following.tipsy({html:true, className: 'ffz-wide-tip'});
|
||||
|
||||
large_following.attr('title', tooltip);
|
||||
}
|
||||
|
||||
|
||||
// Heading
|
||||
var head_following = jQuery('#header_actions #header_following');
|
||||
if ( head_following && head_following.length ) {
|
||||
var data = head_following.data('tipsy');
|
||||
if ( data && data.options ) {
|
||||
data.options.html = true;
|
||||
data.options.className = 'ffz-wide-tip';
|
||||
} else
|
||||
head_following.tipsy({html: true, className: 'ffz-wide-tip'});
|
||||
|
||||
head_following.attr('title', tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FFZ.prototype._draw_following_count = function(count) {
|
||||
// Small
|
||||
var small_following = document.querySelector('#small_nav ul.game_filters li[data-name="following"] a');
|
||||
|
@ -118,8 +194,8 @@ FFZ.prototype._draw_following_count = function(count) {
|
|||
badge.innerHTML = count ? utils.format_unread(count) : '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Large
|
||||
var large_following = document.querySelector('#large_nav #nav_personal li[data-name="following"] a');
|
||||
if ( large_following ) {
|
||||
|
@ -136,7 +212,7 @@ FFZ.prototype._draw_following_count = function(count) {
|
|||
badge.innerHTML = count ? utils.format_unread(count) : '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Heading
|
||||
var head_following = document.querySelector('#header_actions #header_following');
|
||||
if ( head_following ) {
|
||||
|
|
|
@ -3,16 +3,32 @@ var FFZ = window.FrankerFaceZ,
|
|||
utils = require('../utils'),
|
||||
|
||||
TWITCH_BASE = "http://static-cdn.jtvnw.net/emoticons/v1/",
|
||||
|
||||
|
||||
fix_menu_position = function(container) {
|
||||
var swapped = document.body.classList.contains('ffz-sidebar-swap');
|
||||
|
||||
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';
|
||||
right = bounds.left + container.scrollWidth,
|
||||
moved = !!container.style.left;
|
||||
|
||||
if ( swapped ) {
|
||||
if ( bounds.left < 20 ) {
|
||||
container.style.left = '';
|
||||
moved = false;
|
||||
} else if ( right > document.body.clientWidth )
|
||||
container.style.left = (left - (right - document.body.clientWidth)) + 'px';
|
||||
|
||||
} else {
|
||||
if ( bounds.left < 0 )
|
||||
container.style.left = (left - bounds.left) + 'px';
|
||||
else if ( right > (document.body.clientWidth - 20) ) {
|
||||
container.style.left = '';
|
||||
moved = false;
|
||||
}
|
||||
}
|
||||
|
||||
container.classList.toggle('ui-moved', moved);
|
||||
};
|
||||
|
||||
|
||||
|
@ -29,7 +45,7 @@ FFZ.prototype.setup_menu = function() {
|
|||
if ( ! popup ) return;
|
||||
if ( popup.id === 'ffz-chat-menu' && popup.style && popup.style.left )
|
||||
return;
|
||||
|
||||
|
||||
popup = jQuery(popup);
|
||||
parent = popup.parent();
|
||||
|
||||
|
@ -221,7 +237,31 @@ FFZ.prototype.build_ui_popup = function(view) {
|
|||
|
||||
var heading = document.createElement('li');
|
||||
heading.className = 'title';
|
||||
heading.innerHTML = "<span>" + (constants.DEBUG ? "[DEV] " : "") + "FrankerFaceZ</span>";
|
||||
heading.innerHTML = '<span class="title">Franker' + (constants.DEBUG ? 'Dev' : 'Face') + 'Z</span>';
|
||||
|
||||
// Close Button
|
||||
var close_btn = document.createElement('span'),
|
||||
f = this;
|
||||
|
||||
close_btn.className = 'ffz-handle ffz-close-button';
|
||||
heading.insertBefore(close_btn, heading.firstChild);
|
||||
|
||||
var can_close = false;
|
||||
close_btn.addEventListener('mousedown', function() {
|
||||
var popup = f._popup;
|
||||
can_close = popup && popup.id === "ffz-chat-menu" && popup.style.left;
|
||||
});
|
||||
|
||||
close_btn.addEventListener('click', function() {
|
||||
var popup = f._popup;
|
||||
if ( can_close && popup ) {
|
||||
popup.parentElement.removeChild(popup);
|
||||
delete f._popup;
|
||||
f._popup_kill && f._popup_kill();
|
||||
delete f._popup_kill;
|
||||
}
|
||||
});
|
||||
|
||||
menu.appendChild(heading);
|
||||
|
||||
// Draggable
|
||||
|
@ -312,7 +352,7 @@ FFZ.prototype._ui_change_page = function(view, inner, menu, container, page) {
|
|||
this.log("No matching page: " + page);
|
||||
|
||||
FFZ.menu_pages[page].render.bind(this)(view, container, inner, menu);
|
||||
|
||||
|
||||
// Re-position if necessary.
|
||||
var f = this;
|
||||
setTimeout(function(){f._fix_menu_position();});
|
||||
|
@ -328,7 +368,8 @@ FFZ.menu_pages.channel = {
|
|||
// Get the current room.
|
||||
var room_id = view.get('controller.currentRoom.id'),
|
||||
room = this.rooms[room_id],
|
||||
has_product = false;
|
||||
has_product = false,
|
||||
f = this;
|
||||
|
||||
// Check for a product.
|
||||
if ( this.settings.replace_twitch_menu ) {
|
||||
|
@ -351,7 +392,6 @@ FFZ.menu_pages.channel = {
|
|||
// See if we've loaded. If we haven't loaded the ticket yet
|
||||
// then try loading it, and then re-render the menu.
|
||||
if ( tickets && ! is_subscribed && ! is_loaded ) {
|
||||
var f = this;
|
||||
tickets.addObserver('isLoaded', function() {
|
||||
setTimeout(function(){
|
||||
if ( inner.getAttribute('data-page') !== 'channel' )
|
||||
|
@ -360,7 +400,7 @@ FFZ.menu_pages.channel = {
|
|||
inner.innerHTML = '';
|
||||
FFZ.menu_pages.channel.render.bind(f)(view, inner);
|
||||
},0);
|
||||
|
||||
|
||||
});
|
||||
|
||||
tickets.load();
|
||||
|
@ -395,8 +435,17 @@ FFZ.menu_pages.channel = {
|
|||
s.style.width = emote.width + "px";
|
||||
s.style.height = emote.height + "px";
|
||||
s.title = emote.regex;
|
||||
if ( can_use )
|
||||
s.addEventListener('click', this._add_emote.bind(this, view, emote.regex));
|
||||
|
||||
s.addEventListener('click', function(can_use, id, code, e) {
|
||||
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons )
|
||||
window.open("https://twitchemotes.com/emote/" + id);
|
||||
else if ( can_use )
|
||||
this._add_emote(view, code);
|
||||
else
|
||||
return;
|
||||
e.preventDefault();
|
||||
}.bind(this, can_use, emote.id, emote.regex));
|
||||
|
||||
grid.appendChild(s);
|
||||
c++;
|
||||
}
|
||||
|
@ -475,7 +524,7 @@ FFZ.menu_pages.channel = {
|
|||
// --------------------
|
||||
|
||||
FFZ.prototype._emotes_for_sets = function(parent, view, sets, header, image, sub_text) {
|
||||
var grid = document.createElement('div'), c = 0;
|
||||
var grid = document.createElement('div'), c = 0, f = this;
|
||||
grid.className = 'emoticon-grid';
|
||||
|
||||
if ( header != null ) {
|
||||
|
@ -549,7 +598,14 @@ FFZ.prototype._emotes_for_sets = function(parent, view, sets, header, image, sub
|
|||
s.style.height = emote.height + "px";
|
||||
s.title = this._emote_tooltip(emote);
|
||||
|
||||
s.addEventListener('click', this._add_emote.bind(this, view, emote.name));
|
||||
s.addEventListener('click', function(id, code, e) {
|
||||
e.preventDefault();
|
||||
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons )
|
||||
window.open("https://www.frankerfacez.com/emoticons/" + id);
|
||||
else
|
||||
this._add_emote(view, code);
|
||||
}.bind(this, emote.id, emote.name));
|
||||
|
||||
grid.appendChild(s);
|
||||
}
|
||||
|
||||
|
|
|
@ -79,53 +79,10 @@ FFZ.menu_pages.myemotes = {
|
|||
|
||||
render: function(view, container) {
|
||||
var tmi = view.get('controller.currentRoom.tmiSession'),
|
||||
twitch_sets = (tmi && tmi.getEmotes() || {'emoticon_sets': {}})['emoticon_sets'],
|
||||
needed_sets = [];
|
||||
twitch_sets = (tmi && tmi.getEmotes() || {'emoticon_sets': {}})['emoticon_sets'];
|
||||
|
||||
for(var set_id in twitch_sets)
|
||||
if ( twitch_sets.hasOwnProperty(set_id) && ! this._twitch_set_to_channel.hasOwnProperty(set_id) )
|
||||
needed_sets.push(set_id);
|
||||
|
||||
if ( ! needed_sets.length )
|
||||
return FFZ.menu_pages.myemotes.draw_menu.bind(this)(view, container, twitch_sets);
|
||||
|
||||
var f = this,
|
||||
fail = function() {
|
||||
if ( ! needed_sets.length )
|
||||
return;
|
||||
|
||||
needed_sets = [];
|
||||
var ts = {};
|
||||
for(var set_id in twitch_sets)
|
||||
if ( f._twitch_set_to_channel[set_id] )
|
||||
ts[set_id] = twitch_sets[set_id];
|
||||
else
|
||||
ts[set_id] = []; //"twitch_unknown";
|
||||
|
||||
return FFZ.menu_pages.myemotes.draw_menu.bind(f)(view, container, ts);
|
||||
};
|
||||
|
||||
if ( ! this.ws_send("twitch_sets", needed_sets, function(success, data) {
|
||||
if ( ! needed_sets.length )
|
||||
return;
|
||||
|
||||
needed_sets = [];
|
||||
if ( success ) {
|
||||
for(var set_id in data) {
|
||||
if ( ! data.hasOwnProperty(set_id) )
|
||||
continue;
|
||||
|
||||
f._twitch_set_to_channel[set_id] = data[set_id];
|
||||
}
|
||||
|
||||
localStorage.ffzTwitchSets = JSON.stringify(f._twitch_set_to_channel);
|
||||
return FFZ.menu_pages.my_emotes.draw_menu.bind(f)(view, container, twitch_sets);
|
||||
} else
|
||||
fail();
|
||||
}) )
|
||||
fail()
|
||||
else
|
||||
setTimeout(fail, 2000);
|
||||
// We don't have to do async stuff anymore cause we pre-load data~!
|
||||
return FFZ.menu_pages.myemotes.draw_menu.bind(this)(view, container, twitch_sets);
|
||||
},
|
||||
|
||||
toggle_section: function(heading) {
|
||||
|
@ -154,15 +111,15 @@ FFZ.menu_pages.myemotes = {
|
|||
|
||||
menu.className = 'emoticon-grid collapsable';
|
||||
menu.appendChild(heading);
|
||||
|
||||
|
||||
menu.setAttribute('data-set', 'emoji');
|
||||
menu.classList.toggle('collapsed', this.settings.emote_menu_collapsed.indexOf('emoji') !== -1);
|
||||
heading.addEventListener('click', function() { FFZ.menu_pages.myemotes.toggle_section.bind(f)(this); });
|
||||
|
||||
|
||||
var set = [];
|
||||
for(var eid in this.emoji_data)
|
||||
set.push(this.emoji_data[eid]);
|
||||
|
||||
|
||||
set.sort(function(a,b) {
|
||||
var an = a.short_name.toLowerCase(),
|
||||
bn = b.short_name.toLowerCase();
|
||||
|
@ -173,7 +130,7 @@ FFZ.menu_pages.myemotes = {
|
|||
if ( a.raw > b.raw ) return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
|
||||
for(var i=0; i < set.length; i++) {
|
||||
var emoji = set[i],
|
||||
em = document.createElement('span'),
|
||||
|
@ -182,13 +139,13 @@ FFZ.menu_pages.myemotes = {
|
|||
em.className = 'emoticon tooltip';
|
||||
em.title = 'Emoji: ' + emoji.raw + '\nName: :' + emoji.short_name + ':';
|
||||
em.addEventListener('click', this._add_emote.bind(this, view, emoji.raw));
|
||||
|
||||
|
||||
em.style.backgroundImage = 'url("' + emoji.src + '")';
|
||||
em.style.backgroundImage = '-webkit-' + img_set;
|
||||
em.style.backgroundImage = '-moz-' + img_set;
|
||||
em.style.backgroundImage = '-ms-' + img_set;
|
||||
em.style.backgroudnImage = img_set;
|
||||
|
||||
|
||||
menu.appendChild(em);
|
||||
}
|
||||
|
||||
|
@ -268,7 +225,13 @@ FFZ.menu_pages.myemotes = {
|
|||
}
|
||||
|
||||
em.title = code;
|
||||
em.addEventListener("click", this._add_emote.bind(this, view, code));
|
||||
em.addEventListener("click", function(id, code, e) {
|
||||
e.preventDefault();
|
||||
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons )
|
||||
window.open("https://twitchemotes.com/emote/" + id);
|
||||
else
|
||||
this._add_emote(view, code);
|
||||
}.bind(this, emote.id, emote.code));
|
||||
menu.appendChild(em);
|
||||
}
|
||||
|
||||
|
@ -287,7 +250,7 @@ FFZ.menu_pages.myemotes = {
|
|||
|
||||
menu.className = 'emoticon-grid collapsable';
|
||||
menu.appendChild(heading);
|
||||
|
||||
|
||||
menu.setAttribute('data-set', 'ffz-' + set.id);
|
||||
menu.classList.toggle('collapsed', this.settings.emote_menu_collapsed.indexOf('ffz-' + set.id) !== -1);
|
||||
heading.addEventListener('click', function() { FFZ.menu_pages.myemotes.toggle_section.bind(f)(this); });
|
||||
|
@ -333,7 +296,13 @@ FFZ.menu_pages.myemotes = {
|
|||
em.style.width = emote.width + "px";
|
||||
|
||||
em.title = this._emote_tooltip(emote);
|
||||
em.addEventListener("click", this._add_emote.bind(this, view, emote.name));
|
||||
em.addEventListener("click", function(id, code, e) {
|
||||
e.preventDefault();
|
||||
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons )
|
||||
window.open("https://www.frankerfacez.com/emoticons/" + id);
|
||||
else
|
||||
this._add_emote(view, code);
|
||||
}.bind(this, emote.id, emote.name));
|
||||
menu.appendChild(em);
|
||||
}
|
||||
|
||||
|
|
106
style.css
106
style.css
|
@ -579,12 +579,85 @@ body:not(.ffz-minimal-chat):not(.ffz-menu-replace) .emoticon-selector-toggle + s
|
|||
float: left;
|
||||
}
|
||||
|
||||
.ffz-ui-popup ul.menu li.title > span {
|
||||
display: block;
|
||||
padding: 10px 20px;
|
||||
line-height: 16px;
|
||||
span.ffz-handle {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
height: 26px;
|
||||
width: 14px;
|
||||
transition: width 500ms;
|
||||
}
|
||||
|
||||
span.ffz-handle:before,
|
||||
span.ffz-handle:after {
|
||||
position: absolute;
|
||||
left: 4px;
|
||||
top: 5px;
|
||||
content: "";
|
||||
height: 14px;
|
||||
border: 1px solid #bbb;
|
||||
border-radius: 4px;
|
||||
transition: transform 500ms, left 500ms, border-color 500ms, border-width 500ms, height 500ms;
|
||||
}
|
||||
|
||||
span.ffz-handle:after { left: 8px }
|
||||
|
||||
.ffz-ui-popup.ui-moved span.ffz-handle { width: 24px; cursor: pointer; }
|
||||
|
||||
.ffz-ui-popup.ui-moved span.ffz-handle:before,
|
||||
.ffz-ui-popup.ui-moved span.ffz-handle:after {
|
||||
left: 11px;
|
||||
border-color: #333;
|
||||
}
|
||||
|
||||
.ffz-ui-popup.ui-moved span.ffz-handle:before { transform: rotate(45deg); }
|
||||
.ffz-ui-popup.ui-moved span.ffz-handle:after { transform: rotate(-45deg); }
|
||||
|
||||
.app-main.theatre span.ffz-handle:before,
|
||||
.chat-container.dark span.ffz-handle:before,
|
||||
.chat-container.force-dark span.ffz-handle:before,
|
||||
.ember-chat-container.dark span.ffz-handle:before,
|
||||
.ember-chat-container.force-dark span.ffz-handle:before,
|
||||
.ffz-ui-popup.dark span.ffz-handle:before,
|
||||
.app-main.theatre span.ffz-handle:after,
|
||||
.chat-container.dark span.ffz-handle:after,
|
||||
.chat-container.force-dark span.ffz-handle:after,
|
||||
.ember-chat-container.dark span.ffz-handle:after,
|
||||
.ember-chat-container.force-dark span.ffz-handle:after,
|
||||
.ffz-ui-popup.dark span.ffz-handle:after {
|
||||
border-color: #666;
|
||||
}
|
||||
|
||||
.app-main.theatre .ffz-ui-popup.ui-moved span.ffz-handle:before,
|
||||
.chat-container.dark .ffz-ui-popup.ui-moved span.ffz-handle:before,
|
||||
.chat-container.force-dark .ffz-ui-popup.ui-moved span.ffz-handle:before,
|
||||
.ember-chat-container.dark .ffz-ui-popup.ui-moved span.ffz-handle:before,
|
||||
.ember-chat-container.force-dark .ffz-ui-popup.ui-moved span.ffz-handle:before,
|
||||
.ffz-ui-popup.ui-moved.dark span.ffz-handle:before,
|
||||
.app-main.theatre .ffz-ui-popup.ui-moved span.ffz-handle:after,
|
||||
.chat-container.dark .ffz-ui-popup.ui-moved span.ffz-handle:after,
|
||||
.chat-container.force-dark .ffz-ui-popup.ui-moved span.ffz-handle:after,
|
||||
.ember-chat-container.dark .ffz-ui-popup.ui-moved span.ffz-handle:after,
|
||||
.ember-chat-container.force-dark .ffz-ui-popup.ui-moved span.ffz-handle:after,
|
||||
.ffz-ui-popup.ui-moved.dark span.ffz-handle:after {
|
||||
border-color: #d3d3d3;
|
||||
}
|
||||
|
||||
|
||||
.ffz-ui-popup ul.menu li.title > span.ffz-handle {
|
||||
float: left;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.ffz-ui-popup ul.menu li.title > span.title {
|
||||
display: block;
|
||||
margin-left: 24px;
|
||||
padding: 10px 20px 10px 0;
|
||||
line-height: 16px;
|
||||
transition: margin-left 500ms;
|
||||
}
|
||||
|
||||
.ffz-ui-popup.ui-moved ul.menu li.title > span.title { margin-left: 34px; }
|
||||
|
||||
.ffz-ui-popup ul.menu a {
|
||||
display: block;
|
||||
padding: 10px;
|
||||
|
@ -1006,6 +1079,23 @@ body:not(.ffz-chat-purge-icon) .ember-chat .mod-icons .purge { display: none; }
|
|||
|
||||
/* Emoticon Tooltips */
|
||||
|
||||
.ffz-wide-tip .tipsy-inner {
|
||||
max-width: 600px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.ffz-wide-tip span.viewers {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.ffz-wide-tip span.viewers svg {
|
||||
float: left;
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
.ffz-wide-tip svg path { fill: #fff; }
|
||||
.ffz-wide-tip span.playing { opacity: 0.7; }
|
||||
|
||||
.tipsy .tipsy-inner {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
@ -1165,7 +1255,7 @@ a.unsafe-link {
|
|||
|
||||
.ffz-room-row:hover svg path,
|
||||
.ffz-room-row:focus svg path,
|
||||
.ffz-room-row.active svg path { fill: #fff; }
|
||||
.ffz-room-row.active svg path { fill: #fff; }
|
||||
|
||||
.ffz-room-row:hover td,
|
||||
.ffz-room-row:focus td,
|
||||
|
@ -1643,7 +1733,7 @@ li[data-name="following"] a {
|
|||
position: absolute;
|
||||
right: 10px;
|
||||
top: 8px;
|
||||
|
||||
|
||||
line-height: 14px;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
|
@ -1696,12 +1786,12 @@ li[data-name="following"] a {
|
|||
|
||||
/* High Contrast Chat */
|
||||
|
||||
.ffz-high-contrast-chat-text .chat-container,
|
||||
.ffz-high-contrast-chat-text .chat-container,
|
||||
.ffz-high-contrast-chat-text .ember-chat-container {
|
||||
color: "#000";
|
||||
}
|
||||
|
||||
.ffz-high-contrast-chat-bg .chat-container,
|
||||
.ffz-high-contrast-chat-bg .chat-container,
|
||||
.ffz-high-contrast-chat-bg .ember-chat-container {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue