mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-07-24 19:48:30 +00:00
3.5.252. Emoji changes. Fix the Following tooltip and count. Tweaks to the custom getPlayerInfo method to improve its output's accuracy.
This commit is contained in:
parent
ba084cfaa9
commit
86546ba7d8
8 changed files with 120 additions and 29 deletions
|
@ -1,3 +1,17 @@
|
||||||
|
<div class="list-header">3.5.252</div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Changed: Parse emoji out of text that is pasted into the chat box.</li>
|
||||||
|
<li>Changed: Hide channels broadcasting blocked games from the Following tooltip.</li>
|
||||||
|
<li>Changed: Start blocking BetterTTV's emoji parsing if the user has emoji disabled in FFZ's settings.</li>
|
||||||
|
<li>Fixed: Favorite Settings could appear to never load if a user's favorited settings were all disabled with BetterTTV and it is present.</li>
|
||||||
|
<li>Fixed: References to outdated Stream models causing issues with the Following count and tooltip.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="list-header">3.5.251</div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Changed: Apply the FFZ server time offset to the stream latency display on known bad player versions for more accurate time display.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div class="list-header">3.5.250</div>
|
<div class="list-header">3.5.250</div>
|
||||||
<ul class="chat-menu-content menu-side-padding">
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
<li>Changed: Stream Latency now works with the HTML5 player! For now, until Twitch implements <code>getVideoInfo</code>, FFZ will parse stats from the overlay that shows on-stream.</li>
|
<li>Changed: Stream Latency now works with the HTML5 player! For now, until Twitch implements <code>getVideoInfo</code>, FFZ will parse stats from the overlay that shows on-stream.</li>
|
||||||
|
@ -49,6 +63,9 @@
|
||||||
<li>Fixed: Not subscribing to current host target's chat with the socket server.</li>
|
<li>Fixed: Not subscribing to current host target's chat with the socket server.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<div class="list-header" id="ffz-old-news-button"><a href="#">View Older</a></div>
|
||||||
|
<div id="ffz-old-news">
|
||||||
|
|
||||||
<div class="list-header">3.5.241</div>
|
<div class="list-header">3.5.241</div>
|
||||||
<ul class="chat-menu-content menu-side-padding">
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
<li>Changed: Add <code>overflow: hidden</code> to chat lines to hide Zalgo text.</li>
|
<li>Changed: Add <code>overflow: hidden</code> to chat lines to hide Zalgo text.</li>
|
||||||
|
@ -396,9 +413,6 @@
|
||||||
<li>Added: Shortcut key to select the new ban reason dropdown on mod cards. It's not perfect though, since you have to ESC out of the list after picking one before you can press a key to ban.</li>
|
<li>Added: Shortcut key to select the new ban reason dropdown on mod cards. It's not perfect though, since you have to ESC out of the list after picking one before you can press a key to ban.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="list-header" id="ffz-old-news-button"><a href="#">View Older</a></div>
|
|
||||||
<div id="ffz-old-news">
|
|
||||||
|
|
||||||
<div class="list-header">3.5.183</div>
|
<div class="list-header">3.5.183</div>
|
||||||
<ul class="chat-menu-content menu-side-padding">
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
<li>Added: You can now specify a ban reason easilly when banning someone from a moderation card! The list is customizable in Chat Moderation settings.</li>
|
<li>Added: You can now specify a ban reason easilly when banning someone from a moderation card! The list is customizable in Chat Moderation settings.</li>
|
||||||
|
|
|
@ -246,6 +246,7 @@ FFZ.prototype.modify_chat_input = function(component) {
|
||||||
t.off("keyup");
|
t.off("keyup");
|
||||||
t.on("keypress", this._ffzKeyPress.bind(this));
|
t.on("keypress", this._ffzKeyPress.bind(this));
|
||||||
t.on("keydown", this._ffzKeyDown.bind(this));
|
t.on("keydown", this._ffzKeyDown.bind(this));
|
||||||
|
t.on("paste", this._ffzPaste.bind(this));
|
||||||
|
|
||||||
t.attr('rows', 1);
|
t.attr('rows', 1);
|
||||||
|
|
||||||
|
@ -272,11 +273,65 @@ FFZ.prototype.modify_chat_input = function(component) {
|
||||||
t.off("keyup");
|
t.off("keyup");
|
||||||
t.off("keydown");
|
t.off("keydown");
|
||||||
t.off("keypress");
|
t.off("keypress");
|
||||||
|
t.off("paste");
|
||||||
|
|
||||||
t.on("keyup", this._onKeyUp.bind(this));
|
t.on("keyup", this._onKeyUp.bind(this));
|
||||||
t.on("keydown", this._onKeyDown.bind(this));
|
t.on("keydown", this._onKeyDown.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Pasting~!
|
||||||
|
_ffzPaste: function(event) {
|
||||||
|
var data = (event.clipboardData || (event.originalEvent && event.originalEvent.clipboardData) || window.clipboardData),
|
||||||
|
text = data && data.getData('text/plain');
|
||||||
|
|
||||||
|
// If we don't have a colon, there can't be any emoji.
|
||||||
|
// Likewise, if the user doesn't want input emoji, don't convert them.
|
||||||
|
if ( ! f.settings.input_emoji || text.indexOf(':') === -1 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Alright, check for emoji now.
|
||||||
|
var output = [],
|
||||||
|
input = text.split(':'),
|
||||||
|
last_was_emoji = false;
|
||||||
|
|
||||||
|
output.push(input.shift());
|
||||||
|
for(var i=0, l = input.length - 1; i < l; i++) {
|
||||||
|
var segment = input[i],
|
||||||
|
emoji = ! last_was_emoji ? f.emoji_data[f.emoji_names[segment]] : null;
|
||||||
|
|
||||||
|
if ( emoji ) {
|
||||||
|
output.push(emoji.raw);
|
||||||
|
last_was_emoji = true;
|
||||||
|
} else {
|
||||||
|
output.push((last_was_emoji ? '' : ':') + segment);
|
||||||
|
last_was_emoji = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output = output.join("") + (last_was_emoji ? '' : ':') + input[input.length-1];
|
||||||
|
|
||||||
|
// Let the browser's paste be do as it do if there weren't any emoji.
|
||||||
|
if ( output.length === text.length )
|
||||||
|
return f.log("No emoji in paste");
|
||||||
|
|
||||||
|
// Can we get the selection in our input box?
|
||||||
|
var input = this.get('chatTextArea'),
|
||||||
|
s_val = input && input.value,
|
||||||
|
s_start = input && input.selectionStart,
|
||||||
|
s_end = input && input.selectionEnd;
|
||||||
|
|
||||||
|
if ( ! input || typeof s_start !== "number" || typeof s_end !== "number" )
|
||||||
|
return f.log("Can't get input");
|
||||||
|
|
||||||
|
// Still here? We're clear to inject this ourselves then.
|
||||||
|
event.stopPropagation();
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
input.value = s_val.substr(0, s_start) + output + s_val.substr(s_end);
|
||||||
|
move_selection(input, s_start + output.length);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
// Suggestions
|
// Suggestions
|
||||||
|
|
||||||
ffzBuildSuggestionItem: function(i, item) {
|
ffzBuildSuggestionItem: function(i, item) {
|
||||||
|
|
|
@ -163,7 +163,7 @@ FFZ.prototype.modify_twitch_player = function(player) {
|
||||||
var stats_el = stats[0],
|
var stats_el = stats[0],
|
||||||
toggle_btn = this.$('.js-stats-toggle'),
|
toggle_btn = this.$('.js-stats-toggle'),
|
||||||
|
|
||||||
setup_player = function() {
|
setup_player = function(tries) {
|
||||||
// If this player is destroyed, stop trying.
|
// If this player is destroyed, stop trying.
|
||||||
if ( ! document.contains(stats_el) )
|
if ( ! document.contains(stats_el) )
|
||||||
return;
|
return;
|
||||||
|
@ -178,7 +178,11 @@ FFZ.prototype.modify_twitch_player = function(player) {
|
||||||
if ( ! res || ! res.length ) {
|
if ( ! res || ! res.length ) {
|
||||||
// Not available yet. Keep going.
|
// Not available yet. Keep going.
|
||||||
toggle_btn.click();
|
toggle_btn.click();
|
||||||
setTimeout(setup_player, 100);
|
tries = (tries || 0) + 1;
|
||||||
|
if ( tries < 50 )
|
||||||
|
setTimeout(setup_player.bind(this, tries), 100);
|
||||||
|
else
|
||||||
|
stats_el.classList.remove('hidden');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +218,7 @@ FFZ.prototype.modify_twitch_player = function(player) {
|
||||||
match = el && / *([\d,]+) *x *([\d,]+)/i.exec(el.textContent);
|
match = el && / *([\d,]+) *x *([\d,]+)/i.exec(el.textContent);
|
||||||
if ( match ) {
|
if ( match ) {
|
||||||
output.stageWidth = output.vid_display_width = parseInt(match[1]);
|
output.stageWidth = output.vid_display_width = parseInt(match[1]);
|
||||||
output.stageHeight = output.vid_height = parseInt(match[2]);
|
output.stageHeight = output.vid_display_height = parseInt(match[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FPS
|
// FPS
|
||||||
|
@ -245,12 +249,21 @@ FFZ.prototype.modify_twitch_player = function(player) {
|
||||||
var val = parseFloat(el.textContent),
|
var val = parseFloat(el.textContent),
|
||||||
val2 = parseFloat(el2.textContent);
|
val2 = parseFloat(el2.textContent);
|
||||||
|
|
||||||
if ( ! isNaN(val) && isFinite(val) && ! isNaN(val2) && isFinite(val2) ) {
|
if ( val === -1 || val2 === -1 ) {
|
||||||
if ( val < 1000 && val2 < 1000) {
|
// ... nothing :D
|
||||||
|
} else if ( ! isNaN(val) && isFinite(val) && ! isNaN(val2) && isFinite(val2) ) {
|
||||||
|
if ( Math.abs(val) < 1000 && Math.abs(val2) < 1000) {
|
||||||
val *= 1000;
|
val *= 1000;
|
||||||
val2 *= 1000;
|
val2 *= 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only make this change for known bad versions.
|
||||||
|
var version = player.getVersion();
|
||||||
|
if ( version === "0.5.4" ) {
|
||||||
|
val -= (f._ws_server_offset || 0);
|
||||||
|
val2 -= (f._ws_server_offset || 0);
|
||||||
|
}
|
||||||
|
|
||||||
if ( val > val2 ) {
|
if ( val > val2 ) {
|
||||||
output.hls_latency_broadcaster = val;
|
output.hls_latency_broadcaster = val;
|
||||||
output.hls_latency_encoder = val2;
|
output.hls_latency_encoder = val2;
|
||||||
|
|
|
@ -91,10 +91,6 @@ FFZ.prototype.setup_bttv = function(delay) {
|
||||||
this.toggle_style('chat-separator-3d-inset');
|
this.toggle_style('chat-separator-3d-inset');
|
||||||
this.toggle_style('chat-separator-wide');
|
this.toggle_style('chat-separator-wide');
|
||||||
|
|
||||||
/*this.toggle_style('chat-hc-text');
|
|
||||||
this.toggle_style('chat-hc-bold');
|
|
||||||
this.toggle_style('chat-hc-background');*/
|
|
||||||
|
|
||||||
this.toggle_style('chat-colors-gray');
|
this.toggle_style('chat-colors-gray');
|
||||||
this.toggle_style('badges-rounded');
|
this.toggle_style('badges-rounded');
|
||||||
this.toggle_style('badges-circular');
|
this.toggle_style('badges-circular');
|
||||||
|
@ -244,9 +240,6 @@ FFZ.prototype.setup_bttv = function(delay) {
|
||||||
segments = token.split(constants.EMOJI_REGEX),
|
segments = token.split(constants.EMOJI_REGEX),
|
||||||
text = null;
|
text = null;
|
||||||
|
|
||||||
if ( setting === 0 )
|
|
||||||
return [token];
|
|
||||||
|
|
||||||
while(segments.length) {
|
while(segments.length) {
|
||||||
text = (text || '') + segments.shift();
|
text = (text || '') + segments.shift();
|
||||||
if ( segments.length ) {
|
if ( segments.length ) {
|
||||||
|
@ -258,8 +251,16 @@ FFZ.prototype.setup_bttv = function(delay) {
|
||||||
if ( src ) {
|
if ( src ) {
|
||||||
if ( text && text.length )
|
if ( text && text.length )
|
||||||
output.push(text);
|
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 + '">']);
|
// We still want to use a special token even if emoji display is disabled
|
||||||
|
// as, otherwise, BTTV will render the emoji itself, which the user has no
|
||||||
|
// way of disabling if not for this.
|
||||||
|
if ( setting === 0 )
|
||||||
|
output.push([data.raw]);
|
||||||
|
else {
|
||||||
|
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;
|
text = null;
|
||||||
} else
|
} else
|
||||||
text = (text || '') + match;
|
text = (text || '') + match;
|
||||||
|
|
|
@ -37,7 +37,7 @@ FFZ.msg_commands = {};
|
||||||
|
|
||||||
// Version
|
// Version
|
||||||
var VER = FFZ.version_info = {
|
var VER = FFZ.version_info = {
|
||||||
major: 3, minor: 5, revision: 250,
|
major: 3, minor: 5, revision: 252,
|
||||||
toString: function() {
|
toString: function() {
|
||||||
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -553,8 +553,17 @@ FFZ.menu_pages.settings = {
|
||||||
sort_order: 1,
|
sort_order: 1,
|
||||||
|
|
||||||
render: function(view, container) {
|
render: function(view, container) {
|
||||||
var favorites = this.settings.favorite_settings;
|
var favorites = this.settings.favorite_settings,
|
||||||
if ( ! favorites.length ) {
|
count = 0;
|
||||||
|
|
||||||
|
if ( ! this.has_bttv )
|
||||||
|
count = favorites.length;
|
||||||
|
else
|
||||||
|
for(var i=0; i < favorites.length; i++)
|
||||||
|
if ( ! FFZ.settings_info[favorites[i]].no_bttv )
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if ( ! count ) {
|
||||||
var el = utils.createElement('div');
|
var el = utils.createElement('div');
|
||||||
el.className = 'emoticon-grid ffz-no-emotes center';
|
el.className = 'emoticon-grid ffz-no-emotes center';
|
||||||
el.innerHTML = "You have no favorite settings.<br>" +
|
el.innerHTML = "You have no favorite settings.<br>" +
|
||||||
|
|
|
@ -133,7 +133,8 @@ var update_player_stats = function(player, container) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
player_data.backend = player.getBackend();
|
player_data.backend = player.getBackend();
|
||||||
} catch(err) { player_data.backend = undefined }
|
player_data.version = player.getVersion();
|
||||||
|
} catch(err) { }
|
||||||
|
|
||||||
var sorted_keys = Object.keys(player_data).sort();
|
var sorted_keys = Object.keys(player_data).sort();
|
||||||
for(var i=0; i < sorted_keys.length; i++) {
|
for(var i=0; i < sorted_keys.length; i++) {
|
||||||
|
|
|
@ -41,7 +41,7 @@ FFZ.settings_info.following_count = {
|
||||||
on_update: function(val) {
|
on_update: function(val) {
|
||||||
this._schedule_following_count();
|
this._schedule_following_count();
|
||||||
|
|
||||||
var Stream = utils.ember_resolve('model:stream'),
|
var Stream = utils.ember_resolve('model:deprecated-stream'),
|
||||||
Live = Stream && Stream.find("live");
|
Live = Stream && Stream.find("live");
|
||||||
|
|
||||||
if ( Live ) {
|
if ( Live ) {
|
||||||
|
@ -155,7 +155,7 @@ FFZ.prototype._update_following_count = function() {
|
||||||
|
|
||||||
this._following_count_timer = setTimeout(this._update_following_count.bind(this), 55000 + (10000*Math.random()));
|
this._following_count_timer = setTimeout(this._update_following_count.bind(this), 55000 + (10000*Math.random()));
|
||||||
|
|
||||||
var Stream = utils.ember_resolve('model:stream'),
|
var Stream = utils.ember_resolve('model:deprecated-stream'),
|
||||||
Live = Stream && Stream.find("live"),
|
Live = Stream && Stream.find("live"),
|
||||||
|
|
||||||
Host = utils.ember_resolve('model:host'),
|
Host = utils.ember_resolve('model:host'),
|
||||||
|
@ -205,7 +205,7 @@ FFZ.prototype._build_following_tooltip = function(el) {
|
||||||
if ( streams && streams.length ) {
|
if ( streams && streams.length ) {
|
||||||
for(var i=0, l = streams.length; i < l; i++) {
|
for(var i=0, l = streams.length; i < l; i++) {
|
||||||
var stream = streams[i];
|
var stream = streams[i];
|
||||||
if ( ! stream || ! stream.channel )
|
if ( ! stream || ! stream.channel || (stream.game && this.settings.banned_games.indexOf(stream.game.toLowerCase()) !== -1) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
c += 1;
|
c += 1;
|
||||||
|
@ -216,13 +216,11 @@ FFZ.prototype._build_following_tooltip = function(el) {
|
||||||
|
|
||||||
var up_since = this.settings.stream_uptime && stream.created_at && utils.parse_date(stream.created_at),
|
var up_since = this.settings.stream_uptime && stream.created_at && utils.parse_date(stream.created_at),
|
||||||
now = Date.now() - (this._ws_server_offset || 0),
|
now = Date.now() - (this._ws_server_offset || 0),
|
||||||
uptime = up_since && Math.floor((now - up_since.getTime()) / 1000) || 0,
|
uptime = up_since && (Math.floor((now - up_since.getTime()) / 60000) * 60) || 0,
|
||||||
minutes = Math.floor(uptime / 60) % 60,
|
|
||||||
hours = Math.floor(uptime / 3600),
|
|
||||||
tags = stream.channel.game === 'Creative' && this.tokenize_ctags(stream.channel.status, true);
|
tags = stream.channel.game === 'Creative' && this.tokenize_ctags(stream.channel.status, true);
|
||||||
|
|
||||||
tooltip += (i === 0 ? '<hr>' : '') +
|
tooltip += (c === 1 ? '<hr>' : '') +
|
||||||
(uptime > 0 ? '<span class="stat">' + constants.CLOCK + ' ' + (hours > 0 ? hours + 'h' : '') + minutes + 'm</span>' : '') +
|
(uptime > 0 ? '<span class="stat">' + constants.CLOCK + ' ' + utils.duration_string(uptime) + '</span>' : '') +
|
||||||
'<span class="stat">' + constants.LIVE + ' ' + utils.number_commas(stream.viewers) + '</span>' +
|
'<span class="stat">' + constants.LIVE + ' ' + utils.number_commas(stream.viewers) + '</span>' +
|
||||||
'<b>' + utils.sanitize(stream.channel.display_name || stream.channel.name) + '</b><br>' +
|
'<b>' + utils.sanitize(stream.channel.display_name || stream.channel.name) + '</b><br>' +
|
||||||
'<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>';
|
'<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>';
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue