mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-10 08:10:52 +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) {
|
on_update: function(val) {
|
||||||
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' )
|
||||||
this._rebuild_colors();
|
this._rebuild_colors();
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ FFZ.settings_info.luv_contrast = {
|
||||||
|
|
||||||
name: "Username Colors - Luv Minimum Contrast",
|
name: "Username Colors - Luv Minimum Contrast",
|
||||||
help: "Set the minimum contrast ratio used by Luv Adjustment to ensure colors are readable.",
|
help: "Set the minimum contrast ratio used by Luv Adjustment to ensure colors are readable.",
|
||||||
|
|
||||||
method: function() {
|
method: function() {
|
||||||
var old_val = this.settings.luv_contrast,
|
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);
|
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);
|
var parsed = parseFloat(new_val);
|
||||||
if ( parsed === NaN || parsed < 1 )
|
if ( parsed === NaN || parsed < 1 )
|
||||||
parsed = 4.5;
|
parsed = 4.5;
|
||||||
|
|
||||||
this.settings.set("luv_contrast", parsed);
|
this.settings.set("luv_contrast", parsed);
|
||||||
},
|
},
|
||||||
|
|
||||||
on_update: function(val) {
|
on_update: function(val) {
|
||||||
this._rebuild_contrast();
|
this._rebuild_contrast();
|
||||||
|
|
||||||
|
@ -116,19 +116,19 @@ FFZ.settings_info.color_blind = {
|
||||||
FFZ.prototype.setup_colors = function() {
|
FFZ.prototype.setup_colors = function() {
|
||||||
this._colors = {};
|
this._colors = {};
|
||||||
this._rebuild_contrast();
|
this._rebuild_contrast();
|
||||||
|
|
||||||
this._update_colors();
|
this._update_colors();
|
||||||
|
|
||||||
// Events for rebuilding colors.
|
// Events for rebuilding colors.
|
||||||
var Layout = App.__container__.lookup('controller:layout'),
|
var Layout = window.App && App.__container__.lookup('controller:layout'),
|
||||||
Settings = App.__container__.lookup('controller:settings');
|
Settings = window.App && App.__container__.lookup('controller:settings');
|
||||||
|
|
||||||
if ( Layout )
|
if ( Layout )
|
||||||
Layout.addObserver("isTheatreMode", this._update_colors.bind(this, true));
|
Layout.addObserver("isTheatreMode", this._update_colors.bind(this, true));
|
||||||
|
|
||||||
if ( Settings )
|
if ( Settings )
|
||||||
Settings.addObserver("model.darkMode", this._update_colors.bind(this, true))
|
Settings.addObserver("model.darkMode", this._update_colors.bind(this, true))
|
||||||
|
|
||||||
this._color_old_darkness = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('model.darkMode'));
|
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) {
|
RGBColor.fromHSV = function(h, s, v) {
|
||||||
var r, g, b,
|
var r, g, b,
|
||||||
|
|
||||||
i = Math.floor(h * 6),
|
i = Math.floor(h * 6),
|
||||||
f = h * 6 - i,
|
f = h * 6 - i,
|
||||||
p = v * (1 - s),
|
p = v * (1 - s),
|
||||||
q = v * (1 - f * s),
|
q = v * (1 - f * s),
|
||||||
t = v * (1 - (1 - f) * s);
|
t = v * (1 - (1 - f) * s);
|
||||||
|
|
||||||
switch(i % 6) {
|
switch(i % 6) {
|
||||||
case 0: r = v, g = t, b = p; break;
|
case 0: r = v, g = t, b = p; break;
|
||||||
case 1: r = q, g = v, 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 4: r = t, g = p, b = v; break;
|
||||||
case 5: r = v, g = p, b = q;
|
case 5: r = v, g = p, b = q;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RGBColor(
|
return new RGBColor(
|
||||||
Math.round(Math.min(Math.max(0, r*255), 255)),
|
Math.round(Math.min(Math.max(0, r*255), 255)),
|
||||||
Math.round(Math.min(Math.max(0, g*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,
|
var q = l < 0.5 ? l * (1 + s) : l + s - l * s,
|
||||||
p = 2 * l - q;
|
p = 2 * l - q;
|
||||||
|
|
||||||
return new RGBColor(
|
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 + 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)), 255)),
|
||||||
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 - 1/3)), 255))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
RGBColor.prototype.toHSV = function() { return HSVColor.fromRGB(this.r, this.g, this.b); }
|
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.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() {
|
RGBColor.prototype.toHex = function() {
|
||||||
var rgb = this.b | (this.g << 8) | (this.r << 16);
|
var rgb = this.b | (this.g << 8) | (this.r << 16);
|
||||||
return '#' + (0x1000000 + rgb).toString(16).slice(1);
|
return '#' + (0x1000000 + rgb).toString(16).slice(1);
|
||||||
}
|
}
|
||||||
|
@ -276,7 +276,7 @@ RGBColor.prototype.luminance = function() {
|
||||||
RGBColor.prototype.brighten = function(amount) {
|
RGBColor.prototype.brighten = function(amount) {
|
||||||
amount = typeof amount === "number" ? amount : 1;
|
amount = typeof amount === "number" ? amount : 1;
|
||||||
amount = Math.round(255 * (amount / 100));
|
amount = Math.round(255 * (amount / 100));
|
||||||
|
|
||||||
return new RGBColor(
|
return new RGBColor(
|
||||||
Math.max(0, Math.min(255, this.r + amount)),
|
Math.max(0, Math.min(255, this.r + amount)),
|
||||||
Math.max(0, Math.min(255, this.g + 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) )
|
if ( FFZ.Color.CVDMatrix.hasOwnProperty(type) )
|
||||||
cvd = FFZ.Color.CVDMatrix[type];
|
cvd = FFZ.Color.CVDMatrix[type];
|
||||||
else
|
else
|
||||||
throw "Invalid CVD matrix.";
|
throw "Invalid CVD matrix.";
|
||||||
} else
|
} else
|
||||||
cvd = type;
|
cvd = type;
|
||||||
|
|
||||||
var cvd_a = cvd[0], cvd_b = cvd[1], cvd_c = cvd[2],
|
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_d = cvd[3], cvd_e = cvd[4], cvd_f = cvd[5],
|
||||||
cvd_g = cvd[6], cvd_h = cvd[7], cvd_i = cvd[8],
|
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) {
|
HSLColor.fromRGB = function(r, g, b) {
|
||||||
r /= 255; g /= 255; b /= 255;
|
r /= 255; g /= 255; b /= 255;
|
||||||
|
|
||||||
var max = Math.max(r,g,b),
|
var max = Math.max(r,g,b),
|
||||||
min = Math.min(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) {
|
HSVColor.fromRGB = function(r, g, b) {
|
||||||
r /= 255; g /= 255; b /= 255;
|
r /= 255; g /= 255; b /= 255;
|
||||||
|
|
||||||
var max = Math.max(r, g, b),
|
var max = Math.max(r, g, b),
|
||||||
min = Math.min(r, g, b),
|
min = Math.min(r, g, b),
|
||||||
d = Math.min(Math.max(0, max - min), 1),
|
d = Math.min(Math.max(0, max - min), 1),
|
||||||
|
|
||||||
h,
|
h,
|
||||||
s = max === 0 ? 0 : d / max,
|
s = max === 0 ? 0 : d / max,
|
||||||
v = max;
|
v = max;
|
||||||
|
|
||||||
if ( d === 0 )
|
if ( d === 0 )
|
||||||
h = 0;
|
h = 0;
|
||||||
else {
|
else {
|
||||||
|
@ -413,7 +413,7 @@ HSVColor.fromRGB = function(r, g, b) {
|
||||||
}
|
}
|
||||||
h /= 6;
|
h /= 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HSVColor(h, s, v);
|
return new HSVColor(h, s, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -560,25 +560,25 @@ FFZ.prototype._rebuild_colors = function() {
|
||||||
|
|
||||||
FFZ.prototype._update_colors = function(darkness_only) {
|
FFZ.prototype._update_colors = function(darkness_only) {
|
||||||
// Update the lines. ALL of them.
|
// Update the lines. ALL of them.
|
||||||
var Layout = App.__container__.lookup('controller:layout'),
|
var Layout = window.App && App.__container__.lookup('controller:layout'),
|
||||||
Settings = App.__container__.lookup('controller:settings'),
|
Settings = window.App && App.__container__.lookup('controller:settings'),
|
||||||
|
|
||||||
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('model.darkMode'));
|
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('model.darkMode'));
|
||||||
|
|
||||||
if ( darkness_only && this._color_old_darkness === is_dark )
|
if ( darkness_only && this._color_old_darkness === is_dark )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._color_old_darkness = is_dark;
|
this._color_old_darkness = is_dark;
|
||||||
|
|
||||||
var colored_bits = document.querySelectorAll('.chat-line .has-color');
|
var colored_bits = document.querySelectorAll('.chat-line .has-color');
|
||||||
for(var i=0, l=colored_bits.length; i < l; i++) {
|
for(var i=0, l=colored_bits.length; i < l; i++) {
|
||||||
var bit = colored_bits[i],
|
var bit = colored_bits[i],
|
||||||
color = bit.getAttribute('data-color'),
|
color = bit.getAttribute('data-color'),
|
||||||
colors = color && this._handle_color(color);
|
colors = color && this._handle_color(color);
|
||||||
|
|
||||||
if ( ! colors )
|
if ( ! colors )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bit.style.color = is_dark ? colors[1] : colors[0];
|
bit.style.color = is_dark ? colors[1] : colors[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -589,7 +589,7 @@ FFZ.prototype._handle_color = function(color) {
|
||||||
return this._colors[color];
|
return this._colors[color];
|
||||||
|
|
||||||
var rgb = RGBColor.fromHex(color),
|
var rgb = RGBColor.fromHex(color),
|
||||||
|
|
||||||
light_color = color,
|
light_color = color,
|
||||||
dark_color = color;
|
dark_color = color;
|
||||||
|
|
||||||
|
@ -601,20 +601,20 @@ FFZ.prototype._handle_color = function(color) {
|
||||||
light_color = dark_color = rgb.toHex();
|
light_color = dark_color = rgb.toHex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Color Processing - RGB
|
// Color Processing - RGB
|
||||||
if ( this.settings.fix_color === '4' ) {
|
if ( this.settings.fix_color === '4' ) {
|
||||||
var lum = rgb.luminance();
|
var lum = rgb.luminance();
|
||||||
|
|
||||||
if ( lum > 0.3 ) {
|
if ( lum > 0.3 ) {
|
||||||
var s = 127, nc = rgb;
|
var s = 127, nc = rgb;
|
||||||
while(s--) {
|
while(s--) {
|
||||||
nc = nc.brighten(-1);
|
nc = nc.brighten(-1);
|
||||||
if ( nc.luminance() <= 0.3 )
|
if ( nc.luminance() <= 0.3 )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
light_color = nc.toHex();
|
light_color = nc.toHex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,25 +625,25 @@ FFZ.prototype._handle_color = function(color) {
|
||||||
if ( nc.luminance() >= 0.15 )
|
if ( nc.luminance() >= 0.15 )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
dark_color = nc.toHex();
|
dark_color = nc.toHex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Color Processing - HSL
|
// Color Processing - HSL
|
||||||
if ( this.settings.fix_color === '2' ) {
|
if ( this.settings.fix_color === '2' ) {
|
||||||
var hsl = rgb.toHSL();
|
var hsl = rgb.toHSL();
|
||||||
|
|
||||||
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)).toHex();
|
||||||
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)).toHex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 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();
|
||||||
|
|
||||||
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().toHex();
|
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 {
|
} 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();
|
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
|
// Color Processing - LUV
|
||||||
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 )
|
||||||
light_color = luv._l(this._luv_required_dark).toRGB().toHex();
|
light_color = luv._l(this._luv_required_dark).toRGB().toHex();
|
||||||
|
|
||||||
if ( luv.l < this._luv_required_bright )
|
if ( luv.l < this._luv_required_bright )
|
||||||
dark_color = luv._l(this._luv_required_bright).toRGB().toHex();
|
dark_color = luv._l(this._luv_required_bright).toRGB().toHex();
|
||||||
}
|
}
|
||||||
|
|
||||||
var out = this._colors[color] = [light_color, dark_color];
|
var out = this._colors[color] = [light_color, dark_color];
|
||||||
return out;
|
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>',
|
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>',
|
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>',
|
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>',
|
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>',
|
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",
|
name: "Purge Icon in Mod Icons",
|
||||||
help: "Display a Purge Icon in chat line Mod Icons for quickly purging users.",
|
help: "Display a Purge Icon in chat line Mod Icons for quickly purging users.",
|
||||||
|
|
||||||
on_update: function(val) {
|
on_update: function(val) {
|
||||||
if ( this.has_bttv )
|
if ( this.has_bttv )
|
||||||
return;
|
return;
|
||||||
|
@ -49,10 +49,10 @@ FFZ.settings_info.line_purge_icon = {
|
||||||
FFZ.settings_info.replace_bad_emotes = {
|
FFZ.settings_info.replace_bad_emotes = {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: true,
|
value: true,
|
||||||
|
|
||||||
category: "Chat Appearance",
|
category: "Chat Appearance",
|
||||||
no_bttv: true,
|
no_bttv: true,
|
||||||
|
|
||||||
name: "Fix Low Quality Twitch Global Emoticons",
|
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."
|
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 = {
|
FFZ.settings_info.image_hover_all_domains = {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: false,
|
value: false,
|
||||||
|
|
||||||
category: "Chat Tooltips",
|
category: "Chat Tooltips",
|
||||||
no_bttv: true,
|
no_bttv: true,
|
||||||
no_mobile: true,
|
no_mobile: true,
|
||||||
|
|
||||||
name: "Image Preview - All Domains",
|
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>"
|
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",
|
category: "Chat Appearance",
|
||||||
no_bttv: true,
|
no_bttv: true,
|
||||||
|
|
||||||
process_value: function(val) {
|
process_value: function(val) {
|
||||||
if ( val === false )
|
if ( val === false )
|
||||||
return '0';
|
return '0';
|
||||||
|
@ -305,8 +305,8 @@ FFZ.settings_info.chat_separators = {
|
||||||
document.body.classList.toggle("ffz-chat-separator-3d", !this.has_bttv && val === '2');
|
document.body.classList.toggle("ffz-chat-separator-3d", !this.has_bttv && val === '2');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
FFZ.settings_info.chat_padding = {
|
FFZ.settings_info.chat_padding = {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: false,
|
value: false,
|
||||||
|
@ -377,7 +377,7 @@ FFZ.settings_info.chat_font_size = {
|
||||||
var parsed = parseInt(new_val);
|
var parsed = parseInt(new_val);
|
||||||
if ( ! parsed || 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);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -414,10 +414,10 @@ FFZ.settings_info.chat_ts_size = {
|
||||||
|
|
||||||
method: function() {
|
method: function() {
|
||||||
var old_val = this.settings.chat_ts_size;
|
var old_val = this.settings.chat_ts_size;
|
||||||
|
|
||||||
if ( ! old_val )
|
if ( ! old_val )
|
||||||
old_val = this.settings.chat_font_size;
|
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);
|
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 )
|
if ( new_val === null || new_val === undefined )
|
||||||
|
@ -426,7 +426,7 @@ FFZ.settings_info.chat_ts_size = {
|
||||||
var parsed = parseInt(new_val);
|
var parsed = parseInt(new_val);
|
||||||
if ( ! parsed || 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);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -456,7 +456,7 @@ FFZ.prototype.setup_line = function() {
|
||||||
jQuery(document.body).on("mouseleave", ".tipsy", function() {
|
jQuery(document.body).on("mouseleave", ".tipsy", function() {
|
||||||
this.parentElement.removeChild(this);
|
this.parentElement.removeChild(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Aliases
|
// Aliases
|
||||||
try {
|
try {
|
||||||
this.aliases = JSON.parse(localStorage.ffz_aliases || '{}');
|
this.aliases = JSON.parse(localStorage.ffz_aliases || '{}');
|
||||||
|
@ -464,29 +464,29 @@ FFZ.prototype.setup_line = function() {
|
||||||
this.log("Error Loading Aliases: " + err);
|
this.log("Error Loading Aliases: " + err);
|
||||||
this.aliases = {};
|
this.aliases = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Chat Style
|
// Chat Style
|
||||||
var s = this._chat_style = document.createElement('style');
|
var s = this._chat_style = document.createElement('style');
|
||||||
s.id = "ffz-style-chat";
|
s.id = "ffz-style-chat";
|
||||||
s.type = 'text/css';
|
s.type = 'text/css';
|
||||||
document.head.appendChild(s);
|
document.head.appendChild(s);
|
||||||
|
|
||||||
// Initial calculation.
|
// Initial calculation.
|
||||||
FFZ.settings_info.chat_font_size.on_update.bind(this)(this.settings.chat_font_size);
|
FFZ.settings_info.chat_font_size.on_update.bind(this)(this.settings.chat_font_size);
|
||||||
|
|
||||||
|
|
||||||
// Chat Enhancements
|
// Chat Enhancements
|
||||||
document.body.classList.toggle("ffz-chat-colors", !this.has_bttv && this.settings.fix_color !== '-1');
|
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-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-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-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", !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-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-text", !this.has_bttv && this.settings.high_contrast_chat[2] === '1');
|
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-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');
|
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) {
|
FFZ.prototype._modify_line = function(component) {
|
||||||
var f = this,
|
var f = this,
|
||||||
|
|
||||||
Layout = App.__container__.lookup('controller:layout'),
|
Layout = App.__container__.lookup('controller:layout'),
|
||||||
Settings = App.__container__.lookup('controller:settings');
|
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() {
|
ffzUpdated: Ember.observer("msgObject.ffz_deleted", "msgObject.ffz_old_messages", function() {
|
||||||
this.rerender();
|
this.rerender();
|
||||||
}),
|
}),
|
||||||
|
|
||||||
click: function(e) {
|
click: function(e) {
|
||||||
if ( e.target && e.target.classList.contains('ffz-old-messages') )
|
if ( e.target && e.target.classList.contains('ffz-old-messages') )
|
||||||
return f._show_deleted(this.get('msgObject.room'));
|
return f._show_deleted(this.get('msgObject.room'));
|
||||||
|
|
||||||
if ( e.target && e.target.classList.contains('deleted-link') )
|
if ( e.target && e.target.classList.contains('deleted-link') )
|
||||||
return f._deleted_link_click.bind(e.target)(e);
|
return f._deleted_link_click.bind(e.target)(e);
|
||||||
|
|
||||||
if ( e.target && e.target.classList.contains('mod-icon') ) {
|
if ( e.target && e.target.classList.contains('mod-icon') ) {
|
||||||
jQuery(e.target).trigger('mouseout');
|
jQuery(e.target).trigger('mouseout');
|
||||||
|
|
||||||
if ( e.target.classList.contains('purge') ) {
|
if ( e.target.classList.contains('purge') ) {
|
||||||
var i = this.get('msgObject.from'),
|
var i = this.get('msgObject.from'),
|
||||||
room_id = this.get('msgObject.room'),
|
room_id = this.get('msgObject.room'),
|
||||||
room = room_id && f.rooms[room_id] && f.rooms[room_id].room;
|
room = room_id && f.rooms[room_id] && f.rooms[room_id].room;
|
||||||
|
|
||||||
if ( room ) {
|
if ( room ) {
|
||||||
room.send("/timeout " + i + " 1");
|
room.send("/timeout " + i + " 1");
|
||||||
room.clearMessages(i);
|
room.clearMessages(i);
|
||||||
|
@ -596,7 +596,7 @@ FFZ.prototype._modify_line = function(component) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons && e.target && e.target.classList.contains('emoticon') ) {
|
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons && e.target && e.target.classList.contains('emoticon') ) {
|
||||||
var eid = e.target.getAttribute('data-emote');
|
var eid = e.target.getAttribute('data-emote');
|
||||||
if ( eid )
|
if ( eid )
|
||||||
|
@ -606,10 +606,10 @@ FFZ.prototype._modify_line = function(component) {
|
||||||
window.open("https://www.frankerfacez.com/emoticons/" + eid);
|
window.open("https://www.frankerfacez.com/emoticons/" + eid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._super(e);
|
return this._super(e);
|
||||||
},
|
},
|
||||||
|
|
||||||
ffzUserLevel: function() {
|
ffzUserLevel: function() {
|
||||||
if ( this.get('isStaff') )
|
if ( this.get('isStaff') )
|
||||||
return 5;
|
return 5;
|
||||||
|
@ -623,27 +623,27 @@ FFZ.prototype._modify_line = function(component) {
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}.property('msgObject.labels.[]'),
|
}.property('msgObject.labels.[]'),
|
||||||
|
|
||||||
render: function(e) {
|
render: function(e) {
|
||||||
var deleted = this.get('msgObject.deleted'),
|
var deleted = this.get('msgObject.deleted'),
|
||||||
r = this,
|
r = this,
|
||||||
|
|
||||||
badges = {},
|
badges = {},
|
||||||
|
|
||||||
user = this.get('msgObject.from'),
|
user = this.get('msgObject.from'),
|
||||||
room_id = this.get('msgObject.room'),
|
room_id = this.get('msgObject.room'),
|
||||||
room = f.rooms && f.rooms[room_id],
|
room = f.rooms && f.rooms[room_id],
|
||||||
|
|
||||||
recipient = this.get('msgObject.to'),
|
recipient = this.get('msgObject.to'),
|
||||||
is_whisper = recipient && recipient.length,
|
is_whisper = recipient && recipient.length,
|
||||||
|
|
||||||
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'),
|
raw_color = this.get('msgObject.color'),
|
||||||
colors = raw_color && f._handle_color(raw_color),
|
colors = raw_color && f._handle_color(raw_color),
|
||||||
|
|
||||||
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('model.darkMode'));
|
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('model.darkMode'));
|
||||||
|
|
||||||
if ( row_type === undefined ) {
|
if ( row_type === undefined ) {
|
||||||
|
@ -653,19 +653,19 @@ FFZ.prototype._modify_line = function(component) {
|
||||||
|
|
||||||
e.push('<div class="indicator"></div>');
|
e.push('<div class="indicator"></div>');
|
||||||
e.push('<span class="timestamp float-left">' + this.get("timestamp") + '</span> ');
|
e.push('<span class="timestamp float-left">' + this.get("timestamp") + '</span> ');
|
||||||
|
|
||||||
if ( ! is_whisper && this_ul < other_ul ) {
|
if ( ! is_whisper && this_ul < other_ul ) {
|
||||||
e.push('<span class="mod-icons float-left">');
|
e.push('<span class="mod-icons float-left">');
|
||||||
if ( deleted )
|
if ( deleted )
|
||||||
e.push('<a class="mod-icon float-left tooltip unban" title="Unban User" href="#">Unban</a>');
|
e.push('<a class="mod-icon float-left tooltip unban" title="Unban User" href="#">Unban</a>');
|
||||||
else
|
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 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 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('<a class="mod-icon float-left tooltip purge" title="Purge User (Timeout 1s)" href="#">Purge</a>');
|
||||||
e.push('</span>');
|
e.push('</span>');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stock Badges
|
// Stock Badges
|
||||||
if ( ! is_whisper && this.get('isBroadcaster') )
|
if ( ! is_whisper && this.get('isBroadcaster') )
|
||||||
badges[0] = {klass: 'broadcaster', title: 'Broadcaster'};
|
badges[0] = {klass: 'broadcaster', title: 'Broadcaster'};
|
||||||
|
@ -677,7 +677,7 @@ FFZ.prototype._modify_line = function(component) {
|
||||||
badges[0] = {klass: 'global-moderator', title: 'Global Moderator'};
|
badges[0] = {klass: 'global-moderator', title: 'Global Moderator'};
|
||||||
else if ( ! is_whisper && this.get('isModerator') )
|
else if ( ! is_whisper && this.get('isModerator') )
|
||||||
badges[0] = {klass: 'moderator', title: 'Moderator'};
|
badges[0] = {klass: 'moderator', title: 'Moderator'};
|
||||||
|
|
||||||
if ( ! is_whisper && this.get('isSubscriber') )
|
if ( ! is_whisper && this.get('isSubscriber') )
|
||||||
badges[10] = {klass: 'subscriber', title: 'Subscriber'};
|
badges[10] = {klass: 'subscriber', title: 'Subscriber'};
|
||||||
if ( this.get('hasTurbo') )
|
if ( this.get('hasTurbo') )
|
||||||
|
@ -692,10 +692,10 @@ FFZ.prototype._modify_line = function(component) {
|
||||||
for(var key in badges) {
|
for(var key in badges) {
|
||||||
var badge = badges[key],
|
var badge = badges[key],
|
||||||
css = badge.image ? 'background-image:url("' + badge.image + '");' : '';
|
css = badge.image ? 'background-image:url("' + badge.image + '");' : '';
|
||||||
|
|
||||||
if ( badge.color )
|
if ( badge.color )
|
||||||
css += 'background-color:' + badge.color + ';';
|
css += 'background-color:' + badge.color + ';';
|
||||||
|
|
||||||
if ( badge.extra_css )
|
if ( badge.extra_css )
|
||||||
css += badge.extra_css;
|
css += badge.extra_css;
|
||||||
|
|
||||||
|
@ -703,11 +703,11 @@ 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]),
|
style = colors && 'color:' + (is_dark ? colors[1] : colors[0]),
|
||||||
colored = style ? ' has-color' : '';
|
colored = style ? ' has-color' : '';
|
||||||
|
|
||||||
if ( alias )
|
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>');
|
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 ) {
|
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_color = this.get('msgObject.toColor'),
|
||||||
to_colors = to_color && f._handle_color(to_color),
|
to_colors = to_color && f._handle_color(to_color),
|
||||||
to_style = to_color && 'color:' + (is_dark ? to_colors[1] : to_colors[0]),
|
to_style = to_color && 'color:' + (is_dark ? to_colors[1] : to_colors[0]),
|
||||||
to_colored = to_style ? ' has-color' : '';
|
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' + to_colored + '" style="' + to_style + (to_color ? '" data-color="' + to_color : '') + '" 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
|
||||||
|
@ -732,26 +732,26 @@ FFZ.prototype._modify_line = function(component) {
|
||||||
}
|
}
|
||||||
|
|
||||||
e.push('<span class="colon">:</span> ');
|
e.push('<span class="colon">:</span> ');
|
||||||
|
|
||||||
if ( this.get('msgObject.style') !== 'action' ) {
|
if ( this.get('msgObject.style') !== 'action' ) {
|
||||||
style = '';
|
style = '';
|
||||||
colored = '';
|
colored = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( deleted )
|
if ( deleted )
|
||||||
e.push('<span class="deleted"><a class="undelete" href="#"><message deleted></a></span>');
|
e.push('<span class="deleted"><a class="undelete" href="#"><message deleted></a></span>');
|
||||||
else {
|
else {
|
||||||
e.push('<span class="message' + colored + '" style="' + style + '">');
|
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');
|
||||||
if ( old_messages && old_messages.length )
|
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('<div class="button primary float-right ffz-old-messages">Show ' + utils.number_commas(old_messages.length) + ' Old</div>');
|
||||||
|
|
||||||
e.push('</span>');
|
e.push('</span>');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
classNameBindings: [
|
classNameBindings: [
|
||||||
'msgObject.ffz_alternate:ffz-alternate',
|
'msgObject.ffz_alternate:ffz-alternate',
|
||||||
'msgObject.ffz_has_mention:ffz-mentioned',
|
'msgObject.ffz_has_mention:ffz-mentioned',
|
||||||
|
@ -759,12 +759,12 @@ FFZ.prototype._modify_line = function(component) {
|
||||||
'ffzHasOldMessages:clearfix',
|
'ffzHasOldMessages:clearfix',
|
||||||
'ffzHasOldMessages:ffz-has-deleted'
|
'ffzHasOldMessages:ffz-has-deleted'
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
||||||
ffzWasDeleted: function() {
|
ffzWasDeleted: function() {
|
||||||
return f.settings.prevent_clear && this.get('msgObject.ffz_deleted');
|
return f.settings.prevent_clear && this.get('msgObject.ffz_deleted');
|
||||||
}.property('msgObject.ffz_deleted'),
|
}.property('msgObject.ffz_deleted'),
|
||||||
|
|
||||||
ffzHasOldMessages: function() {
|
ffzHasOldMessages: function() {
|
||||||
var old_messages = this.get('msgObject.ffz_old_messages');
|
var old_messages = this.get('msgObject.ffz_old_messages');
|
||||||
return old_messages && old_messages.length;
|
return old_messages && old_messages.length;
|
||||||
|
@ -773,7 +773,7 @@ FFZ.prototype._modify_line = function(component) {
|
||||||
|
|
||||||
didInsertElement: function() {
|
didInsertElement: function() {
|
||||||
this._super();
|
this._super();
|
||||||
|
|
||||||
var el = this.get('element');
|
var el = this.get('element');
|
||||||
|
|
||||||
el.setAttribute('data-room', this.get('msgObject.room'));
|
el.setAttribute('data-room', this.get('msgObject.room'));
|
||||||
|
|
|
@ -49,22 +49,8 @@ FFZ.prototype._emote_menu_enumerator = function() {
|
||||||
if ( emote.hidden )
|
if ( emote.hidden )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// TODO: Stop having to calculate this here.
|
var title = "FrankerFaceZ " + set.title,
|
||||||
var title = set.title, badge = set.icon || null;
|
badge = set.icon || '//cdn.frankerfacez.com/script/devicon.png';
|
||||||
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;
|
|
||||||
|
|
||||||
emotes.push({text: emote.name, url: emote.urls[1],
|
emotes.push({text: emote.name, url: emote.urls[1],
|
||||||
hidden: false, channel: title, badge: badge});
|
hidden: false, channel: title, badge: badge});
|
||||||
|
|
|
@ -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: 8,
|
major: 3, minor: 5, revision: 10,
|
||||||
toString: function() {
|
toString: function() {
|
||||||
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ FFZ.prototype.initialize = function(increment, delay) {
|
||||||
this.init_normal(delay);
|
this.init_normal(delay);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( location.hostname === 'passport' && /^\/(?:authorize)/.test(location.pathname) ) {
|
if ( location.hostname === 'passport' && /^\/(?:authorize)/.test(location.pathname) ) {
|
||||||
this.log("Running on passport!");
|
this.log("Running on passport!");
|
||||||
this.init_normal(delay, true);
|
this.init_normal(delay, true);
|
||||||
|
|
|
@ -2,6 +2,7 @@ var FFZ = window.FrankerFaceZ;
|
||||||
|
|
||||||
FFZ.prototype._ws_open = false;
|
FFZ.prototype._ws_open = false;
|
||||||
FFZ.prototype._ws_delay = 0;
|
FFZ.prototype._ws_delay = 0;
|
||||||
|
FFZ.prototype._ws_last_iframe = 0;
|
||||||
|
|
||||||
FFZ.ws_commands = {};
|
FFZ.ws_commands = {};
|
||||||
FFZ.ws_on_close = [];
|
FFZ.ws_on_close = [];
|
||||||
|
@ -11,6 +12,22 @@ FFZ.ws_on_close = [];
|
||||||
// Socket Creation
|
// 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() {
|
FFZ.prototype.ws_create = function() {
|
||||||
var f = this, ws;
|
var f = this, ws;
|
||||||
|
|
||||||
|
@ -30,6 +47,7 @@ FFZ.prototype.ws_create = function() {
|
||||||
ws.onopen = function(e) {
|
ws.onopen = function(e) {
|
||||||
f._ws_open = true;
|
f._ws_open = true;
|
||||||
f._ws_delay = 0;
|
f._ws_delay = 0;
|
||||||
|
f._ws_last_iframe = Date.now();
|
||||||
f.log("Socket connected.");
|
f.log("Socket connected.");
|
||||||
|
|
||||||
// Check for incognito. We don't want to do a hello in incognito mode.
|
// 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.
|
// We never ever want to not have a socket.
|
||||||
if ( f._ws_delay < 60000 )
|
if ( f._ws_delay < 60000 )
|
||||||
f._ws_delay += (Math.floor(Math.random()*10) + 5) * 1000;
|
f._ws_delay += (Math.floor(Math.random()*10) + 5) * 1000;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
var FFZ = window.FrankerFaceZ,
|
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) {
|
on_update: function(val) {
|
||||||
this._schedule_following_count();
|
this._schedule_following_count();
|
||||||
|
|
||||||
var Stream = window.App && App.__container__.resolve('model:stream'),
|
var Stream = window.App && App.__container__.resolve('model:stream'),
|
||||||
Live = Stream && Stream.find("live");
|
Live = Stream && Stream.find("live");
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ FFZ.prototype.setup_following_count = function(has_ember) {
|
||||||
// Start it updating.
|
// Start it updating.
|
||||||
if ( this.settings.following_count )
|
if ( this.settings.following_count )
|
||||||
this._schedule_following_count();
|
this._schedule_following_count();
|
||||||
|
|
||||||
// If we don't have Ember, no point in trying this stuff.
|
// If we don't have Ember, no point in trying this stuff.
|
||||||
if ( ! has_ember )
|
if ( ! has_ember )
|
||||||
return this._update_following_count();
|
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.");
|
return this.log("Unable to find Live Streams collection.");
|
||||||
|
|
||||||
Live.addObserver('total', function() { f._draw_following_count(this.get('total')); });
|
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();
|
Live.load();
|
||||||
|
|
||||||
var total = Live.get('total');
|
var total = Live.get('total'),
|
||||||
if ( typeof total === "number" )
|
streams = Live.get('content');
|
||||||
|
if ( typeof total === "number" ) {
|
||||||
this._draw_following_count(total);
|
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()));
|
this._following_count_timer = setTimeout(this._update_following_count.bind(this), 55000 + (10000*Math.random()));
|
||||||
|
|
||||||
var Stream = window.App && App.__container__.resolve('model:stream'),
|
var Stream = window.App && App.__container__.resolve('model:stream'),
|
||||||
Live = Stream && Stream.find("live"),
|
Live = Stream && Stream.find("live"),
|
||||||
f = this;
|
f = this;
|
||||||
|
@ -92,15 +99,84 @@ FFZ.prototype._update_following_count = function() {
|
||||||
if ( Live )
|
if ( Live )
|
||||||
Live.load();
|
Live.load();
|
||||||
else
|
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) {
|
.done(function(data) {
|
||||||
f._draw_following_count(data._total);
|
f._draw_following_count(data._total);
|
||||||
|
f._draw_following_channels(data.streams, data._total);
|
||||||
}).fail(function() {
|
}).fail(function() {
|
||||||
f._draw_following_count();
|
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) {
|
FFZ.prototype._draw_following_count = function(count) {
|
||||||
// Small
|
// Small
|
||||||
var small_following = document.querySelector('#small_nav ul.game_filters li[data-name="following"] a');
|
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) : '';
|
badge.innerHTML = count ? utils.format_unread(count) : '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Large
|
// Large
|
||||||
var large_following = document.querySelector('#large_nav #nav_personal li[data-name="following"] a');
|
var large_following = document.querySelector('#large_nav #nav_personal li[data-name="following"] a');
|
||||||
if ( large_following ) {
|
if ( large_following ) {
|
||||||
|
@ -136,7 +212,7 @@ FFZ.prototype._draw_following_count = function(count) {
|
||||||
badge.innerHTML = count ? utils.format_unread(count) : '';
|
badge.innerHTML = count ? utils.format_unread(count) : '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Heading
|
// Heading
|
||||||
var head_following = document.querySelector('#header_actions #header_following');
|
var head_following = document.querySelector('#header_actions #header_following');
|
||||||
if ( head_following ) {
|
if ( head_following ) {
|
||||||
|
|
|
@ -3,16 +3,32 @@ var FFZ = window.FrankerFaceZ,
|
||||||
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) {
|
fix_menu_position = function(container) {
|
||||||
|
var swapped = document.body.classList.contains('ffz-sidebar-swap');
|
||||||
|
|
||||||
var bounds = container.getBoundingClientRect(),
|
var bounds = container.getBoundingClientRect(),
|
||||||
left = parseInt(container.style.left || '0'),
|
left = parseInt(container.style.left || '0'),
|
||||||
right = bounds.left + container.scrollWidth;
|
right = bounds.left + container.scrollWidth,
|
||||||
|
moved = !!container.style.left;
|
||||||
if ( bounds.left < 0 )
|
|
||||||
container.style.left = (left - bounds.left) + 'px';
|
if ( swapped ) {
|
||||||
else if ( right > document.body.clientWidth )
|
if ( bounds.left < 20 ) {
|
||||||
container.style.left = (left - (right - document.body.clientWidth)) + 'px';
|
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 ) return;
|
||||||
if ( popup.id === 'ffz-chat-menu' && popup.style && popup.style.left )
|
if ( popup.id === 'ffz-chat-menu' && popup.style && popup.style.left )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
popup = jQuery(popup);
|
popup = jQuery(popup);
|
||||||
parent = popup.parent();
|
parent = popup.parent();
|
||||||
|
|
||||||
|
@ -221,7 +237,31 @@ FFZ.prototype.build_ui_popup = function(view) {
|
||||||
|
|
||||||
var heading = document.createElement('li');
|
var heading = document.createElement('li');
|
||||||
heading.className = 'title';
|
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);
|
menu.appendChild(heading);
|
||||||
|
|
||||||
// Draggable
|
// Draggable
|
||||||
|
@ -312,7 +352,7 @@ FFZ.prototype._ui_change_page = function(view, inner, menu, container, page) {
|
||||||
this.log("No matching page: " + page);
|
this.log("No matching page: " + page);
|
||||||
|
|
||||||
FFZ.menu_pages[page].render.bind(this)(view, container, inner, menu);
|
FFZ.menu_pages[page].render.bind(this)(view, container, inner, menu);
|
||||||
|
|
||||||
// Re-position if necessary.
|
// Re-position if necessary.
|
||||||
var f = this;
|
var f = this;
|
||||||
setTimeout(function(){f._fix_menu_position();});
|
setTimeout(function(){f._fix_menu_position();});
|
||||||
|
@ -328,7 +368,8 @@ FFZ.menu_pages.channel = {
|
||||||
// Get the current room.
|
// Get the current room.
|
||||||
var room_id = view.get('controller.currentRoom.id'),
|
var room_id = view.get('controller.currentRoom.id'),
|
||||||
room = this.rooms[room_id],
|
room = this.rooms[room_id],
|
||||||
has_product = false;
|
has_product = false,
|
||||||
|
f = this;
|
||||||
|
|
||||||
// Check for a product.
|
// Check for a product.
|
||||||
if ( this.settings.replace_twitch_menu ) {
|
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
|
// See if we've loaded. If we haven't loaded the ticket yet
|
||||||
// then try loading it, and then re-render the menu.
|
// then try loading it, and then re-render the menu.
|
||||||
if ( tickets && ! is_subscribed && ! is_loaded ) {
|
if ( tickets && ! is_subscribed && ! is_loaded ) {
|
||||||
var f = this;
|
|
||||||
tickets.addObserver('isLoaded', function() {
|
tickets.addObserver('isLoaded', function() {
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
if ( inner.getAttribute('data-page') !== 'channel' )
|
if ( inner.getAttribute('data-page') !== 'channel' )
|
||||||
|
@ -360,7 +400,7 @@ FFZ.menu_pages.channel = {
|
||||||
inner.innerHTML = '';
|
inner.innerHTML = '';
|
||||||
FFZ.menu_pages.channel.render.bind(f)(view, inner);
|
FFZ.menu_pages.channel.render.bind(f)(view, inner);
|
||||||
},0);
|
},0);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
tickets.load();
|
tickets.load();
|
||||||
|
@ -395,8 +435,17 @@ FFZ.menu_pages.channel = {
|
||||||
s.style.width = emote.width + "px";
|
s.style.width = emote.width + "px";
|
||||||
s.style.height = emote.height + "px";
|
s.style.height = emote.height + "px";
|
||||||
s.title = emote.regex;
|
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);
|
grid.appendChild(s);
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
|
@ -475,7 +524,7 @@ FFZ.menu_pages.channel = {
|
||||||
// --------------------
|
// --------------------
|
||||||
|
|
||||||
FFZ.prototype._emotes_for_sets = function(parent, view, sets, header, image, sub_text) {
|
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';
|
grid.className = 'emoticon-grid';
|
||||||
|
|
||||||
if ( header != null ) {
|
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.style.height = emote.height + "px";
|
||||||
s.title = this._emote_tooltip(emote);
|
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);
|
grid.appendChild(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,53 +79,10 @@ FFZ.menu_pages.myemotes = {
|
||||||
|
|
||||||
render: function(view, container) {
|
render: function(view, container) {
|
||||||
var tmi = view.get('controller.currentRoom.tmiSession'),
|
var tmi = view.get('controller.currentRoom.tmiSession'),
|
||||||
twitch_sets = (tmi && tmi.getEmotes() || {'emoticon_sets': {}})['emoticon_sets'],
|
twitch_sets = (tmi && tmi.getEmotes() || {'emoticon_sets': {}})['emoticon_sets'];
|
||||||
needed_sets = [];
|
|
||||||
|
|
||||||
for(var set_id in twitch_sets)
|
// We don't have to do async stuff anymore cause we pre-load data~!
|
||||||
if ( twitch_sets.hasOwnProperty(set_id) && ! this._twitch_set_to_channel.hasOwnProperty(set_id) )
|
return FFZ.menu_pages.myemotes.draw_menu.bind(this)(view, container, twitch_sets);
|
||||||
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);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
toggle_section: function(heading) {
|
toggle_section: function(heading) {
|
||||||
|
@ -154,15 +111,15 @@ FFZ.menu_pages.myemotes = {
|
||||||
|
|
||||||
menu.className = 'emoticon-grid collapsable';
|
menu.className = 'emoticon-grid collapsable';
|
||||||
menu.appendChild(heading);
|
menu.appendChild(heading);
|
||||||
|
|
||||||
menu.setAttribute('data-set', 'emoji');
|
menu.setAttribute('data-set', 'emoji');
|
||||||
menu.classList.toggle('collapsed', this.settings.emote_menu_collapsed.indexOf('emoji') !== -1);
|
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); });
|
heading.addEventListener('click', function() { FFZ.menu_pages.myemotes.toggle_section.bind(f)(this); });
|
||||||
|
|
||||||
var set = [];
|
var set = [];
|
||||||
for(var eid in this.emoji_data)
|
for(var eid in this.emoji_data)
|
||||||
set.push(this.emoji_data[eid]);
|
set.push(this.emoji_data[eid]);
|
||||||
|
|
||||||
set.sort(function(a,b) {
|
set.sort(function(a,b) {
|
||||||
var an = a.short_name.toLowerCase(),
|
var an = a.short_name.toLowerCase(),
|
||||||
bn = b.short_name.toLowerCase();
|
bn = b.short_name.toLowerCase();
|
||||||
|
@ -173,7 +130,7 @@ FFZ.menu_pages.myemotes = {
|
||||||
if ( a.raw > b.raw ) return 1;
|
if ( a.raw > b.raw ) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
for(var i=0; i < set.length; i++) {
|
for(var i=0; i < set.length; i++) {
|
||||||
var emoji = set[i],
|
var emoji = set[i],
|
||||||
em = document.createElement('span'),
|
em = document.createElement('span'),
|
||||||
|
@ -182,13 +139,13 @@ FFZ.menu_pages.myemotes = {
|
||||||
em.className = 'emoticon tooltip';
|
em.className = 'emoticon tooltip';
|
||||||
em.title = 'Emoji: ' + emoji.raw + '\nName: :' + emoji.short_name + ':';
|
em.title = 'Emoji: ' + emoji.raw + '\nName: :' + emoji.short_name + ':';
|
||||||
em.addEventListener('click', this._add_emote.bind(this, view, emoji.raw));
|
em.addEventListener('click', this._add_emote.bind(this, view, emoji.raw));
|
||||||
|
|
||||||
em.style.backgroundImage = 'url("' + emoji.src + '")';
|
em.style.backgroundImage = 'url("' + emoji.src + '")';
|
||||||
em.style.backgroundImage = '-webkit-' + img_set;
|
em.style.backgroundImage = '-webkit-' + img_set;
|
||||||
em.style.backgroundImage = '-moz-' + img_set;
|
em.style.backgroundImage = '-moz-' + img_set;
|
||||||
em.style.backgroundImage = '-ms-' + img_set;
|
em.style.backgroundImage = '-ms-' + img_set;
|
||||||
em.style.backgroudnImage = img_set;
|
em.style.backgroudnImage = img_set;
|
||||||
|
|
||||||
menu.appendChild(em);
|
menu.appendChild(em);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +225,13 @@ FFZ.menu_pages.myemotes = {
|
||||||
}
|
}
|
||||||
|
|
||||||
em.title = code;
|
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);
|
menu.appendChild(em);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +250,7 @@ FFZ.menu_pages.myemotes = {
|
||||||
|
|
||||||
menu.className = 'emoticon-grid collapsable';
|
menu.className = 'emoticon-grid collapsable';
|
||||||
menu.appendChild(heading);
|
menu.appendChild(heading);
|
||||||
|
|
||||||
menu.setAttribute('data-set', 'ffz-' + set.id);
|
menu.setAttribute('data-set', 'ffz-' + set.id);
|
||||||
menu.classList.toggle('collapsed', this.settings.emote_menu_collapsed.indexOf('ffz-' + set.id) !== -1);
|
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); });
|
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.style.width = emote.width + "px";
|
||||||
|
|
||||||
em.title = this._emote_tooltip(emote);
|
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);
|
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;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-ui-popup ul.menu li.title > span {
|
span.ffz-handle {
|
||||||
display: block;
|
display: inline-block;
|
||||||
padding: 10px 20px;
|
position: relative;
|
||||||
line-height: 16px;
|
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 {
|
.ffz-ui-popup ul.menu a {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
@ -1006,6 +1079,23 @@ body:not(.ffz-chat-purge-icon) .ember-chat .mod-icons .purge { display: none; }
|
||||||
|
|
||||||
/* Emoticon Tooltips */
|
/* 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 {
|
.tipsy .tipsy-inner {
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
@ -1165,7 +1255,7 @@ a.unsafe-link {
|
||||||
|
|
||||||
.ffz-room-row:hover svg path,
|
.ffz-room-row:hover svg path,
|
||||||
.ffz-room-row:focus 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:hover td,
|
||||||
.ffz-room-row:focus td,
|
.ffz-room-row:focus td,
|
||||||
|
@ -1643,7 +1733,7 @@ li[data-name="following"] a {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
top: 8px;
|
top: 8px;
|
||||||
|
|
||||||
line-height: 14px;
|
line-height: 14px;
|
||||||
padding: 2px 5px;
|
padding: 2px 5px;
|
||||||
}
|
}
|
||||||
|
@ -1696,12 +1786,12 @@ li[data-name="following"] a {
|
||||||
|
|
||||||
/* High Contrast Chat */
|
/* 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 {
|
.ffz-high-contrast-chat-text .ember-chat-container {
|
||||||
color: "#000";
|
color: "#000";
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-high-contrast-chat-bg .chat-container,
|
.ffz-high-contrast-chat-bg .chat-container,
|
||||||
.ffz-high-contrast-chat-bg .ember-chat-container {
|
.ffz-high-contrast-chat-bg .ember-chat-container {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue