1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-08-31 02:10:55 +00:00

Clean up file formatting. Mixed line endings and white spacing are the worst.

This commit is contained in:
SirStendec 2016-07-13 02:31:26 -04:00
parent 3fb0c5a358
commit 4b11c2f591
41 changed files with 4053 additions and 4053 deletions

View file

@ -275,6 +275,6 @@ if (typeof module !== "undefined" && module.exports) {
module.exports.saveAs = saveAs;
} else if ((typeof define !== "undefined" && define !== null) && (define.amd !== null)) {
define([], function() {
return saveAs;
return saveAs;
});
}

View file

@ -132,9 +132,9 @@ FFZ.settings_info.sub_notice_badges = {
name: "Old-Style Subscriber Notice Badges",
no_bttv: true,
help: "Display a subscriber badge on old-style chat messages about new subscribers.",
help: "Display a subscriber badge on old-style chat messages about new subscribers.",
on_update: function(val) {
on_update: function(val) {
this.toggle_style('badges-sub-notice', ! this.has_bttv && ! val);
this.toggle_style('badges-sub-notice-on', ! this.has_bttv && val);
}
@ -231,8 +231,8 @@ FFZ.prototype.setup_badges = function() {
this.toggle_style('badges-transparent', val === 5);
document.body.classList.toggle('ffz-transparent-badges', val === 5);
this.toggle_style('badges-sub-notice', ! this.settings.sub_notice_badges);
this.toggle_style('badges-sub-notice-on', this.settings.sub_notice_badges);
this.toggle_style('badges-sub-notice', ! this.settings.sub_notice_badges);
this.toggle_style('badges-sub-notice-on', this.settings.sub_notice_badges);
}
this.toggle_style('badges-legacy', this.settings.legacy_badges === 3);
@ -345,9 +345,9 @@ FFZ.prototype.get_line_badges = function(msg) {
last_id = -1,
had_last = false,
room = msg.get && msg.get('room') || msg.room,
from = msg.get && msg.get('from') || msg.from,
tags = msg.get && msg.get('tags') || msg.tags || {},
room = msg.get && msg.get('room') || msg.room,
from = msg.get && msg.get('from') || msg.from,
tags = msg.get && msg.get('tags') || msg.tags || {},
badge_tag = tags.badges || {},
service = utils.ember_lookup('service:badges'),

View file

@ -1,5 +1,5 @@
var FFZ = window.FrankerFaceZ,
utils = require('./utils'),
utils = require('./utils'),
hue2rgb = function(p, q, t) {
if ( t < 0 ) t += 1;
@ -66,30 +66,30 @@ FFZ.settings_info.luv_contrast = {
method: function() {
var f = this,
old_val = this.settings.luv_contrast;
old_val = this.settings.luv_contrast;
utils.prompt(
"Luv Adjustment Minimum Contrast Ratio",
"Please enter a new value for the minimum contrast ratio required between username colors and the background.</p><p><b>Default:</b> 4.5",
old_val,
function(new_val) {
if ( new_val === null || new_val === undefined )
return;
utils.prompt(
"Luv Adjustment Minimum Contrast Ratio",
"Please enter a new value for the minimum contrast ratio required between username colors and the background.</p><p><b>Default:</b> 4.5",
old_val,
function(new_val) {
if ( new_val === null || new_val === undefined )
return;
var parsed = parseFloat(new_val);
if ( Number.isNaN(parsed) || ! Number.isFinite(parsed) )
parsed = 4.5;
var parsed = parseFloat(new_val);
if ( Number.isNaN(parsed) || ! Number.isFinite(parsed) )
parsed = 4.5;
f.settings.set("luv_contrast", parsed);
});
f.settings.set("luv_contrast", parsed);
});
},
on_update: function(val) {
this._rebuild_contrast();
this._rebuild_filter_styles();
this._rebuild_filter_styles();
if ( ! this.has_bttv && this.settings.fix_color == '1' )
this._rebuild_colors();
this._rebuild_colors();
}
};
@ -199,26 +199,26 @@ RGBAColor.prototype.eq = function(rgb) {
}
RGBAColor.fromName = function(name) {
var context = FFZ.Color._context;
if ( ! context ) {
var canvas = FFZ.Color._canvas = document.createElement('canvas');
context = FFZ.Color._context = canvas.getContext("2d");
}
var context = FFZ.Color._context;
if ( ! context ) {
var canvas = FFZ.Color._canvas = document.createElement('canvas');
context = FFZ.Color._context = canvas.getContext("2d");
}
context.clearRect(0,0,1,1);
context.fillStyle = name;
context.fillRect(0,0,1,1);
var data = context.getImageData(0,0,1,1);
context.clearRect(0,0,1,1);
context.fillStyle = name;
context.fillRect(0,0,1,1);
var data = context.getImageData(0,0,1,1);
if ( ! data || ! data.data || data.data.length !== 4 )
return null;
if ( ! data || ! data.data || data.data.length !== 4 )
return null;
return new RGBAColor(data.data[0], data.data[1], data.data[2], data.data[3] / 255);
return new RGBAColor(data.data[0], data.data[1], data.data[2], data.data[3] / 255);
}
RGBAColor.fromCSS = function(rgb) {
if ( ! rgb )
return null;
if ( ! rgb )
return null;
rgb = rgb.trim();
@ -230,7 +230,7 @@ RGBAColor.fromCSS = function(rgb) {
var r = match[1],
g = match[2],
b = match[3],
a = match[4];
a = match[4];
if ( r.charAt(r.length-1) === '%' )
r = 255 * (parseInt(r) / 100);
@ -247,19 +247,19 @@ RGBAColor.fromCSS = function(rgb) {
else
b = parseInt(b);
if ( a )
if ( a.charAt(a.length-1) === '%' )
a = parseInt(a) / 100;
else
a = parseFloat(a);
else
a = 1;
if ( a )
if ( a.charAt(a.length-1) === '%' )
a = parseInt(a) / 100;
else
a = parseFloat(a);
else
a = 1;
return new RGBAColor(
Math.min(Math.max(0, r), 255),
Math.min(Math.max(0, g), 255),
Math.min(Math.max(0, b), 255),
Math.min(Math.max(0, a), 1)
Math.min(Math.max(0, a), 1)
);
}
@ -272,7 +272,7 @@ RGBAColor.fromHex = function(code) {
(raw >> 16), // Red
(raw >> 8 & 0x00FF), // Green
(raw & 0x0000FF), // Blue,
1 // Alpha
1 // Alpha
)
}
@ -298,7 +298,7 @@ RGBAColor.fromHSVA = function(h, s, v, a) {
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, b*255), 255)),
a === undefined ? 1 : a
a === undefined ? 1 : a
);
}
@ -312,7 +312,7 @@ RGBAColor.fromXYZA = function(x, y, z, a) {
Math.max(0, Math.min(255, 255 * XYZAColor.channelConverter(R))),
Math.max(0, Math.min(255, 255 * XYZAColor.channelConverter(G))),
Math.max(0, Math.min(255, 255 * XYZAColor.channelConverter(B))),
a === undefined ? 1 : a
a === undefined ? 1 : a
);
}
@ -329,7 +329,7 @@ RGBAColor.fromHSLA = function(h, s, l, a) {
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)),
a === undefined ? 1 : a
a === undefined ? 1 : a
);
}
@ -366,7 +366,7 @@ RGBAColor.prototype.brighten = function(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.b + amount)),
this.a
this.a
);
}
@ -548,7 +548,7 @@ XYZAColor.fromRGBA = function(r, g, b, a) {
0.412453 * R + 0.357580 * G + 0.180423 * B,
0.212671 * R + 0.715160 * G + 0.072169 * B,
0.019334 * R + 0.119193 * G + 0.950227 * B,
a === undefined ? 1 : a
a === undefined ? 1 : a
);
}
@ -638,8 +638,8 @@ FFZ.prototype._rebuild_contrast = function() {
this._luv_required_bright = new XYZAColor(0, (this.settings.luv_contrast * (new RGBAColor(35,35,35,1).toXYZA().y + 0.05) - 0.05), 0, 1).toLUVA().l;
this._luv_required_dark = new XYZAColor(0, ((new RGBAColor(217,217,217,1).toXYZA().y + 0.05) / this.settings.luv_contrast - 0.05), 0, 1).toLUVA().l;
this._luv_background_bright = new XYZAColor(0, (this.settings.luv_contrast * (RGBAColor.fromCSS("#3c3a41").toXYZA().y + 0.05) - 0.05), 0, 1).toLUVA().l;
this._luv_background_dark = new XYZAColor(0, ((RGBAColor.fromCSS("#acacbf").toXYZA().y + 0.05) / this.settings.luv_contrast - 0.05), 0, 1).toLUVA().l;
this._luv_background_bright = new XYZAColor(0, (this.settings.luv_contrast * (RGBAColor.fromCSS("#3c3a41").toXYZA().y + 0.05) - 0.05), 0, 1).toLUVA().l;
this._luv_background_dark = new XYZAColor(0, ((RGBAColor.fromCSS("#acacbf").toXYZA().y + 0.05) / this.settings.luv_contrast - 0.05), 0, 1).toLUVA().l;
}
FFZ.prototype._rebuild_colors = function() {
@ -658,7 +658,7 @@ FFZ.prototype._update_colors = function(darkness_only) {
Settings = utils.ember_lookup('controller:settings'),
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('settings.darkMode')),
cr_dark = this.settings.dark_twitch || (Layout && Layout.get('isTheatreMode'));
cr_dark = this.settings.dark_twitch || (Layout && Layout.get('isTheatreMode'));
if ( darkness_only && this._color_old_darkness === is_dark )
return;
@ -680,20 +680,20 @@ FFZ.prototype._update_colors = function(darkness_only) {
FFZ.prototype._handle_filter_color = function(color) {
if (!( color instanceof RGBAColor ))
color = RGBAColor.fromCSS(color);
if (!( color instanceof RGBAColor ))
color = RGBAColor.fromCSS(color);
var light_color = color,
dark_color = color,
luv = color.toLUVA();
var light_color = color,
dark_color = color,
luv = color.toLUVA();
if ( luv.l < this._luv_background_bright )
light_color = luv._l(this._luv_background_bright).toRGBA();
if ( luv.l < this._luv_background_bright )
light_color = luv._l(this._luv_background_bright).toRGBA();
if ( luv.l > this._luv_background_dark )
dark_color = luv._l(this._luv_background_dark).toRGBA();
if ( luv.l > this._luv_background_dark )
dark_color = luv._l(this._luv_background_dark).toRGBA();
return [light_color, dark_color];
return [light_color, dark_color];
}
@ -701,90 +701,90 @@ FFZ.prototype._handle_color = function(color) {
if ( color instanceof RGBAColor )
color = color.toCSS();
if ( ! color )
return null;
if ( ! color )
return null;
if ( this._hex_colors.hasOwnProperty(color) )
return this._hex_colors[color];
return this._hex_colors[color];
var rgb = RGBAColor.fromCSS(color),
var rgb = RGBAColor.fromCSS(color),
light_color = rgb,
dark_color = rgb;
light_color = rgb,
dark_color = rgb;
// Color Blindness Handling
if ( this.settings.color_blind !== '0' ) {
var new_color = rgb.daltonize(this.settings.color_blind);
if ( ! rgb.eq(new_color) ) {
rgb = new_color;
light_color = dark_color = rgb;
}
}
// Color Blindness Handling
if ( this.settings.color_blind !== '0' ) {
var new_color = rgb.daltonize(this.settings.color_blind);
if ( ! rgb.eq(new_color) ) {
rgb = new_color;
light_color = dark_color = rgb;
}
}
// Color Processing - RGB
if ( this.settings.fix_color === '4' ) {
var lum = rgb.luminance();
// 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;
}
if ( lum > 0.3 ) {
var s = 127, nc = rgb;
while(s--) {
nc = nc.brighten(-1);
if ( nc.luminance() <= 0.3 )
break;
}
light_color = nc;
}
light_color = nc;
}
if ( lum < 0.15 ) {
var s = 127, nc = rgb;
while(s--) {
nc = nc.brighten();
if ( nc.luminance() >= 0.15 )
break;
}
if ( lum < 0.15 ) {
var s = 127, nc = rgb;
while(s--) {
nc = nc.brighten();
if ( nc.luminance() >= 0.15 )
break;
}
dark_color = nc;
}
}
dark_color = nc;
}
}
// Color Processing - HSL
if ( this.settings.fix_color === '2' ) {
var hsl = rgb.toHSLA();
// Color Processing - HSL
if ( this.settings.fix_color === '2' ) {
var hsl = rgb.toHSLA();
light_color = hsl._l(Math.min(Math.max(0, 0.7 * hsl.l), 1)).toRGBA();
dark_color = hsl._l(Math.min(Math.max(0, 0.3 + (0.7 * hsl.l)), 1)).toRGBA();
}
light_color = hsl._l(Math.min(Math.max(0, 0.7 * hsl.l), 1)).toRGBA();
dark_color = hsl._l(Math.min(Math.max(0, 0.3 + (0.7 * hsl.l)), 1)).toRGBA();
}
// Color Processing - HSV
if ( this.settings.fix_color === '3' ) {
var hsv = rgb.toHSVA();
// Color Processing - HSV
if ( this.settings.fix_color === '3' ) {
var hsv = rgb.toHSVA();
if ( hsv.s === 0 ) {
// Black and White
light_color = hsv._v(Math.min(Math.max(0.5, 0.5 * hsv.v), 1)).toRGBA();
dark_color = hsv._v(Math.min(Math.max(0.5, 0.5 + (0.5 * hsv.v)), 1)).toRGBA();
if ( hsv.s === 0 ) {
// Black and White
light_color = hsv._v(Math.min(Math.max(0.5, 0.5 * hsv.v), 1)).toRGBA();
dark_color = hsv._v(Math.min(Math.max(0.5, 0.5 + (0.5 * hsv.v)), 1)).toRGBA();
} else {
light_color = RGBAColor.fromHSVA(hsv.h, Math.min(Math.max(0.7, 0.7 + (0.3 * hsv.s)), 1), Math.min(0.7, hsv.v), hsv.a);
dark_color = RGBAColor.fromHSVA(hsv.h, Math.min(0.7, hsv.s), Math.min(Math.max(0.7, 0.7 + (0.3 * hsv.v)), 1), hsv.a);
}
}
} else {
light_color = RGBAColor.fromHSVA(hsv.h, Math.min(Math.max(0.7, 0.7 + (0.3 * hsv.s)), 1), Math.min(0.7, hsv.v), hsv.a);
dark_color = RGBAColor.fromHSVA(hsv.h, Math.min(0.7, hsv.s), Math.min(Math.max(0.7, 0.7 + (0.3 * hsv.v)), 1), hsv.a);
}
}
// Color Processing - LUV
if ( this.settings.fix_color === '1' ) {
var luv = rgb.toLUVA();
// Color Processing - LUV
if ( this.settings.fix_color === '1' ) {
var luv = rgb.toLUVA();
if ( luv.l > this._luv_required_dark )
light_color = luv._l(this._luv_required_dark).toRGBA();
if ( luv.l > this._luv_required_dark )
light_color = luv._l(this._luv_required_dark).toRGBA();
if ( luv.l < this._luv_required_bright )
dark_color = luv._l(this._luv_required_bright).toRGBA();
}
if ( luv.l < this._luv_required_bright )
dark_color = luv._l(this._luv_required_bright).toRGBA();
}
var out = this._hex_colors[color] = [light_color.toHex(), dark_color.toHex()];
return out;
var out = this._hex_colors[color] = [light_color.toHex(), dark_color.toHex()];
return out;
}

View file

@ -6,12 +6,12 @@ var SVGPATH = 'm120.95 1.74c4.08-0.09 8.33-0.84 12.21 0.82 3.61 1.8 7 4.16 11.01
IS_OSX = navigator.platform ? navigator.platform.indexOf('Mac') !== -1 : /OS X/.test(navigator.userAgent),
IS_WIN = navigator.platform ? navigator.platform.indexOf('Win') !== -1 : /Windows/.test(navigator.userAgent),
SEPARATORS = "[\\s`~<>!-#%-\\x2A,-/:;\\x3F@\\x5B-\\x5D_\\x7B}\\u00A1\\u00A7\\u00AB\\u00B6\\u00B7\\u00BB\\u00BF\\u037E\\u0387\\u055A-\\u055F\\u0589\\u058A\\u05BE\\u05C0\\u05C3\\u05C6\\u05F3\\u05F4\\u0609\\u060A\\u060C\\u060D\\u061B\\u061E\\u061F\\u066A-\\u066D\\u06D4\\u0700-\\u070D\\u07F7-\\u07F9\\u0830-\\u083E\\u085E\\u0964\\u0965\\u0970\\u0AF0\\u0DF4\\u0E4F\\u0E5A\\u0E5B\\u0F04-\\u0F12\\u0F14\\u0F3A-\\u0F3D\\u0F85\\u0FD0-\\u0FD4\\u0FD9\\u0FDA\\u104A-\\u104F\\u10FB\\u1360-\\u1368\\u1400\\u166D\\u166E\\u169B\\u169C\\u16EB-\\u16ED\\u1735\\u1736\\u17D4-\\u17D6\\u17D8-\\u17DA\\u1800-\\u180A\\u1944\\u1945\\u1A1E\\u1A1F\\u1AA0-\\u1AA6\\u1AA8-\\u1AAD\\u1B5A-\\u1B60\\u1BFC-\\u1BFF\\u1C3B-\\u1C3F\\u1C7E\\u1C7F\\u1CC0-\\u1CC7\\u1CD3\\u2010-\\u2027\\u2030-\\u2043\\u2045-\\u2051\\u2053-\\u205E\\u207D\\u207E\\u208D\\u208E\\u2329\\u232A\\u2768-\\u2775\\u27C5\\u27C6\\u27E6-\\u27EF\\u2983-\\u2998\\u29D8-\\u29DB\\u29FC\\u29FD\\u2CF9-\\u2CFC\\u2CFE\\u2CFF\\u2D70\\u2E00-\\u2E2E\\u2E30-\\u2E3B\\u3001-\\u3003\\u3008-\\u3011\\u3014-\\u301F\\u3030\\u303D\\u30A0\\u30FB\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA673\\uA67E\\uA6F2-\\uA6F7\\uA874-\\uA877\\uA8CE\\uA8CF\\uA8F8-\\uA8FA\\uA92E\\uA92F\\uA95F\\uA9C1-\\uA9CD\\uA9DE\\uA9DF\\uAA5C-\\uAA5F\\uAADE\\uAADF\\uAAF0\\uAAF1\\uABEB\\uFD3E\\uFD3F\\uFE10-\\uFE19\\uFE30-\\uFE52\\uFE54-\\uFE61\\uFE63\\uFE68\\uFE6A\\uFE6B\\uFF01-\\uFF03\\uFF05-\\uFF0A\\uFF0C-\\uFF0F\\uFF1A\\uFF1B\\uFF1F\\uFF20\\uFF3B-\\uFF3D\\uFF3F\\uFF5B\\uFF5D\\uFF5F-\\uFF65]",
SEPARATORS = "[\\s`~<>!-#%-\\x2A,-/:;\\x3F@\\x5B-\\x5D_\\x7B}\\u00A1\\u00A7\\u00AB\\u00B6\\u00B7\\u00BB\\u00BF\\u037E\\u0387\\u055A-\\u055F\\u0589\\u058A\\u05BE\\u05C0\\u05C3\\u05C6\\u05F3\\u05F4\\u0609\\u060A\\u060C\\u060D\\u061B\\u061E\\u061F\\u066A-\\u066D\\u06D4\\u0700-\\u070D\\u07F7-\\u07F9\\u0830-\\u083E\\u085E\\u0964\\u0965\\u0970\\u0AF0\\u0DF4\\u0E4F\\u0E5A\\u0E5B\\u0F04-\\u0F12\\u0F14\\u0F3A-\\u0F3D\\u0F85\\u0FD0-\\u0FD4\\u0FD9\\u0FDA\\u104A-\\u104F\\u10FB\\u1360-\\u1368\\u1400\\u166D\\u166E\\u169B\\u169C\\u16EB-\\u16ED\\u1735\\u1736\\u17D4-\\u17D6\\u17D8-\\u17DA\\u1800-\\u180A\\u1944\\u1945\\u1A1E\\u1A1F\\u1AA0-\\u1AA6\\u1AA8-\\u1AAD\\u1B5A-\\u1B60\\u1BFC-\\u1BFF\\u1C3B-\\u1C3F\\u1C7E\\u1C7F\\u1CC0-\\u1CC7\\u1CD3\\u2010-\\u2027\\u2030-\\u2043\\u2045-\\u2051\\u2053-\\u205E\\u207D\\u207E\\u208D\\u208E\\u2329\\u232A\\u2768-\\u2775\\u27C5\\u27C6\\u27E6-\\u27EF\\u2983-\\u2998\\u29D8-\\u29DB\\u29FC\\u29FD\\u2CF9-\\u2CFC\\u2CFE\\u2CFF\\u2D70\\u2E00-\\u2E2E\\u2E30-\\u2E3B\\u3001-\\u3003\\u3008-\\u3011\\u3014-\\u301F\\u3030\\u303D\\u30A0\\u30FB\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA673\\uA67E\\uA6F2-\\uA6F7\\uA874-\\uA877\\uA8CE\\uA8CF\\uA8F8-\\uA8FA\\uA92E\\uA92F\\uA95F\\uA9C1-\\uA9CD\\uA9DE\\uA9DF\\uAA5C-\\uAA5F\\uAADE\\uAADF\\uAAF0\\uAAF1\\uABEB\\uFD3E\\uFD3F\\uFE10-\\uFE19\\uFE30-\\uFE52\\uFE54-\\uFE61\\uFE63\\uFE68\\uFE6A\\uFE6B\\uFF01-\\uFF03\\uFF05-\\uFF0A\\uFF0C-\\uFF0F\\uFF1A\\uFF1B\\uFF1F\\uFF20\\uFF3B-\\uFF3D\\uFF3F\\uFF5B\\uFF5D\\uFF5F-\\uFF65]",
SPLITTER = new RegExp(SEPARATORS + "*," + SEPARATORS + "*"),
svg = function(cls, width, height, path, viewbox) {
return '<svg version="1.1" class="ffz-svg svg-' + cls + '" height="' + height + 'px" width="' + width + 'px" x="0px" y="0px" viewbox="' + (viewbox||'0 0 16 16') + '"><path clip-rule="evenodd" fill-rule="evenodd" d="' + path + '"></path></svg>';
};
svg = function(cls, width, height, path, viewbox) {
return '<svg version="1.1" class="ffz-svg svg-' + cls + '" height="' + height + 'px" width="' + width + 'px" x="0px" y="0px" viewbox="' + (viewbox||'0 0 16 16') + '"><path clip-rule="evenodd" fill-rule="evenodd" d="' + path + '"></path></svg>';
};
module.exports = FrankerFaceZ.constants = {
@ -22,8 +22,8 @@ module.exports = FrankerFaceZ.constants = {
IS_WIN: IS_WIN,
META_NAME: IS_OSX ? "⌘" : (IS_WIN ? "Win" : "Meta"),
// Twitch Client ID for API Stuff
CLIENT_ID: "a3bc9znoz6vi8ozsoca0inlcr4fcvkl",
// Twitch Client ID for API Stuff
CLIENT_ID: "a3bc9znoz6vi8ozsoca0inlcr4fcvkl",
API_SERVER: "https://api.frankerfacez.com/",
@ -36,12 +36,12 @@ module.exports = FrankerFaceZ.constants = {
["wss://localhost:8001/", 1]]
},
CHAT_COLORS: ["#FF0000", "#0000FF", "#008000", "#B22222", "#FF7F50", "#9ACD32", "#FF4500", "#2E8B57", "#DAA520", "#D2691E", "#5F9EA0", "#1E90FF", "#FF69B4", "#8A2BE2", "#00FF7F"],
CHAT_COLORS: ["#FF0000", "#0000FF", "#008000", "#B22222", "#FF7F50", "#9ACD32", "#FF4500", "#2E8B57", "#DAA520", "#D2691E", "#5F9EA0", "#1E90FF", "#FF69B4", "#8A2BE2", "#00FF7F"],
TOOLTIP_DISTANCE: 50,
SEPARATORS: SEPARATORS,
SPLITTER: SPLITTER,
SEPARATORS: SEPARATORS,
SPLITTER: SPLITTER,
UUID_TEST: /(?:^| +)([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}) *$/i,
@ -92,44 +92,44 @@ module.exports = FrankerFaceZ.constants = {
EMOJI_REGEX: /(\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc41\u200d\ud83d\udde8|(?:[\u0023\u002a\u0030-\u0039])\ufe0f?\u20e3|(?:(?:[\u261d\u270c])(?:\ufe0f|(?!\ufe0e))|\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca\udfcb]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd75\udd90\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0]|\ud83e\udd18|[\u26f9\u270a\u270b\u270d])(?:\ud83c[\udffb-\udfff]|)|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf21\udf24-\udf84\udf86-\udf93\udf96\udf97\udf99-\udf9b\udf9e-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcc-\udff0\udff3-\udff5\udff7-\udfff]|\ud83d[\udc00-\udc41\udc44\udc45\udc51-\udc65\udc6a-\udc6d\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udca9\udcab-\udcfd\udcff-\udd3d\udd49-\udd4e\udd50-\udd67\udd6f\udd70\udd73\udd74\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\udecb-\uded0\udee0-\udee5\udee9\udeeb\udeec\udef0\udef3]|\ud83e[\udd10-\udd17\udd80-\udd84\uddc0]|[\u2328\u23cf\u23e9-\u23f3\u23f8-\u23fa\u2602-\u2604\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638\u2692\u2694\u2696\u2697\u2699\u269b\u269c\u26b0\u26b1\u26c8\u26ce\u26cf\u26d1\u26d3\u26e9\u26f0\u26f1\u26f4\u26f7\u26f8\u2705\u271d\u2721\u2728\u274c\u274e\u2753-\u2755\u2763\u2795-\u2797\u27b0\u27bf\ue50a]|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37]|[\u00a9\u00ae\u203c\u2049\u2122\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600\u2601\u260e\u2611\u2614\u2615\u2639\u263a\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2693\u26a0\u26a1\u26aa\u26ab\u26bd\u26be\u26c4\u26c5\u26d4\u26ea\u26f2\u26f3\u26f5\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u2733\u2734\u2744\u2747\u2757\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e)))/g,
EMOJI_CATEGORIES: {
people: "People & Smileys",
nature: "Animals & Nature",
food: "Food & Drink",
activity: "Activity",
travel: "Travel & Places",
objects: "Objects",
symbols: "Symbols",
flags: "Flags"
//modifier: "Modifiers"
},
EMOJI_CATEGORIES: {
people: "People & Smileys",
nature: "Animals & Nature",
food: "Food & Drink",
activity: "Activity",
travel: "Travel & Places",
objects: "Objects",
symbols: "Symbols",
flags: "Flags"
//modifier: "Modifiers"
},
EMOJI_LOGOS: {
activity: '26bd',
food: '1f34e',
flags: '1f1fa-1f1f8',
nature: '1f436',
objects: '1f4a1',
people: '1f632',
symbols: '2049',
travel: '1f697'
//modifier: '262f'
},
EMOJI_LOGOS: {
activity: '26bd',
food: '1f34e',
flags: '1f1fa-1f1f8',
nature: '1f436',
objects: '1f4a1',
people: '1f632',
symbols: '2049',
travel: '1f697'
//modifier: '262f'
},
ZREKNARF: svg('glyph_views svg-zreknarf', 16, 12.5, SVGPATH, '0 0 249 195'),
CHAT_BUTTON: svg('emoticons', 24, 18, SVGPATH, '0 0 249 195'),
ROOMS: svg('glyph_views svg-roomlist', 16, 16, 'M1,13v-2h14v2H1z M1,5h13v2H1V5z M1,2h10v2H1V2z M12,10H1V8h11V10z'),
CAMERA: svg('camera', 16, 16, 'M24,20v6H4V10h20v6l8-6v16L24,20z', '0 0 36 36'),
INVITE: svg('plus', 16, 16, 'M15,9h-3v3h-2V9H7V7h3V4h2v3h3V9z M9,6H6v4h2h1v3h4l0,0l0,0v1h-3H4H1v-1l3-3h2L4,8V2h6v1H9V6z'),
LIVE: svg('glyph_live_small', 13, 16,'M11,14H5H2v-1l3-3h2L5,8V2h6v6l-2,2h2l3,3v1H11z'),
EYE: svg('glyph_views svg-eye', 16, 16, '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'),
CLOCK: svg('glyph_views svg-clock', 16, 16, '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'),
GEAR: svg('gear', 16, 16, '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'),
HEART: svg('heart', 16, 16, 'M8,13.5L1.5,7V4l2-2h3L8,3.5L9.5,2h3l2,2v3L8,13.5z'),
UNHEART: svg('unheart', 16, 16, 'M1,9V7h14v2H1z M1,4l2-2h3l2,2l2-2h3l2,2v2H1V4z M8,14l-4.667-4h9.333L8,14z'),
EMOTE: svg('emote', 16, 16, 'M9,18c-4.971,0-9-4.029-9-9s4.029-9,9-9s9,4.029,9,9S13.971,18,9,18z M14,4.111V4h-0.111C12.627,2.766,10.904,2,9,2C7.095,2,5.373,2.766,4.111,4H4v0.111C2.766,5.373,2,7.096,2,9s0.766,3.627,2,4.889V14l0.05-0.051C5.317,15.217,7.067,16,9,16c1.934,0,3.684-0.783,4.949-2.051L14,14v-0.111c1.234-1.262,2-2.984,2-4.889S15.234,5.373,14,4.111zM11,6h2v4h-2V6z M12.535,12.535C11.631,13.44,10.381,14,9,14s-2.631-0.56-3.536-1.465l0.707-0.707C6.896,12.553,7.896,13,9,13s2.104-0.447,2.828-1.172L12.535,12.535z M5,6h2v4H5V6z', '0 0 18 18'),
STAR: svg('star', 16, 16, 'M15,6l-4.041,2.694L13,14l-5-3.333L3,14l2.041-5.306L1,6h5.077L8,1l1.924,5H15z'),
CLOSE: svg('close_small', 16, 16, 'M12.657,4.757L9.414,8l3.243,3.242l-1.415,1.415L8,9.414l-3.243,3.243l-1.414-1.415L6.586,8L3.343,4.757l1.414-1.414L8,6.586l3.242-3.243L12.657,4.757z'),
EDIT: svg('edit', 16, 16, 'M6.414,12.414L3.586,9.586l8-8l2.828,2.828L6.414,12.414z M4.829,14H2l0,0v-2.828l0.586-0.586l2.828,2.828L4.829,14z'),
GRAPH: svg('glyph_views graph', 16, 16, 'M1,16V2h16v14H1z M5,4H3v1h2V4z M5,7H3v1h2V7z M5,10H3v1h2V10zM5,13H3v1h2V13z M9,7H7v7h2V7z M12,10h-2v4h2V10z M15,4h-2v10h2V4z', '0 0 18 18')
ZREKNARF: svg('glyph_views svg-zreknarf', 16, 12.5, SVGPATH, '0 0 249 195'),
CHAT_BUTTON: svg('emoticons', 24, 18, SVGPATH, '0 0 249 195'),
ROOMS: svg('glyph_views svg-roomlist', 16, 16, 'M1,13v-2h14v2H1z M1,5h13v2H1V5z M1,2h10v2H1V2z M12,10H1V8h11V10z'),
CAMERA: svg('camera', 16, 16, 'M24,20v6H4V10h20v6l8-6v16L24,20z', '0 0 36 36'),
INVITE: svg('plus', 16, 16, 'M15,9h-3v3h-2V9H7V7h3V4h2v3h3V9z M9,6H6v4h2h1v3h4l0,0l0,0v1h-3H4H1v-1l3-3h2L4,8V2h6v1H9V6z'),
LIVE: svg('glyph_live_small', 13, 16,'M11,14H5H2v-1l3-3h2L5,8V2h6v6l-2,2h2l3,3v1H11z'),
EYE: svg('glyph_views svg-eye', 16, 16, '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'),
CLOCK: svg('glyph_views svg-clock', 16, 16, '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'),
GEAR: svg('gear', 16, 16, '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'),
HEART: svg('heart', 16, 16, 'M8,13.5L1.5,7V4l2-2h3L8,3.5L9.5,2h3l2,2v3L8,13.5z'),
UNHEART: svg('unheart', 16, 16, 'M1,9V7h14v2H1z M1,4l2-2h3l2,2l2-2h3l2,2v2H1V4z M8,14l-4.667-4h9.333L8,14z'),
EMOTE: svg('emote', 16, 16, 'M9,18c-4.971,0-9-4.029-9-9s4.029-9,9-9s9,4.029,9,9S13.971,18,9,18z M14,4.111V4h-0.111C12.627,2.766,10.904,2,9,2C7.095,2,5.373,2.766,4.111,4H4v0.111C2.766,5.373,2,7.096,2,9s0.766,3.627,2,4.889V14l0.05-0.051C5.317,15.217,7.067,16,9,16c1.934,0,3.684-0.783,4.949-2.051L14,14v-0.111c1.234-1.262,2-2.984,2-4.889S15.234,5.373,14,4.111zM11,6h2v4h-2V6z M12.535,12.535C11.631,13.44,10.381,14,9,14s-2.631-0.56-3.536-1.465l0.707-0.707C6.896,12.553,7.896,13,9,13s2.104-0.447,2.828-1.172L12.535,12.535z M5,6h2v4H5V6z', '0 0 18 18'),
STAR: svg('star', 16, 16, 'M15,6l-4.041,2.694L13,14l-5-3.333L3,14l2.041-5.306L1,6h5.077L8,1l1.924,5H15z'),
CLOSE: svg('close_small', 16, 16, 'M12.657,4.757L9.414,8l3.243,3.242l-1.415,1.415L8,9.414l-3.243,3.243l-1.414-1.415L6.586,8L3.343,4.757l1.414-1.414L8,6.586l3.242-3.243L12.657,4.757z'),
EDIT: svg('edit', 16, 16, 'M6.414,12.414L3.586,9.586l8-8l2.828,2.828L6.414,12.414z M4.829,14H2l0,0v-2.828l0.586-0.586l2.828,2.828L4.829,14z'),
GRAPH: svg('glyph_views graph', 16, 16, 'M1,16V2h16v14H1z M5,4H3v1h2V4z M5,7H3v1h2V7z M5,10H3v1h2V10zM5,13H3v1h2V13z M9,7H7v7h2V7z M12,10h-2v4h2V10z M15,4h-2v10h2V4z', '0 0 18 18')
}

View file

@ -241,8 +241,8 @@ FFZ.prototype.modify_channel_index = function(view) {
var top = event && event.target && event.target.scrollTop,
height = this.get('layout.playerSize.1');
if ( ! top )
top = jQuery(this.get('element')).parents('.tse-scroll-content').scrollTop();
if ( ! top )
top = jQuery(this.get('element')).parents('.tse-scroll-content').scrollTop();
document.body.classList.toggle('ffz-small-player', f.settings.small_player && top >= height);
},

File diff suppressed because it is too large Load diff

View file

@ -14,11 +14,11 @@ FFZ.basic_settings.delayed_chat = {
300: "Minor (Bot Moderation; 0.3s)",
1200: "Normal (Human Moderation; 1.2s)",
5000: "Large (Spoiler Removal / Really Slow Mods; 5s)",
10000: "Extra Large (10s)",
15000: "Extremely Large (15s)",
20000: "Mods Asleep; Delay Chat (20s)",
30000: "Half a Minute (30s)",
60000: "Why??? (1m)"
10000: "Extra Large (10s)",
15000: "Extremely Large (15s)",
20000: "Mods Asleep; Delay Chat (20s)",
30000: "Half a Minute (30s)",
60000: "Why??? (1m)"
},
category: "Chat",
@ -141,11 +141,11 @@ FFZ.settings_info.chat_delay = {
300: "Minor (Bot Moderation; 0.3s)",
1200: "Normal (Human Moderation; 1.2s)",
5000: "Large (Spoiler Removal / Really Slow Mods; 5s)",
10000: "Extra Large (10s)",
15000: "Extremely Large (15s)",
20000: "Mods Asleep; Delay Chat (20s)",
30000: "Half a Minute (30s)",
60000: "Why??? (1m)"
10000: "Extra Large (10s)",
15000: "Extremely Large (15s)",
20000: "Mods Asleep; Delay Chat (20s)",
30000: "Half a Minute (30s)",
60000: "Why??? (1m)"
},
value: 0,
@ -328,22 +328,22 @@ FFZ.settings_info.visible_rooms = {
// --------------------
FFZ.prototype.refresh_chat = function() {
var parents, lines = jQuery('ul.chat-lines');
if ( this.has_bttv || ! lines || ! lines.length )
return;
var parents, lines = jQuery('ul.chat-lines');
if ( this.has_bttv || ! lines || ! lines.length )
return;
parents = lines.parents('.chatReplay');
if ( parents && parents.length )
return;
parents = lines.parents('.chatReplay');
if ( parents && parents.length )
return;
// There are chat-lines in the DOM and they aren't chat replay.
var controller = utils.ember_lookup('controller:chat');
if ( ! controller )
return;
// There are chat-lines in the DOM and they aren't chat replay.
var controller = utils.ember_lookup('controller:chat');
if ( ! controller )
return;
var current_room = controller.get("currentRoom");
controller.blurRoom();
controller.focusRoom(current_room);
var current_room = controller.get("currentRoom");
controller.blurRoom();
controller.focusRoom(current_room);
}
FFZ.prototype.setup_chatview = function() {
@ -402,10 +402,10 @@ FFZ.prototype.setup_chatview = function() {
f._chatv.ffzUpdateMenuUnread();
}.observes("invitedPrivateGroupRooms"),
ffzChangedRoom: function() {
if ( f._inputv )
Ember.propertyDidChange(f._inputv, 'ffz_emoticons');
}.observes('currentRoom'),
ffzChangedRoom: function() {
if ( f._inputv )
Ember.propertyDidChange(f._inputv, 'ffz_emoticons');
}.observes('currentRoom'),
notificationsCount: function() {
if ( ! f._chatv || f.has_bttv )
@ -487,7 +487,7 @@ FFZ.prototype.modify_chat_view = function(view) {
var f = this;
utils.ember_reopen_view(view, {
ffz_init: function() {
f._chatv = this;
f._chatv = this;
var room_id = this.get('controller.currentRoom.id'),
el = this.get('element');
@ -559,7 +559,7 @@ FFZ.prototype.modify_chat_view = function(view) {
ffzChangeRoom: Ember.observer('controller.currentRoom', function() {
f.update_ui_link();
this.ffz_unread = this.ffz_unread || {};
this.ffz_unread = this.ffz_unread || {};
// Close mod cards when changing to a new room.
if ( f._mod_card )
@ -699,7 +699,7 @@ FFZ.prototype.modify_chat_view = function(view) {
ffzUpdateUnread: function(target_id) {
var current_id = this.get('controller.currentRoom.id');
this.ffz_unread = this.ffz_unread || {};
this.ffz_unread = this.ffz_unread || {};
if ( target_id === current_id )
// We don't care about updates to the current room.
@ -1036,7 +1036,7 @@ FFZ.prototype.modify_chat_view = function(view) {
link.title = "Chat Room Management";
link.innerHTML = '<figure class="icon">' + constants.ROOMS + '</figure><span class="notifications"></span>';
jQuery(link).tipsy({gravity: "n", offset: 5});
jQuery(link).tipsy({gravity: "n", offset: 5});
link.addEventListener('click', function() {
var controller = view.get('controller');

View file

@ -177,22 +177,22 @@ FFZ.prototype.modify_conversation_line = function(component) {
return this._super(e);
},
didUpdate: function() { this.ffzRender() },
ffz_init: function() { this.ffzRender() },
didUpdate: function() { this.ffzRender() },
ffz_init: function() { this.ffzRender() },
ffzRender: function() {
var el = this.get('element'),
e = [],
var el = this.get('element'),
e = [],
user = this.get('message.from.username'),
user = this.get('message.from.username'),
raw_color = this.get('message.from.color'),
colors = raw_color && f._handle_color(raw_color),
is_dark = (Layout && Layout.get('isTheatreMode')) || f.settings.dark_twitch,
myself = f.get_user(),
from_me = myself && myself.login === user,
myself = f.get_user(),
from_me = myself && myself.login === user,
alias = f.aliases[user],
alias = f.aliases[user],
name = this.get('message.from.displayName') || (user && user.capitalize()) || "unknown user",
style = colors && 'color:' + (is_dark ? colors[1] : colors[0]),
colored = style ? ' has-color' : '';
@ -212,7 +212,7 @@ FFZ.prototype.modify_conversation_line = function(component) {
e.push('<span class="message' + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '') + '">');
e.push(f.render_tokens(this.get('tokenizedMessage'), true, f.settings.filter_whispered_links && !from_me));
e.push('</span>');
el.innerHTML = e.join('');
el.innerHTML = e.join('');
}
});
}

View file

@ -246,13 +246,13 @@ FFZ.prototype._modify_following = function() {
this.log("Found Following model.");
Following.reopen({
ffz_streams: {},
ffz_hosts_for: {},
ffz_hosts_for: {},
ffz_skipped: 0,
empty: function() {
this._super();
this.set("ffz_streams", {});
this.set("ffz_hosts_for", {});
this.set("ffz_hosts_for", {});
this.set("ffz_skipped", 0);
},
@ -260,7 +260,7 @@ FFZ.prototype._modify_following = function() {
// We have to override request with nearly the same logic
// to prevent infinitely trying to load more streams.
if (!Twitch.user.isLoggedIn() || window.App.get("disableFollowingDirectory")) return RSVP.resolve({
hosts: [], _total: 0
hosts: [], _total: 0
});
var t = {
@ -268,16 +268,16 @@ FFZ.prototype._modify_following = function() {
offset: this.get('content.length') + this.get('ffz_skipped')
};
// Don't use FFZ's Client ID because loading hosts is a normal part
// of the dashboard. We're just manipulating the logic a bit.
// Don't use FFZ's Client ID because loading hosts is a normal part
// of the dashboard. We're just manipulating the logic a bit.
return Twitch.api.get("/api/users/:login/followed/hosting", t);
},
afterSuccess: function(e) {
var valid_hosts = [],
var valid_hosts = [],
streams = this.get('ffz_streams'),
skipped = this.get('ffz_skipped'),
hosts_for = this.get('ffz_hosts_for'),
hosts_for = this.get('ffz_hosts_for'),
t = this;
@ -285,27 +285,27 @@ FFZ.prototype._modify_following = function() {
var host = e.hosts[i],
target = host && host.target && host.target.id;
if ( host.rollbackData )
host.rollbackData = undefined;
if ( host.rollbackData )
host.rollbackData = undefined;
if ( f.settings.directory_group_hosts && streams[target] ) {
skipped++;
//hosts_for[target] && hosts_for[target]
streams[target].ffz_hosts && streams[target].ffz_hosts.push({logo: host.logo, name: host.name, display_name: host.display_name});
//hosts_for[target] && hosts_for[target]
streams[target].ffz_hosts && streams[target].ffz_hosts.push({logo: host.logo, name: host.name, display_name: host.display_name});
continue;
}
streams[target] = host;
//hosts_for[target] = [{logo: host.logo, name: host.name, display_name: host.display_name}];
//hosts_for[target] = [{logo: host.logo, name: host.name, display_name: host.display_name}];
host.ffz_hosts = [{logo: host.logo, name: host.name, display_name: host.display_name}];
valid_hosts.push(host);
}
//f.log("Stuff!", [this, e, valid_hosts, skipped]);
//f.log("Stuff!", [this, e, valid_hosts, skipped]);
this.set('ffz_skipped', skipped);
this.setContent(valid_hosts);
this.set('ffz_skipped', skipped);
this.setContent(valid_hosts);
// We could get non-empty results even with no new hosts.
this.set('gotNonEmptyResults', e.hosts && e.hosts.length);
@ -321,31 +321,31 @@ FFZ.prototype._modify_following = function() {
// TODO: Something less stupid.
for(var i=0; i < content.length; i++) {
var host = content[i];
var host = content[i];
host_copy.push({
display_name: host.display_name,
game: host.game,
id: host.id,
logo: host.logo,
name: host.name,
target: {
_id: host.target._id,
channel: {
display_name: host.target.channel.display_name,
id: host.target.channel.id,
logo: host.target.channel.logo,
name: host.target.channel.name,
url: host.target.channel.url
},
id: host.target.id,
meta_game: host.target.meta_game,
preview: host.target.preview,
title: host.target.title,
url: host.target.url,
viewers: host.target.viewers
}
});
}
display_name: host.display_name,
game: host.game,
id: host.id,
logo: host.logo,
name: host.name,
target: {
_id: host.target._id,
channel: {
display_name: host.target.channel.display_name,
id: host.target.channel.id,
logo: host.target.channel.logo,
name: host.target.channel.name,
url: host.target.channel.url
},
id: host.target.id,
meta_game: host.target.meta_game,
preview: host.target.preview,
title: host.target.title,
url: host.target.url,
viewers: host.target.viewers
}
});
}
Following.clear();
Following.afterSuccess({hosts: host_copy, _total: total});
@ -421,7 +421,7 @@ FFZ.prototype.modify_game_follow_button = function(component) {
FFZ.prototype.modify_directory_live = function(component, is_csgo) {
var f = this,
pref = is_csgo ? 'channel.' : 'stream.';
pref = is_csgo ? 'channel.' : 'stream.';
utils.ember_reopen_view(component, {
ffz_init: function() {
@ -429,11 +429,11 @@ FFZ.prototype.modify_directory_live = function(component, is_csgo) {
meta = el && el.querySelector('.meta'),
thumb = el && el.querySelector('.thumb'),
cap = thumb && thumb.querySelector('.cap'),
channel_id = this.get(pref + 'channel.name'),
channel_id = this.get(pref + 'channel.name'),
game = this.get(pref + 'game');
el.classList.add('ffz-directory-preview');
el.setAttribute('data-channel', channel_id);
el.setAttribute('data-channel', channel_id);
el.setAttribute('data-game', game);
el.classList.toggle('ffz-game-banned', f.settings.banned_games.indexOf(game && game.toLowerCase()) !== -1);
@ -450,8 +450,8 @@ FFZ.prototype.modify_directory_live = function(component, is_csgo) {
this.ffzUpdateUptime();
}
this._ffz_image_timer = setInterval(this.ffzRotateImage.bind(this), 30000);
this.ffzRotateImage();
this._ffz_image_timer = setInterval(this.ffzRotateImage.bind(this), 30000);
this.ffzRotateImage();
if ( f.settings.directory_logos ) {
el.classList.add('ffz-directory-logo');
@ -468,8 +468,8 @@ FFZ.prototype.modify_directory_live = function(component, is_csgo) {
link.href = '/' + channel_id;
link.addEventListener('click', function(e) {
if ( e.button !== 0 || e.altKey || e.ctrlKey || e.shiftKey || e.metaKey )
return;
if ( e.button !== 0 || e.altKey || e.ctrlKey || e.shiftKey || e.metaKey )
return;
var Channel = utils.ember_resolve('model:deprecated-channel');
if ( ! Channel )
@ -494,21 +494,21 @@ FFZ.prototype.modify_directory_live = function(component, is_csgo) {
if ( this._ffz_uptime_timer )
clearInterval(this._ffz_uptime_timer);
if ( this._ffz_image_timer )
clearInterval(this._ffz_image_timer);
if ( this._ffz_image_timer )
clearInterval(this._ffz_image_timer);
},
ffzRotateImage: function() {
var url = this.get(pref + 'preview.medium'),
now = Math.round((new Date).getTime() / 150000);
ffzRotateImage: function() {
var url = this.get(pref + 'preview.medium'),
now = Math.round((new Date).getTime() / 150000);
if ( FFZ._image_cache[url] && FFZ._image_cache[url] !== now )
url += '?_=' + now;
else
FFZ._image_cache[url] = now;
if ( FFZ._image_cache[url] && FFZ._image_cache[url] !== now )
url += '?_=' + now;
else
FFZ._image_cache[url] = now;
this.$('.thumb .cap img').attr('src', url);
},
this.$('.thumb .cap img').attr('src', url);
},
ffzUpdateUptime: function() {
var raw_created = this.get(pref + 'created_at'),
@ -554,7 +554,7 @@ FFZ.prototype.modify_video_preview = function(component) {
boxart.setAttribute('original-title', game);
boxart.addEventListener('click', function(e) {
if ( e.button !== 0 || e.altKey || e.ctrlKey || e.shiftKey || e.metaKey )
return;
return;
e.preventDefault();
jQuery('.tipsy').remove();
@ -661,25 +661,25 @@ FFZ.prototype.modify_directory_host = function(component) {
f.show_popup(menu, [x, y], document.querySelector('#main_col > .tse-scroll-content > .tse-content'));
},
ffzRotateImage: function() {
var url = this.get('stream.target.preview'),
now = Math.round((new Date).getTime() / 150000);
ffzRotateImage: function() {
var url = this.get('stream.target.preview'),
now = Math.round((new Date).getTime() / 150000);
if ( FFZ._image_cache[url] && FFZ._image_cache[url] !== now )
url += '?_=' + now;
else
FFZ._image_cache[url] = now;
if ( FFZ._image_cache[url] && FFZ._image_cache[url] !== now )
url += '?_=' + now;
else
FFZ._image_cache[url] = now;
this.$('.thumb .cap img').attr('src', url);
},
this.$('.thumb .cap img').attr('src', url);
},
ffz_destroy: function() {
var target = this.get('stream.target.channel');
if ( f._popup && f._popup.classList.contains('ffz-channel-selector') && f._popup.getAttribute('data-channel') === target )
f.close_popup();
if ( this._ffz_image_timer )
clearInterval(this._ffz_image_timer);
if ( this._ffz_image_timer )
clearInterval(this._ffz_image_timer);
},
ffz_init: function() {
@ -700,8 +700,8 @@ FFZ.prototype.modify_directory_host = function(component) {
el.classList.toggle('ffz-game-banned', f.settings.banned_games.indexOf(game && game.toLowerCase()) !== -1);
el.classList.toggle('ffz-game-spoilered', f.settings.spoiler_games.indexOf(game && game.toLowerCase()) !== -1);
this._ffz_image_timer = setInterval(this.ffzRotateImage.bind(this), 30000);
this.ffzRotateImage();
this._ffz_image_timer = setInterval(this.ffzRotateImage.bind(this), 30000);
this.ffzRotateImage();
if ( f.settings.directory_logos ) {
el.classList.add('ffz-directory-logo');

View file

@ -140,7 +140,7 @@ FFZ.prototype.setup_profile_following = function() {
}
});
// TODO: Add nice Manage Following button to the directory.
// TODO: Add nice Manage Following button to the directory.
// Now, rebuild any views.
try { FollowedItem.create().destroy();
@ -148,9 +148,9 @@ FFZ.prototype.setup_profile_following = function() {
var views = utils.ember_views();
if ( views ) {
for(var key in views) {
var view = views[key];
if ( views ) {
for(var key in views) {
var view = views[key];
if ( view instanceof FollowedItem ) {
this.log("Manually updating existing component:display-followed-item.", view);
try {
@ -161,7 +161,7 @@ FFZ.prototype.setup_profile_following = function() {
this.error("setup: component:display-followed-item ffzInit: " + err);
}
}
}
}
}
@ -358,11 +358,11 @@ FFZ.prototype._modify_display_followed_item = function(component) {
FFZ.prototype._hook_following = function(Following) {
var f = this;
if ( ! Following || Following.ffz_hooked )
return;
if ( ! Following || Following.ffz_hooked )
return;
Following.reopen({
ffz_hooked: true,
ffz_hooked: true,
apiLoad: function(e) {
var channel_id = this.get('id'),
t = this;
@ -398,11 +398,11 @@ FFZ.prototype._hook_following = function(Following) {
FFZ.prototype._hook_followers = function(Followers) {
var f = this;
if ( ! Followers || Followers.ffz_hooked )
return;
if ( ! Followers || Followers.ffz_hooked )
return;
Followers.reopen({
ffz_hooked: true,
ffz_hooked: true,
apiLoad: function(e) {
var channel_id = this.get('id'),
t = this;

View file

@ -1,5 +1,5 @@
var FFZ = window.FrankerFaceZ,
utils = require('../utils');
utils = require('../utils');
// --------------------
@ -108,18 +108,18 @@ FFZ.settings_info.right_column_width = {
method: function() {
var f = this,
old_val = this.settings.right_column_width || 340;
old_val = this.settings.right_column_width || 340;
utils.prompt("Right Sidebar Width", "Please enter a new width for the right sidebar, in pixels.</p><p><b>Minimum:</b> 250<br><b>Default:</b> 340", old_val, function(new_val) {
if ( new_val === null || new_val === undefined )
return;
utils.prompt("Right Sidebar Width", "Please enter a new width for the right sidebar, in pixels.</p><p><b>Minimum:</b> 250<br><b>Default:</b> 340", old_val, function(new_val) {
if ( new_val === null || new_val === undefined )
return;
var width = parseInt(new_val);
if ( ! width || Number.isNaN(width) || ! Number.isFinite(width) )
width = 340;
var width = parseInt(new_val);
if ( ! width || Number.isNaN(width) || ! Number.isFinite(width) )
width = 340;
f.settings.set('right_column_width', Math.max(250, width));
});
f.settings.set('right_column_width', Math.max(250, width));
});
},
on_update: function(val) {
@ -223,19 +223,19 @@ FFZ.prototype.setup_layout = function() {
height = size[1],
host_height = size[2];
return "<style>.dynamic-player, .dynamic-player object, .dynamic-player video{width:" + width + "px !important;height:" + height + "px !important} .dynamic-target-player,.dynamic-target-player object, .dynamic-target-player video{width:" + width + "px !important;height:" + host_height + "px !important}</style><style>.dynamic-player .player object, .dynamic-player .player video{width:100% !important; height:100% !important}</style>";
return "<style>.dynamic-player, .dynamic-player object, .dynamic-player video{width:" + width + "px !important;height:" + height + "px !important} .dynamic-target-player,.dynamic-target-player object, .dynamic-target-player video{width:" + width + "px !important;height:" + host_height + "px !important}</style><style>.dynamic-player .player object, .dynamic-player .player video{width:100% !important; height:100% !important}</style>";
}.property("playerSize"),
ffzPortraitWarning: function() {
var t = this;
// Delay this, in case we're just resizing the window.
setTimeout(function() {
if ( ! f.settings.portrait_mode || f._portrait_warning || f.settings.portrait_warning || document.body.getAttribute('data-current-path').indexOf('user.') !== 0 || ! t.get('isTooSmallForRightColumn') )
return;
var t = this;
// Delay this, in case we're just resizing the window.
setTimeout(function() {
if ( ! f.settings.portrait_mode || f._portrait_warning || f.settings.portrait_warning || document.body.getAttribute('data-current-path').indexOf('user.') !== 0 || ! t.get('isTooSmallForRightColumn') )
return;
f._portrait_warning = true;
f.show_message('Twitch\'s Chat Sidebar has been hidden as a result of FrankerFaceZ\'s Portrait Mode because the window is too wide.<br><br>Please <a href="#" onclick="ffz.settings.set(\'portrait_mode\',0);jQuery(this).parents(\'.ffz-noty\').remove();ffz._portrait_warning = false;return false">disable Portrait Mode</a> or make your window narrower.<br><br><a href="#" onclick="ffz.settings.set(\'portrait_warning\',true);jQuery(this).parents(\'.ffz-noty\').remove();return false">Do not show this message again</a>');
}, 50);
f._portrait_warning = true;
f.show_message('Twitch\'s Chat Sidebar has been hidden as a result of FrankerFaceZ\'s Portrait Mode because the window is too wide.<br><br>Please <a href="#" onclick="ffz.settings.set(\'portrait_mode\',0);jQuery(this).parents(\'.ffz-noty\').remove();ffz._portrait_warning = false;return false">disable Portrait Mode</a> or make your window narrower.<br><br><a href="#" onclick="ffz.settings.set(\'portrait_warning\',true);jQuery(this).parents(\'.ffz-noty\').remove();return false">Do not show this message again</a>');
}, 50);
}.observes("isTooSmallForRightColumn"),
@ -253,73 +253,73 @@ FFZ.prototype.setup_layout = function() {
out += 'width: 50vh !important; height: 28.125vh !important;';
if ( ! f.has_bttv ) {
if ( this.get('isRightColumnClosed') )
if ( this.get('isRightColumnClosed') )
out += 'top: 0; right: 0}';
else {
if ( this.get('portraitMode') ) {
var size = this.get('playerSize'),
video_below = this.get('portraitVideoBelow'),
else {
if ( this.get('portraitMode') ) {
var size = this.get('playerSize'),
video_below = this.get('portraitVideoBelow'),
video_height = size[1] + 120 + 60,
chat_height = window_height - video_height,
video_height = size[1] + 120 + 60,
chat_height = window_height - video_height,
video_top = video_below ? chat_height : 0,
chat_top = video_below ? 0 : video_height,
video_top = video_below ? chat_height : 0,
chat_top = video_below ? 0 : video_height,
theatre_video_height = Math.floor(Math.max(window_height * 0.1, Math.min(window_height - 300, 9 * window_width / 16))),
theatre_chat_height = window_height - theatre_video_height,
theatre_video_height = Math.floor(Math.max(window_height * 0.1, Math.min(window_height - 300, 9 * window_width / 16))),
theatre_chat_height = window_height - theatre_video_height,
theatre_video_top = video_below ? theatre_chat_height : 0,
theatre_chat_top = video_below ? 0 : theatre_video_height;
theatre_video_top = video_below ? theatre_chat_height : 0,
theatre_chat_top = video_below ? 0 : theatre_video_height;
out += 'top: ' + video_top + 'px;right: 0}' +
'body[data-current-path^="user."] #left_col .warp { min-height: inherit }' +
'body[data-current-path^="user."] #left_col { overflow: hidden }' +
'body[data-current-path^="user."] #left_col .warp,' +
'body[data-current-path^="user."] #left_col .warp,' +
'body[data-current-path^="user."] #left_col,' +
'body[data-current-path^="user."]:not(.ffz-sidebar-swap) #main_col{' +
'margin-right:0 !important;' +
'top:' + video_top + 'px;' +
'height:' + video_height + 'px}' +
'body[data-current-path^="user."].ffz-sidebar-swap #main_col{' +
'margin-left:0 !important;' +
'top:' + video_top + 'px;' +
'height:' + video_height + 'px}' +
'body[data-current-path^="user."] #right_col{' +
'width:100%;' +
'top:' + chat_top + 'px;' +
'height:' + chat_height + 'px}' +
'body[data-current-path^="user."]:not(.ffz-sidebar-swap) #main_col{' +
'margin-right:0 !important;' +
'top:' + video_top + 'px;' +
'height:' + video_height + 'px}' +
'body[data-current-path^="user."].ffz-sidebar-swap #main_col{' +
'margin-left:0 !important;' +
'top:' + video_top + 'px;' +
'height:' + video_height + 'px}' +
'body[data-current-path^="user."] #right_col{' +
'width:100%;' +
'top:' + chat_top + 'px;' +
'height:' + chat_height + 'px}' +
'body[data-current-path^="user."] .app-main.theatre #left_col .warp,' +
'body[data-current-path^="user."] .app-main.theatre #left_col,' +
'body[data-current-path^="user."] .app-main.theatre #main_col{' +
'top:' + theatre_video_top + 'px;' +
'height:' + theatre_video_height + 'px}' +
'body[data-current-path^="user."] .app-main.theatre #right_col{' +
'top:' + theatre_chat_top + 'px;' +
'height:' + theatre_chat_height + 'px}';
'body[data-current-path^="user."] .app-main.theatre #left_col,' +
'body[data-current-path^="user."] .app-main.theatre #main_col{' +
'top:' + theatre_video_top + 'px;' +
'height:' + theatre_video_height + 'px}' +
'body[data-current-path^="user."] .app-main.theatre #right_col{' +
'top:' + theatre_chat_top + 'px;' +
'height:' + theatre_chat_height + 'px}';
} else {
var width = this.get('rightColumnWidth');
} else {
var width = this.get('rightColumnWidth');
out += 'top: 0; right: ' + width + 'px}' +
'#main_col.expandRight #right_close{left: none !important}' +
'#right_col{width:' + width + 'px}' +
'body:not(.ffz-sidebar-swap) #main_col:not(.expandRight){' +
'margin-right:' + width + 'px}' +
'body.ffz-sidebar-swap #main_col:not(.expandRight){' +
'margin-left:' + width + 'px}';
}
}
'#right_col{width:' + width + 'px}' +
'body:not(.ffz-sidebar-swap) #main_col:not(.expandRight){' +
'margin-right:' + width + 'px}' +
'body.ffz-sidebar-swap #main_col:not(.expandRight){' +
'margin-left:' + width + 'px}';
}
}
f._layout_style.innerHTML = out;
}
}.observes("isRightColumnClosed", "playerSize", "rightColumnWidth", "portraitMode", "windowHeight", "windowWidth"),
ffzUpdatePlayerStyle: function() {
Ember.propertyDidChange(Layout, 'playerStyle');
}.observes('windowHeight', 'windowWidth'),
ffzUpdatePlayerStyle: function() {
Ember.propertyDidChange(Layout, 'playerStyle');
}.observes('windowHeight', 'windowWidth'),
ffzUpdatePortraitCSS: function() {
var portrait = this.get("portraitMode");

File diff suppressed because it is too large Load diff

View file

@ -323,7 +323,7 @@ FFZ.settings_info.mod_buttons = {
method: function() {
var f = this,
old_val = "";
old_val = "";
for(var i=0; i < this.settings.mod_buttons.length; i++) {
var pair = this.settings.mod_buttons[i],
@ -349,113 +349,113 @@ FFZ.settings_info.mod_buttons = {
}
utils.prompt(
"Custom In-Line Moderation Icons",
"Please enter a list of commands to be made available as mod icons within chat lines. Commands are separated by spaces. " +
"To include spaces in a command, surround the command with double quotes (\"). Use <code>{user}</code> to insert the user's name " +
"into the command, otherwise it will be appended to the end. Use <code>{id}</code> to insert the unique message ID into the command.</p>" +
utils.prompt(
"Custom In-Line Moderation Icons",
"Please enter a list of commands to be made available as mod icons within chat lines. Commands are separated by spaces. " +
"To include spaces in a command, surround the command with double quotes (\"). Use <code>{user}</code> to insert the user's name " +
"into the command, otherwise it will be appended to the end. Use <code>{id}</code> to insert the unique message ID into the command.</p>" +
"<p><b>Example:</b> <code>!permit \"!reg add {user}\" \"/timeout {user} 1 {id}\"</code></p><p>To " +
"send multiple commands, separate them with <code>&lt;LINE&gt;</code>.</p><p>Numeric values will become timeout buttons for " +
"that number of seconds. The text <code>&lt;BAN&gt;</code> is a special value that will act like the normal Ban button in chat.</p><p>" +
"To assign a specific letter for use as the icon, specify it at the start of the command followed by an equals sign.</p><p>" +
"<b>Example:</b> <code>A=\"!reg add\"</code></p><p><b>Default:</b> <code>&lt;BAN&gt; 600</code>",
old_val.substr(1),
function(new_val) {
if ( new_val === null || new_val === undefined )
return;
"send multiple commands, separate them with <code>&lt;LINE&gt;</code>.</p><p>Numeric values will become timeout buttons for " +
"that number of seconds. The text <code>&lt;BAN&gt;</code> is a special value that will act like the normal Ban button in chat.</p><p>" +
"To assign a specific letter for use as the icon, specify it at the start of the command followed by an equals sign.</p><p>" +
"<b>Example:</b> <code>A=\"!reg add\"</code></p><p><b>Default:</b> <code>&lt;BAN&gt; 600</code>",
old_val.substr(1),
function(new_val) {
if ( new_val === null || new_val === undefined )
return;
var vals = [], prefix = '';
new_val = new_val.trim();
var vals = [], prefix = '';
new_val = new_val.trim();
while(new_val) {
if ( new_val.charAt(1) === '=' ) {
prefix = new_val.charAt(0);
new_val = new_val.substr(2);
continue;
}
while(new_val) {
if ( new_val.charAt(1) === '=' ) {
prefix = new_val.charAt(0);
new_val = new_val.substr(2);
continue;
}
if ( new_val.charAt(0) === '"' ) {
var end = new_val.indexOf('"', 1);
if ( end === -1 )
end = new_val.length;
if ( new_val.charAt(0) === '"' ) {
var end = new_val.indexOf('"', 1);
if ( end === -1 )
end = new_val.length;
var segment = new_val.substr(1, end - 1);
if ( segment ) {
vals.push([prefix, segment]);
prefix = '';
}
var segment = new_val.substr(1, end - 1);
if ( segment ) {
vals.push([prefix, segment]);
prefix = '';
}
new_val = new_val.substr(end + 1);
new_val = new_val.substr(end + 1);
} else {
var ind = new_val.indexOf(' ');
if ( ind === -1 ) {
if ( new_val ) {
vals.push([prefix, new_val]);
prefix = '';
}
} else {
var ind = new_val.indexOf(' ');
if ( ind === -1 ) {
if ( new_val ) {
vals.push([prefix, new_val]);
prefix = '';
}
new_val = '';
new_val = '';
} else {
var segment = new_val.substr(0, ind);
if ( segment ) {
vals.push([prefix, segment]);
prefix = '';
}
} else {
var segment = new_val.substr(0, ind);
if ( segment ) {
vals.push([prefix, segment]);
prefix = '';
}
new_val = new_val.substr(ind + 1);
}
}
}
new_val = new_val.substr(ind + 1);
}
}
}
var final = [];
for(var i=0; i < vals.length; i++) {
var had_prefix = false, prefix = vals[i][0], val = vals[i][1];
if ( val === "<BAN>" )
val = false;
var final = [];
for(var i=0; i < vals.length; i++) {
var had_prefix = false, prefix = vals[i][0], val = vals[i][1];
if ( val === "<BAN>" )
val = false;
var num = parseInt(val);
if ( num > 0 && ! Number.isNaN(num) )
val = num;
var num = parseInt(val);
if ( num > 0 && ! Number.isNaN(num) )
val = num;
if ( ! prefix ) {
var tmp;
if ( typeof val === "string" )
tmp = /\w/.exec(val);
else
tmp = utils.duration_string(val);
if ( ! prefix ) {
var tmp;
if ( typeof val === "string" )
tmp = /\w/.exec(val);
else
tmp = utils.duration_string(val);
prefix = tmp && tmp.length ? tmp[0].toUpperCase() : "C";
} else
had_prefix = true;
prefix = tmp && tmp.length ? tmp[0].toUpperCase() : "C";
} else
had_prefix = true;
if ( typeof val === "string" ) {
// Split it up for this step.
var lines = val.split(/ *<LINE> */);
for(var x=0; x < lines.length; x++) {
if ( lines[x].indexOf('{user}') === -1 )
lines[x] += ' {user}';
}
val = lines.join("<LINE>");
}
if ( typeof val === "string" ) {
// Split it up for this step.
var lines = val.split(/ *<LINE> */);
for(var x=0; x < lines.length; x++) {
if ( lines[x].indexOf('{user}') === -1 )
lines[x] += ' {user}';
}
val = lines.join("<LINE>");
}
final.push([prefix, val, had_prefix]);
}
final.push([prefix, val, had_prefix]);
}
f.settings.set('mod_buttons', final);
f.settings.set('mod_buttons', final);
// Update existing chat lines.
var CL = utils.ember_resolve('component:chat/chat-line'),
views = CL ? utils.ember_views() : [];
// Update existing chat lines.
var CL = utils.ember_resolve('component:chat/chat-line'),
views = CL ? utils.ember_views() : [];
for(var vid in views) {
var view = views[vid];
if ( view instanceof CL && view.buildModIconsHTML )
view.$('.mod-icons').replaceWith(view.buildModIconsHTML());
}
for(var vid in views) {
var view = views[vid];
if ( view instanceof CL && view.buildModIconsHTML )
view.$('.mod-icons').replaceWith(view.buildModIconsHTML());
}
}, 600);
}, 600);
}
};
@ -472,7 +472,7 @@ FFZ.settings_info.mod_card_buttons = {
method: function() {
var f = this,
old_val = "";
old_val = "";
for(var i=0; i < this.settings.mod_card_buttons.length; i++) {
var cmd = this.settings.mod_card_buttons[i];
if ( cmd.indexOf(' ') !== -1 )
@ -481,51 +481,51 @@ FFZ.settings_info.mod_card_buttons = {
old_val += ' ' + cmd;
}
utils.prompt(
"Moderation Card Additional Buttons",
"Please enter a list of additional commands to display buttons for on moderation cards. Commands are separated by spaces. " +
"To include spaces in a command, surround the command with double quotes (\"). Use <code>{user}</code> to insert the " +
"user's name into the command, otherwise it will be appended to the end.</p><p><b>Example:</b> !permit \"!reg add {user}\"",
old_val.substr(1),
function(new_val) {
if ( new_val === null || new_val === undefined )
return;
utils.prompt(
"Moderation Card Additional Buttons",
"Please enter a list of additional commands to display buttons for on moderation cards. Commands are separated by spaces. " +
"To include spaces in a command, surround the command with double quotes (\"). Use <code>{user}</code> to insert the " +
"user's name into the command, otherwise it will be appended to the end.</p><p><b>Example:</b> !permit \"!reg add {user}\"",
old_val.substr(1),
function(new_val) {
if ( new_val === null || new_val === undefined )
return;
var vals = [];
new_val = new_val.trim();
var vals = [];
new_val = new_val.trim();
while(new_val) {
if ( new_val.charAt(0) === '"' ) {
var end = new_val.indexOf('"', 1);
if ( end === -1 )
end = new_val.length;
while(new_val) {
if ( new_val.charAt(0) === '"' ) {
var end = new_val.indexOf('"', 1);
if ( end === -1 )
end = new_val.length;
var segment = new_val.substr(1, end - 1);
if ( segment )
vals.push(segment);
var segment = new_val.substr(1, end - 1);
if ( segment )
vals.push(segment);
new_val = new_val.substr(end + 1);
new_val = new_val.substr(end + 1);
} else {
var ind = new_val.indexOf(' ');
if ( ind === -1 ) {
if ( new_val )
vals.push(new_val);
} else {
var ind = new_val.indexOf(' ');
if ( ind === -1 ) {
if ( new_val )
vals.push(new_val);
new_val = '';
new_val = '';
} else {
var segment = new_val.substr(0, ind);
if ( segment )
vals.push(segment);
} else {
var segment = new_val.substr(0, ind);
if ( segment )
vals.push(segment);
new_val = new_val.substr(ind + 1);
}
}
}
new_val = new_val.substr(ind + 1);
}
}
}
f.settings.set("mod_card_buttons", vals);
}, 600);
f.settings.set("mod_card_buttons", vals);
}, 600);
}
};
@ -541,36 +541,36 @@ FFZ.settings_info.mod_card_durations = {
help: "Add additional timeout buttons to moderation cards with specific durations.",
method: function() {
var f = this,
old_val = this.settings.mod_card_durations.join(", ");
var f = this,
old_val = this.settings.mod_card_durations.join(", ");
utils.prompt(
"Moderation Card Timeout Buttons",
"Please enter a comma-separated list of durations that you would like to have timeout buttons for. " +
"Durations must be expressed in seconds.</p><p><b>Default:</b> 300, 600, 3600, 43200, 86400, 604800",
old_val,
function(new_val) {
if ( new_val === null || new_val === undefined )
return;
utils.prompt(
"Moderation Card Timeout Buttons",
"Please enter a comma-separated list of durations that you would like to have timeout buttons for. " +
"Durations must be expressed in seconds.</p><p><b>Default:</b> 300, 600, 3600, 43200, 86400, 604800",
old_val,
function(new_val) {
if ( new_val === null || new_val === undefined )
return;
if ( new_val === "reset" )
new_val = FFZ.settings_info.mod_card_durations.value.join(", ");
if ( new_val === "reset" )
new_val = FFZ.settings_info.mod_card_durations.value.join(", ");
// Split them up.
new_val = new_val.trim().split(/[ ,]+/);
var vals = [];
// Split them up.
new_val = new_val.trim().split(/[ ,]+/);
var vals = [];
for(var i=0; i < new_val.length; i++) {
var val = parseInt(new_val[i]);
if ( val === 0 )
val = 1;
for(var i=0; i < new_val.length; i++) {
var val = parseInt(new_val[i]);
if ( val === 0 )
val = 1;
if ( ! Number.isNaN(val) && val > 0 )
vals.push(val);
}
if ( ! Number.isNaN(val) && val > 0 )
vals.push(val);
}
f.settings.set("mod_card_durations", vals);
}, 600);
f.settings.set("mod_card_durations", vals);
}, 600);
}
};
@ -1335,11 +1335,11 @@ FFZ.prototype._build_mod_card_history = function(msg, modcard, show_from) {
// Interactivity
jQuery('a.undelete', l_el).click(function(e) { this.parentElement.outerHTML = this.getAttribute('data-message'); });
jQuery('.deleted-word', l_el).click(function(e) { jQuery(this).trigger('mouseout'); this.outerHTML = this.getAttribute('data-text'); });
jQuery('.deleted-word', l_el).click(function(e) { jQuery(this).trigger('mouseout'); this.outerHTML = this.getAttribute('data-text'); });
jQuery('a.deleted-link', l_el).click(f._deleted_link_click);
jQuery('img.emoticon', l_el).click(function(e) { f._click_emote(this, e) });
//jQuery('.html-tooltip', l_el).tipsy({html:true, gravity: utils.tooltip_placement(2*constants.TOOLTIP_DISTANCE, 's')});
//jQuery('.ffz-tooltip', l_el).tipsy({live: true, html: true, title: f.render_tooltip(), gravity: utils.tooltip_placement(2*constants.TOOLTIP_DISTANCE, 's')});
//jQuery('.ffz-tooltip', l_el).tipsy({live: true, html: true, title: f.render_tooltip(), gravity: utils.tooltip_placement(2*constants.TOOLTIP_DISTANCE, 's')});
if ( modcard ) {
modcard.get('cardInfo.user.id') !== msg.from && jQuery('span.from', l_el).click(function(e) {
@ -1379,8 +1379,8 @@ FFZ.prototype._update_alias = function(user) {
var line = lines[i],
el_from = line.querySelector('.from');
if ( ! el_from )
continue;
if ( ! el_from )
continue;
el_from.classList.toggle('ffz-alias', alias);
el_from.textContent = display_name;
@ -1389,8 +1389,8 @@ FFZ.prototype._update_alias = function(user) {
// Update tab completion.
if ( this._inputv )
Ember.propertyDidChange(this._inputv, 'ffz_name_suggestions');
if ( this._inputv )
Ember.propertyDidChange(this._inputv, 'ffz_name_suggestions');
// TODO: Update conversations~
}

View file

@ -1,6 +1,6 @@
var FFZ = window.FrankerFaceZ,
utils = require('../utils'),
constants = require('../constants');
utils = require('../utils'),
constants = require('../constants');
// ---------------
@ -88,9 +88,9 @@ FFZ.prototype.modify_twitch_player = function(player) {
var id = this.get('channel.id');
f.players[id] = this;
var player = this.get('player');
if ( player )
this.ffzPostPlayer();
var player = this.get('player');
if ( player )
this.ffzPostPlayer();
},
ffz_destroy: function() {
@ -128,11 +128,11 @@ FFZ.prototype.modify_twitch_player = function(player) {
ffzPostPlayer: function() {
var player = this.get('player');
if ( ! player )
return;
return;
// Make the stats window draggable and fix the button.
var stats = this.$('.player .js-playback-stats');
stats.draggable({cancel: 'li', containment: 'parent'});
// Make the stats window draggable and fix the button.
var stats = this.$('.player .js-playback-stats');
stats.draggable({cancel: 'li', containment: 'parent'});
// Add an option to the menu to recreate the player.
var t = this,

View file

@ -332,7 +332,7 @@ FFZ.prototype.modify_room_view = function(view) {
if ( this._ffz_mouse_move ) {
messages.removeEventListener('mousemove', this._ffz_mouse_move);
messages.removeEventListener('touchmove', this._ffz_mouse_move);
messages.removeEventListener('touchmove', this._ffz_mouse_move);
this._ffz_mouse_move = undefined;
}
@ -1502,17 +1502,17 @@ FFZ.prototype._modify_room = function(room) {
// Tokenization
f.tokenize_chat_line(msg, false, this.get('roomProperties.hide_chat_links'));
// If it's from Twitch notify, and it's directly related to
if ( msg.from === 'twitchnotify' && msg.message.indexOf('subscribed to') === -1 && msg.message.indexOf('subscribed') !== -1 ) {
if ( ! msg.tags )
msg.tags = {};
// If it's from Twitch notify, and it's directly related to
if ( msg.from === 'twitchnotify' && msg.message.indexOf('subscribed to') === -1 && msg.message.indexOf('subscribed') !== -1 ) {
if ( ! msg.tags )
msg.tags = {};
if ( ! msg.tags.badges )
msg.tags.badges = {};
msg.tags.badges.subscriber = '1';
msg.tags.subscriber = true;
if ( msg.labels && msg.labels.indexOf("subscriber") === -1 )
msg.labels.push("subscriber");
}
msg.tags.subscriber = true;
if ( msg.labels && msg.labels.indexOf("subscriber") === -1 )
msg.labels.push("subscriber");
}
// Keep the history.
if ( ! is_whisper && msg.from && msg.from !== 'jtv' && msg.from !== 'twitchnotify' && f.settings.mod_card_history ) {
@ -1610,9 +1610,9 @@ FFZ.prototype._modify_room = function(room) {
ids[msg_id] = msg;
}
// Report this message to the dashboard.
if ( window !== window.parent && parent.postMessage && msg.from && msg.from !== "jtv" && msg.from !== "twitchnotify" )
parent.postMessage({from_ffz: true, command: 'chat_message', data: {from: msg.from, room: msg.room}}, "*"); //location.protocol + "//www.twitch.tv/");
// Report this message to the dashboard.
if ( window !== window.parent && parent.postMessage && msg.from && msg.from !== "jtv" && msg.from !== "twitchnotify" )
parent.postMessage({from_ffz: true, command: 'chat_message', data: {from: msg.from, room: msg.room}}, "*"); //location.protocol + "//www.twitch.tv/");
// Add the message.
return this._super(msg);
@ -1735,8 +1735,8 @@ FFZ.prototype._modify_room = function(room) {
if ( f._cindex )
f._cindex.ffzUpdateChatters();
if ( window !== window.parent && parent.postMessage )
parent.postMessage({from_ffz: true, command: 'chatter_count', data: Object.keys(this.get('ffz_chatters') || {}).length}, "*"); //location.protocol + "//www.twitch.tv/");
if ( window !== window.parent && parent.postMessage )
parent.postMessage({from_ffz: true, command: 'chatter_count', data: Object.keys(this.get('ffz_chatters') || {}).length}, "*"); //location.protocol + "//www.twitch.tv/");
},

View file

@ -1,5 +1,5 @@
var FFZ = window.FrankerFaceZ,
utils = require("../utils");
utils = require("../utils");
// --------------------

View file

@ -48,7 +48,7 @@ FFZ.settings_info.sidebar_hide_recommended_channels = {
no_mobile: true,
name: "Hide Recommended Channels",
help: "Hide the Recommended Channels section from the sidebar.",
help: "Hide the Recommended Channels section from the sidebar.",
on_update: utils.toggle_cls('ffz-hide-recommended-channels')
};
@ -62,7 +62,7 @@ FFZ.settings_info.sidebar_hide_recommended_friends = {
no_mobile: true,
name: "Hide Recommended Friends",
help: "Hide the Recommended Friends section from the sidebar.",
help: "Hide the Recommended Friends section from the sidebar.",
on_update: utils.toggle_cls('ffz-hide-recommended-friends')
};

View file

@ -1,5 +1,5 @@
var FFZ = window.FrankerFaceZ,
utils = require('../utils');
utils = require('../utils');
// --------------------

View file

@ -12,206 +12,206 @@ var FFZ = window.FrankerFaceZ,
// ---------------------
FFZ.prototype.setup_vod_chat = function() {
// Get the VOD Chat Service
var f = this,
VODService = utils.ember_lookup('service:vod-chat-service');
// Get the VOD Chat Service
var f = this,
VODService = utils.ember_lookup('service:vod-chat-service');
if ( VODService )
VODService.reopen({
messageBufferSize: f.settings.scrollback_length,
if ( VODService )
VODService.reopen({
messageBufferSize: f.settings.scrollback_length,
pushMessage: function(msg) {
if ( msg.get("color") === null ) {
var colors = this.get("colorSettings"),
from = msg.get("from");
pushMessage: function(msg) {
if ( msg.get("color") === null ) {
var colors = this.get("colorSettings"),
from = msg.get("from");
if ( ! colors.get(from) )
colors.set(from, constants.CHAT_COLORS[Math.floor(Math.random() * constants.CHAT_COLORS.length)]);
if ( ! colors.get(from) )
colors.set(from, constants.CHAT_COLORS[Math.floor(Math.random() * constants.CHAT_COLORS.length)]);
msg.set("color", colors.get(from));
}
msg.set("color", colors.get(from));
}
this.get("messages").pushObject(msg);
this.get("messages").pushObject(msg);
var messages = this.get("messages"),
len = this.get("messages.length"),
limit = this.get("messageBufferSize");
var messages = this.get("messages"),
len = this.get("messages.length"),
limit = this.get("messageBufferSize");
if ( len > limit )
messages.removeAt(0, len - limit);
}
});
else
f.error("Unable to locate VOD Chat Service.");
if ( len > limit )
messages.removeAt(0, len - limit);
}
});
else
f.error("Unable to locate VOD Chat Service.");
this.update_views('component:vod-right-column', this.modify_vod_right_column);
this.update_views('view:vod', this.modify_vod_view);
this.update_views('component:vod-chat-display', this.modify_vod_chat_display);
this.update_views('component:vod-right-column', this.modify_vod_right_column);
this.update_views('view:vod', this.modify_vod_view);
this.update_views('component:vod-chat-display', this.modify_vod_chat_display);
}
FFZ.prototype.modify_vod_view = function(view) {
var f = this;
utils.ember_reopen_view(view, {
ffz_init: function() {
f._vodv = this;
var f = this;
utils.ember_reopen_view(view, {
ffz_init: function() {
f._vodv = this;
var channel_id = this.get('context.channel.name');
var channel_id = this.get('context.channel.name');
if ( f.settings.auto_theater ) {
if ( f.settings.auto_theater ) {
var player = f.players && f.players[channel_id] && f.players[channel_id].get('player');
if ( player )
player.setTheatre(true);
}
// Listen to scrolling.
// Listen to scrolling.
this._ffz_scroller = this.ffzOnScroll.bind(this);
jQuery(this.get('element')).parents('.tse-scroll-content').on('scroll', this._ffz_scroller);
},
},
ffz_destroy: function() {
if ( f._vodv === this )
f._vodv = null;
ffz_destroy: function() {
if ( f._vodv === this )
f._vodv = null;
if ( this._ffz_scroller ) {
if ( this._ffz_scroller ) {
jQuery(this.get('element')).parents('.tse-scroll-content').off('scroll', this._ffz_scroller);
this._ffz_scroller = null;
}
},
},
ffzOnScroll: function(event) {
ffzOnScroll: function(event) {
// When we scroll past the bottom of the player, do stuff!
var top = event && event.target && event.target.scrollTop,
height = this.get('layout.playerSize.1');
if ( ! top )
top = jQuery(this.get('element')).parents('.tse-scroll-content').scrollTop();
if ( ! top )
top = jQuery(this.get('element')).parents('.tse-scroll-content').scrollTop();
document.body.classList.toggle('ffz-small-player', f.settings.small_player && top >= height);
}
});
});
}
FFZ.prototype.modify_vod_right_column = function(component) {
var f = this;
utils.ember_reopen_view(component, {
ffz_init: function() {
if ( f.settings.dark_twitch ) {
var el = this.get('element'),
cont = el && el.querySelector('.chat-container');
var f = this;
utils.ember_reopen_view(component, {
ffz_init: function() {
if ( f.settings.dark_twitch ) {
var el = this.get('element'),
cont = el && el.querySelector('.chat-container');
if ( cont )
cont.classList.add('dark');
}
}
});
if ( cont )
cont.classList.add('dark');
}
}
});
}
FFZ.prototype.modify_vod_chat_display = function(component) {
var f = this,
VODService = utils.ember_lookup('service:vod-chat-service');
var f = this,
VODService = utils.ember_lookup('service:vod-chat-service');
utils.ember_reopen_view(component, {
_prepareToolTips: function() {
this.$(".tooltip").tipsy({
live: true,
gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 's')
})
},
utils.ember_reopen_view(component, {
_prepareToolTips: function() {
this.$(".tooltip").tipsy({
live: true,
gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 's')
})
},
ffz_init: function() {
f._vodc = this;
ffz_init: function() {
f._vodc = this;
// Load the room, if necessary
var room_id = this.get('video.channel.name');
if ( room_id && ! f.rooms[room_id] )
f.load_room(room_id); // TODO: Function to reprocess existing messages.
// Load the room, if necessary
var room_id = this.get('video.channel.name');
if ( room_id && ! f.rooms[room_id] )
f.load_room(room_id); // TODO: Function to reprocess existing messages.
this.ffz_frozen = false;
if ( f.settings.chat_hover_pause )
this.ffzEnableFreeze();
},
this.ffz_frozen = false;
if ( f.settings.chat_hover_pause )
this.ffzEnableFreeze();
},
ffz_destroy: function() {
if ( f._vodc === this )
f._vodc = undefined;
ffz_destroy: function() {
if ( f._vodc === this )
f._vodc = undefined;
// TODO: Function to unload the old room?
// TODO: Function to unload the old room?
this.ffzDisableFreeze();
},
this.ffzDisableFreeze();
},
ffzEnableFreeze: function() {
var scroller = this.get('chatMessagesScroller');
if ( ! scroller )
return;
ffzEnableFreeze: function() {
var scroller = this.get('chatMessagesScroller');
if ( ! scroller )
return;
this._ffz_interval = setInterval(this.ffzPulse.bind(this), 200);
this._ffz_interval = setInterval(this.ffzPulse.bind(this), 200);
this._ffz_mouse_move = this.ffzMouseMove.bind(this);
this._ffz_mouse_out = this.ffzMouseOut.bind(this);
this._ffz_mouse_move = this.ffzMouseMove.bind(this);
this._ffz_mouse_out = this.ffzMouseOut.bind(this);
scroller.on('mousemove', this._ffz_mouse_move);
scroller.on('touchmove', this._ffz_mouse_move);
scroller.on('mouseout', this._ffz_mouse_out);
},
scroller.on('mousemove', this._ffz_mouse_move);
scroller.on('touchmove', this._ffz_mouse_move);
scroller.on('mouseout', this._ffz_mouse_out);
},
ffzDisableFreeze: function() {
if ( this._ffz_interval ) {
clearInterval(this._ffz_interval);
this._ffz_interval = undefined;
}
ffzDisableFreeze: function() {
if ( this._ffz_interval ) {
clearInterval(this._ffz_interval);
this._ffz_interval = undefined;
}
this.ffzUnfreeze();
var scroller = this.get('chatMessagesScroller');
if ( ! scroller )
return;
this.ffzUnfreeze();
var scroller = this.get('chatMessagesScroller');
if ( ! scroller )
return;
if ( this._ffz_mouse_move ) {
scroller.off('mousemove', this._ffz_mouse_move);
scroller.off('touchmove', this._ffz_mouse_move);
this._ffz_mouse_move = undefined;
}
if ( this._ffz_mouse_move ) {
scroller.off('mousemove', this._ffz_mouse_move);
scroller.off('touchmove', this._ffz_mouse_move);
this._ffz_mouse_move = undefined;
}
if ( this._ffz_mouse_out ) {
scroller.off('mouseout', this._ffz_mouse_out);
this._ffz_mouse_out = undefined;
}
},
if ( this._ffz_mouse_out ) {
scroller.off('mouseout', this._ffz_mouse_out);
this._ffz_mouse_out = undefined;
}
},
ffzUnfreeze: function(from_stuck) {
this.ffz_frozen = false;
this._ffz_last_move = 0;
this.ffzUnwarnPaused();
ffzUnfreeze: function(from_stuck) {
this.ffz_frozen = false;
this._ffz_last_move = 0;
this.ffzUnwarnPaused();
if ( ! from_stuck && this.get('stuckToBottom') )
this._scrollToBottom();
},
if ( ! from_stuck && this.get('stuckToBottom') )
this._scrollToBottom();
},
ffzPulse: function() {
if ( this.ffz_frozen ) {
var elapsed = Date.now() - this._ffz_last_move;
if ( elapsed > 750 )
this.ffzUnfreeze();
}
},
ffzPulse: function() {
if ( this.ffz_frozen ) {
var elapsed = Date.now() - this._ffz_last_move;
if ( elapsed > 750 )
this.ffzUnfreeze();
}
},
ffzMouseOut: function(event) {
this._ffz_outside = true;
var e = this;
setTimeout(function() {
if ( e._ffz_outside )
e.ffzUnfreeze();
}, 25);
},
ffzMouseOut: function(event) {
this._ffz_outside = true;
var e = this;
setTimeout(function() {
if ( e._ffz_outside )
e.ffzUnfreeze();
}, 25);
},
ffzMouseMove: function(event) {
this._ffz_last_move = Date.now();
this._ffz_outside = false;
ffzMouseMove: function(event) {
this._ffz_last_move = Date.now();
this._ffz_outside = false;
if ( event.screenX === this._ffz_last_screenx && event.screenY === this._ffz_last_screeny )
if ( event.screenX === this._ffz_last_screenx && event.screenY === this._ffz_last_screeny )
return;
this._ffz_last_screenx = event.screenX;
@ -222,37 +222,37 @@ FFZ.prototype.modify_vod_chat_display = function(component) {
this.ffz_frozen = true;
if ( this.get('stuckToBottom') ) {
VODService && VODService.set("messageBufferSize", f.settings.scrollback_length + 150);
VODService && VODService.set("messageBufferSize", f.settings.scrollback_length + 150);
this.ffzWarnPaused();
}
},
}
},
_scrollToBottom: _.throttle(function() {
var e = this,
scroller = e.get('chatMessagesScroller');
_scrollToBottom: _.throttle(function() {
var e = this,
scroller = e.get('chatMessagesScroller');
if ( ! scroller || ! scroller.length )
return;
if ( ! scroller || ! scroller.length )
return;
Ember.run.next(function() {
(window.requestAnimationFrame||setTimeout)(function() {
if ( e.ffz_frozen )
return;
Ember.run.next(function() {
(window.requestAnimationFrame||setTimeout)(function() {
if ( e.ffz_frozen )
return;
scroller[0].scrollTop = scroller[0].scrollHeight;
e._setStuckToBottom(true);
})
})
}, 300),
scroller[0].scrollTop = scroller[0].scrollHeight;
e._setStuckToBottom(true);
})
})
}, 300),
_setStuckToBottom: function(val) {
this.set("stuckToBottom", val);
VODService && VODService.set("messageBufferSize", f.settings.scrollback_length + (val ? 0 : 150));
if ( ! val )
this.ffUnfreeze(true);
},
_setStuckToBottom: function(val) {
this.set("stuckToBottom", val);
VODService && VODService.set("messageBufferSize", f.settings.scrollback_length + (val ? 0 : 150));
if ( ! val )
this.ffUnfreeze(true);
},
ffzWarnPaused: function() {
ffzWarnPaused: function() {
var el = this.get('element'),
warning = el && el.querySelector('.chat-interface .more-messages-indicator.ffz-freeze-indicator');
@ -280,5 +280,5 @@ FFZ.prototype.modify_vod_chat_display = function(component) {
if ( warning )
warning.classList.add('hidden');
}
});
});
}

View file

@ -1,5 +1,5 @@
var FFZ = window.FrankerFaceZ,
utils = require("../utils"),
utils = require("../utils"),
constants = require("../constants");
// --------------------
@ -66,23 +66,23 @@ FFZ.prototype._update_views = function(klasses) {
// Iterate over all existing views and update them as necessary.
var views = utils.ember_views();
for(var view_id in views) {
var view = views[view_id];
if ( ! view )
continue;
var view = views[view_id];
if ( ! view )
continue;
for(var i=0; i < klasses.length; i++)
if ( view instanceof klasses[i][1] ) {
try {
if ( ! view.ffz_modified )
klasses[i][2].call(this, view);
for(var i=0; i < klasses.length; i++)
if ( view instanceof klasses[i][1] ) {
try {
if ( ! view.ffz_modified )
klasses[i][2].call(this, view);
(view.ffz_update || view.ffz_init).call(view);
(view.ffz_update || view.ffz_init).call(view);
} catch(err) {
this.error("An error occured when updating an existing Ember instance of: " + klasses[i][0], err);
}
} catch(err) {
this.error("An error occured when updating an existing Ember instance of: " + klasses[i][0], err);
}
break;
}
}
break;
}
}
}

View file

@ -221,29 +221,29 @@ FFZ.prototype.load_emoji_data = function(callback, tries) {
emoji.code = eid;
new_data[eid] = emoji;
if ( emoji.short_name )
by_name[emoji.short_name] = eid;
if ( emoji.names && emoji.names.length )
for(var x=0,y=emoji.names.length; x < y; x++)
by_name[emoji.names[x]] = eid;
if ( emoji.short_name )
by_name[emoji.short_name] = eid;
if ( emoji.names && emoji.names.length )
for(var x=0,y=emoji.names.length; x < y; x++)
by_name[emoji.names[x]] = eid;
emoji.raw = _.map(emoji.code.split("-"), utils.codepoint_to_emoji).join("");
emoji.tw_src = constants.SERVER + 'emoji/tw/' + eid + '.svg';
emoji.noto_src = constants.SERVER + 'emoji/noto-' + eid + '.svg';
emoji.one_src = constants.SERVER + 'emoji/one/' + eid + '.svg';
emoji.one_src = constants.SERVER + 'emoji/one/' + eid + '.svg';
emoji.token = {
type: "emoticon",
imgSrc: true,
type: "emoticon",
imgSrc: true,
tw_src: emoji.tw_src,
noto_src: emoji.noto_src,
one_src: emoji.one_src,
one_src: emoji.one_src,
tw: emoji.tw,
noto: emoji.noto,
one: emoji.one,
one: emoji.one,
ffzEmoji: eid,
altText: emoji.raw
@ -347,8 +347,8 @@ FFZ.prototype.unload_set = function(set_id) {
api.emote_sets[set_id] = undefined;
}
if ( this._inputv )
Ember.propertyDidChange(this._inputv, 'ffz_emoticons');
if ( this._inputv )
Ember.propertyDidChange(this._inputv, 'ffz_emoticons');
}
@ -388,14 +388,14 @@ FFZ.prototype._load_set_json = function(set_id, callback, data) {
else
emote.regex = new RegExp("(^|\\W|\\b)(" + utils.escape_regex(emote.name) + ")\\b", "g");
emote.token = {
type: "emoticon",
srcSet: emote.srcSet,
imgSrc: emote.urls[1],
ffzEmote: emote.id,
ffzEmoteSet: set_id,
altText: emote.hidden ? '???' : emote.name
};
emote.token = {
type: "emoticon",
srcSet: emote.srcSet,
imgSrc: emote.urls[1],
ffzEmote: emote.id,
ffzEmoteSet: set_id,
altText: emote.hidden ? '???' : emote.name
};
output_css += build_css(emote);
data.count++;
@ -410,8 +410,8 @@ FFZ.prototype._load_set_json = function(set_id, callback, data) {
this.update_ui_link();
if ( this._inputv )
Ember.propertyDidChange(this._inputv, 'ffz_emoticons');
if ( this._inputv )
Ember.propertyDidChange(this._inputv, 'ffz_emoticons');
this.rerender_feed_cards(set_id);

View file

@ -59,7 +59,7 @@ var API = FFZ.API = function(instance, name, icon, version) {
this.name_key = this.name.replace(/[^A-Z0-9_\-]/g, '').toLowerCase();
this.icon = icon || null;
this.version = version || null;
this.version = version || null;
this.ffz.log('Registered New Extension #' + this.id + ': ' + this.name);
};
@ -169,14 +169,14 @@ API.prototype._load_set = function(real_id, set_id, data) {
else
new_emote.regex = new RegExp("(^|\\W|\\b)(" + utils.escape_regex(emote.name) + ")(?=\\W|$)", "g");
new_emote.token = {
type: "emoticon",
srcSet: new_emote.srcSet,
imgSrc: new_emote.urls[1],
ffzEmote: id,
ffzEmoteSet: real_id,
altText: new_emote.hidden ? '???' : new_emote.name
};
new_emote.token = {
type: "emoticon",
srcSet: new_emote.srcSet,
imgSrc: new_emote.urls[1],
ffzEmote: id,
ffzEmoteSet: real_id,
altText: new_emote.hidden ? '???' : new_emote.name
};
output_css += build_css(new_emote);
emote_set.count++;
@ -294,9 +294,9 @@ API.prototype.register_global_set = function(id, emote_set) {
if ( this.ffz.default_sets && this.ffz.default_sets.indexOf(exact_id) === -1 )
this.ffz.default_sets.push(exact_id);
// Update tab completion.
if ( this.ffz._inputv )
Ember.propertyDidChange(this.ffz._inputv, 'ffz_emoticons');
// Update tab completion.
if ( this.ffz._inputv )
Ember.propertyDidChange(this.ffz._inputv, 'ffz_emoticons');
};
@ -324,9 +324,9 @@ API.prototype.unregister_global_set = function(id) {
if ( ind !== -1 )
this.ffz.default_sets.splice(ind,1);
// Update tab completion.
if ( this.ffz._inputv )
Ember.propertyDidChange(this.ffz._inputv, 'ffz_emoticons');
// Update tab completion.
if ( this.ffz._inputv )
Ember.propertyDidChange(this.ffz._inputv, 'ffz_emoticons');
};
@ -361,9 +361,9 @@ API.prototype.register_room_set = function(room_id, id, emote_set) {
room.ext_sets && room.ext_sets.push(exact_id);
emote_set.users.push(room_id);
// Update tab completion.
if ( this.ffz._inputv )
Ember.propertyDidChange(this.ffz._inputv, 'ffz_emoticons');
// Update tab completion.
if ( this.ffz._inputv )
Ember.propertyDidChange(this.ffz._inputv, 'ffz_emoticons');
}
@ -383,9 +383,9 @@ API.prototype.unregister_room_set = function(room_id, id) {
if ( ind !== -1 )
emote_set.users.splice(ind,1);
// Update tab completion.
if ( this.ffz._inputv )
Ember.propertyDidChange(this.ffz._inputv, 'ffz_emoticons');
// Update tab completion.
if ( this.ffz._inputv )
Ember.propertyDidChange(this.ffz._inputv, 'ffz_emoticons');
}
@ -473,7 +473,7 @@ API.prototype.user_add_set = function(username, set_id) {
// Update tab completion.
var user = this.ffz.get_user();
if ( this.ffz._inputv && user && user.login === username )
Ember.propertyDidChange(this.ffz._inputv, 'ffz_emoticons');
Ember.propertyDidChange(this.ffz._inputv, 'ffz_emoticons');
}
@ -497,7 +497,7 @@ API.prototype.user_remove_set = function(username, set_id) {
// Update tab completion.
var user = this.ffz.get_user();
if ( this.ffz._inputv && user && user.login === username )
Ember.propertyDidChange(this.ffz._inputv, 'ffz_emoticons');
Ember.propertyDidChange(this.ffz._inputv, 'ffz_emoticons');
}

View file

@ -42,11 +42,11 @@ FFZ.prototype.setup_bttv = function(delay) {
utils.update_css(this._chat_style, 'chat_ts_font_size', '');
}
// Remove Sub Count and the Chart
// Remove Sub Count and the Chart
if ( this.is_dashboard ) {
this._update_subscribers();
this._remove_dash_chart();
}
this._remove_dash_chart();
}
document.body.classList.add('ffz-bttv');
@ -101,8 +101,8 @@ FFZ.prototype.setup_bttv = function(delay) {
this.toggle_style('badges-blank');
this.toggle_style('badges-circular-small');
this.toggle_style('badges-transparent');
this.toggle_style('badges-sub-notice');
this.toggle_style('badges-sub-notice-on');
this.toggle_style('badges-sub-notice');
this.toggle_style('badges-sub-notice-on');
// Disable other features too.
document.body.classList.remove('ffz-transparent-badges');
@ -237,39 +237,39 @@ FFZ.prototype.setup_bttv = function(delay) {
}
};
// Emoji!
var parse_emoji = function(token) {
var setting = f.settings.parse_emoji,
output = [],
segments = token.split(constants.EMOJI_REGEX),
text = null;
// Emoji!
var parse_emoji = function(token) {
var setting = f.settings.parse_emoji,
output = [],
segments = token.split(constants.EMOJI_REGEX),
text = null;
if ( setting === 0 )
return [token];
if ( setting === 0 )
return [token];
while(segments.length) {
text = (text || '') + segments.shift();
if ( segments.length ) {
var match = segments.shift(),
eid = utils.emoji_to_codepoint(match),
data = f.emoji_data[eid],
src = data && (setting === 3 ? data.one_src : (setting === 2 ? data.noto_src : data.tw_src));
while(segments.length) {
text = (text || '') + segments.shift();
if ( segments.length ) {
var match = segments.shift(),
eid = utils.emoji_to_codepoint(match),
data = f.emoji_data[eid],
src = data && (setting === 3 ? data.one_src : (setting === 2 ? data.noto_src : data.tw_src));
if ( src ) {
if ( text && text.length )
output.push(text);
var code = utils.quote_attr(data.raw);
output.push(['<img class="emoticon emoji ffz-tooltip" height="18px" data-ffz-emoji="' + eid + '" src="' + utils.quote_attr(src) + '" alt="' + code + '">']);
text = null;
} else
text = (text || '') + match;
}
}
if ( src ) {
if ( text && text.length )
output.push(text);
var code = utils.quote_attr(data.raw);
output.push(['<img class="emoticon emoji ffz-tooltip" height="18px" data-ffz-emoji="' + eid + '" src="' + utils.quote_attr(src) + '" alt="' + code + '">']);
text = null;
} else
text = (text || '') + match;
}
}
if ( text && text.length )
output.push(text);
if ( text && text.length )
output.push(text);
return output;
return output;
}
// Emoticonize
@ -283,62 +283,62 @@ FFZ.prototype.setup_bttv = function(delay) {
sets = f.getEmotes(l_sender, l_room),
emotes = {}, emote,
user = f.get_user(),
new_tokens = [],
new_tokens = [],
mine = user && user.login === l_sender;
// Build an object with all of our emotes.
for(var i=0; i < sets.length; i++) {
var emote_set = f.emote_sets[sets[i]];
if ( emote_set && emote_set.emoticons )
for(var emote_id in emote_set.emoticons) {
emote = emote_set.emoticons[emote_id];
if ( ! emotes.hasOwnProperty(emote.name) )
emotes[emote.name] = emote;
}
}
// Build an object with all of our emotes.
for(var i=0; i < sets.length; i++) {
var emote_set = f.emote_sets[sets[i]];
if ( emote_set && emote_set.emoticons )
for(var emote_id in emote_set.emoticons) {
emote = emote_set.emoticons[emote_id];
if ( ! emotes.hasOwnProperty(emote.name) )
emotes[emote.name] = emote;
}
}
for(var i=0, l=tokens.length; i < l; i++) {
var token = tokens[i];
if ( typeof token !== "string" ) {
new_tokens.push(token);
continue;
}
for(var i=0, l=tokens.length; i < l; i++) {
var token = tokens[i];
if ( typeof token !== "string" ) {
new_tokens.push(token);
continue;
}
// Split the token!
var segments = token.split(' '),
text = [], segment;
// Split the token!
var segments = token.split(' '),
text = [], segment;
for(var x=0,y=segments.length; x < y; x++) {
segment = segments[x];
if ( emotes.hasOwnProperty(segment) ) {
emote = emotes[segment];
if ( text.length ) {
var toks = parse_emoji(text.join(' ') + ' ');
for(var q=0; q < toks.length; q++)
new_tokens.push(toks[q]);
for(var x=0,y=segments.length; x < y; x++) {
segment = segments[x];
if ( emotes.hasOwnProperty(segment) ) {
emote = emotes[segment];
if ( text.length ) {
var toks = parse_emoji(text.join(' ') + ' ');
for(var q=0; q < toks.length; q++)
new_tokens.push(toks[q]);
text = [];
}
text = [];
}
new_tokens.push(['<img class="emoticon ffz-tooltip" data-ffz-set="' + emote.set_id + '" data-ffz-emote="' + emote.id + '" srcset="' + utils.quote_attr(emote.srcSet || "") + '" src="' + utils.quote_attr(emote.urls[1]) + '" alt="' + utils.quote_attr(emote.name) + '">']);
new_tokens.push(['<img class="emoticon ffz-tooltip" data-ffz-set="' + emote.set_id + '" data-ffz-emote="' + emote.id + '" srcset="' + utils.quote_attr(emote.srcSet || "") + '" src="' + utils.quote_attr(emote.urls[1]) + '" alt="' + utils.quote_attr(emote.name) + '">']);
if ( mine && l_room )
f.add_usage(l_room, emote);
if ( mine && l_room )
f.add_usage(l_room, emote);
text.push('');
} else
text.push(segment);
}
text.push('');
} else
text.push(segment);
}
if ( text.length > 1 || (text.length === 1 && text[0] !== '') ) {
var toks = parse_emoji(text.join(' ') + ' ');
for(var q=0; q < toks.length; q++)
new_tokens.push(toks[q]);
}
}
if ( text.length > 1 || (text.length === 1 && text[0] !== '') ) {
var toks = parse_emoji(text.join(' ') + ' ');
for(var q=0; q < toks.length; q++)
new_tokens.push(toks[q]);
}
}
return new_tokens;
}
return new_tokens;
}
this.update_ui_link();
}

View file

@ -1,5 +1,5 @@
var FFZ = window.FrankerFaceZ,
utils = require('../utils');
utils = require('../utils');
// --------------------

View file

@ -1,6 +1,6 @@
var FFZ = window.FrankerFaceZ,
constants = require('./constants'),
utils = require('./utils');
utils = require('./utils');
// --------------------

View file

@ -13,16 +13,16 @@ var FFZ = window.FrankerFaceZ = function() {
this._apis = {};
this._chat_filters = [];
// Error Logging
var t = this;
window.addEventListener('error', function(event) {
if ( ! event.error )
return;
// Error Logging
var t = this;
window.addEventListener('error', function(event) {
if ( ! event.error )
return;
//var has_stack = event.error && event.error.stack;
//var has_stack = event.error && event.error.stack;
t.error("Uncaught JavaScript Error", event.error);
//t.log("JavaScript Error: " + event.message + " [" + event.filename + ":" + event.lineno + ":" + event.colno + "]", has_stack ? event.error.stack : undefined, false, has_stack);
});
//t.log("JavaScript Error: " + event.message + " [" + event.filename + ":" + event.lineno + ":" + event.colno + "]", has_stack ? event.error.stack : undefined, false, has_stack);
});
// Get things started.
this.initialize();
@ -47,8 +47,8 @@ var VER = FFZ.version_info = {
// Logging
FFZ.prototype.log = function(msg, data, to_json, log_json) {
if ( to_json )
msg = msg + ' -- ' + JSON.stringify(data);
if ( to_json )
msg = msg + ' -- ' + JSON.stringify(data);
this._log_data.push(msg + ((!to_json && log_json) ? " -- " + JSON.stringify(data) : ""));
@ -116,16 +116,16 @@ FFZ.prototype.get_user = function(force_reload) {
if ( ! force_reload && this.__user )
return this.__user;
var LC = FFZ.utils.ember_lookup('service:login'),
user = LC ? LC.get('userData') : undefined;
var LC = FFZ.utils.ember_lookup('service:login'),
user = LC ? LC.get('userData') : undefined;
if ( ! user && window.PP && PP.login )
user = PP;
if ( ! user && window.PP && PP.login )
user = PP;
if ( user )
this.__user = user;
if ( user )
this.__user = user;
return user;
return user;
}
@ -268,7 +268,7 @@ FFZ.prototype.initialize = function(increment, delay) {
FFZ.prototype.init_player = function(delay) {
var start = (window.performance && performance.now) ? performance.now() : Date.now();
this.log("Found Twitch Player after " + (delay||0) + " ms at: " + location);
this.log("Initializing FrankerFaceZ version " + FFZ.version_info);
this.log("Initializing FrankerFaceZ version " + FFZ.version_info);
this.users = {};
this.is_dashboard = false;
@ -292,7 +292,7 @@ FFZ.prototype.init_player = function(delay) {
FFZ.prototype.init_normal = function(delay, no_socket) {
var start = (window.performance && performance.now) ? performance.now() : Date.now();
this.log("Found non-Ember Twitch after " + (delay||0) + " ms at: " + location);
this.log("Initializing FrankerFaceZ version " + FFZ.version_info);
this.log("Initializing FrankerFaceZ version " + FFZ.version_info);
this.users = {};
this.is_dashboard = false;
@ -322,7 +322,7 @@ FFZ.prototype.init_normal = function(delay, no_socket) {
this.setup_following_count(false);
this.setup_menu();
this.setup_message_event();
this.setup_message_event();
this.fix_tooltips();
this.find_bttv(10);
@ -338,10 +338,10 @@ FFZ.prototype.is_dashboard = false;
FFZ.prototype.init_dashboard = function(delay) {
var start = (window.performance && performance.now) ? performance.now() : Date.now();
this.log("Found Twitch Dashboard after " + (delay||0) + " ms at: " + location);
this.log("Initializing FrankerFaceZ version " + FFZ.version_info);
this.log("Initializing FrankerFaceZ version " + FFZ.version_info);
var match = location.pathname.match(/\/([^\/]+)/);
this.dashboard_channel = match && match[1] || undefined;
var match = location.pathname.match(/\/([^\/]+)/);
this.dashboard_channel = match && match[1] || undefined;
this.users = {};
this.is_dashboard = true;
@ -366,7 +366,7 @@ FFZ.prototype.init_dashboard = function(delay) {
this.setup_notifications();
this.setup_following_count(false);
this.setup_menu();
this.setup_dash_stats();
this.setup_dash_stats();
this.setup_dash_feed();
this._update_subscribers();
@ -387,7 +387,7 @@ FFZ.prototype.init_dashboard = function(delay) {
FFZ.prototype.init_ember = function(delay) {
var start = (window.performance && performance.now) ? performance.now() : Date.now();
this.log("Found Twitch application after " + (delay||0) + " ms at: " + location);
this.log("Initializing FrankerFaceZ version " + FFZ.version_info);
this.log("Initializing FrankerFaceZ version " + FFZ.version_info);
this.users = {};
this.is_dashboard = false;
@ -426,7 +426,7 @@ FFZ.prototype.init_ember = function(delay) {
this.setup_player();
this.setup_channel();
this.setup_room();
this.setup_vod_chat();
this.setup_vod_chat();
this.setup_line();
this.setup_bits();
this.setup_layout();
@ -456,13 +456,13 @@ FFZ.prototype.init_ember = function(delay) {
this.fix_tooltips();
this.connect_extra_chat();
this.setup_message_event();
this.setup_message_event();
this.find_bttv(10);
this.find_emote_menu(10);
//this.check_news();
this.check_ff();
this.refresh_chat();
this.refresh_chat();
var end = (window.performance && performance.now) ? performance.now() : Date.now(),
duration = end - start;
@ -482,10 +482,10 @@ FFZ.prototype.setup_message_event = function() {
FFZ.prototype._on_window_message = function(e) {
var msg = e.data;
if ( typeof msg === "string" )
var msg = e.data;
if ( typeof msg === "string" )
try {
msg = JSON.parse(msg);
msg = JSON.parse(msg);
} catch(err) {
// Not JSON? We don't care.
return;
@ -495,8 +495,8 @@ FFZ.prototype._on_window_message = function(e) {
return;
var handler = FFZ.msg_commands[msg.command];
if ( handler )
handler.call(this, msg.data);
else
this.log("Invalid Message: " + msg.command, msg.data, false, true);
if ( handler )
handler.call(this, msg.data);
else
this.log("Invalid Message: " + msg.command, msg.data, false, true);
}

File diff suppressed because it is too large Load diff

View file

@ -7,13 +7,13 @@ var FFZ = window.FrankerFaceZ,
bits_helpers,
bits_service,
EXPLANATION_WARN = '<hr>This link has been sent to you via a whisper rather than standard chat, and has not been checked or approved of by any moderators or staff members. Please treat this link with caution and do not visit it if you do not trust the sender.',
EXPLANATION_WARN = '<hr>This link has been sent to you via a whisper rather than standard chat, and has not been checked or approved of by any moderators or staff members. Please treat this link with caution and do not visit it if you do not trust the sender.',
reg_escape = function(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
},
LINK = /(?:https?:\/\/)?(?:[-a-zA-Z0-9@:%_\+~#=]+\.)+[a-z]{2,6}\b(?:[-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)/g,
LINK = /(?:https?:\/\/)?(?:[-a-zA-Z0-9@:%_\+~#=]+\.)+[a-z]{2,6}\b(?:[-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)/g,
CLIP_URL = /(?:https?:\/\/)?clips\.twitch\.tv\/(\w+)\/(\w+)/,
@ -53,12 +53,12 @@ var FFZ = window.FrankerFaceZ,
this._link_data[href] = data;
//data.unsafe = false;
if ( ! this.settings.link_info )
return;
if ( ! this.settings.link_info )
return;
// If this link is unsafe, add the unsafe-link class to all instances of the link.
if ( data.unsafe )
jQuery('a.chat-link[data-url="' + href + '"]').addClass('unsafe-link');
// If this link is unsafe, add the unsafe-link class to all instances of the link.
if ( data.unsafe )
jQuery('a.chat-link[data-url="' + href + '"]').addClass('unsafe-link');
};
@ -85,7 +85,7 @@ FFZ._emote_mirror_swap = function(img) {
img.setAttribute('data-alt-attempts', attempts + 1);
var id = img.getAttribute('data-emote'),
src = '//' + img.src.split('//')[1];
src = '//' + img.src.split('//')[1];
if ( src.substr(0, constants.TWITCH_BASE.length) === constants.TWITCH_BASE ) {
img.src = constants.EMOTE_MIRROR_BASE + id + ".png";
@ -218,8 +218,8 @@ FFZ.prototype.setup_tokenization = function() {
var show_deleted = f.settings.show_deleted_links;
return _.chain(tokens).map(function(token) {
if ( token.type === "text" )
token = token.text;
if ( token.type === "text" )
token = token.text;
if ( ! _.isString(token) )
return token;
@ -231,21 +231,21 @@ FFZ.prototype.setup_tokenization = function() {
return _.zip(
token.split(LINK),
_.map(matches, function(e) {
var long = e.length > 255,
out = {
type: "link",
length: e.length,
isDeleted: ! show_deleted && (delete_links || long),
isLong: long,
isMailTo: e.indexOf("@") > -1 && (-1 === e.indexOf("/") || e.indexOf("@") < e.indexOf("/")),
text: e,
link: e
};
var long = e.length > 255,
out = {
type: "link",
length: e.length,
isDeleted: ! show_deleted && (delete_links || long),
isLong: long,
isMailTo: e.indexOf("@") > -1 && (-1 === e.indexOf("/") || e.indexOf("@") < e.indexOf("/")),
text: e,
link: e
};
if ( ! out.isMailTo && ! e.match(/^(?:https?:\/\/)/) )
out.link = "http://" + e;
if ( ! out.isMailTo && ! e.match(/^(?:https?:\/\/)/) )
out.link = "http://" + e;
return out;
return out;
})
);
}).flatten().compact().value();
@ -290,8 +290,8 @@ FFZ.prototype.load_twitch_emote_data = function(tries) {
// ---------------------
FFZ.prototype.render_tooltip = function(el) {
var f = this,
func = function() {
var f = this,
func = function() {
if ( this.classList.contains('ffz-bit') ) {
var amount = parseInt(this.getAttribute('data-amount').replace(/,/g, '')),
individuals = JSON.parse(this.getAttribute('data-individuals') || "null"),
@ -317,102 +317,102 @@ FFZ.prototype.render_tooltip = function(el) {
return image + out;
} else if ( this.classList.contains('emoticon') ) {
var preview_url, width=0, height=0, image, set_id, emote, emote_set,
emote_id = this.getAttribute('data-ffz-emote');
if ( emote_id ) {
var preview_url, width=0, height=0, image, set_id, emote, emote_set,
emote_id = this.getAttribute('data-ffz-emote');
if ( emote_id ) {
if ( emote_id == "93269" )
return '';
set_id = this.getAttribute('data-ffz-set');
emote_set = f.emote_sets[set_id];
emote = emote_set && emote_set.emoticons[emote_id];
set_id = this.getAttribute('data-ffz-set');
emote_set = f.emote_sets[set_id];
emote = emote_set && emote_set.emoticons[emote_id];
if ( emote ) {
var owner = emote.owner,
title = emote_set.title || "Global",
source = emote_set.source || "FFZ";
if ( emote ) {
var owner = emote.owner,
title = emote_set.title || "Global",
source = emote_set.source || "FFZ";
if ( f.settings.emote_image_hover ) {
if ( emote.urls[4] ) {
height = emote.height * 4;
width = emote.width * 4;
preview_url = emote.urls[4];
if ( f.settings.emote_image_hover ) {
if ( emote.urls[4] ) {
height = emote.height * 4;
width = emote.width * 4;
preview_url = emote.urls[4];
} else if ( emote.urls[2] ) {
height = emote.height * 2;
width = emote.width * 2;
}
} else if ( emote.urls[2] ) {
height = emote.height * 2;
width = emote.width * 2;
}
if ( width > 186 )
height *= 186 / width;
height = Math.min(186, height);
if ( width > 186 )
height *= 186 / width;
height = Math.min(186, height);
} else
preview_url = null;
} else
preview_url = null;
//image = preview_url ? `<img style="height:${height}px" class="emoticon ffz-image-hover" src="${preview_url}?_=preview">` : '';
image = preview_url ? '<img style="height:' + height + 'px" class="emoticon ffz-image-hover" src="' + preview_url + '"?_=preview">' : '';
return image + 'Emoticon: ' + (emote.hidden ? '???' : emote.name) + '<br>' + source + ' ' + title + (owner ? '<br>By: ' + owner.display_name : '');
//image = preview_url ? `<img style="height:${height}px" class="emoticon ffz-image-hover" src="${preview_url}?_=preview">` : '';
image = preview_url ? '<img style="height:' + height + 'px" class="emoticon ffz-image-hover" src="' + preview_url + '"?_=preview">' : '';
return image + 'Emoticon: ' + (emote.hidden ? '???' : emote.name) + '<br>' + source + ' ' + title + (owner ? '<br>By: ' + owner.display_name : '');
//return `${image}Emoticon: ${emote.hidden ? '???' : emote.name}<br>${source} ${title}${owner ? '<br>By: ' + owner.display_name : ""}`;
}
}
//return `${image}Emoticon: ${emote.hidden ? '???' : emote.name}<br>${source} ${title}${owner ? '<br>By: ' + owner.display_name : ""}`;
}
}
emote_id = this.getAttribute('data-emote');
if ( emote_id ) {
set_id = f._twitch_emote_to_set[emote_id];
emote_set = set_id && f._twitch_set_to_channel[set_id];
var set_type = "Channel";
emote_id = this.getAttribute('data-emote');
if ( emote_id ) {
set_id = f._twitch_emote_to_set[emote_id];
emote_set = set_id && f._twitch_set_to_channel[set_id];
var set_type = "Channel";
preview_url = f.settings.emote_image_hover && (constants.TWITCH_BASE + emote_id + '/3.0');
//image = preview_url ? `<img style="height:112px" class="emoticon ffz-image-hover" src="${preview_url}?_=preview">` : '';
image = preview_url ? '<img style="height:112px" class="emoticon ffz-image-hover" src="' + preview_url + '"?_=preview">' : '';
preview_url = f.settings.emote_image_hover && (constants.TWITCH_BASE + emote_id + '/3.0');
//image = preview_url ? `<img style="height:112px" class="emoticon ffz-image-hover" src="${preview_url}?_=preview">` : '';
image = preview_url ? '<img style="height:112px" class="emoticon ffz-image-hover" src="' + preview_url + '"?_=preview">' : '';
// Global OR Golden Kappa
if ( emote_set === "--global--" || emote_id === '80393' ) {
emote_set = "Twitch Global";
set_type = null;
} else if ( emote_set === "--twitch-turbo--" || emote_set === "turbo" || emote_set === "--turbo-faces--" ) {
emote_set = "Twitch Turbo";
set_type = null;
}
if ( emote_set === "--global--" || emote_id === '80393' ) {
emote_set = "Twitch Global";
set_type = null;
} else if ( emote_set === "--twitch-turbo--" || emote_set === "turbo" || emote_set === "--turbo-faces--" ) {
emote_set = "Twitch Turbo";
set_type = null;
}
if ( this.classList.contains('ffz-tooltip-no-credit') )
return image + this.alt;
else
return image + 'Emoticon: ' + this.alt + '<br>' + (set_type ? set_type + ': ' : '') + emote_set;
//return `${image}Emoticon: ${this.alt}<br>${set_type ? set_type + ": " : ""}${emote_set}`;
}
if ( this.classList.contains('ffz-tooltip-no-credit') )
return image + this.alt;
else
return image + 'Emoticon: ' + this.alt + '<br>' + (set_type ? set_type + ': ' : '') + emote_set;
//return `${image}Emoticon: ${this.alt}<br>${set_type ? set_type + ": " : ""}${emote_set}`;
}
emote_id = this.getAttribute('data-ffz-emoji');
if ( emote_id ) {
emote = f.emoji_data[emote_id];
var src = emote && (f.settings.parse_emoji === 3 ? emote.one_src : (f.settings.parse_emoji === 2 ? emote.noto_src : emote.tw_src));
emote_id = this.getAttribute('data-ffz-emoji');
if ( emote_id ) {
emote = f.emoji_data[emote_id];
var src = emote && (f.settings.parse_emoji === 3 ? emote.one_src : (f.settings.parse_emoji === 2 ? emote.noto_src : emote.tw_src));
preview_url = f.settings.emote_image_hover && src;
//image = preview_url ? `<img style="height:72px" class="emoticon ffz-image-hover" src="${preview_url}">` : '';
image = preview_url ? '<img style="height:72px" class="emoticon ffz-image-hover" src="' + preview_url + '"?_=preview">' : '';
preview_url = f.settings.emote_image_hover && src;
//image = preview_url ? `<img style="height:72px" class="emoticon ffz-image-hover" src="${preview_url}">` : '';
image = preview_url ? '<img style="height:72px" class="emoticon ffz-image-hover" src="' + preview_url + '"?_=preview">' : '';
return image + "Emoji: " + this.alt + '<br>Name: ' + emote.name + (emote.short_name ? '<br>Short Name :' + emote.short_name + ':' : '') + (emote.cat ? '<br>Category: ' + utils.sanitize(constants.EMOJI_CATEGORIES[emote.cat] || emote.cat) : '');
//return `${image}Emoji: ${this.alt}<br>Name: ${emote.name}${emote.short_name ? '<br>Short Name: :' + emote.short_name + ':' : ''}`;
}
return image + "Emoji: " + this.alt + '<br>Name: ' + emote.name + (emote.short_name ? '<br>Short Name :' + emote.short_name + ':' : '') + (emote.cat ? '<br>Category: ' + utils.sanitize(constants.EMOJI_CATEGORIES[emote.cat] || emote.cat) : '');
//return `${image}Emoji: ${this.alt}<br>Name: ${emote.name}${emote.short_name ? '<br>Short Name: :' + emote.short_name + ':' : ''}`;
}
} else if ( this.classList.contains('email-link') ) {
var url = this.getAttribute("data-url");
return url ? "E-Mail " + url.substr(7) : '';
} else if ( this.classList.contains('email-link') ) {
var url = this.getAttribute("data-url");
return url ? "E-Mail " + url.substr(7) : '';
} else if ( this.classList.contains('chat-link') ) {
// TODO: A lot of shit. Lookup data.
var url = this.getAttribute("data-url"),
} else if ( this.classList.contains('chat-link') ) {
// TODO: A lot of shit. Lookup data.
var url = this.getAttribute("data-url"),
data = url && f._link_data[url],
preview_url = null,
preview_iframe = true,
image = '',
text = '';
text = '';
if ( ! url )
return;
if ( ! url )
return;
// Do we have data?
if ( data && data !== true ) {
@ -428,21 +428,21 @@ FFZ.prototype.render_tooltip = function(el) {
else
image = '<img class="emoticon ffz-image-hover" src="' + utils.quote_attr(preview_url) + '">';
// If it's not a deleted link, don't waste time showing the URL in the tooltip.
if ( this.classList.contains('deleted-link') )
text = url;
// If it's not a deleted link, don't waste time showing the URL in the tooltip.
if ( this.classList.contains('deleted-link') )
text = url;
if ( this.classList.contains('warn-link') )
text += EXPLANATION_WARN;
if ( this.classList.contains('warn-link') )
text += EXPLANATION_WARN;
return image + text; //`${image}${text}`;
}
return image + text; //`${image}${text}`;
}
f.log("Unable to Build Tooltip For: " + this.className, this);
return "";
};
f.log("Unable to Build Tooltip For: " + this.className, this);
return "";
};
return el ? func(el) : func;
return el ? func(el) : func;
};
@ -500,53 +500,53 @@ FFZ.prototype.tokenize_conversation_line = function(message, prevent_notificatio
FFZ.prototype.tokenize_vod_line = function(msgObject, delete_links) {
var cached = msgObject.get('cachedTokens');
if ( cached )
return cached;
var cached = msgObject.get('cachedTokens');
if ( cached )
return cached;
var msg = msgObject.get('message'),
room_id = msgObject.get('room'),
from_user = msgObject.get('from'),
user = this.get_user(),
from_me = user && from_user === user.login,
emotes = msgObject.get('tags.emotes'),
tokens = [msg];
var msg = msgObject.get('message'),
room_id = msgObject.get('room'),
from_user = msgObject.get('from'),
user = this.get_user(),
from_me = user && from_user === user.login,
emotes = msgObject.get('tags.emotes'),
tokens = [msg];
if ( helpers && helpers.linkifyMessage )
tokens = helpers.linkifyMessage(tokens, delete_links);
if ( helpers && helpers.linkifyMessage )
tokens = helpers.linkifyMessage(tokens, delete_links);
if ( user && user.login && helpers && helpers.mentionizeMessage )
tokens = helpers.mentionizeMessage(tokens, user.login, from_me);
if ( user && user.login && helpers && helpers.mentionizeMessage )
tokens = helpers.mentionizeMessage(tokens, user.login, from_me);
if ( helpers && helpers.emoticonizeMessage && emotes && this.settings.parse_emoticons )
tokens = helpers.emoticonizeMessage(tokens, emotes);
if ( helpers && helpers.emoticonizeMessage && emotes && this.settings.parse_emoticons )
tokens = helpers.emoticonizeMessage(tokens, emotes);
// FrankerFaceZ Extras
tokens = this._remove_banned(tokens);
// FrankerFaceZ Extras
tokens = this._remove_banned(tokens);
if ( this.settings.parse_emoticons && this.settings.parse_emoticons !== 2 )
tokens = this.tokenize_emotes(from_user, room_id, tokens, from_me);
tokens = this.tokenize_emotes(from_user, room_id, tokens, from_me);
if ( this.settings.parse_emoji )
tokens = this.tokenize_emoji(tokens);
if ( this.settings.parse_emoji )
tokens = this.tokenize_emoji(tokens);
var display = msgObject.get('tags.display-name');
if ( display && display.length )
FFZ.capitalization[from_user] = [display.trim(), Date.now()];
var display = msgObject.get('tags.display-name');
if ( display && display.length )
FFZ.capitalization[from_user] = [display.trim(), Date.now()];
if ( ! from_me ) {
tokens = this.tokenize_mentions(tokens);
for(var i=0; i < tokens.length; i++) {
var token = tokens[i];
if ( token.type === 'mention' && ! token.isOwnMessage ) {
msgObject.set('ffz_has_mention', true);
break;
}
}
}
if ( ! from_me ) {
tokens = this.tokenize_mentions(tokens);
for(var i=0; i < tokens.length; i++) {
var token = tokens[i];
if ( token.type === 'mention' && ! token.isOwnMessage ) {
msgObject.set('ffz_has_mention', true);
break;
}
}
}
msgObject.set('cachedTokens', tokens);
return tokens;
msgObject.set('cachedTokens', tokens);
return tokens;
}
@ -554,14 +554,14 @@ FFZ.prototype.tokenize_chat_line = function(msgObject, prevent_notification, del
if ( msgObject.cachedTokens )
return msgObject.cachedTokens;
var msg = msgObject.message,
room_id = msgObject.room,
from_user = msgObject.from,
user = this.get_user(),
from_me = user && from_user === user.login,
var msg = msgObject.message,
room_id = msgObject.room,
from_user = msgObject.from,
user = this.get_user(),
from_me = user && from_user === user.login,
tags = msgObject.tags || {},
emotes = tags.emotes,
tokens = [msg];
emotes = tags.emotes,
tokens = [msg];
// Standard Tokenization
if ( tags.bits && bits_helpers && bits_helpers.tokenizeBits )
@ -628,13 +628,13 @@ FFZ.prototype.tokenize_chat_line = function(msgObject, prevent_notification, del
for(var i=0; i < tokens.length; i++) {
var token = tokens[i],
is_mention = token.type === "mention";
is_mention = token.type === "mention";
if ( ! is_mention || token.isOwnMessage )
continue;
if ( ! is_mention || token.isOwnMessage )
continue;
// We have a mention!
msgObject.ffz_has_mention = true;
msgObject.ffz_has_mention = true;
// If we have chat tabs/rows, update the status.
if ( room_id && ! this.has_bttv && this._chatv ) {
@ -979,79 +979,79 @@ FFZ.prototype.tokenize_ctags = function(tokens, tags_only) {
// ---------------------
FFZ.prototype.tokenize_emotes = function(user, room, tokens, do_report) {
"use strict";
"use strict";
var sets = this.getEmotes(user, room),
emotes = {},
emote,
var sets = this.getEmotes(user, room),
emotes = {},
emote,
new_tokens = [];
new_tokens = [];
if ( ! tokens || ! tokens.length || ! sets || ! sets.length )
return tokens;
if ( ! tokens || ! tokens.length || ! sets || ! sets.length )
return tokens;
// Build an object with all of our emotes.
for(var i=0; i < sets.length; i++) {
var emote_set = this.emote_sets[sets[i]];
if ( emote_set && emote_set.emoticons )
for(var emote_id in emote_set.emoticons) {
emote = emote_set.emoticons[emote_id];
if ( ! emotes.hasOwnProperty(emote.name) )
emotes[emote.name] = emote;
}
}
// Build an object with all of our emotes.
for(var i=0; i < sets.length; i++) {
var emote_set = this.emote_sets[sets[i]];
if ( emote_set && emote_set.emoticons )
for(var emote_id in emote_set.emoticons) {
emote = emote_set.emoticons[emote_id];
if ( ! emotes.hasOwnProperty(emote.name) )
emotes[emote.name] = emote;
}
}
if ( typeof tokens === "string" )
tokens = [tokens];
if ( typeof tokens === "string" )
tokens = [tokens];
for(var i=0, l=tokens.length; i < l; i++) {
var token = tokens[i];
if ( ! token )
continue;
for(var i=0, l=tokens.length; i < l; i++) {
var token = tokens[i];
if ( ! token )
continue;
if ( typeof token !== "string" )
if ( token.type === "text" )
token = token.text;
else {
new_tokens.push(token);
continue;
}
if ( typeof token !== "string" )
if ( token.type === "text" )
token = token.text;
else {
new_tokens.push(token);
continue;
}
// Split the token!
var segments = token.split(' '),
text = [], segment;
// Split the token!
var segments = token.split(' '),
text = [], segment;
for(var x=0,y=segments.length; x < y; x++) {
segment = segments[x];
if ( emotes.hasOwnProperty(segment) ) {
emote = emotes[segment];
for(var x=0,y=segments.length; x < y; x++) {
segment = segments[x];
if ( emotes.hasOwnProperty(segment) ) {
emote = emotes[segment];
if ( text.length ) {
// We have pending text. Join it together, with an extra space
// on the end for good measure.
new_tokens.push({type: "text", text: text.join(' ') + ' '});
text = []
}
if ( text.length ) {
// We have pending text. Join it together, with an extra space
// on the end for good measure.
new_tokens.push({type: "text", text: text.join(' ') + ' '});
text = []
}
// Push this emote to the tokens.
new_tokens.push(emote.token);
// Push this emote to the tokens.
new_tokens.push(emote.token);
if ( do_report && room )
this.add_usage(room, emote);
if ( do_report && room )
this.add_usage(room, emote);
// Finally, push an empty string to text so that this emote gets spaced.
text.push('');
// Finally, push an empty string to text so that this emote gets spaced.
text.push('');
} else
text.push(segment);
}
} else
text.push(segment);
}
// Add any left over text from this segment.
if ( text.length > 1 || (text.length === 1 && text[0] !== '') )
new_tokens.push({type: "text", text: text.join(' ')});
}
// Add any left over text from this segment.
if ( text.length > 1 || (text.length === 1 && text[0] !== '') )
new_tokens.push({type: "text", text: text.join(' ')});
}
return new_tokens;
return new_tokens;
}
@ -1060,54 +1060,54 @@ FFZ.prototype.tokenize_emotes = function(user, room, tokens, do_report) {
// ---------------------
FFZ.prototype.tokenize_emoji = function(tokens) {
"use strict";
if ( ! tokens || ! tokens.length || ! this.emoji_data )
return tokens;
"use strict";
if ( ! tokens || ! tokens.length || ! this.emoji_data )
return tokens;
if ( typeof tokens === "string" )
tokens = [tokens];
if ( typeof tokens === "string" )
tokens = [tokens];
var new_tokens = [];
var new_tokens = [];
for(var i=0, l=tokens.length; i < l; i++) {
var token = tokens[i];
if ( ! token )
continue;
for(var i=0, l=tokens.length; i < l; i++) {
var token = tokens[i];
if ( ! token )
continue;
if ( typeof token !== "string" )
if ( token.type === "text" )
token = token.text;
else {
new_tokens.push(token);
continue;
}
if ( typeof token !== "string" )
if ( token.type === "text" )
token = token.text;
else {
new_tokens.push(token);
continue;
}
var segments = token.split(constants.EMOJI_REGEX),
text = null;
var segments = token.split(constants.EMOJI_REGEX),
text = null;
while(segments.length) {
text = (text || '') + segments.shift();
while(segments.length) {
text = (text || '') + segments.shift();
if ( segments.length ) {
var match = segments.shift(),
eid = utils.emoji_to_codepoint(match),
data = this.emoji_data[eid];
if ( segments.length ) {
var match = segments.shift(),
eid = utils.emoji_to_codepoint(match),
data = this.emoji_data[eid];
if ( data ) {
if ( text && text.length )
new_tokens.push({type: "text", text: text});
new_tokens.push(data.token);
text = null;
} else
text = (text || '') + match;
}
}
if ( data ) {
if ( text && text.length )
new_tokens.push({type: "text", text: text});
new_tokens.push(data.token);
text = null;
} else
text = (text || '') + match;
}
}
if ( text && text.length )
new_tokens.push({type: "text", text: text});
}
if ( text && text.length )
new_tokens.push({type: "text", text: text});
}
return new_tokens;
return new_tokens;
}
@ -1152,8 +1152,8 @@ FFZ.prototype.tokenize_mentions = function(tokens) {
for(var i=0; i < tokens.length; i++) {
var token = tokens[i];
if ( token.type === "text" )
token = token.text;
if ( token.type === "text" )
token = token.text;
if ( ! _.isString(token) || ! token.match(regex) ) {
new_tokens.push(token);
@ -1163,10 +1163,10 @@ FFZ.prototype.tokenize_mentions = function(tokens) {
token = token.replace(regex, function(all, prefix, match) {
new_tokens.push(prefix);
new_tokens.push({
type: "mention",
length: match.length,
user: match,
isOwnMessage: false,
type: "mention",
length: match.length,
user: match,
isOwnMessage: false,
});
return "";
@ -1188,7 +1188,7 @@ FFZ.prototype._deleted_link_click = function(e) {
if ( ! this.classList.contains("deleted-link") )
return true;
// Stop from Navigating
// Stop from Navigating
e.preventDefault();
// Get the URL
@ -1198,7 +1198,7 @@ FFZ.prototype._deleted_link_click = function(e) {
// Delete Old Stuff
this.classList.remove('deleted-link');
this.classList.remove('warn-link');
this.classList.remove('warn-link');
// Set up the Link
this.href = link;
@ -1206,7 +1206,7 @@ FFZ.prototype._deleted_link_click = function(e) {
this.textContent = text;
// Refresh tipsy.
jQuery(this).trigger('mouseout').trigger('mouseover');
jQuery(this).trigger('mouseout').trigger('mouseover');
}

View file

@ -1,13 +1,13 @@
var FFZ = window.FrankerFaceZ,
constants = require("../constants"),
utils = require("../utils"),
createElement = utils.createElement,
utils = require("../utils"),
createElement = utils.createElement,
NICE_DESCRIPTION = {
"cluster": null,
"manifest_cluster": null,
"user_ip": null
};
NICE_DESCRIPTION = {
"cluster": null,
"manifest_cluster": null,
"user_ip": null
};
// -------------------
@ -53,430 +53,430 @@ FFZ.ws_commands.update_news = function(version) {
// -------------------
var include_html = function(heading_text, filename, callback) {
return function(view, container) {
var heading = createElement('div', 'chat-menu-content center');
heading.innerHTML = '<h1>FrankerFaceZ</h1>' + (heading_text ? '<div class="ffz-about-subheading">' + heading_text + '</div>' : '');
return function(view, container) {
var heading = createElement('div', 'chat-menu-content center');
heading.innerHTML = '<h1>FrankerFaceZ</h1>' + (heading_text ? '<div class="ffz-about-subheading">' + heading_text + '</div>' : '');
jQuery.ajax(filename, {cache: false, context: this})
.done(function(data) {
container.appendChild(heading);
container.innerHTML += data;
jQuery.ajax(filename, {cache: false, context: this})
.done(function(data) {
container.appendChild(heading);
container.innerHTML += data;
jQuery('#ffz-old-news-button', container).on('click', function() {
jQuery(this).remove();
jQuery('#ffz-old-news', container).css('display', 'block');
});
jQuery('#ffz-old-news-button', container).on('click', function() {
jQuery(this).remove();
jQuery('#ffz-old-news', container).css('display', 'block');
});
typeof callback === "function" && callback(view, container);
typeof callback === "function" && callback(view, container);
}).fail(function(data) {
var content = createElement('div', 'chat-menu-content menu-side-padding');
content.textContent = 'There was an error loading this page from the server.';
}).fail(function(data) {
var content = createElement('div', 'chat-menu-content menu-side-padding');
content.textContent = 'There was an error loading this page from the server.';
container.appendChild(heading);
container.appendChild(content);
});
}
},
render_news = include_html("news", constants.SERVER + "script/news.html");
container.appendChild(heading);
container.appendChild(content);
});
}
},
render_news = include_html("news", constants.SERVER + "script/news.html");
var make_line = function(key, container) {
var desc = NICE_DESCRIPTION.hasOwnProperty(key) ? NICE_DESCRIPTION[key] : key;
if ( ! desc )
return;
var desc = NICE_DESCRIPTION.hasOwnProperty(key) ? NICE_DESCRIPTION[key] : key;
if ( ! desc )
return;
line = createElement('li', null, desc + '<span></span>');
line.setAttribute('data-property', key);
container.appendChild(line);
return line;
line = createElement('li', null, desc + '<span></span>');
line.setAttribute('data-property', key);
container.appendChild(line);
return line;
};
var update_mem_stats = function(container) {
if ( ! document.querySelector('.ffz-ui-sub-menu-page[data-page="debugging"]') )
return;
if ( ! document.querySelector('.ffz-ui-sub-menu-page[data-page="debugging"]') )
return;
setTimeout(update_mem_stats.bind(this, container), 1000);
setTimeout(update_mem_stats.bind(this, container), 1000);
var mem = window.performance && performance.memory;
if ( ! mem )
return;
var mem = window.performance && performance.memory;
if ( ! mem )
return;
var sorted_keys = ['jsHeapSizeLimit', 'totalJSHeapSize', 'usedJSHeapSize'];
for(var i=0; i < sorted_keys.length; i++) {
var key = sorted_keys[i],
data = mem[key],
line = container.querySelector('li[data-property="' + key + '"]');
var sorted_keys = ['jsHeapSizeLimit', 'totalJSHeapSize', 'usedJSHeapSize'];
for(var i=0; i < sorted_keys.length; i++) {
var key = sorted_keys[i],
data = mem[key],
line = container.querySelector('li[data-property="' + key + '"]');
if ( ! line )
line = make_line(key, container);
if ( ! line )
line = make_line(key, container);
if ( line )
line.querySelector('span').textContent = utils.format_size(data) + ' (' + data + ')';
}
if ( line )
line.querySelector('span').textContent = utils.format_size(data) + ' (' + data + ')';
}
};
var update_player_stats = function(player, container) {
if ( ! document.querySelector('.ffz-ui-sub-menu-page[data-page="debugging"]') || ! player.getVideoInfo )
return;
if ( ! document.querySelector('.ffz-ui-sub-menu-page[data-page="debugging"]') || ! player.getVideoInfo )
return;
setTimeout(update_player_stats.bind(this, player, container), 1000);
setTimeout(update_player_stats.bind(this, player, container), 1000);
var player_data;
var player_data;
try {
player_data = player.getVideoInfo();
} catch(err) { }
try {
player_data = player.getVideoInfo();
} catch(err) { }
if ( ! player_data )
return;
if ( ! player_data )
return;
try {
player_data.backend = player.getBackend();
} catch(err) { player_data.backend = undefined }
try {
player_data.backend = player.getBackend();
} catch(err) { player_data.backend = undefined }
var sorted_keys = Object.keys(player_data).sort();
for(var i=0; i < sorted_keys.length; i++) {
var key = sorted_keys[i],
data = player_data[key],
line = container.querySelector('li[data-property="' + key + '"]');
var sorted_keys = Object.keys(player_data).sort();
for(var i=0; i < sorted_keys.length; i++) {
var key = sorted_keys[i],
data = player_data[key],
line = container.querySelector('li[data-property="' + key + '"]');
if ( ! line )
line = make_line(key, container);
if ( ! line )
line = make_line(key, container);
if ( line )
line.querySelector('span').textContent = data;
}
if ( line )
line.querySelector('span').textContent = data;
}
};
FFZ.menu_pages.about = {
name: "About",
icon: constants.HEART,
sort_order: 100000,
pages: {
about: {
name: "About",
render: function(view, container, inner, menu) {
var room = this.rooms[view.get("context.currentRoom.id")],
has_emotes = false, f = this;
if ( room && room.set ) {
var set = this.emote_sets[room.set];
if ( set && set.count > 0 )
has_emotes = true;
}
// Heading
var heading = createElement('div'),
content = '';
content += "<h1>FrankerFaceZ</h1>";
content += '<div class="ffz-about-subheading">new ways to woof</div>';
heading.className = 'chat-menu-content center';
heading.innerHTML = content;
container.appendChild(heading);
var clicks = 0, head = heading.querySelector("h1");
head && head.addEventListener("click", function() {
head.style.cursor = "pointer";
clicks++;
if ( clicks >= 3 ) {
clicks = 0;
var el = document.querySelector(".app-main") || document.querySelector(".ember-chat-container");
el && el.classList.toggle('ffz-flip');
}
setTimeout(function(){clicks=0;head.style.cursor=""},2000);
});
// Button Stuff
var btn_container = createElement('div'),
ad_button = createElement('a'),
news_button = createElement('a'),
donate_button = createElement('a'),
message = "To use custom emoticons in " + (has_emotes ? "this channel" : "tons of channels") + ", get FrankerFaceZ from https://www.frankerfacez.com";
// Advertising
ad_button.className = 'button primary';
ad_button.innerHTML = "Advertise in Chat";
ad_button.addEventListener('click', this._add_emote.bind(this, view, message));
btn_container.appendChild(ad_button);
// Donate
donate_button.className = 'button ffz-donate';
donate_button.href = "https://www.frankerfacez.com/donate";
donate_button.target = "_new";
donate_button.innerHTML = "Donate";
btn_container.appendChild(donate_button);
btn_container.className = 'chat-menu-content center';
container.appendChild(btn_container);
// Credits
var credits = createElement('div');
content = '<table class="ffz-about-table">';
content += '<tr><th colspan="4">Developers</th></tr>';
content += '<tr><td>Dan Salvato</td><td><a class="twitch" href="//www.twitch.tv/dansalvato" title="Twitch" target="_new">&nbsp;</a></td><td><a class="twitter" href="https://twitter.com/dansalvato" title="Twitter" target="_new">&nbsp;</a></td><td><a class="youtube" href="https://www.youtube.com/user/dansalvato1" title="YouTube" target="_new">&nbsp;</a></td></tr>';
content += '<tr><td>Stendec</td><td><a class="twitch" href="//www.twitch.tv/sirstendec" title="Twitch" target="_new">&nbsp;</a></td><td><a class="twitter" href="https://twitter.com/SirStendec" title="Twitter" target="_new">&nbsp;</a></td><td><a class="youtube" href="https://www.youtube.com/channel/UCnxuvmK1DCPCXSJ-mXIh4KQ" title="YouTube" target="_new">&nbsp;</a></td></tr>';
content += '<tr class="debug"><td><a href="#" id="ffz-changelog">Version ' + FFZ.version_info + '</a></td><td colspan="3"><a href="#" id="ffz-debug-logs">Logs</a></td></tr>';
credits.className = 'chat-menu-content center';
credits.innerHTML = content;
// Make the Version clickable.
credits.querySelector('#ffz-changelog').addEventListener('click',
f._ui_change_subpage.bind(f, view, inner, menu, container, 'changelog'));
// Make the Logs button functional.
var getting_logs = false;
credits.querySelector('#ffz-debug-logs').addEventListener('click', function() {
if ( getting_logs )
return;
getting_logs = true;
f._pastebin(f._log_data.join("\n"), function(url) {
getting_logs = false;
if ( ! url )
alert("There was an error uploading the FrankerFaceZ logs.");
else
prompt("Your FrankerFaceZ logs have been uploaded to the URL:", url);
});
});
container.appendChild(credits);
}
},
changelog: {
name: "Changes",
wide: true,
render: include_html("change log", constants.SERVER + "script/changelog.html")
},
/*news: {
name: "News",
wide: true,
render: function(view, container) {
if ( this._has_news ) {
this._has_news = false;
localStorage.ffzLastNewsId = this._news_id;
this.update_ui_link();
}
return render_news.call(this, view, container);
}
},*/
credits: {
name: "Credit",
wide: true,
render: include_html("credits", constants.SERVER + "script/credits.html")
},
/*status: {
name: "Status",
wide: true,
render: include_html("server status", constants.SERVER + "script/status.html", function(view, container) {
})
},*/
debugging: {
name: "Debug",
wide: true,
render: function(view, container) {
// Heading
var heading = createElement('div'),
info_head = createElement('div'),
info = createElement('ul'),
info_list = [
['Client ID', localStorage.ffzClientId || '<i>not set</i>'],
['Socket Server', this._ws_sock && this._ws_sock.url || '<i>disconnected</i>' ],
['Server Ping', this._ws_last_ping || '<i>unknown</i>'],
['Time Offset', this._ws_sock && this._ws_server_offset && (this._ws_server_offset < 0 ? "-" : "") + utils.time_to_string(Math.abs(this._ws_server_offset) / 1000) || '<i>unknown</i>']
],
twitch_head = createElement('div'),
twitch = createElement('ul'),
twitch_list = [
['Deploy Flavor', SiteOptions.deploy_flavor]
],
exp_head = createElement('div'),
experiments = createElement('ul'),
has_memory = window.performance && performance.memory,
mem_head = createElement('div'),
mem_list = createElement('ul'),
player_head = createElement('div'),
player_list = createElement('ul'),
player, player_data,
ver_head = createElement('div'),
vers = createElement('ul'),
version_list = [
['Ember', Ember.VERSION],
['Ember Data', window.DS && DS.VERSION || '<i>unknown</i>'],
['GIT Version', EmberENV.GIT_VERSION],
null,
['FrankerFaceZ', FFZ.version_info.toString()]
],
log_head = createElement('div'),
logs = createElement('pre');
for(var pkey in this.players) {
player = this.players[pkey] && this.players[pkey].player;
if ( player )
break;
}
if ( player ) {
try {
player_data = player.getVideoInfo();
} catch(err) { }
}
heading.className = 'chat-menu-content center';
heading.innerHTML = '<h1>FrankerFaceZ</h1><div class="ffz-about-subheading">woofs for nerds</div>';
info_head.className = exp_head.className = mem_head.className = twitch_head.className = player_head.className = ver_head.className = log_head.className = 'list-header';
info.className = mem_list.className = twitch.className = experiments.className = player_list.className = vers.className = 'chat-menu-content menu-side-padding version-list';
info_head.innerHTML = 'Client Status';
for(var i=0; i < info_list.length; i++) {
var data = info_list[i],
line = createElement('li');
line.innerHTML = data === null ? '<br>' : data[0] + '<span>' + data[1] + '</span>';
info.appendChild(line);
}
twitch_head.innerHTML = 'Twitch Configuration';
// Check for Twitch geo-location
var user = this.get_user();
if ( user && user.login ) {
twitch_list.push(["Current User", user.login + " [" + user.id + "]"]);
var us = [];
user.is_staff && us.push("staff");
user.is_admin && us.push("admin");
user.is_partner && us.push("partner");
user.is_broadcaster && us.push("broadcaster");
user.has_turbo && us.push("turbo");
twitch_list.push(["User State", us.join(", ") || "<i>none</i>"]);
} else
twitch_list.push(["Current User", "<i>not logged in</i>"]);
if ( window.Twitch && Twitch.geo && Twitch.geo._result ) {
var data = Twitch.geo._result;
if ( data.geo )
twitch_list.push(["Region", data.geo + (data.eu ? " [EU]" : "")]);
if ( data.received_language )
twitch_list.push(["Received Language", data.received_language])
}
for(var i=0; i < twitch_list.length; i++) {
var data = twitch_list[i],
line = createElement('li');
line.innerHTML = data === null ? '<br>' : data[0] + '<span>' + data[1] + '</span>';
twitch.appendChild(line);
}
var exp_service = utils.ember_lookup('service:experiments');
if ( exp_service ) {
exp_head.innerHTML = 'Twitch Experiments';
for(var key in exp_service.values) {
if ( ! exp_service.values.hasOwnProperty(key) )
continue;
var val = exp_service.values[key],
line = createElement('li');
line.innerHTML = key + '<span>' + utils.sanitize(val) + '</span>';
experiments.appendChild(line);
}
}
ver_head.innerHTML = 'Versions';
if ( this.has_bttv )
version_list.push(["BetterTTV", BetterTTV.info.version + 'r' + BetterTTV.info.release]);
if ( Object.keys(this._apis).length ) {
version_list.push(null);
for(var key in this._apis) {
var api = this._apis[key];
version_list.push(['<b>Ext #' + api.id + '.</b> ' + api.name, api.version || '<i>unknown</i>']);
}
}
for(var i=0; i < version_list.length; i++) {
var data = version_list[i],
line = createElement('li');
line.innerHTML = data === null ? '<br>' : data[0] + '<span>' + data[1] + '</span>';
vers.appendChild(line);
}
log_head.className = 'list-header';
log_head.innerHTML = 'Logs';
logs.className = 'chat-menu-content menu-side-padding';
logs.textContent = this._log_data.join("\n");
container.appendChild(heading);
container.appendChild(ver_head);
container.appendChild(vers);
container.appendChild(info_head);
container.appendChild(info);
name: "About",
icon: constants.HEART,
sort_order: 100000,
pages: {
about: {
name: "About",
render: function(view, container, inner, menu) {
var room = this.rooms[view.get("context.currentRoom.id")],
has_emotes = false, f = this;
if ( room && room.set ) {
var set = this.emote_sets[room.set];
if ( set && set.count > 0 )
has_emotes = true;
}
// Heading
var heading = createElement('div'),
content = '';
content += "<h1>FrankerFaceZ</h1>";
content += '<div class="ffz-about-subheading">new ways to woof</div>';
heading.className = 'chat-menu-content center';
heading.innerHTML = content;
container.appendChild(heading);
var clicks = 0, head = heading.querySelector("h1");
head && head.addEventListener("click", function() {
head.style.cursor = "pointer";
clicks++;
if ( clicks >= 3 ) {
clicks = 0;
var el = document.querySelector(".app-main") || document.querySelector(".ember-chat-container");
el && el.classList.toggle('ffz-flip');
}
setTimeout(function(){clicks=0;head.style.cursor=""},2000);
});
// Button Stuff
var btn_container = createElement('div'),
ad_button = createElement('a'),
news_button = createElement('a'),
donate_button = createElement('a'),
message = "To use custom emoticons in " + (has_emotes ? "this channel" : "tons of channels") + ", get FrankerFaceZ from https://www.frankerfacez.com";
// Advertising
ad_button.className = 'button primary';
ad_button.innerHTML = "Advertise in Chat";
ad_button.addEventListener('click', this._add_emote.bind(this, view, message));
btn_container.appendChild(ad_button);
// Donate
donate_button.className = 'button ffz-donate';
donate_button.href = "https://www.frankerfacez.com/donate";
donate_button.target = "_new";
donate_button.innerHTML = "Donate";
btn_container.appendChild(donate_button);
btn_container.className = 'chat-menu-content center';
container.appendChild(btn_container);
// Credits
var credits = createElement('div');
content = '<table class="ffz-about-table">';
content += '<tr><th colspan="4">Developers</th></tr>';
content += '<tr><td>Dan Salvato</td><td><a class="twitch" href="//www.twitch.tv/dansalvato" title="Twitch" target="_new">&nbsp;</a></td><td><a class="twitter" href="https://twitter.com/dansalvato" title="Twitter" target="_new">&nbsp;</a></td><td><a class="youtube" href="https://www.youtube.com/user/dansalvato1" title="YouTube" target="_new">&nbsp;</a></td></tr>';
content += '<tr><td>Stendec</td><td><a class="twitch" href="//www.twitch.tv/sirstendec" title="Twitch" target="_new">&nbsp;</a></td><td><a class="twitter" href="https://twitter.com/SirStendec" title="Twitter" target="_new">&nbsp;</a></td><td><a class="youtube" href="https://www.youtube.com/channel/UCnxuvmK1DCPCXSJ-mXIh4KQ" title="YouTube" target="_new">&nbsp;</a></td></tr>';
content += '<tr class="debug"><td><a href="#" id="ffz-changelog">Version ' + FFZ.version_info + '</a></td><td colspan="3"><a href="#" id="ffz-debug-logs">Logs</a></td></tr>';
credits.className = 'chat-menu-content center';
credits.innerHTML = content;
// Make the Version clickable.
credits.querySelector('#ffz-changelog').addEventListener('click',
f._ui_change_subpage.bind(f, view, inner, menu, container, 'changelog'));
// Make the Logs button functional.
var getting_logs = false;
credits.querySelector('#ffz-debug-logs').addEventListener('click', function() {
if ( getting_logs )
return;
getting_logs = true;
f._pastebin(f._log_data.join("\n"), function(url) {
getting_logs = false;
if ( ! url )
alert("There was an error uploading the FrankerFaceZ logs.");
else
prompt("Your FrankerFaceZ logs have been uploaded to the URL:", url);
});
});
container.appendChild(credits);
}
},
changelog: {
name: "Changes",
wide: true,
render: include_html("change log", constants.SERVER + "script/changelog.html")
},
/*news: {
name: "News",
wide: true,
render: function(view, container) {
if ( this._has_news ) {
this._has_news = false;
localStorage.ffzLastNewsId = this._news_id;
this.update_ui_link();
}
return render_news.call(this, view, container);
}
},*/
credits: {
name: "Credit",
wide: true,
render: include_html("credits", constants.SERVER + "script/credits.html")
},
/*status: {
name: "Status",
wide: true,
render: include_html("server status", constants.SERVER + "script/status.html", function(view, container) {
})
},*/
debugging: {
name: "Debug",
wide: true,
render: function(view, container) {
// Heading
var heading = createElement('div'),
info_head = createElement('div'),
info = createElement('ul'),
info_list = [
['Client ID', localStorage.ffzClientId || '<i>not set</i>'],
['Socket Server', this._ws_sock && this._ws_sock.url || '<i>disconnected</i>' ],
['Server Ping', this._ws_last_ping || '<i>unknown</i>'],
['Time Offset', this._ws_sock && this._ws_server_offset && (this._ws_server_offset < 0 ? "-" : "") + utils.time_to_string(Math.abs(this._ws_server_offset) / 1000) || '<i>unknown</i>']
],
twitch_head = createElement('div'),
twitch = createElement('ul'),
twitch_list = [
['Deploy Flavor', SiteOptions.deploy_flavor]
],
exp_head = createElement('div'),
experiments = createElement('ul'),
has_memory = window.performance && performance.memory,
mem_head = createElement('div'),
mem_list = createElement('ul'),
player_head = createElement('div'),
player_list = createElement('ul'),
player, player_data,
ver_head = createElement('div'),
vers = createElement('ul'),
version_list = [
['Ember', Ember.VERSION],
['Ember Data', window.DS && DS.VERSION || '<i>unknown</i>'],
['GIT Version', EmberENV.GIT_VERSION],
null,
['FrankerFaceZ', FFZ.version_info.toString()]
],
log_head = createElement('div'),
logs = createElement('pre');
for(var pkey in this.players) {
player = this.players[pkey] && this.players[pkey].player;
if ( player )
break;
}
if ( player ) {
try {
player_data = player.getVideoInfo();
} catch(err) { }
}
heading.className = 'chat-menu-content center';
heading.innerHTML = '<h1>FrankerFaceZ</h1><div class="ffz-about-subheading">woofs for nerds</div>';
info_head.className = exp_head.className = mem_head.className = twitch_head.className = player_head.className = ver_head.className = log_head.className = 'list-header';
info.className = mem_list.className = twitch.className = experiments.className = player_list.className = vers.className = 'chat-menu-content menu-side-padding version-list';
info_head.innerHTML = 'Client Status';
for(var i=0; i < info_list.length; i++) {
var data = info_list[i],
line = createElement('li');
line.innerHTML = data === null ? '<br>' : data[0] + '<span>' + data[1] + '</span>';
info.appendChild(line);
}
twitch_head.innerHTML = 'Twitch Configuration';
// Check for Twitch geo-location
var user = this.get_user();
if ( user && user.login ) {
twitch_list.push(["Current User", user.login + " [" + user.id + "]"]);
var us = [];
user.is_staff && us.push("staff");
user.is_admin && us.push("admin");
user.is_partner && us.push("partner");
user.is_broadcaster && us.push("broadcaster");
user.has_turbo && us.push("turbo");
twitch_list.push(["User State", us.join(", ") || "<i>none</i>"]);
} else
twitch_list.push(["Current User", "<i>not logged in</i>"]);
if ( window.Twitch && Twitch.geo && Twitch.geo._result ) {
var data = Twitch.geo._result;
if ( data.geo )
twitch_list.push(["Region", data.geo + (data.eu ? " [EU]" : "")]);
if ( data.received_language )
twitch_list.push(["Received Language", data.received_language])
}
for(var i=0; i < twitch_list.length; i++) {
var data = twitch_list[i],
line = createElement('li');
line.innerHTML = data === null ? '<br>' : data[0] + '<span>' + data[1] + '</span>';
twitch.appendChild(line);
}
var exp_service = utils.ember_lookup('service:experiments');
if ( exp_service ) {
exp_head.innerHTML = 'Twitch Experiments';
for(var key in exp_service.values) {
if ( ! exp_service.values.hasOwnProperty(key) )
continue;
var val = exp_service.values[key],
line = createElement('li');
line.innerHTML = key + '<span>' + utils.sanitize(val) + '</span>';
experiments.appendChild(line);
}
}
ver_head.innerHTML = 'Versions';
if ( this.has_bttv )
version_list.push(["BetterTTV", BetterTTV.info.version + 'r' + BetterTTV.info.release]);
if ( Object.keys(this._apis).length ) {
version_list.push(null);
for(var key in this._apis) {
var api = this._apis[key];
version_list.push(['<b>Ext #' + api.id + '.</b> ' + api.name, api.version || '<i>unknown</i>']);
}
}
for(var i=0; i < version_list.length; i++) {
var data = version_list[i],
line = createElement('li');
line.innerHTML = data === null ? '<br>' : data[0] + '<span>' + data[1] + '</span>';
vers.appendChild(line);
}
log_head.className = 'list-header';
log_head.innerHTML = 'Logs';
logs.className = 'chat-menu-content menu-side-padding';
logs.textContent = this._log_data.join("\n");
container.appendChild(heading);
container.appendChild(ver_head);
container.appendChild(vers);
container.appendChild(info_head);
container.appendChild(info);
container.appendChild(twitch_head);
container.appendChild(twitch);
container.appendChild(twitch_head);
container.appendChild(twitch);
if ( exp_service ) {
container.appendChild(exp_head);
container.appendChild(experiments);
}
if ( has_memory ) {
mem_head.innerHTML = 'Memory Statistics';
setTimeout(update_mem_stats.bind(this,mem_list),0);
container.appendChild(mem_head);
container.appendChild(mem_list);
}
if ( player_data ) {
player_head.innerHTML = "Player Statistics";
setTimeout(update_player_stats.bind(this,player,player_list),0);
container.appendChild(player_head);
container.appendChild(player_list);
}
container.appendChild(log_head);
container.appendChild(logs);
}
}
}
if ( exp_service ) {
container.appendChild(exp_head);
container.appendChild(experiments);
}
if ( has_memory ) {
mem_head.innerHTML = 'Memory Statistics';
setTimeout(update_mem_stats.bind(this,mem_list),0);
container.appendChild(mem_head);
container.appendChild(mem_list);
}
if ( player_data ) {
player_head.innerHTML = "Player Statistics";
setTimeout(update_player_stats.bind(this,player,player_list),0);
container.appendChild(player_head);
container.appendChild(player_list);
}
container.appendChild(log_head);
container.appendChild(logs);
}
}
}
}

View file

@ -1,6 +1,6 @@
var FFZ = window.FrankerFaceZ,
constants = require('../constants'),
utils = require('../utils');
constants = require('../constants'),
utils = require('../utils');
// --------------

View file

@ -1,6 +1,6 @@
var FFZ = window.FrankerFaceZ,
constants = require("../constants"),
utils = require("../utils");
utils = require("../utils");
//styles = require("../styles");
@ -148,7 +148,7 @@ FFZ.settings_info.dark_twitch = {
settings && settings.set('darkMode', this.settings.twitch_chat_dark);
// Try coloring chat replay
jQuery('.chatReplay').toggleClass('dark', val || false);
jQuery('.chatReplay').toggleClass('dark', val || false);
//jQuery('.rechat-chat-line').parents('.chat-container').toggleClass('dark', val || this.settings.twitch_chat_dark);
}
};

View file

@ -1,5 +1,5 @@
var FFZ = window.FrankerFaceZ,
utils = require('../utils'),
utils = require('../utils'),
createElement = utils.createElement;

View file

@ -1,5 +1,5 @@
var FFZ = window.FrankerFaceZ,
utils = require('../utils'),
utils = require('../utils'),
update_viewer_count = function(text) {
var vc = jQuery("#channel_viewer_count");
@ -12,15 +12,15 @@ var FFZ = window.FrankerFaceZ,
// -------------------
FFZ.settings_info.dashboard_graph = {
type: "boolean",
value: true,
type: "boolean",
value: true,
no_mobile: true,
no_bttv: true,
no_mobile: true,
no_bttv: true,
category: "Dashboard",
name: "Statistics Graph <small>(Requires Refresh)</small>",
help: "Display a graph of your viewers, followers, and chat activity over time."
category: "Dashboard",
name: "Statistics Graph <small>(Requires Refresh)</small>",
help: "Display a graph of your viewers, followers, and chat activity over time."
}
@ -29,12 +29,12 @@ FFZ.settings_info.dashboard_graph = {
// -------------------
FFZ.msg_commands.chat_message = function(data) {
if ( ! this.dashboard_channel || data.room !== this.dashboard_channel )
return;
if ( ! this.dashboard_channel || data.room !== this.dashboard_channel )
return;
this._stat_chat_lines++;
if ( this._stat_chatters.indexOf(data.from) === -1 )
this._stat_chatters.push(data.from);
this._stat_chat_lines++;
if ( this._stat_chatters.indexOf(data.from) === -1 )
this._stat_chatters.push(data.from);
}
@ -43,233 +43,233 @@ FFZ.msg_commands.chat_message = function(data) {
// -------------------
FFZ.prototype.setup_dash_stats = function() {
this._stat_chat_lines = 0;
this._stat_chatters = [];
this._stat_last_game = null;
this._stat_last_status = null;
this._stat_chat_lines = 0;
this._stat_chatters = [];
this._stat_last_game = null;
this._stat_last_status = null;
this._update_dash_stats_timer = setTimeout(this.update_dash_stats.bind(this), 0);
this._update_dash_stats_timer = setTimeout(this.update_dash_stats.bind(this), 0);
var f = this,
stats = document.querySelector('#stats');
var f = this,
stats = document.querySelector('#stats');
if ( this.has_bttv || ! stats || ! window.Highcharts || ! this.settings.dashboard_graph )
return;
if ( this.has_bttv || ! stats || ! window.Highcharts || ! this.settings.dashboard_graph )
return;
f.log("Adding dashboard statistics chart.");
f.log("Adding dashboard statistics chart.");
// Build a chart, under stats.
var container = document.createElement('div');
container.id = "chart_container";
container.className = 'ffz-stat-chart';
stats.parentElement.insertBefore(container, stats.nextSibling);
// Build a chart, under stats.
var container = document.createElement('div');
container.id = "chart_container";
container.className = 'ffz-stat-chart';
stats.parentElement.insertBefore(container, stats.nextSibling);
Highcharts.setOptions({global: {useUTC: false}});
Highcharts.setOptions({global: {useUTC: false}});
// Load chart visibility
var vis = {};
if ( localStorage.ffz_dash_chart_visibility )
vis = JSON.parse(localStorage.ffz_dash_chart_visibility);
// Load chart visibility
var vis = {};
if ( localStorage.ffz_dash_chart_visibility )
vis = JSON.parse(localStorage.ffz_dash_chart_visibility);
var date_format = this.settings.twenty_four_timestamps ? "%H:%M" : "%l:%M",
chart = this._dash_chart = new Highcharts.Chart({
chart: {
type: 'line',
zoomType: "x",
animation: false,
renderTo: container,
height: 200
},
var date_format = this.settings.twenty_four_timestamps ? "%H:%M" : "%l:%M",
chart = this._dash_chart = new Highcharts.Chart({
chart: {
type: 'line',
zoomType: "x",
animation: false,
renderTo: container,
height: 200
},
title: { text: null },
credits: { enabled: false },
exporting: { enabled: false },
legend: {
backgroundColor: "#fff"
},
title: { text: null },
credits: { enabled: false },
exporting: { enabled: false },
legend: {
backgroundColor: "#fff"
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150,
dateTimeLabelFormats: {
millisecond: date_format,
second: date_format,
minute: date_format
}
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150,
dateTimeLabelFormats: {
millisecond: date_format,
second: date_format,
minute: date_format
}
},
tooltip: {
formatter: function() {
if ( this.point )
this.points = [this.point];
tooltip: {
formatter: function() {
if ( this.point )
this.points = [this.point];
var s = [],
key = this.points[0].key || this.points[0].x;
var s = [],
key = this.points[0].key || this.points[0].x;
if ( key ) {
if ( typeof key === "number" )
key = Highcharts.dateFormat((f.settings.twenty_four_timestamps ? "%H:%M" : "%l:%M %P"), key);
if ( key ) {
if ( typeof key === "number" )
key = Highcharts.dateFormat((f.settings.twenty_four_timestamps ? "%H:%M" : "%l:%M %P"), key);
s.push('<span style="font-size:10px">' + key + '</span>');
}
s.push('<span style="font-size:10px">' + key + '</span>');
}
for(var i=0; i < this.points.length; i++) {
var point = this.points[i],
series = point.series,
to = series.tooltipOptions,
y = point.text || point.y;
for(var i=0; i < this.points.length; i++) {
var point = this.points[i],
series = point.series,
to = series.tooltipOptions,
y = point.text || point.y;
if ( ! to || ! to.enabled || y === undefined || y === null )
continue;
if ( ! to || ! to.enabled || y === undefined || y === null )
continue;
if ( typeof y === "number" )
y = utils.number_commas(y);
if ( typeof y === "number" )
y = utils.number_commas(y);
s.push('<span style="color:' + series.color + '">' + series.name + '</span>: <b>' + y + '</b>');
}
s.push('<span style="color:' + series.color + '">' + series.name + '</span>: <b>' + y + '</b>');
}
return s.join("<br>");
},
crosshairs: true,
shared: true
},
return s.join("<br>");
},
crosshairs: true,
shared: true
},
yAxis: [
{title: { text: null }, min: 0},
{title: { text: null }, min: 0},
{title: { text: null }, min: 0, opposite: true},
{title: { text: null }, min: 0, opposite: true}
],
yAxis: [
{title: { text: null }, min: 0},
{title: { text: null }, min: 0},
{title: { text: null }, min: 0, opposite: true},
{title: { text: null }, min: 0, opposite: true}
],
series: [
{
type: 'flags',
name: 'Status',
showInLegend: false,
shape: 'squarepin',
data: [],
zIndex: 5
},
{name: "Viewers", data: [], zIndex: 4, visible: vis.hasOwnProperty('viewers')?vis.viewers:true},
{name: "Followers", data: [], yAxis: 1, zIndex: 3, visible: vis.hasOwnProperty('followers')?vis.followers:true},
{name: "Subscribers", data: [], zIndex: 3, showInLegend: false, visible: vis.hasOwnProperty('subscribers')?vis.subscribers:true},
{name: "Chat Lines", type: 'area', data: [], yAxis: 2, visible: vis.hasOwnProperty('chat_lines')?vis.chat_lines:false, zIndex: 1},
{name: "Chatters", data: [], yAxis: 3, visible: vis.hasOwnProperty('chatters')?vis.chatters:false, zIndex: 2}
]
});
series: [
{
type: 'flags',
name: 'Status',
showInLegend: false,
shape: 'squarepin',
data: [],
zIndex: 5
},
{name: "Viewers", data: [], zIndex: 4, visible: vis.hasOwnProperty('viewers')?vis.viewers:true},
{name: "Followers", data: [], yAxis: 1, zIndex: 3, visible: vis.hasOwnProperty('followers')?vis.followers:true},
{name: "Subscribers", data: [], zIndex: 3, showInLegend: false, visible: vis.hasOwnProperty('subscribers')?vis.subscribers:true},
{name: "Chat Lines", type: 'area', data: [], yAxis: 2, visible: vis.hasOwnProperty('chat_lines')?vis.chat_lines:false, zIndex: 1},
{name: "Chatters", data: [], yAxis: 3, visible: vis.hasOwnProperty('chatters')?vis.chatters:false, zIndex: 2}
]
});
}
FFZ.prototype._dash_chart_chatters = function(force) {
var now = utils.last_minute(),
series = this._dash_chart.series[4],
len = series.data.length,
last_point = len > 0 && series.data[len-1],
rendered = false;
var now = utils.last_minute(),
series = this._dash_chart.series[4],
len = series.data.length,
last_point = len > 0 && series.data[len-1],
rendered = false;
if ( ! force && ! this._stat_chat_lines && len > 0 && last_point.y === 0 ) {
series.addPoint({x: now, y: null}, false);
this._dash_chart.series[5].addPoint({x: now, y: null}, false);
rendered = true;
if ( ! force && ! this._stat_chat_lines && len > 0 && last_point.y === 0 ) {
series.addPoint({x: now, y: null}, false);
this._dash_chart.series[5].addPoint({x: now, y: null}, false);
rendered = true;
} else if ( force || this._stat_chat_lines || len > 0 && last_point && last_point.y !== null ) {
if ( this._stat_chat_lines !== 0 && last_point && last_point.y === null ) {
series.addPoint({x:now-60000, y: 0}, false);
this._dash_chart.series[5].addPoint({x:now-60000, y: 0}, false);
}
} else if ( force || this._stat_chat_lines || len > 0 && last_point && last_point.y !== null ) {
if ( this._stat_chat_lines !== 0 && last_point && last_point.y === null ) {
series.addPoint({x:now-60000, y: 0}, false);
this._dash_chart.series[5].addPoint({x:now-60000, y: 0}, false);
}
series.addPoint({x: now, y: this._stat_chat_lines || 0}, false);
this._dash_chart.series[5].addPoint({x: now, y: this._stat_chatters.length || 0}, false);
rendered = true;
}
series.addPoint({x: now, y: this._stat_chat_lines || 0}, false);
this._dash_chart.series[5].addPoint({x: now, y: this._stat_chatters.length || 0}, false);
rendered = true;
}
this._stat_chat_lines = 0;
this._stat_chatters = [];
return rendered;
this._stat_chat_lines = 0;
this._stat_chatters = [];
return rendered;
}
FFZ.prototype._remove_dash_chart = function() {
if ( ! this._dash_chart )
return;
if ( ! this._dash_chart )
return;
this.log("Removing dashboard statistics chart.");
this.log("Removing dashboard statistics chart.");
this._dash_chart.destroy();
this._dash_chart = null;
jQuery("#chart_container.ffz-stat-chart").remove();
this._dash_chart.destroy();
this._dash_chart = null;
jQuery("#chart_container.ffz-stat-chart").remove();
}
FFZ.prototype.update_dash_stats = function() {
var f = this,
id = this.dashboard_channel;
var f = this,
id = this.dashboard_channel;
if ( this.has_bttv || ! id )
return this._remove_dash_chart();
if ( this.has_bttv || ! id )
return this._remove_dash_chart();
this._update_dash_stats_timer = setTimeout(this.update_dash_stats.bind(this), 60000);
this._update_dash_stats_timer = setTimeout(this.update_dash_stats.bind(this), 60000);
if ( f._dash_chart ) {
var series = f._dash_chart.series;
localStorage.ffz_dash_chart_visibility = JSON.stringify({
viewers: series[1].visble,
followers: series[2].visible,
subscribers: series[3].visible,
chat_lines: series[4].visible,
chatters: series[5].visible
});
}
if ( f._dash_chart ) {
var series = f._dash_chart.series;
localStorage.ffz_dash_chart_visibility = JSON.stringify({
viewers: series[1].visble,
followers: series[2].visible,
subscribers: series[3].visible,
chat_lines: series[4].visible,
chatters: series[5].visible
});
}
utils.api.get("streams/" + id , {}, {version: 3})
.done(function(data) {
var viewers = null,
followers = null,
game = null,
status = null;
utils.api.get("streams/" + id , {}, {version: 3})
.done(function(data) {
var viewers = null,
followers = null,
game = null,
status = null;
if ( ! data || ! data.stream )
!f.has_bttv && update_viewer_count("Offline");
if ( ! data || ! data.stream )
!f.has_bttv && update_viewer_count("Offline");
else {
!f.has_bttv && update_viewer_count(utils.number_commas(data.stream.viewers));
viewers = data.stream.viewers;
else {
!f.has_bttv && update_viewer_count(utils.number_commas(data.stream.viewers));
viewers = data.stream.viewers;
var chan = data.stream.channel;
if ( chan ) {
followers = chan.hasOwnProperty('followers') ? chan.followers || 0 : null;
game = chan.game || "Not Playing";
status = chan.status || "Untitled Broadcast";
var chan = data.stream.channel;
if ( chan ) {
followers = chan.hasOwnProperty('followers') ? chan.followers || 0 : null;
game = chan.game || "Not Playing";
status = chan.status || "Untitled Broadcast";
if ( chan.views )
jQuery("#views_count span").text(utils.number_commas(chan.views));
if ( followers )
jQuery("#followers_count span").text(utils.number_commas(followers));
}
}
if ( chan.views )
jQuery("#views_count span").text(utils.number_commas(chan.views));
if ( followers )
jQuery("#followers_count span").text(utils.number_commas(followers));
}
}
if ( f._dash_chart ) {
var now = utils.last_minute(),
force_draw;
if ( f._dash_chart ) {
var now = utils.last_minute(),
force_draw;
// If the game or status changed, we need to insert a pin.
if ( f._stat_last_game !== game || f._stat_last_status !== status ) {
f._dash_chart.series[0].addPoint({x: now, title: game, text: status}, false);
f._stat_last_game = game;
f._stat_last_status = status;
}
// If the game or status changed, we need to insert a pin.
if ( f._stat_last_game !== game || f._stat_last_status !== status ) {
f._dash_chart.series[0].addPoint({x: now, title: game, text: status}, false);
f._stat_last_game = game;
f._stat_last_status = status;
}
force_draw = utils.maybe_chart(f._dash_chart.series[1], {x: now, y: viewers}, false);
force_draw = f._dash_chart_chatters(force_draw) || force_draw;
force_draw = utils.maybe_chart(f._dash_chart.series[1], {x: now, y: viewers}, false);
force_draw = f._dash_chart_chatters(force_draw) || force_draw;
utils.maybe_chart(f._dash_chart.series[2], {x: now, y: followers}, false, force_draw);
utils.maybe_chart(f._dash_chart.series[2], {x: now, y: followers}, false, force_draw);
f._dash_chart.redraw();
}
}).fail(function() {
if ( f._dash_chart ) {
f._dash_chart_chatters();
f._dash_chart.redraw();
}
});
f._dash_chart.redraw();
}
}).fail(function() {
if ( f._dash_chart ) {
f._dash_chart_chatters();
f._dash_chart.redraw();
}
});
}

View file

@ -88,11 +88,11 @@ FFZ.prototype.setup_following_count = function(has_ember) {
Live.load();
/*var Host = utils.ember_resolve('model:hist'),
HostLive = Host && Host.find("following");
/*var Host = utils.ember_resolve('model:hist'),
HostLive = Host && Host.find("following");
if ( HostLive )
HostLive.load();*/
if ( HostLive )
HostLive.load();*/
var init = function() {
var total = Live.get('total'),
@ -158,13 +158,13 @@ FFZ.prototype._update_following_count = function() {
var Stream = utils.ember_resolve('model:stream'),
Live = Stream && Stream.find("live"),
Host = utils.ember_resolve('model:host'),
HostLive = Host && Host.find("following"),
Host = utils.ember_resolve('model:host'),
HostLive = Host && Host.find("following"),
f = this;
if ( ! this.is_dashboard && HostLive && document.body.getAttribute('data-current-path').indexOf('directory.following') !== -1 )
HostLive.load();
if ( ! this.is_dashboard && HostLive && document.body.getAttribute('data-current-path').indexOf('directory.following') !== -1 )
HostLive.load();
if ( ! this.is_dashboard && Live )
Live.load();
@ -195,12 +195,12 @@ FFZ.prototype._build_following_tooltip = function(el) {
height = document.body.clientHeight - (bb.bottom + 50),
max_lines = Math.max(Math.floor(height / 40) - 1, 2),
/*Host = utils.ember_resolve('model:host'),
HostLive = Host && Host.find("following"),*/
/*Host = utils.ember_resolve('model:host'),
HostLive = Host && Host.find("following"),*/
streams = this._tooltip_streams,
total = this._tooltip_total || (streams && streams.length) || 0,
c = 0;
c = 0;
if ( streams && streams.length ) {
for(var i=0, l = streams.length; i < l; i++) {
@ -228,46 +228,46 @@ FFZ.prototype._build_following_tooltip = function(el) {
'<span class="playing">' + (stream.channel.game === 'Creative' ? 'Being Creative' : (stream.channel.game ? 'Playing ' + utils.sanitize(stream.channel.game) : 'Not Playing')) + (tags ? ' | ' + _.pluck(tags, "text").join(" ") : '') + '</span>';
}
} else {
c++; // is a terrible programming language
c++; // is a terrible programming language
tooltip += "<hr>No one you're following is online.";
}
}
// If we have hosts, and room, try displaying some hosts.
/*if ( HostLive && (c + 1) < max_lines && HostLive.get('content.length') > 0 ) {
var t = HostLive.get('content.length');
c++;
tooltip += '<hr>Live Hosts';
for(var i=0; i < t; i++) {
var host = HostLive.get('content.' + i),
stream = host && host.target;
if ( ! stream )
continue;
// If we have hosts, and room, try displaying some hosts.
/*if ( HostLive && (c + 1) < max_lines && HostLive.get('content.length') > 0 ) {
var t = HostLive.get('content.length');
c++;
tooltip += '<hr>Live Hosts';
for(var i=0; i < t; i++) {
var host = HostLive.get('content.' + i),
stream = host && host.target;
if ( ! stream )
continue;
c += 1;
if ( c > max_lines ) {
var sc = 1 + (streams && streams.length || 0);
tooltip += '<hr><span>And ' + utils.number_commas(t - (max_lines - sc)) + ' more...</span>';
break;
}
c += 1;
if ( c > max_lines ) {
var sc = 1 + (streams && streams.length || 0);
tooltip += '<hr><span>And ' + utils.number_commas(t - (max_lines - sc)) + ' more...</span>';
break;
}
var hosting;
if ( ! host.ffz_hosts || host.ffz_hosts.length === 1 )
hosting = host.display_name;
else
hosting = utils.number_commas(host.ffz_hosts.length);
var hosting;
if ( ! host.ffz_hosts || host.ffz_hosts.length === 1 )
hosting = host.display_name;
else
hosting = utils.number_commas(host.ffz_hosts.length);
tooltip += (i === 0 ? '<hr>' : '') +
'<span class="stat">' + constants.LIVE + ' ' + utils.number_commas(stream.viewers) + '</span>' +
tooltip += (i === 0 ? '<hr>' : '') +
'<span class="stat">' + constants.LIVE + ' ' + utils.number_commas(stream.viewers) + '</span>' +
hosting + ' hosting <b>' + utils.sanitize(stream.channel.display_name || stream.channel.name) + '</b><br>' +
'<span class="playing">' + (stream.meta_game ? 'Playing ' + utils.sanitize(stream.meta_game) : 'Not Playing') + '</span>';
}
}*/
}
}*/
// Reposition the tooltip.
setTimeout(function() {
var tip = document.querySelector('.tipsy');
if ( ! tip )
return;
if ( ! tip )
return;
var bb = tip.getBoundingClientRect(),

View file

@ -4,7 +4,7 @@ var FFZ = window.FrankerFaceZ,
IS_OSX = constants.IS_OSX,
reported_sets = [],
reported_sets = [],
fix_menu_position = function(container) {
var swapped = document.body.classList.contains('ffz-sidebar-swap') && ! document.body.classList.contains('ffz-portrait');
@ -217,7 +217,7 @@ FFZ.prototype.build_ui_popup = function(view) {
// Stuff
//jQuery(inner).find('.html-tooltip').tipsy({live: true, html: true, gravity: utils.tooltip_placement(2*constants.TOOLTIP_DISTANCE, 's')});
//jQuery(inner).find('.ffz-tooltip').tipsy({live: true, html: true, title: this.render_tooltip(), gravity: utils.tooltip_placement(2*constants.TOOLTIP_DISTANCE, 'n')});
//jQuery(inner).find('.ffz-tooltip').tipsy({live: true, html: true, title: this.render_tooltip(), gravity: utils.tooltip_placement(2*constants.TOOLTIP_DISTANCE, 'n')});
// Menu Container
var sub_container = document.createElement('div');
@ -336,33 +336,33 @@ FFZ.prototype.build_ui_popup = function(view) {
FFZ.prototype._ui_change_subpage = function(view, inner, menu, container, subpage) {
var page = this._last_page,
last_subpages = this._last_subpage = this._last_subpage || {};
var page = this._last_page,
last_subpages = this._last_subpage = this._last_subpage || {};
last_subpages[page] = subpage;
last_subpages[page] = subpage;
container.innerHTML = "";
container.setAttribute('data-page', subpage);
container.innerHTML = "";
container.setAttribute('data-page', subpage);
// Get the data structure for this page.
var page_data = FFZ.menu_pages[page],
data = page_data.pages[subpage];
// Get the data structure for this page.
var page_data = FFZ.menu_pages[page],
data = page_data.pages[subpage];
// Render the page first. If there's an error, it won't update the other UI stuff.
// Render the page first. If there's an error, it won't update the other UI stuff.
data.render.call(this, view, container, inner, menu);
// Make sure the correct menu tab is selected
jQuery('li.active', menu).removeClass('active');
jQuery('#ffz-menu-page-' + page + '-subpage-' + subpage, menu).addClass('active');
// Make sure the correct menu tab is selected
jQuery('li.active', menu).removeClass('active');
jQuery('#ffz-menu-page-' + page + '-subpage-' + subpage, menu).addClass('active');
// Apply wideness - TODO: Revamp wide menus entirely for thin containers
var is_wide = false,
app = document.querySelector(".app-main") || document.querySelector(".ember-chat-container");
// Apply wideness - TODO: Revamp wide menus entirely for thin containers
var is_wide = false,
app = document.querySelector(".app-main") || document.querySelector(".ember-chat-container");
if ( data.hasOwnProperty('wide') )
is_wide = data.wide || (typeof data.wide === "function" && data.wide.call(this));
else if ( page_data.hasOwnProperty('wide') )
is_wide = page_data.wide || (typeof page_data.wide === "function" && page_data.wide.call(this));
if ( data.hasOwnProperty('wide') )
is_wide = data.wide || (typeof data.wide === "function" && data.wide.call(this));
else if ( page_data.hasOwnProperty('wide') )
is_wide = page_data.wide || (typeof page_data.wide === "function" && page_data.wide.call(this));
inner.style.maxWidth = is_wide ? (app.offsetWidth < 640 ? (app.offsetWidth-40) : 600) + "px" : "";
@ -377,33 +377,33 @@ FFZ.prototype._ui_change_page = function(view, inner, menu, container, page) {
container.innerHTML = "";
container.setAttribute('data-page', page);
// Get the data structure for the new page.
var data = FFZ.menu_pages[page];
// Get the data structure for the new page.
var data = FFZ.menu_pages[page];
// See if we're dealing with a sub-menu situation.
if ( data.pages ) {
// We need to render the sub-menu, and then call the _ui_change_sub_page method
// to render the sub-page.
var submenu = document.createElement('ul'),
subcontainer = document.createElement('div'),
// See if we're dealing with a sub-menu situation.
if ( data.pages ) {
// We need to render the sub-menu, and then call the _ui_change_sub_page method
// to render the sub-page.
var submenu = document.createElement('ul'),
subcontainer = document.createElement('div'),
height = parseInt(container.style.maxHeight || '0');
height = parseInt(container.style.maxHeight || '0');
if ( ! height )
height = Math.max(200, view.$().height() - 172);
if ( ! height )
height = Math.max(200, view.$().height() - 172);
if ( height && ! Number.isNaN(height) ) {
height -= 37;
subcontainer.style.maxHeight = height + 'px';
}
if ( height && ! Number.isNaN(height) ) {
height -= 37;
subcontainer.style.maxHeight = height + 'px';
}
submenu.className = 'menu sub-menu clearfix';
subcontainer.className = 'ffz-ui-sub-menu-page';
submenu.className = 'menu sub-menu clearfix';
subcontainer.className = 'ffz-ui-sub-menu-page';
// Building Tabs
var subpages = [];
for(var key in data.pages) {
var subpage = data.pages[key];
// Building Tabs
var subpages = [];
for(var key in data.pages) {
var subpage = data.pages[key];
try {
if ( ! subpage || (subpage.hasOwnProperty("visible") && (!subpage.visible || (typeof subpage.visible == "function" && !subpage.visible.call(this, view)))) )
continue;
@ -412,65 +412,65 @@ FFZ.prototype._ui_change_page = function(view, inner, menu, container, page) {
continue;
}
subpages.push([subpage.sort_order || 0, key, subpage]);
}
subpages.push([subpage.sort_order || 0, key, subpage]);
}
subpages.sort(function(a,b) {
if ( a[0] < b[0] ) return -1;
else if ( a[0] > b[0] ) return 1;
subpages.sort(function(a,b) {
if ( a[0] < b[0] ) return -1;
else if ( a[0] > b[0] ) return 1;
var al = a[1].toLowerCase(),
bl = b[1].toLowerCase();
var al = a[1].toLowerCase(),
bl = b[1].toLowerCase();
if ( al < bl ) return -1;
if ( al > bl ) return 1;
return 0;
});
if ( al < bl ) return -1;
if ( al > bl ) return 1;
return 0;
});
for(var i=0; i < subpages.length; i++) {
var key = subpages[i][1],
subpage = subpages[i][2],
tab = document.createElement('li'),
link = document.createElement('a');
for(var i=0; i < subpages.length; i++) {
var key = subpages[i][1],
subpage = subpages[i][2],
tab = document.createElement('li'),
link = document.createElement('a');
tab.className = 'item';
tab.id = 'ffz-menu-page-' + page + '-subpage-' + key;
link.innerHTML = subpage.name;
link.addEventListener('click', this._ui_change_subpage.bind(this, view, inner, submenu, subcontainer, key));
tab.className = 'item';
tab.id = 'ffz-menu-page-' + page + '-subpage-' + key;
link.innerHTML = subpage.name;
link.addEventListener('click', this._ui_change_subpage.bind(this, view, inner, submenu, subcontainer, key));
tab.appendChild(link);
submenu.appendChild(tab);
}
tab.appendChild(link);
submenu.appendChild(tab);
}
// Activate a Tab
var last_subpages = this._last_subpage = this._last_subpage || {},
last_subpage = last_subpages[page] = last_subpages[page] || data.default_page || subpages[0][1];
// Activate a Tab
var last_subpages = this._last_subpage = this._last_subpage || {},
last_subpage = last_subpages[page] = last_subpages[page] || data.default_page || subpages[0][1];
if ( typeof last_subpage === "function" )
last_subpage = last_subpage.call(this);
if ( typeof last_subpage === "function" )
last_subpage = last_subpage.call(this);
this._ui_change_subpage(view, inner, submenu, subcontainer, last_subpage);
this._ui_change_subpage(view, inner, submenu, subcontainer, last_subpage);
// Make sure the correct menu tab is selected
jQuery('li.active', menu).removeClass('active');
jQuery('#ffz-menu-page-' + page, menu).addClass('active');
// Make sure the correct menu tab is selected
jQuery('li.active', menu).removeClass('active');
jQuery('#ffz-menu-page-' + page, menu).addClass('active');
// Add this to the container.
container.appendChild(subcontainer);
container.appendChild(submenu);
return;
}
// Add this to the container.
container.appendChild(subcontainer);
container.appendChild(submenu);
return;
}
// Render the page first. If there's an error, it won't update the other UI stuff.
// Render the page first. If there's an error, it won't update the other UI stuff.
data.render.call(this, view, container, inner, menu);
// Make sure the correct menu tab is selected
jQuery('li.active', menu).removeClass('active');
jQuery('#ffz-menu-page-' + page, menu).addClass('active');
// Make sure the correct menu tab is selected
jQuery('li.active', menu).removeClass('active');
jQuery('#ffz-menu-page-' + page, menu).addClass('active');
// Apply wideness - TODO: Revamp wide menus entirely for thin containers
var is_wide = data.wide || (typeof data.wide === "function" && data.wide.call(this)),
app = document.querySelector(".app-main") || document.querySelector(".ember-chat-container");
// Apply wideness - TODO: Revamp wide menus entirely for thin containers
var is_wide = data.wide || (typeof data.wide === "function" && data.wide.call(this)),
app = document.querySelector(".app-main") || document.querySelector(".ember-chat-container");
inner.style.maxWidth = is_wide ? (app.offsetWidth < 640 ? (app.offsetWidth-40) : 600) + "px" : "";
@ -498,8 +498,8 @@ FFZ.menu_pages.channel = {
if ( product && !product.get("error") ) {
// We have a product, and no error~!
has_product = true;
var Ticket = utils.ember_resolve('model:ticket'),
tickets = Ticket && Ticket.find('user', {channel: room_id}),
var Ticket = utils.ember_resolve('model:ticket'),
tickets = Ticket && Ticket.find('user', {channel: room_id}),
is_subscribed = tickets ? tickets.get('content') : false,
is_loaded = tickets ? tickets.get('isLoaded') : false,
icon = room.room.get("badgeSet.subscriber.image"),
@ -540,7 +540,7 @@ FFZ.menu_pages.channel = {
header.innerHTML = '<span class="right">Twitch</span>Subscriber Emoticons';
grid.appendChild(header);
var known_sets = [];
var known_sets = [];
for(var emotes=product.get("emoticons") || [], i=0; i < emotes.length; i++) {
var emote = emotes[i];
@ -553,17 +553,17 @@ FFZ.menu_pages.channel = {
s.className = 'emoticon ffz-tooltip ffz-tooltip-no-credit' + (!can_use ? " locked" : "");
if ( known_sets.indexOf(emote.emoticon_set) === -1 )
known_sets.push(emote.emoticon_set);
if ( known_sets.indexOf(emote.emoticon_set) === -1 )
known_sets.push(emote.emoticon_set);
if ( emote.emoticon_set ) {
var favs = this.settings.favorite_emotes["twitch-" + emote.emoticon_set];
s.classList.add('ffz-can-favorite');
s.classList.toggle('ffz-favorite', favs && favs.indexOf(emote.id) !== -1 || false);
}
if ( emote.emoticon_set ) {
var favs = this.settings.favorite_emotes["twitch-" + emote.emoticon_set];
s.classList.add('ffz-can-favorite');
s.classList.toggle('ffz-favorite', favs && favs.indexOf(emote.id) !== -1 || false);
}
s.setAttribute('data-emote', emote.id);
s.alt = emote.regex;
s.setAttribute('data-emote', emote.id);
s.alt = emote.regex;
s.style.backgroundImage = 'url("' + constants.TWITCH_BASE + emote.id + '/1.0")';
s.style.backgroundImage = '-webkit-' + img_set;
@ -578,7 +578,7 @@ FFZ.menu_pages.channel = {
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, "twitch-" + emote_set, id, e);
this._add_emote(view, code, "twitch-" + emote_set, id, e);
else
return;
e.preventDefault();
@ -588,11 +588,11 @@ FFZ.menu_pages.channel = {
c++;
}
if ( reported_sets.indexOf(product.get('id')) === -1 && known_sets.length ) {
reported_sets.push(product.get('id'));
this.log("Sets for " + product.get('id') + " [" + product.get('ticketProductId') + "]: " + JSON.stringify(known_sets));
this.ws_send("report_twitch_set", [product.get('id'), product.get('ticketProductId'), known_sets]);
}
if ( reported_sets.indexOf(product.get('id')) === -1 && known_sets.length ) {
reported_sets.push(product.get('id'));
this.log("Sets for " + product.get('id') + " [" + product.get('ticketProductId') + "]: " + JSON.stringify(known_sets));
this.ws_send("report_twitch_set", [product.get('id'), product.get('ticketProductId'), known_sets]);
}
if ( c > 0 )
@ -646,7 +646,7 @@ FFZ.menu_pages.channel = {
var extra_sets = _.union(room && room.extra_sets || [], room && room.ext_sets || [], []);
// Basic Emote Sets
this._emotes_for_sets(inner, view, room && room.set && [room.set] || [], (this.feature_friday || has_product || extra_sets.length ) ? "Channel Emoticons" : null, (room && room.moderator_badge) || "//cdn.frankerfacez.com/script/devicon.png", "FrankerFaceZ");
this._emotes_for_sets(inner, view, room && room.set && [room.set] || [], (this.feature_friday || has_product || extra_sets.length ) ? "Channel Emoticons" : null, (room && room.moderator_badge) || "//cdn.frankerfacez.com/script/devicon.png", "FrankerFaceZ");
for(var i=0; i < extra_sets.length; i++) {
// Look up the set name.
@ -734,8 +734,8 @@ FFZ.prototype._emotes_for_sets = function(parent, view, sets, header, image, sub
var s = document.createElement('span');
s.className = 'emoticon ffz-tooltip';
s.setAttribute('data-ffz-emote', emote.id);
s.setAttribute('data-ffz-set', set.id);
s.setAttribute('data-ffz-emote', emote.id);
s.setAttribute('data-ffz-set', set.id);
s.style.backgroundImage = 'url("' + emote.urls[1] + '")';
@ -748,7 +748,7 @@ FFZ.prototype._emotes_for_sets = function(parent, view, sets, header, image, sub
}
s.style.width = (10+emote.width) + "px";
s.style.height = (10+emote.height) + "px";
s.style.height = (10+emote.height) + "px";
s.addEventListener('click', function(id, code, e) {
e.preventDefault();
@ -779,27 +779,27 @@ FFZ.prototype._emotes_for_sets = function(parent, view, sets, header, image, sub
FFZ.prototype._add_emote = function(view, emote, favorites_set, favorites_key, event) {
if ( event && ((!IS_OSX && event.ctrlKey) || (IS_OSX && event.metaKey)) ) {
var el = event.target;
if ( ! el.classList.contains('locked') && el.classList.contains('ffz-can-favorite') && favorites_set && favorites_key ) {
var favs = this.settings.favorite_emotes[favorites_set] = this.settings.favorite_emotes[favorites_set] || [],
is_favorited = favs.indexOf(favorites_key) !== -1;
if ( event && ((!IS_OSX && event.ctrlKey) || (IS_OSX && event.metaKey)) ) {
var el = event.target;
if ( ! el.classList.contains('locked') && el.classList.contains('ffz-can-favorite') && favorites_set && favorites_key ) {
var favs = this.settings.favorite_emotes[favorites_set] = this.settings.favorite_emotes[favorites_set] || [],
is_favorited = favs.indexOf(favorites_key) !== -1;
if ( is_favorited )
favs.removeObject(favorites_key);
else
favs.push(favorites_key);
if ( is_favorited )
favs.removeObject(favorites_key);
else
favs.push(favorites_key);
this.settings.set("favorite_emotes", this.settings.favorite_emotes, true);
this.settings.set("favorite_emotes", this.settings.favorite_emotes, true);
if ( el.classList.contains('ffz-is-favorite') && is_favorited ) {
jQuery(el).trigger('mouseout');
el.parentElement.removeChild(el);
} else
el.classList.toggle('ffz-favorite', ! is_favorited);
}
return;
}
if ( el.classList.contains('ffz-is-favorite') && is_favorited ) {
jQuery(el).trigger('mouseout');
el.parentElement.removeChild(el);
} else
el.classList.toggle('ffz-favorite', ! is_favorited);
}
return;
}
var input_el, text, room;

View file

@ -1,6 +1,6 @@
var FFZ = window.FrankerFaceZ,
constants = require('../constants'),
utils = require('../utils');
utils = require('../utils');
// --------------------
// Initialization

View file

@ -66,15 +66,15 @@ FFZ.settings_info.emoji_in_menu = {
FFZ.settings_info.emote_menu_collapsed = {
storage_key: "ffz_setting_my_emoticons_collapsed_sections",
storage_key: "ffz_setting_my_emoticons_collapsed_sections",
value: [],
visible: false
}
FFZ.settings_info.favorite_emotes = {
value: {},
visible: false
value: {},
visible: false
}
@ -111,164 +111,164 @@ FFZ.menu_pages.myemotes = {
return this.settings.emoji_in_menu || FFZ.menu_pages.myemotes.has_sets.call(this, view);
},
default_page: function() {
for(var key in this.settings.favorite_emotes)
if ( this.settings.favorite_emotes[key] && this.settings.favorite_emotes[key].length )
return 'favorites';
default_page: function() {
for(var key in this.settings.favorite_emotes)
if ( this.settings.favorite_emotes[key] && this.settings.favorite_emotes[key].length )
return 'favorites';
return 'all';
},
return 'all';
},
pages: {
favorites: {
name: "Favorites",
sort_order: 1,
pages: {
favorites: {
name: "Favorites",
sort_order: 1,
render: function(view, container) {
FFZ.menu_pages.myemotes.render_lists.call(this, view, container, true);
render: function(view, container) {
FFZ.menu_pages.myemotes.render_lists.call(this, view, container, true);
var el = document.createElement("div");
el.className = "emoticon-grid ffz-no-emotes center";
el.innerHTML = "You have no favorite emoticons.<br> <img src=\"//cdn.frankerfacez.com/emoticon/26608/2\"><br>To make an emote a favorite, find it on the <nobr>All Emoticons</nobr> tab and <nobr>" + (constants.IS_OSX ? '⌘' : 'Ctrl') + "-Click</nobr> it.";
container.appendChild(el);
}
},
var el = document.createElement("div");
el.className = "emoticon-grid ffz-no-emotes center";
el.innerHTML = "You have no favorite emoticons.<br> <img src=\"//cdn.frankerfacez.com/emoticon/26608/2\"><br>To make an emote a favorite, find it on the <nobr>All Emoticons</nobr> tab and <nobr>" + (constants.IS_OSX ? '⌘' : 'Ctrl') + "-Click</nobr> it.";
container.appendChild(el);
}
},
all: {
name: "All Emoticons",
sort_order: 2,
all: {
name: "All Emoticons",
sort_order: 2,
visible: function(view) {
return FFZ.menu_pages.myemotes.has_sets.call(this, view);
},
render: function(view, container) {
FFZ.menu_pages.myemotes.render_lists.call(this, view, container, false);
}
},
render: function(view, container) {
FFZ.menu_pages.myemotes.render_lists.call(this, view, container, false);
}
},
emoji: {
name: "Emoji",
sort_order: 3,
visible: function() { return this.settings.emoji_in_menu },
emoji: {
name: "Emoji",
sort_order: 3,
visible: function() { return this.settings.emoji_in_menu },
render: function(view, container) {
var sets = [];
render: function(view, container) {
var sets = [];
for(var cat in constants.EMOJI_CATEGORIES) {
var menu = FFZ.menu_pages.myemotes.draw_emoji.call(this, view, cat, false);
if ( menu )
sets.push([cat, menu]);
}
for(var cat in constants.EMOJI_CATEGORIES) {
var menu = FFZ.menu_pages.myemotes.draw_emoji.call(this, view, cat, false);
if ( menu )
sets.push([cat, menu]);
}
sets.sort(function(a,b) {
var an = a[0], bn = b[0];
if ( an < bn ) return -1;
if ( an > bn ) return 1;
return 0;
});
sets.sort(function(a,b) {
var an = a[0], bn = b[0];
if ( an < bn ) return -1;
if ( an > bn ) return 1;
return 0;
});
for(var i=0; i < sets.length; i++)
container.appendChild(sets[i][1]);
}
}
},
for(var i=0; i < sets.length; i++)
container.appendChild(sets[i][1]);
}
}
},
render_lists: function(view, container, favorites_only) {
var tmi = view.get('controller.currentRoom.tmiSession'),
render_lists: function(view, container, favorites_only) {
var tmi = view.get('controller.currentRoom.tmiSession'),
twitch_sets = (tmi && tmi.getEmotes() || {'emoticon_sets': {}})['emoticon_sets'],
user = this.get_user(),
ffz_sets = this.getEmotes(user && user.login, null),
sets = [];
user = this.get_user(),
ffz_sets = this.getEmotes(user && user.login, null),
sets = [];
// Start with Twitch Sets
for(var set_id in twitch_sets) {
if ( ! twitch_sets.hasOwnProperty(set_id) || ( ! this.settings.global_emotes_in_menu && set_id === '0' ) )
continue;
// Start with Twitch Sets
for(var set_id in twitch_sets) {
if ( ! twitch_sets.hasOwnProperty(set_id) || ( ! this.settings.global_emotes_in_menu && set_id === '0' ) )
continue;
var favorites_list = this.settings.favorite_emotes["twitch-" + set_id];
if ( favorites_only && (! favorites_list || ! favorites_list.length) )
continue;
var favorites_list = this.settings.favorite_emotes["twitch-" + set_id];
if ( favorites_only && (! favorites_list || ! favorites_list.length) )
continue;
var set = twitch_sets[set_id];
if ( ! set.length )
continue;
var set = twitch_sets[set_id];
if ( ! set.length )
continue;
var menu = FFZ.menu_pages.myemotes.draw_twitch_set.call(this, view, set_id, set, favorites_only);
if ( menu )
sets.push([this._twitch_set_to_channel[set_id], menu]);
}
var menu = FFZ.menu_pages.myemotes.draw_twitch_set.call(this, view, set_id, set, favorites_only);
if ( menu )
sets.push([this._twitch_set_to_channel[set_id], menu]);
}
// Emoji~!
if ( favorites_only && this.settings.emoji_in_menu ) {
var favorites_list = this.settings.favorite_emotes["emoji"];
if ( favorites_list && favorites_list.length ) {
var menu = FFZ.menu_pages.myemotes.draw_emoji.call(this, view, null, favorites_only);
if ( menu )
sets.push(["emoji", menu]);
}
}
// Emoji~!
if ( favorites_only && this.settings.emoji_in_menu ) {
var favorites_list = this.settings.favorite_emotes["emoji"];
if ( favorites_list && favorites_list.length ) {
var menu = FFZ.menu_pages.myemotes.draw_emoji.call(this, view, null, favorites_only);
if ( menu )
sets.push(["emoji", menu]);
}
}
// Now, FFZ!
for(var i=0; i < ffz_sets.length; i++) {
var set_id = ffz_sets[i],
set = this.emote_sets[set_id],
// Now, FFZ!
for(var i=0; i < ffz_sets.length; i++) {
var set_id = ffz_sets[i],
set = this.emote_sets[set_id],
menu_id = set.hasOwnProperty('source_ext') ? 'ffz-ext-' + set.source_ext + '-' + set.source_id : 'ffz-' + set.id,
favorites_list = this.settings.favorite_emotes[menu_id];
menu_id = set.hasOwnProperty('source_ext') ? 'ffz-ext-' + set.source_ext + '-' + set.source_id : 'ffz-' + set.id,
favorites_list = this.settings.favorite_emotes[menu_id];
if ( favorites_only && (! favorites_list || ! favorites_list.length) )
continue;
if ( favorites_only && (! favorites_list || ! favorites_list.length) )
continue;
if ( ! set || ! set.count || ( ! this.settings.global_emotes_in_menu && this.default_sets.indexOf(set_id) !== -1 ) )
continue;
if ( ! set || ! set.count || ( ! this.settings.global_emotes_in_menu && this.default_sets.indexOf(set_id) !== -1 ) )
continue;
var menu = FFZ.menu_pages.myemotes.draw_ffz_set.call(this, view, set, favorites_only);
if ( menu )
sets.push([set.title.toLowerCase(), menu]);
}
var menu = FFZ.menu_pages.myemotes.draw_ffz_set.call(this, view, set, favorites_only);
if ( menu )
sets.push([set.title.toLowerCase(), menu]);
}
if ( ! sets.length )
return false;
if ( ! sets.length )
return false;
// Finally, sort and add them all.
sets.sort(function(a,b) {
var an = a[0], bn = b[0];
if ( an === "turbo" || an === "--turbo-faces--" )
an = "zza|" + an;
else if ( an === "global" || (an && an.substr(0,16) === "global emoticons") || an === "--global--" )
an = "zzy|" + an;
else if ( an.substr(0,5) === "emoji" )
an = "zzz|" + an;
// Finally, sort and add them all.
sets.sort(function(a,b) {
var an = a[0], bn = b[0];
if ( an === "turbo" || an === "--turbo-faces--" )
an = "zza|" + an;
else if ( an === "global" || (an && an.substr(0,16) === "global emoticons") || an === "--global--" )
an = "zzy|" + an;
else if ( an.substr(0,5) === "emoji" )
an = "zzz|" + an;
if ( bn === "turbo" || bn === "--turbo-faces--" )
bn = "zza|" + bn;
else if ( bn === "global" || (bn && bn.substr(0,16) === "global emoticons") || bn === "--global--" )
bn = "zzy|" + bn;
else if ( bn.substr(0,5) === "emoji" )
bn = "zzz|" + bn;
if ( bn === "turbo" || bn === "--turbo-faces--" )
bn = "zza|" + bn;
else if ( bn === "global" || (bn && bn.substr(0,16) === "global emoticons") || bn === "--global--" )
bn = "zzy|" + bn;
else if ( bn.substr(0,5) === "emoji" )
bn = "zzz|" + bn;
if ( an < bn ) return -1;
if ( an > bn ) return 1;
return 0;
});
if ( an < bn ) return -1;
if ( an > bn ) return 1;
return 0;
});
if ( favorites_only ) {
var grid = document.createElement('div');
grid.className = 'emoticon-grid favorites-grid';
for(var i=0; i < sets.length; i++)
grid.appendChild(sets[i][1]);
if ( favorites_only ) {
var grid = document.createElement('div');
grid.className = 'emoticon-grid favorites-grid';
for(var i=0; i < sets.length; i++)
grid.appendChild(sets[i][1]);
container.appendChild(grid);
container.appendChild(grid);
} else
for(var i=0; i < sets.length; i++)
container.appendChild(sets[i][1]);
} else
for(var i=0; i < sets.length; i++)
container.appendChild(sets[i][1]);
return true;
return true;
},
toggle_section: function(heading, container) {
@ -285,38 +285,38 @@ FFZ.menu_pages.myemotes = {
this.settings.set('emote_menu_collapsed', collapsed_list, true);
menu.classList.toggle('collapsed', !is_collapsed);
if ( is_collapsed )
menu.appendChild(container);
else
menu.removeChild(container);
if ( is_collapsed )
menu.appendChild(container);
else
menu.removeChild(container);
},
draw_emoji: function(view, cat, favorites_only) {
var heading = document.createElement('div'),
menu = document.createElement('div'),
menu_id = 'emoji' + (cat ? '-' + cat : ''),
emotes = favorites_only ? document.createDocumentFragment() : document.createElement('div'),
collapsed = ! favorites_only && this.settings.emote_menu_collapsed.indexOf(menu_id) === -1,
menu_id = 'emoji' + (cat ? '-' + cat : ''),
emotes = favorites_only ? document.createDocumentFragment() : document.createElement('div'),
collapsed = ! favorites_only && this.settings.emote_menu_collapsed.indexOf(menu_id) === -1,
f = this,
settings = this.settings.parse_emoji || 1,
favorites = this.settings.favorite_emotes["emoji"] || [],
c = 0;
favorites = this.settings.favorite_emotes["emoji"] || [],
c = 0;
menu.className = 'emoticon-grid';
menu.setAttribute('data-set', menu_id);
menu.className = 'emoticon-grid';
menu.setAttribute('data-set', menu_id);
if ( ! favorites_only ) {
heading.className = 'heading';
heading.innerHTML = '<span class="right">Unicode</span>' + (cat ? utils.sanitize(constants.EMOJI_CATEGORIES[cat]) : 'Emoji');
heading.style.backgroundImage = 'url("' + constants.SERVER + 'emoji/' + (settings === 3 ? 'one/' : (settings === 2 ? 'noto-' : 'tw/')) + (constants.EMOJI_LOGOS[cat] || '1f4af') + '.svg")';
heading.style.backgroundSize = "18px";
if ( ! favorites_only ) {
heading.className = 'heading';
heading.innerHTML = '<span class="right">Unicode</span>' + (cat ? utils.sanitize(constants.EMOJI_CATEGORIES[cat]) : 'Emoji');
heading.style.backgroundImage = 'url("' + constants.SERVER + 'emoji/' + (settings === 3 ? 'one/' : (settings === 2 ? 'noto-' : 'tw/')) + (constants.EMOJI_LOGOS[cat] || '1f4af') + '.svg")';
heading.style.backgroundSize = "18px";
menu.classList.add('collapsable');
menu.appendChild(heading);
menu.classList.toggle('collapsed', collapsed);
menu.classList.add('collapsable');
menu.appendChild(heading);
menu.classList.toggle('collapsed', collapsed);
heading.addEventListener('click', function() { FFZ.menu_pages.myemotes.toggle_section.bind(f)(this, emotes); });
}
}
var set = [];
@ -342,36 +342,36 @@ FFZ.menu_pages.myemotes = {
continue;
var is_favorite = favorites.indexOf(emoji.raw) !== -1,
src = settings === 3 ? emoji.one_src : (settings === 2 ? emoji.noto_src : emoji.tw_src),
src = settings === 3 ? emoji.one_src : (settings === 2 ? emoji.noto_src : emoji.tw_src),
image = this.settings.emote_image_hover ? '<img class="emoticon ffz-image-hover" src="' + src + '">' : '';
if ( favorites_only && ! is_favorite )
continue;
if ( favorites_only && ! is_favorite )
continue;
em.className = 'emoticon emoji ffz-tooltip ffz-can-favorite';
em.classList.toggle('ffz-favorite', is_favorite);
em.classList.toggle('ffz-is-favorite', favorites_only);
em.classList.toggle('ffz-favorite', is_favorite);
em.classList.toggle('ffz-is-favorite', favorites_only);
em.setAttribute('data-ffz-emoji', emoji.code);
em.alt = emoji.raw;
em.setAttribute('data-ffz-emoji', emoji.code);
em.alt = emoji.raw;
em.addEventListener('click', this._add_emote.bind(this, view, emoji.raw, "emoji", emoji.raw));
em.style.backgroundImage = 'url("' + src + '")';
em.style.backgroundSize = "18px";
c++;
c++;
emotes.appendChild(em);
}
if ( ! c )
return;
if ( ! c )
return;
if ( favorites_only )
return emotes;
if ( favorites_only )
return emotes;
if ( ! collapsed )
menu.appendChild(emotes);
if ( ! collapsed )
menu.appendChild(emotes);
return menu;
},
@ -379,51 +379,51 @@ FFZ.menu_pages.myemotes = {
draw_twitch_set: function(view, set_id, set, favorites_only) {
var heading = document.createElement('div'),
menu = document.createElement('div'),
emotes = favorites_only ? document.createDocumentFragment() : document.createElement('div'),
collapsed = ! favorites_only && this.settings.emote_menu_collapsed.indexOf('twitch-' + set_id) === -1,
emotes = favorites_only ? document.createDocumentFragment() : document.createElement('div'),
collapsed = ! favorites_only && this.settings.emote_menu_collapsed.indexOf('twitch-' + set_id) === -1,
f = this,
channel_id = this._twitch_set_to_channel[set_id], title,
favorites = this.settings.favorite_emotes["twitch-" + set_id] || [],
c = 0;
favorites = this.settings.favorite_emotes["twitch-" + set_id] || [],
c = 0;
menu.className = 'emoticon-grid';
menu.className = 'emoticon-grid';
menu.setAttribute('data-set', 'twitch-' + set_id);
if ( ! favorites_only ) {
if ( channel_id === "twitch_unknown" )
title = "Unknown Channel";
else if ( channel_id === "--global--" )
title = "Global Emoticons";
else if ( channel_id === "turbo" || channel_id === "--turbo-faces--" )
title = "Twitch Turbo";
else
title = FFZ.get_capitalization(channel_id, function(name) {
heading.innerHTML = '<span class="right">Twitch</span>' + utils.sanitize(name);
});
if ( ! favorites_only ) {
if ( channel_id === "twitch_unknown" )
title = "Unknown Channel";
else if ( channel_id === "--global--" )
title = "Global Emoticons";
else if ( channel_id === "turbo" || channel_id === "--turbo-faces--" )
title = "Twitch Turbo";
else
title = FFZ.get_capitalization(channel_id, function(name) {
heading.innerHTML = '<span class="right">Twitch</span>' + utils.sanitize(name);
});
heading.className = 'heading';
heading.innerHTML = '<span class="right">Twitch</span>' + utils.sanitize(title);
heading.className = 'heading';
heading.innerHTML = '<span class="right">Twitch</span>' + utils.sanitize(title);
if ( this._twitch_badges[channel_id] )
heading.style.backgroundImage = 'url("' + this._twitch_badges[channel_id] + '")';
else {
var f = this;
utils.api.get("chat/" + channel_id + "/badges", null, {version: 3})
.done(function(data) {
if ( data.subscriber && data.subscriber.image ) {
f._twitch_badges[channel_id] = data.subscriber.image;
localStorage.ffzTwitchBadges = JSON.stringify(f._twitch_badges);
heading.style.backgroundImage = 'url("' + data.subscriber.image + '")';
}
});
}
if ( this._twitch_badges[channel_id] )
heading.style.backgroundImage = 'url("' + this._twitch_badges[channel_id] + '")';
else {
var f = this;
utils.api.get("chat/" + channel_id + "/badges", null, {version: 3})
.done(function(data) {
if ( data.subscriber && data.subscriber.image ) {
f._twitch_badges[channel_id] = data.subscriber.image;
localStorage.ffzTwitchBadges = JSON.stringify(f._twitch_badges);
heading.style.backgroundImage = 'url("' + data.subscriber.image + '")';
}
});
}
menu.classList.add('collapsable');
menu.appendChild(heading);
menu.classList.toggle('collapsed', collapsed);
heading.addEventListener('click', function() { FFZ.menu_pages.myemotes.toggle_section.bind(f)(this, emotes); });
}
menu.classList.add('collapsable');
menu.appendChild(heading);
menu.classList.toggle('collapsed', collapsed);
heading.addEventListener('click', function() { FFZ.menu_pages.myemotes.toggle_section.bind(f)(this, emotes); });
}
set.sort(function(a,b) {
var an = a.code.toLowerCase(),
@ -439,21 +439,21 @@ FFZ.menu_pages.myemotes = {
for(var i=0; i < set.length; i++) {
var emote = set[i],
code = constants.KNOWN_CODES[emote.code] || emote.code,
is_favorite = favorites.indexOf(emote.id) !== -1;
is_favorite = favorites.indexOf(emote.id) !== -1;
if ( favorites_only && ! is_favorite )
continue;
if ( favorites_only && ! is_favorite )
continue;
var em = document.createElement('span'),
var em = document.createElement('span'),
img_set = 'image-set(url("' + constants.TWITCH_BASE + emote.id + '/1.0") 1x, url("' + constants.TWITCH_BASE + emote.id + '/2.0") 2x)';
em.className = 'emoticon ffz-tooltip ffz-can-favorite';
em.setAttribute('data-emote', emote.id);
em.alt = code;
em.setAttribute('data-emote', emote.id);
em.alt = code;
em.classList.toggle('ffz-favorite', is_favorite);
em.classList.toggle('ffz-is-favorite', favorites_only);
em.classList.toggle('ffz-tooltip-no-credit', ! favorites_only);
em.classList.toggle('ffz-favorite', is_favorite);
em.classList.toggle('ffz-is-favorite', favorites_only);
em.classList.toggle('ffz-tooltip-no-credit', ! favorites_only);
if ( this.settings.replace_bad_emotes && constants.EMOTE_REPLACEMENTS[emote.id] ) {
em.style.backgroundImage = 'url("' + constants.EMOTE_REPLACEMENT_BASE + constants.EMOTE_REPLACEMENTS[emote.id] + '")';
@ -473,18 +473,18 @@ FFZ.menu_pages.myemotes = {
this._add_emote(view, c, "twitch-" + set_id, id, e);
}.bind(this, emote.id, code));
c++;
c++;
emotes.appendChild(em);
}
if ( ! c )
return;
if ( ! c )
return;
if ( favorites_only )
return emotes;
if ( favorites_only )
return emotes;
if ( ! collapsed )
menu.appendChild(emotes);
if ( ! collapsed )
menu.appendChild(emotes);
return menu;
},
@ -492,33 +492,33 @@ FFZ.menu_pages.myemotes = {
draw_ffz_set: function(view, set, favorites_only) {
var heading = document.createElement('div'),
menu = document.createElement('div'),
emote_container = favorites_only ? document.createDocumentFragment() : document.createElement('div'),
emote_container = favorites_only ? document.createDocumentFragment() : document.createElement('div'),
f = this,
emotes = [],
menu_id = set.hasOwnProperty('source_ext') ? 'ffz-ext-' + set.source_ext + '-' + set.source_id : 'ffz-' + set.id,
favorites = this.settings.favorite_emotes[menu_id] || [],
c = 0,
favorites = this.settings.favorite_emotes[menu_id] || [],
c = 0,
icon = set.icon || (set.hasOwnProperty('source_ext') && '//cdn.frankerfacez.com/emoji/tw-1f4ac.svg') || '//cdn.frankerfacez.com/script/devicon.png',
collapsed = ! favorites_only && this.settings.emote_menu_collapsed.indexOf(menu_id) === -1;
collapsed = ! favorites_only && this.settings.emote_menu_collapsed.indexOf(menu_id) === -1;
menu.className = 'emoticon-grid';
menu.setAttribute('data-set', menu_id);
menu.setAttribute('data-set', menu_id);
if ( ! favorites_only ) {
menu.classList.add('collapsable');
if ( ! favorites_only ) {
menu.classList.add('collapsable');
heading.className = 'heading';
heading.innerHTML = '<span class="right">' + (utils.sanitize(set.source) || 'FrankerFaceZ') + '</span>' + set.title;
heading.className = 'heading';
heading.innerHTML = '<span class="right">' + (utils.sanitize(set.source) || 'FrankerFaceZ') + '</span>' + set.title;
heading.style.backgroundImage = 'url("' + icon + '")';
if ( icon.indexOf('.svg') !== -1 )
heading.style.backgroundSize = "18px";
heading.style.backgroundImage = 'url("' + icon + '")';
if ( icon.indexOf('.svg') !== -1 )
heading.style.backgroundSize = "18px";
menu.appendChild(heading);
menu.classList.toggle('collapsed', collapsed);
heading.addEventListener('click', function() { FFZ.menu_pages.myemotes.toggle_section.bind(f)(this, emote_container); });
}
menu.appendChild(heading);
menu.classList.toggle('collapsed', collapsed);
heading.addEventListener('click', function() { FFZ.menu_pages.myemotes.toggle_section.bind(f)(this, emote_container); });
}
for(var emote_id in set.emoticons)
set.emoticons.hasOwnProperty(emote_id) && ! set.emoticons[emote_id].hidden && emotes.push(set.emoticons[emote_id]);
@ -536,12 +536,12 @@ FFZ.menu_pages.myemotes = {
for(var i=0; i < emotes.length; i++) {
var emote = emotes[i],
is_favorite = favorites.indexOf(emote.id) !== -1;
is_favorite = favorites.indexOf(emote.id) !== -1;
if ( favorites_only && ! is_favorite )
continue;
if ( favorites_only && ! is_favorite )
continue;
var em = document.createElement('span'),
var em = document.createElement('span'),
img_set = 'image-set(url("' + emote.urls[1] + '") 1x';
if ( emote.urls[2] )
@ -553,11 +553,11 @@ FFZ.menu_pages.myemotes = {
img_set += ')';
em.className = 'emoticon ffz-tooltip ffz-can-favorite';
em.classList.toggle('ffz-favorite', is_favorite);
em.classList.toggle('ffz-is-favorite', favorites_only);
em.classList.toggle('ffz-favorite', is_favorite);
em.classList.toggle('ffz-is-favorite', favorites_only);
em.setAttribute('data-ffz-emote', emote.id);
em.setAttribute('data-ffz-set', set.id);
em.setAttribute('data-ffz-emote', emote.id);
em.setAttribute('data-ffz-set', set.id);
em.style.backgroundImage = 'url("' + emote.urls[1] + '")';
em.style.backgroundImage = '-webkit-' + img_set;
@ -587,18 +587,18 @@ FFZ.menu_pages.myemotes = {
this._add_emote(view, code, menu_id, id, e);
}.bind(this, emote.id, emote.name));
c++;
c++;
emote_container.appendChild(em);
}
if ( ! c )
return;
if ( ! c )
return;
if ( favorites_only )
return emote_container;
if ( favorites_only )
return emote_container;
if ( ! collapsed )
menu.appendChild(emote_container);
if ( ! collapsed )
menu.appendChild(emote_container);
return menu;
}

View file

@ -1,5 +1,5 @@
var FFZ = window.FrankerFaceZ,
utils = require("../utils"),
utils = require("../utils"),
constants = require("../constants");
@ -76,21 +76,21 @@ FFZ.settings_info.notification_timeout = {
help: "Specify how long notifications should be displayed before automatically closing.",
method: function() {
var f = this;
utils.prompt(
"Notification Timeout",
"Please enter the time you'd like notifications to be displayed before automatically closing, in seconds.</p><p><b>Default:</b> 60",
this.settings.notification_timeout,
function(new_val) {
if ( new_val === null || new_val === undefined )
return;
var f = this;
utils.prompt(
"Notification Timeout",
"Please enter the time you'd like notifications to be displayed before automatically closing, in seconds.</p><p><b>Default:</b> 60",
this.settings.notification_timeout,
function(new_val) {
if ( new_val === null || new_val === undefined )
return;
new_val = parseInt(new_val);
if ( Number.isNaN(new_val) || ! Number.isFinite(new_val) || new_val < 1 )
new_val = 60;
new_val = parseInt(new_val);
if ( Number.isNaN(new_val) || ! Number.isFinite(new_val) || new_val < 1 )
new_val = 60;
f.settings.set("notification_timeout", new_val);
});
f.settings.set("notification_timeout", new_val);
});
}
};

View file

@ -1,5 +1,5 @@
var FFZ = window.FrankerFaceZ,
constants = require('../constants');
constants = require('../constants');
// ---------------
@ -14,10 +14,10 @@ FFZ.prototype.setup_popups = function() {
if ( e.button && e.button !== 0 )
return;
// Check for modal clicks
var modal = document.getElementById('ffz-modal-container');
if ( modal && (modal === e.target || modal.contains(e.target)) )
return;
// Check for modal clicks
var modal = document.getElementById('ffz-modal-container');
if ( modal && (modal === e.target || modal.contains(e.target)) )
return;
var popup = f._popup,
parent = f._popup_parent;

View file

@ -31,70 +31,70 @@ FFZ.prototype._update_subscribers = function() {
// context of the web user.
// Get the count!
jQuery.getJSON("/" + id + "/dashboard/revenue/summary_data").done(function(data) {
var el, sub_count = data && data.data && data.data.total_subscriptions;
if ( typeof sub_count === "string" )
sub_count = parseInt(sub_count.replace(/[,\.]/g, ""));
jQuery.getJSON("/" + id + "/dashboard/revenue/summary_data").done(function(data) {
var el, sub_count = data && data.data && data.data.total_subscriptions;
if ( typeof sub_count === "string" )
sub_count = parseInt(sub_count.replace(/[,\.]/g, ""));
if ( typeof sub_count !== "number" || sub_count === 0 || sub_count === NaN || sub_count === Infinity ) {
el = document.querySelector("#ffz-sub-display");
if ( el )
el.parentElement.removeChild(el);
if ( typeof sub_count !== "number" || sub_count === 0 || sub_count === NaN || sub_count === Infinity ) {
el = document.querySelector("#ffz-sub-display");
if ( el )
el.parentElement.removeChild(el);
var failed = f._failed_sub_checks = (f._failed_sub_checks || 0) + 1;
if ( f._update_subscribers_timer && failed >= 5 ) {
f.log("Subscriber count failed 5 times. Giving up.");
clearTimeout(f._update_subscribers_timer);
delete f._update_subscribers_timer;
}
var failed = f._failed_sub_checks = (f._failed_sub_checks || 0) + 1;
if ( f._update_subscribers_timer && failed >= 5 ) {
f.log("Subscriber count failed 5 times. Giving up.");
clearTimeout(f._update_subscribers_timer);
delete f._update_subscribers_timer;
}
return;
}
return;
}
// Graph this glorious data point
if ( f._dash_chart ) {
if ( ! f._dash_chart.series[3].options.showInLegend ) {
f._dash_chart.series[3].options.showInLegend = true;
f._dash_chart.legend.renderLegend();
}
// Graph this glorious data point
if ( f._dash_chart ) {
if ( ! f._dash_chart.series[3].options.showInLegend ) {
f._dash_chart.series[3].options.showInLegend = true;
f._dash_chart.legend.renderLegend();
}
f._dash_chart.series[3].addPoint({x: utils.last_minute(), y: sub_count});
}
f._dash_chart.series[3].addPoint({x: utils.last_minute(), y: sub_count});
}
el = document.querySelector('#ffz-sub-display span');
if ( ! el ) {
var cont = f.is_dashboard ? document.querySelector("#stats") : document.querySelector("#channel .stats-and-actions .channel-stats");
if ( ! cont )
return;
el = document.querySelector('#ffz-sub-display span');
if ( ! el ) {
var cont = f.is_dashboard ? document.querySelector("#stats") : document.querySelector("#channel .stats-and-actions .channel-stats");
if ( ! cont )
return;
var stat = document.createElement('span');
stat.className = 'ffz stat';
stat.id = 'ffz-sub-display';
stat.title = 'Subscribers';
var stat = document.createElement('span');
stat.className = 'ffz stat';
stat.id = 'ffz-sub-display';
stat.title = 'Subscribers';
stat.innerHTML = constants.STAR + ' ';
stat.innerHTML = constants.STAR + ' ';
el = document.createElement('span');
stat.appendChild(el);
el = document.createElement('span');
stat.appendChild(el);
utils.api.get("chat/" + id + "/badges", null, {version: 3})
.done(function(data) {
if ( data.subscriber && data.subscriber.image ) {
stat.innerHTML = '';
stat.appendChild(el);
utils.api.get("chat/" + id + "/badges", null, {version: 3})
.done(function(data) {
if ( data.subscriber && data.subscriber.image ) {
stat.innerHTML = '';
stat.appendChild(el);
stat.style.backgroundImage = 'url("' + data.subscriber.image + '")';
stat.style.backgroundRepeat = 'no-repeat';
stat.style.paddingLeft = '23px';
stat.style.backgroundPosition = '0 50%';
}
});
stat.style.backgroundImage = 'url("' + data.subscriber.image + '")';
stat.style.backgroundRepeat = 'no-repeat';
stat.style.paddingLeft = '23px';
stat.style.backgroundPosition = '0 50%';
}
});
cont.appendChild(stat);
jQuery(stat).tipsy({gravity: f.is_dashboard ? "s" : utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
}
cont.appendChild(stat);
jQuery(stat).tipsy({gravity: f.is_dashboard ? "s" : utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
}
el.innerHTML = utils.number_commas(sub_count);
el.innerHTML = utils.number_commas(sub_count);
}).fail(function(){
var el = document.querySelector("#ffz-sub-display");

View file

@ -154,44 +154,44 @@ var createElement = function(tag, className, content) {
},
// This code borrowed from the twemoji project, with tweaks.
UFE0Fg = /\uFE0F/g,
U200D = String.fromCharCode(0x200D),
// This code borrowed from the twemoji project, with tweaks.
UFE0Fg = /\uFE0F/g,
U200D = String.fromCharCode(0x200D),
EMOJI_CODEPOINTS = {},
emoji_to_codepoint = function(surrogates, sep) {
if ( EMOJI_CODEPOINTS[surrogates] && EMOJI_CODEPOINTS[surrogates][sep] )
return EMOJI_CODEPOINTS[surrogates][sep];
return EMOJI_CODEPOINTS[surrogates][sep];
var input = surrogates.indexOf(U200D) === -1 ? surrogates.replace(UFE0Fg, '') : surrogates,
out = [],
c = 0, p = 0, i = 0;
var input = surrogates.indexOf(U200D) === -1 ? surrogates.replace(UFE0Fg, '') : surrogates,
out = [],
c = 0, p = 0, i = 0;
while (i < input.length) {
c = input.charCodeAt(i++);
if ( p ) {
out.push((0x10000 + ((p - 0xD800) << 10) + (c - 0xDC00)).toString(16));
p = 0;
} else if ( 0xD800 <= c && c <= 0xDBFF )
p = c;
else
out.push(c.toString(16));
}
while (i < input.length) {
c = input.charCodeAt(i++);
if ( p ) {
out.push((0x10000 + ((p - 0xD800) << 10) + (c - 0xDC00)).toString(16));
p = 0;
} else if ( 0xD800 <= c && c <= 0xDBFF )
p = c;
else
out.push(c.toString(16));
}
var retval = EMOJI_CODEPOINTS[surrogates] = out.join('-');
var retval = EMOJI_CODEPOINTS[surrogates] = out.join('-');
return retval;
},
codepoint_to_emoji = function(codepoint) {
var code = typeof codepoint === 'string' ? parseInt(codepoint, 16) : codepoint;
if ( code < 0x10000 )
return String.fromCharCode(code);
code -= 0x10000;
return String.fromCharCode(
0xD800 + (code >> 10),
0xDC00 + (code & 0x3FF)
)
},
codepoint_to_emoji = function(codepoint) {
var code = typeof codepoint === 'string' ? parseInt(codepoint, 16) : codepoint;
if ( code < 0x10000 )
return String.fromCharCode(code);
code -= 0x10000;
return String.fromCharCode(
0xD800 + (code >> 10),
0xDC00 + (code & 0x3FF)
)
},
// Twitch Emote Helpers
@ -205,118 +205,118 @@ var createElement = function(tag, className, content) {
},
// Twitch API
// Twitch API
api_call = function(method, url, data, options, token) {
options = options || {};
var headers = options.headers = options.headers || {};
headers['Client-ID'] = constants.CLIENT_ID;
if ( token )
headers.Authorization = 'OAuth ' + token;
return Twitch.api[method].call(this, url, data, options);
},
api_call = function(method, url, data, options, token) {
options = options || {};
var headers = options.headers = options.headers || {};
headers['Client-ID'] = constants.CLIENT_ID;
if ( token )
headers.Authorization = 'OAuth ' + token;
return Twitch.api[method].call(this, url, data, options);
},
// Dialogs
show_modal = function(contents, on_close, width) {
var container = createElement('div', 'twitch_subwindow_container'),
subwindow = createElement('div', 'twitch_subwindow ffz-subwindow'),
card = createElement('div', 'card'),
close_button = createElement('div', 'modal-close-button', constants.CLOSE),
// Dialogs
show_modal = function(contents, on_close, width) {
var container = createElement('div', 'twitch_subwindow_container'),
subwindow = createElement('div', 'twitch_subwindow ffz-subwindow'),
card = createElement('div', 'card'),
close_button = createElement('div', 'modal-close-button', constants.CLOSE),
closer = function() { container.parentElement.removeChild(container) };
closer = function() { container.parentElement.removeChild(container) };
container.id = 'ffz-modal-container';
container.id = 'ffz-modal-container';
subwindow.style.width = '100%';
subwindow.style.maxWidth = (width||420) + 'px';
subwindow.style.width = '100%';
subwindow.style.maxWidth = (width||420) + 'px';
close_button.addEventListener('click', function() {
closer();
if ( on_close )
on_close(false);
});
close_button.addEventListener('click', function() {
closer();
if ( on_close )
on_close(false);
});
container.appendChild(subwindow);
subwindow.appendChild(card);
subwindow.appendChild(close_button);
container.appendChild(subwindow);
subwindow.appendChild(card);
subwindow.appendChild(close_button);
card.appendChild(contents);
card.appendChild(contents);
var el = document.querySelector('app-main');
var el = document.querySelector('app-main');
if ( el )
el.parentElement.insertBefore(container, el.nextSibling);
else
document.body.appendChild(container);
if ( el )
el.parentElement.insertBefore(container, el.nextSibling);
else
document.body.appendChild(container);
return closer;
},
return closer;
},
ember_lookup = function(thing) {
if ( ! window.App )
return;
ember_lookup = function(thing) {
if ( ! window.App )
return;
try {
if ( App.__deprecatedInstance__ && App.__deprecatedInstance__.registry && App.__deprecatedInstance__.registry.lookup )
return App.__deprecatedInstance__.registry.lookup(thing);
if ( App.__container__ && App.__container__.lookup )
return App.__container__.lookup(thing);
if ( App.__deprecatedInstance__ && App.__deprecatedInstance__.registry && App.__deprecatedInstance__.registry.lookup )
return App.__deprecatedInstance__.registry.lookup(thing);
if ( App.__container__ && App.__container__.lookup )
return App.__container__.lookup(thing);
} catch(err) {
FrankerFaceZ.get().error("There was an error looking up an Ember instance: " + thing, err);
return null;
}
};
};
module.exports = FFZ.utils = {
// Ember Manipulation
ember_views: function() {
return ember_lookup('-view-registry:main') || {};
},
ember_views: function() {
return ember_lookup('-view-registry:main') || {};
},
ember_lookup: ember_lookup,
ember_lookup: ember_lookup,
ember_resolve: function(thing) {
if ( ! window.App )
return;
ember_resolve: function(thing) {
if ( ! window.App )
return;
if ( App.__deprecatedInstance__ && App.__deprecatedInstance__.registry && App.__deprecatedInstance__.registry.resolve )
return App.__deprecatedInstance__.registry.resolve(thing);
if ( App.__container__ && App.__container__.resolve )
return App.__container__.resolve(thing);
},
if ( App.__deprecatedInstance__ && App.__deprecatedInstance__.registry && App.__deprecatedInstance__.registry.resolve )
return App.__deprecatedInstance__.registry.resolve(thing);
if ( App.__container__ && App.__container__.resolve )
return App.__container__.resolve(thing);
},
ember_reopen_view: function(component, data) {
if ( typeof component === 'string' )
component = ember_resolve(component);
if ( typeof component === 'string' )
component = ember_resolve(component);
data.ffz_modified = true;
if ( data.ffz_init && ! data.didInsertElement )
data.didInsertElement = function() {
this._super();
try {
this.ffz_init();
} catch(err) {
FFZ.get().error("An error occured running ffz_init on " + this.toString(), err);
}
};
if ( data.ffz_init && ! data.didInsertElement )
data.didInsertElement = function() {
this._super();
try {
this.ffz_init();
} catch(err) {
FFZ.get().error("An error occured running ffz_init on " + this.toString(), err);
}
};
if ( data.ffz_destroy && ! data.willClearRender )
data.willClearRender = function() {
try {
this.ffz_destroy();
} catch(err) {
FFZ.get().error("An error occured running ffz_destroy on " + this.toString(), err);
}
if ( data.ffz_destroy && ! data.willClearRender )
data.willClearRender = function() {
try {
this.ffz_destroy();
} catch(err) {
FFZ.get().error("An error occured running ffz_destroy on " + this.toString(), err);
}
this._super();
};
this._super();
};
return component.reopen(data);
},
return component.reopen(data);
},
// Other Stuff
@ -324,15 +324,15 @@ module.exports = FFZ.utils = {
/*build_tooltip: build_tooltip,
load_emote_data: load_emote_data,*/
api: {
del: function(u,d,o,t) { return api_call('del', u,d,o,t); },
get: function(u,d,o,t) { return api_call('get', u,d,o,t); },
post: function(u,d,o,t) { return api_call('post', u,d,o,t); },
put: function(u,d,o,t) { return api_call('put', u,d,o,t); }
},
api: {
del: function(u,d,o,t) { return api_call('del', u,d,o,t); },
get: function(u,d,o,t) { return api_call('get', u,d,o,t); },
post: function(u,d,o,t) { return api_call('post', u,d,o,t); },
put: function(u,d,o,t) { return api_call('put', u,d,o,t); }
},
show_modal: show_modal,
show_modal: show_modal,
confirm: function(title, description, callback) {
var contents = createElement('div', 'text-content'),
heading = title ? createElement('div', 'content-header', '<h4>' + title + '</h4>') : null,
@ -340,7 +340,7 @@ module.exports = FFZ.utils = {
buttons = createElement('div', 'buttons', '<a class="js-subwindow-close button"><span>Cancel</span></a><button class="button primary" type="submit"><span>OK</span></button>'),
close_btn = buttons.querySelector('.js-subwindow-close'),
okay_btn = buttons.querySelector('.button.primary');
okay_btn = buttons.querySelector('.button.primary');
if ( heading )
contents.appendChild(heading);
@ -368,21 +368,21 @@ module.exports = FFZ.utils = {
closer = show_modal(contents, cb);
okay_btn.addEventListener('click', function(e) { e.preventDefault(); cb(true); return false });
close_btn.addEventListener('click', function(e) { e.preventDefault(); cb(false); return false });
close_btn.addEventListener('click', function(e) { e.preventDefault(); cb(false); return false });
},
prompt: function(title, description, old_value, callback, width, input) {
var contents = createElement('div', 'text-content'),
heading = createElement('div', 'content-header', '<h4>' + title + '</h4>'),
form = createElement('form'),
close_btn, okay_btn;
prompt: function(title, description, old_value, callback, width, input) {
var contents = createElement('div', 'text-content'),
heading = createElement('div', 'content-header', '<h4>' + title + '</h4>'),
form = createElement('form'),
close_btn, okay_btn;
if ( ! input ) {
input = createElement('input');
input.type = 'text';
}
form.innerHTML = '<div class="item">' + (description ? '<p>' + description + '</p>' : '') + '<div class="input-placeholder"></div><div class="buttons"><a class="js-subwindow-close button"><span>Cancel</span></a><button class="button primary" type="submit"><span>OK</span></button></div>';
form.innerHTML = '<div class="item">' + (description ? '<p>' + description + '</p>' : '') + '<div class="input-placeholder"></div><div class="buttons"><a class="js-subwindow-close button"><span>Cancel</span></a><button class="button primary" type="submit"><span>OK</span></button></div>';
var ph = form.querySelector('.input-placeholder'),
par = ph.parentElement;
@ -390,54 +390,54 @@ module.exports = FFZ.utils = {
par.insertBefore(input, ph);
par.removeChild(ph);
contents.appendChild(heading);
contents.appendChild(form);
contents.appendChild(heading);
contents.appendChild(form);
close_btn = form.querySelector('.js-subwindow-close');
okay_btn = form.querySelector('.button.primary');
close_btn = form.querySelector('.js-subwindow-close');
okay_btn = form.querySelector('.button.primary');
if ( old_value !== undefined )
input.value = old_value;
if ( old_value !== undefined )
input.value = old_value;
var closer,
cb = function(success) {
closer();
if ( ! callback )
return;
var closer,
cb = function(success) {
closer();
if ( ! callback )
return;
callback(success ? input.value : null);
};
callback(success ? input.value : null);
};
closer = show_modal(contents, cb, width);
closer = show_modal(contents, cb, width);
try {
input.focus();
} catch(err) { }
form.addEventListener('submit', function(e) { e.preventDefault(); cb(true); return false });
okay_btn.addEventListener('click', function(e) { e.preventDefault(); cb(true); return false });
close_btn.addEventListener('click', function(e) { e.preventDefault(); cb(false); return false });
},
form.addEventListener('submit', function(e) { e.preventDefault(); cb(true); return false });
okay_btn.addEventListener('click', function(e) { e.preventDefault(); cb(true); return false });
close_btn.addEventListener('click', function(e) { e.preventDefault(); cb(false); return false });
},
last_minute: function() {
var now = new Date();
if ( now.getSeconds() >= 30 )
now.setMinutes(now.getMinutes()+1);
last_minute: function() {
var now = new Date();
if ( now.getSeconds() >= 30 )
now.setMinutes(now.getMinutes()+1);
now.setSeconds(0);
now.setMilliseconds(0);
return now.getTime();
},
now.setSeconds(0);
now.setMilliseconds(0);
return now.getTime();
},
maybe_chart: function(series, point, render, force) {
var len = series.data.length;
if ( force || point.y !== null || (len > 0 && series.data[len-1].y !== null) ) {
series.addPoint(point, render);
return true;
}
return false;
},
maybe_chart: function(series, point, render, force) {
var len = series.data.length;
if ( force || point.y !== null || (len > 0 && series.data[len-1].y !== null) ) {
series.addPoint(point, render);
return true;
}
return false;
},
update_css: function(element, id, css) {
var all = element.innerHTML,
@ -462,16 +462,16 @@ module.exports = FFZ.utils = {
tooltip_placement: function(margin, prefer) {
return function() {
var pref = prefer;
if ( typeof pref === "function" )
pref = pref.call(this);
var pref = prefer;
if ( typeof pref === "function" )
pref = pref.call(this);
var dir = {ns: pref[0], ew: (pref.length > 1 ? pref[1] : false)},
$this = $(this),
$this = $(this),
half_width = $this.width() / 2,
half_height = $this.height() / 2,
boundTop = $(document).scrollTop() + half_height + (margin*2),
boundLeft = $(document).scrollLeft() + half_width + margin;
boundLeft = $(document).scrollLeft() + half_width + margin;
if ($this.offset().top < boundTop) dir.ns = 'n';
if ($this.offset().left < boundLeft) dir.ew = 'w';
@ -486,7 +486,7 @@ module.exports = FFZ.utils = {
uncompressEmotes: uncompressEmotes,
emoji_to_codepoint: emoji_to_codepoint,
codepoint_to_emoji: codepoint_to_emoji,
codepoint_to_emoji: codepoint_to_emoji,
parse_date: parse_date,