mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-07-03 17:48:30 +00:00
3.5.320. Fix a bunch of stuff. Remove auto-pause hosts because Twitch made it impossible to implement to the best of my knowledge. Closes #34. Closes #32. Closes #23. Closes #21. Closes #10.
This commit is contained in:
parent
9ddfabb1b1
commit
dca6f0f103
13 changed files with 243 additions and 280 deletions
|
@ -1,3 +1,16 @@
|
|||
<div class="list-header">3.5.320 <time datetime="2016-10-03">(2016-10-11)</time></div>
|
||||
<ul class="chat-menu-content menu-side-padding">
|
||||
<li>Fixed: Automatic theater mode should hopefully be working for everyone now.</li>
|
||||
<li>Fixed: Don't scroll down when exiting fullscreen with the player.</li>
|
||||
<li>Fixed: Channel metadata order is set via CSS so it should <em>always</em> work consistently.</li>
|
||||
<li>Fixed: Use normal tooltips for FFZ-added channel metadata to ensure they're positioned well.</li>
|
||||
<li>Fixed: Delete chat messages in batches of 2 to prevent message background colors from jumping.</li>
|
||||
<li>Fixed: Format localized display names correctly in whisper conversations.</li>
|
||||
<li>Fixed: The navigation controller has changed into a navigation service. Likewise, there's now a component rather than a view. This broke a couple sidebar features.</li>
|
||||
<li>Fixed: Twitch Prime emotes would display <code>--prime--</code> in FFZ's emote tooltips.</li>
|
||||
<li>Removed: Automatically pausing the player when a host starts is not currently possible due to how the player reacts to a `setChannel` event. There is no way to prevent it from playing without glitching out.</li>
|
||||
</ul>
|
||||
|
||||
<div class="list-header">3.5.319 <time datetime="2016-10-03">(2016-10-07)</time></div>
|
||||
<ul class="chat-menu-content menu-side-padding">
|
||||
<li>Added: Load emote set <-> user mappings from the API.</li>
|
||||
|
|
|
@ -32,6 +32,10 @@ FFZ.prototype.setup_channel = function() {
|
|||
this.update_views('component:channel-redesign', this.modify_channel_redesign);
|
||||
this.update_views('component:channel-redesign/live', this.modify_channel_live);
|
||||
|
||||
this.update_views('component:share-box', this.modify_channel_share_box);
|
||||
this.update_views('component:channel-options', this.modify_channel_options);
|
||||
this.update_views('component:edit-broadcast-link', this.modify_channel_broadcast_link);
|
||||
|
||||
/*this.log("Hooking the Ember Channel Index component.");
|
||||
if ( ! this.update_views('component:legacy-channel', this.modify_channel_index) )
|
||||
return;*/
|
||||
|
@ -159,6 +163,30 @@ FFZ.prototype.setup_channel = function() {
|
|||
Channel.ffzUpdateInfo();
|
||||
}
|
||||
|
||||
FFZ.prototype.modify_channel_share_box = function(view) {
|
||||
utils.ember_reopen_view(view, {
|
||||
ffz_init: function() {
|
||||
this.get('element').classList.toggle('ffz-share-box', true)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
FFZ.prototype.modify_channel_options = function(view) {
|
||||
utils.ember_reopen_view(view, {
|
||||
ffz_init: function() {
|
||||
this.get('element').classList.toggle('ffz-channel-options', true)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
FFZ.prototype.modify_channel_broadcast_link = function(view) {
|
||||
utils.ember_reopen_view(view, {
|
||||
ffz_init: function() {
|
||||
this.get('element').classList.toggle('ffz-channel-broadcast-link', true)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
FFZ.prototype.modify_channel_live = function(view) {
|
||||
var f = this;
|
||||
|
@ -180,9 +208,20 @@ FFZ.prototype.modify_channel_live = function(view) {
|
|||
this.ffzUpdatePlayerStats();
|
||||
|
||||
if ( f.settings.auto_theater ) {
|
||||
var player = f.players && f.players[channel_id] && f.players[channel_id].get('player');
|
||||
if ( player )
|
||||
var layout = this.get('layout'),
|
||||
player = f.players && f.players[channel_id] && f.players[channel_id].get('player'),
|
||||
func = function() {
|
||||
if ( player.isLoading() )
|
||||
return setTimeout(func, 500);
|
||||
|
||||
// In case this happens before the event bindings are in, we just set
|
||||
// the layout into theater mode manually.
|
||||
player.setTheatre(true);
|
||||
layout.setTheatreMode(true);
|
||||
}
|
||||
|
||||
if ( player )
|
||||
func();
|
||||
}
|
||||
|
||||
this.$().on("click", ".ffz-creative-tag-link", function(e) {
|
||||
|
@ -288,22 +327,13 @@ FFZ.prototype.modify_channel_live = function(view) {
|
|||
|
||||
var stat = utils.createElement('span'),
|
||||
figure = utils.createElement('figure', 'icon cn-metabar__icon', constants.CLOCK + ' '),
|
||||
balloon = utils.createElement('div', 'balloon balloon--tooltip balloon--down balloon--center'),
|
||||
balloon_wrapper = utils.createElement('div', 'balloon-wrapper', figure),
|
||||
stat_wrapper = utils.createElement('div', 'cn-metabar__ffz flex__item mg-l-1', balloon_wrapper);
|
||||
|
||||
balloon_wrapper.appendChild(stat);
|
||||
balloon_wrapper.appendChild(balloon);
|
||||
stat_wrapper = utils.createElement('div', 'cn-metabar__ffz html-tooltip flex__item', figure);
|
||||
|
||||
stat_wrapper.appendChild(stat);
|
||||
stat_wrapper.id = 'ffz-uptime-display';
|
||||
balloon.innerHTML = 'Stream Uptime <nobr>(since ' + online.toLocaleString() + ')</nobr>';
|
||||
stat_wrapper.title = 'Stream Uptime <nobr>(since ' + online.toLocaleString() + ')</nobr>';
|
||||
|
||||
var viewers = cont.querySelector(".cn-metabar__livecount");
|
||||
if ( viewers )
|
||||
cont.insertBefore(stat_wrapper, viewers.nextSibling);
|
||||
else
|
||||
cont.appendChild(stat_wrapper);
|
||||
|
||||
el = stat;
|
||||
}
|
||||
|
||||
|
@ -337,35 +367,37 @@ FFZ.prototype.modify_channel_live = function(view) {
|
|||
if ( ! container || ! f.settings.player_stats || ! stats || ! stats.hls_latency_broadcaster )
|
||||
return container && this.$("#ffz-player-stats").remove();
|
||||
|
||||
var el = container.querySelector("#ffz-player-stats");
|
||||
var je, el = container.querySelector("#ffz-player-stats");
|
||||
if ( ! el ) {
|
||||
var cont = container.querySelector('.cn-metabar__more');
|
||||
if ( ! cont )
|
||||
return;
|
||||
|
||||
var stat = utils.createElement('span'),
|
||||
figure = utils.createElement('figure', 'icon cn-metabar__icon', constants.GRAPH + ' '),
|
||||
balloon = utils.createElement('div', 'balloon balloon--tooltip balloon--up balloon--center'),
|
||||
balloon_wrapper = utils.createElement('div', 'balloon-wrapper', figure);
|
||||
|
||||
el = utils.createElement('div', 'cn-metabar__ffz flex__item mg-l-1', balloon_wrapper);
|
||||
|
||||
balloon_wrapper.appendChild(stat);
|
||||
balloon_wrapper.appendChild(balloon);
|
||||
figure = utils.createElement('figure', 'icon cn-metabar__icon', constants.GRAPH + ' ');
|
||||
|
||||
el = utils.createElement('div', 'cn-metabar__ffz flex__item', figure);
|
||||
el.id = 'ffz-player-stats';
|
||||
el.appendChild(stat);
|
||||
|
||||
je = jQuery(el);
|
||||
je.hover(
|
||||
function() { je.data("hover", true).tipsy("show") },
|
||||
function() { je.data("hover", false).tipsy("hide") })
|
||||
.data("hover", false)
|
||||
.tipsy({
|
||||
trigger: 'manual',
|
||||
html: true,
|
||||
gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')
|
||||
});
|
||||
|
||||
var viewers = cont.querySelector('#ffz-uptime-display') || cont.querySelector(".cn-metabar__livecount");
|
||||
if ( viewers )
|
||||
cont.insertBefore(el, viewers.nextSibling);
|
||||
else
|
||||
cont.appendChild(el);
|
||||
}
|
||||
} else
|
||||
je = jQuery(el)
|
||||
|
||||
var stat = el.querySelector('span'),
|
||||
balloon = el.querySelector('.balloon');
|
||||
|
||||
var delay = Math.round(stats.hls_latency_broadcaster / 10) / 100,
|
||||
delay = Math.round(stats.hls_latency_broadcaster / 10) / 100,
|
||||
dropped = utils.number_commas(stats.dropped_frames || 0),
|
||||
bitrate;
|
||||
|
||||
|
@ -385,11 +417,14 @@ FFZ.prototype.modify_channel_live = function(view) {
|
|||
stat.textContent = delay;
|
||||
}
|
||||
|
||||
balloon.innerHTML = (is_old ? 'Video Information<br>' +
|
||||
el.setAttribute('original-title', (is_old ? 'Video Information<br>' +
|
||||
'Broadcast ' + utils.time_to_string(delay, true) + ' Ago<br><br>' : 'Stream Latency<br>') +
|
||||
'Video: ' + stats.vid_width + 'x' + stats.vid_height + 'p ' + stats.current_fps + ' fps<br>' +
|
||||
'Playback Rate: ' + bitrate + ' Kbps<br>' +
|
||||
'Dropped Frames: ' + dropped;
|
||||
'Dropped Frames: ' + dropped);
|
||||
|
||||
if ( je.data("hover") )
|
||||
je.tipsy("hide").tipsy("show");
|
||||
},
|
||||
|
||||
ffzUpdateChatters: function() {
|
||||
|
@ -521,7 +556,9 @@ FFZ.prototype.modify_channel_live = function(view) {
|
|||
|
||||
|
||||
FFZ.prototype.modify_channel_redesign = function(view) {
|
||||
var f = this;
|
||||
var f = this,
|
||||
Layout = utils.ember_lookup('service:layout');
|
||||
|
||||
utils.ember_reopen_view(view, {
|
||||
ffz_init: function() {
|
||||
// Twitch y u make me do dis
|
||||
|
@ -551,6 +588,12 @@ FFZ.prototype.modify_channel_redesign = function(view) {
|
|||
f._credesign = null;
|
||||
},
|
||||
|
||||
handleScroll: function(top) {
|
||||
this._super();
|
||||
var height = Layout.get('playerSize.1');
|
||||
document.body.classList.toggle('ffz-small-player', f.settings.small_player && top >= (height * .8));
|
||||
},
|
||||
|
||||
ffzUpdateCoverHeight: function() {
|
||||
var old_height = this.get('channelCoverHeight'),
|
||||
setting = f.settings.hide_channel_banner,
|
||||
|
|
|
@ -228,23 +228,32 @@ FFZ.prototype.modify_conversation_line = function(component) {
|
|||
var el = this.get('element'),
|
||||
e = [],
|
||||
|
||||
user = this.get('message.from.username'),
|
||||
username = this.get('message.from.username').toLowerCase(),
|
||||
raw_display = this.get('message.from.displayName'),
|
||||
alias = f.aliases[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,
|
||||
colors = raw_color && f._handle_color(raw_color),
|
||||
|
||||
style = colors ? 'color:' + (is_dark ? colors[1] : colors[0]) : '',
|
||||
colored = colors ? ' has-color' : '',
|
||||
|
||||
results = f.format_display_name(raw_display, username),
|
||||
|
||||
myself = f.get_user(),
|
||||
from_me = myself && myself.login === user,
|
||||
from_me = myself && myself.login === username;
|
||||
|
||||
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' : '';
|
||||
|
||||
if ( alias )
|
||||
e.push('<span class="from ffz-alias html-tooltip' + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '') + '" title="' + utils.quote_san(name) + '">' + utils.sanitize(alias) + '</span>');
|
||||
else
|
||||
e.push('<span class="from' + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '') + '">' + utils.sanitize(name) + '</span>');
|
||||
e.push('<span class="from' +
|
||||
(alias ? ' ffz-alias' : '') +
|
||||
(results[1] ? ' html-tooltip' : '') +
|
||||
colored +
|
||||
'" style="' + style + '"' +
|
||||
(colors ? ' data-color="' + raw_color + '"' : '') +
|
||||
(results[1] ? ' title="' + utils.quote_attr(results[1]) + '"' : '') +
|
||||
'>' + results[0] + '</span>');
|
||||
|
||||
e.push('<span class="colon">:</span> ');
|
||||
|
||||
|
|
|
@ -222,7 +222,7 @@ 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} .cn-hosted .dynamic-target-player,.cn-hosted .dynamic-target-player object, .cn-hosted .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>#player,.dynamic-player, .dynamic-player object, .dynamic-player video{width:" + width + "px !important;height:" + height + "px !important} .cn-hosted .dynamic-target-player,.cn-hosted .dynamic-target-player object,.cn-hosted #player, .cn-hosted .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() {
|
||||
|
|
|
@ -961,6 +961,11 @@ FFZ.prototype._modify_chat_subline = function(component) {
|
|||
this.ffzRender();
|
||||
},
|
||||
|
||||
ffz_update: function() {
|
||||
this.set('msgObject._line', this);
|
||||
this.ffzRender();
|
||||
},
|
||||
|
||||
willClearRender: function() {
|
||||
this.set('msgObject._line', null);
|
||||
},
|
||||
|
|
|
@ -840,9 +840,11 @@ FFZ.prototype.modify_moderation_card = function(component) {
|
|||
this.lv_delete_notes = level >= channel.deletecomments;
|
||||
|
||||
var el = this.get('element');
|
||||
if ( el ) {
|
||||
el.classList.toggle('lv-notes', this.lv_view_notes);
|
||||
el.classList.toggle('lv-logs', this.lv_view);
|
||||
el.classList.toggle('lv-tabs', this.lv_view || this.lv_view_notes);
|
||||
}
|
||||
},
|
||||
|
||||
ffz_destroy: function() {
|
||||
|
|
|
@ -59,7 +59,7 @@ FFZ.settings_info.player_volume_bar = {
|
|||
};
|
||||
|
||||
|
||||
FFZ.settings_info.player_pause_hosts = {
|
||||
/*FFZ.settings_info.player_pause_hosts = {
|
||||
type: "select",
|
||||
options: {
|
||||
0: "Disabled",
|
||||
|
@ -73,7 +73,7 @@ FFZ.settings_info.player_pause_hosts = {
|
|||
category: "Player",
|
||||
name: "Auto-Pause Hosted Channels",
|
||||
help: "Automatically pause hosted channels if you paused the channel doing the hosting, or just pause all hosts."
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
// ---------------
|
||||
|
@ -89,7 +89,6 @@ FFZ.prototype.setup_player = function() {
|
|||
Layout.set('PLAYER_CONTROLS_HEIGHT', this.settings.classic_player ? 32 : 0);
|
||||
|
||||
this.players = {};
|
||||
this.players_paused = {};
|
||||
|
||||
this.update_views('component:twitch-player2', this.modify_twitch_player);
|
||||
}
|
||||
|
@ -103,8 +102,8 @@ FFZ.prototype.modify_twitch_player = function(player) {
|
|||
var f = this;
|
||||
utils.ember_reopen_view(player, {
|
||||
ffz_init: function() {
|
||||
var id = this.get('channel.id');
|
||||
f.players[id] = this;
|
||||
var channel_id = this.get('hostChannel.name');
|
||||
f.players[channel_id] = this;
|
||||
|
||||
var player = this.get('player');
|
||||
if ( player && !this.get('ffz_post_player') )
|
||||
|
@ -112,15 +111,17 @@ FFZ.prototype.modify_twitch_player = function(player) {
|
|||
},
|
||||
|
||||
ffz_destroy: function() {
|
||||
var id = this.get('channel.id');
|
||||
if ( f.players[id] === this )
|
||||
f.players[id] = undefined;
|
||||
var channel_id = this.get('hostChannel.name');
|
||||
if ( f.players[channel_id] === this )
|
||||
f.players[channel_id] = undefined;
|
||||
},
|
||||
|
||||
insertPlayer: function(ffz_reset) {
|
||||
/*insertPlayer: function(ffz_reset) {
|
||||
// We want to see if this is a hosted video on a play
|
||||
var should_start_paused = this.get('shouldStartPaused'),
|
||||
hosting_channel = this.get('hostChannel.id');
|
||||
channel_id = this.get('hostChannel.name'),
|
||||
hosted_id = this.get('channel.name'),
|
||||
is_hosting = channel_id !== hosted_id;
|
||||
|
||||
// Always start unpaused if the person used the FFZ setting to Reset Player.
|
||||
if ( ffz_reset )
|
||||
|
@ -128,8 +129,8 @@ FFZ.prototype.modify_twitch_player = function(player) {
|
|||
|
||||
// Alternatively, depending on the setting...
|
||||
else if (
|
||||
(f.settings.player_pause_hosts === 1 && f.players_paused[hosting_channel]) ||
|
||||
(f.settings.player_pause_hosts === 2 && hosting_channel) )
|
||||
(f.settings.player_pause_hosts === 1 && this.get('ffz_original_paused') ) ||
|
||||
(f.settings.player_pause_hosts === 2 && is_hosting) )
|
||||
this.set('shouldStartPaused', true);
|
||||
|
||||
this._super();
|
||||
|
@ -137,7 +138,7 @@ FFZ.prototype.modify_twitch_player = function(player) {
|
|||
// Restore the previous value so it doesn't mess anything up.
|
||||
this.set('shouldStartPaused', should_start_paused);
|
||||
|
||||
}.on('didInsertElement'),
|
||||
}.on('didInsertElement'),*/
|
||||
|
||||
postPlayerSetup: function() {
|
||||
this._super();
|
||||
|
@ -167,24 +168,35 @@ FFZ.prototype.modify_twitch_player = function(player) {
|
|||
Ember.run.next(this.insertPlayer.bind(this, true));
|
||||
},
|
||||
|
||||
ffzUpdatePlayerPaused: function() {
|
||||
var id = this.get('channel.id'),
|
||||
/*ffzUpdatePlayerPaused: function() {
|
||||
var channel_id = this.get('hostChannel.name'),
|
||||
hosted_id = this.get('channel.name'),
|
||||
is_hosting = channel_id !== hosted_id,
|
||||
|
||||
is_paused = this.get('player.paused');
|
||||
|
||||
f.log("Player Pause State for " + id + ": " + is_paused);
|
||||
f.players_paused[id] = is_paused;
|
||||
},
|
||||
if ( ! is_hosting )
|
||||
this.set('ffz_original_paused', is_paused);
|
||||
|
||||
f.log("Player Pause State for " + channel_id + ": " + is_paused);
|
||||
},*/
|
||||
|
||||
ffzPostPlayer: function() {
|
||||
var player = this.get('player');
|
||||
var channel_id = this.get('hostChannel.name'),
|
||||
hosted_id = this.get('channel.name'),
|
||||
is_hosting = channel_id !== hosted_id,
|
||||
|
||||
player = this.get('player');
|
||||
if ( ! player )
|
||||
return;
|
||||
|
||||
this.set('ffz_post_player', true);
|
||||
f.players_paused[this.get('channel.id')] = player.paused;
|
||||
|
||||
/*if ( ! is_hosting )
|
||||
this.set('ffz_original_paused', player.paused);
|
||||
|
||||
player.addEventListener('pause', this.ffzUpdatePlayerPaused.bind(this));
|
||||
player.addEventListener('play', this.ffzUpdatePlayerPaused.bind(this));
|
||||
player.addEventListener('play', this.ffzUpdatePlayerPaused.bind(this));*/
|
||||
|
||||
// Make the stats window draggable and fix the button.
|
||||
var stats = this.$('.player .js-playback-stats');
|
||||
|
@ -210,139 +222,6 @@ FFZ.prototype.modify_twitch_player = function(player) {
|
|||
|
||||
container.insertBefore(btn, el.nextSibling);
|
||||
}
|
||||
|
||||
// Check player statistics. If necessary, override getVideoInfo.
|
||||
/*
|
||||
if ( ! Object.keys(player.getVideoInfo()).length && ! player.ffz_stats_hooked ) {
|
||||
f.log("No Video Data. Installing handler.");
|
||||
player.ffz_stats_hooked = true;
|
||||
|
||||
var stats_el = stats[0],
|
||||
toggle_btn = this.$('.js-stats-toggle'),
|
||||
|
||||
setup_player = function(tries) {
|
||||
// If this player is destroyed, stop trying.
|
||||
if ( ! document.contains(stats_el) )
|
||||
return;
|
||||
|
||||
stats_el.classList.add('hidden');
|
||||
|
||||
if ( stats_el.getAttribute('data-state') !== 'on' )
|
||||
toggle_btn.click();
|
||||
|
||||
setTimeout(function() {
|
||||
var res = jQuery('.js-stat-display-resolution', stats_el).text();
|
||||
if ( ! res || ! res.length ) {
|
||||
// Not available yet. Keep going.
|
||||
toggle_btn.click();
|
||||
tries = (tries || 0) + 1;
|
||||
if ( tries < 50 )
|
||||
setTimeout(setup_player.bind(this, tries), 100);
|
||||
else
|
||||
stats_el.classList.remove('hidden');
|
||||
return;
|
||||
}
|
||||
|
||||
toggle_btn.text('Show Video Stats');
|
||||
|
||||
jQuery('.js-stats-close', stats_el).remove();
|
||||
|
||||
toggle_btn.off().on('click', function(e) {
|
||||
var visible = stats_el.classList.contains('hidden');
|
||||
stats_el.classList.toggle('hidden', ! visible);
|
||||
this.textContent = (visible ? 'Hide' : 'Show') + ' Video Stats';
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
|
||||
player.getVideoInfo = function() {
|
||||
var output = {};
|
||||
|
||||
// Video Resolution
|
||||
var el = stats_el.querySelector('.js-stat-video-resolution'),
|
||||
match = el && / *([\d,]+) *x *([\d,]+)/i.exec(el.textContent);
|
||||
if ( match ) {
|
||||
output.vid_width = parseInt(match[1]);
|
||||
output.vid_height = parseInt(match[2]);
|
||||
}
|
||||
|
||||
// Display Resolution
|
||||
el = stats_el.querySelector('.js-stat-display-resolution');
|
||||
match = el && / *([\d,]+) *x *([\d,]+)/i.exec(el.textContent);
|
||||
if ( match ) {
|
||||
output.stageWidth = output.vid_display_width = parseInt(match[1]);
|
||||
output.stageHeight = output.vid_display_height = parseInt(match[2]);
|
||||
}
|
||||
|
||||
// FPS
|
||||
el = stats_el.querySelector('.js-stat-fps');
|
||||
if ( el && el.textContent )
|
||||
output.current_fps = parseInt(el.textContent);
|
||||
|
||||
// Skipped Frames
|
||||
el = stats_el.querySelector('.js-stat-skipped-frames');
|
||||
if ( el && el.textContent )
|
||||
output.dropped_frames = parseInt(el.textContent);
|
||||
|
||||
// Buffer Size
|
||||
el = stats_el.querySelector('.js-stat-buffer-size');
|
||||
if ( el && el.textContent ) {
|
||||
var val = parseFloat(el.textContent);
|
||||
if ( ! isNaN(val) && isFinite(val) ) {
|
||||
if ( val < 1000 ) val *= 1000;
|
||||
output.hls_buffer_duration = val;
|
||||
}
|
||||
}
|
||||
|
||||
// Latency to Broadcaster
|
||||
el = stats_el.querySelector('.js-stat-hls-latency-broadcaster');
|
||||
var el2 = stats_el.querySelector('.js-stat-hls-latency-encoder');
|
||||
|
||||
if ( el && el.textContent && el2 && el2.textContent ) {
|
||||
var val = parseFloat(el.textContent),
|
||||
val2 = parseFloat(el2.textContent);
|
||||
|
||||
if ( val === -1 || val2 === -1 ) {
|
||||
// ... nothing :D
|
||||
} else if ( ! isNaN(val) && isFinite(val) && ! isNaN(val2) && isFinite(val2) ) {
|
||||
if ( Math.abs(val) < 1000 && Math.abs(val2) < 1000) {
|
||||
val *= 1000;
|
||||
val2 *= 1000;
|
||||
}
|
||||
|
||||
if ( val > val2 ) {
|
||||
output.hls_latency_broadcaster = val;
|
||||
output.hls_latency_encoder = val2;
|
||||
} else {
|
||||
output.hls_latency_broadcaster = val2;
|
||||
output.hls_latency_encoder = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Playback Rate
|
||||
el = stats_el.querySelector('.js-stat-playback-rate');
|
||||
if ( el && el.textContent ) {
|
||||
var val = parseFloat(el.textContent);
|
||||
if ( ! isNaN(val) && isFinite(val) ) {
|
||||
output.bandwidth = output.current_bitrate = val;
|
||||
output.playback_bytes_per_second = val * 1024 / 8;
|
||||
}
|
||||
}
|
||||
|
||||
// Other Stats
|
||||
output.paused = player.paused;
|
||||
output.playing = ! player.paused;
|
||||
output.volume = player.volume;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
}, 10);
|
||||
};
|
||||
|
||||
setup_player();
|
||||
}*/
|
||||
}
|
||||
});
|
||||
}
|
|
@ -218,10 +218,19 @@ FFZ.prototype._modify_chat_pubsub = function(pubsub) {
|
|||
old_topics = this.chatTopics;
|
||||
|
||||
for(var i=0; i < old_topics.length; i++) {
|
||||
var topic = old_topics[i];
|
||||
// Try stupid stuff to remove duplicate events.
|
||||
if ( topic.substr(0, 23) === 'chat_moderator_actions.' )
|
||||
ps.Unlisten({
|
||||
topic: old_topics[i],
|
||||
topic: topic.split('.', 2).join('.'),
|
||||
success: function() {},
|
||||
failure: function(t) { f.log("[PubSub] Failed to unlisten to topic: " + old_topics[i], t); }
|
||||
failure: function() {}
|
||||
});
|
||||
|
||||
ps.Unlisten({
|
||||
topic: topic,
|
||||
success: function() {},
|
||||
failure: function(topic, t) { f.log("[PubSub] Failed to unlisten to topic: " +topic, t); }.bind(this, topic)
|
||||
});
|
||||
this.chatTopics.removeObject(old_topics[i]);
|
||||
}
|
||||
|
@ -257,18 +266,27 @@ FFZ.prototype._modify_chat_pubsub = function(pubsub) {
|
|||
token = user.chat_oauth_token;
|
||||
|
||||
for(var i=0; i < pubsub.chatTopics.length; i++) {
|
||||
var topic = pubsub.chatTopics[i];
|
||||
// Try stupid stuff to remove duplicate events.
|
||||
if ( topic.substr(0, 23) === 'chat_moderator_actions.' )
|
||||
ps.Unlisten({
|
||||
topic: pubsub.chatTopics[i],
|
||||
topic: topic.split('.', 2).join('.'),
|
||||
success: function() {},
|
||||
failure: function(t) { f.log("[PubSub] Failed to unlisten to topic: " + old_topics[i], t); }
|
||||
failure: function() {}
|
||||
});
|
||||
|
||||
ps.Unlisten({
|
||||
topic: topic,
|
||||
success: function() {},
|
||||
failure: function(topic, t) { f.log("[PubSub] Failed to unlisten to topic: " + topic, t); }.bind(this, topic)
|
||||
});
|
||||
|
||||
ps.Listen({
|
||||
topic: pubsub.chatTopics[i],
|
||||
topic: topic,
|
||||
auth: token,
|
||||
success: function() {},
|
||||
failure: function(t) { f.log("[PubSub] Failed to listen to topic: " + new_topics[i], t); },
|
||||
message: Ember.run.bind(pubsub, pubsub._onPubsubMessage, pubsub.chatTopics[i])
|
||||
failure: function(topic, t) { f.log("[PubSub] Failed to listen to topic: " + topic, t); }.bind(this, topic),
|
||||
message: Ember.run.bind(pubsub, pubsub._onPubsubMessage, topic)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -1604,30 +1622,6 @@ FFZ.prototype._modify_room = function(room) {
|
|||
}
|
||||
},
|
||||
|
||||
/*trimMessages: function() {
|
||||
var messages = this.get("messages"),
|
||||
len = messages.get("length"),
|
||||
limit = this.get("messageBufferSize");
|
||||
|
||||
if ( len > limit ) {
|
||||
var to_remove = len - limit;
|
||||
for(var i = 0; i < to_remove; i++) {
|
||||
// Remove this message from the ID tracker.
|
||||
var msg = messages.get(i),
|
||||
msg_id = msg.tags && msg.tags.id,
|
||||
notice_type = msg.tags && msg.tags['msg-id'];
|
||||
|
||||
if ( msg_id && this.ffz_ids && this.ffz_ids[msg_id] )
|
||||
delete this.ffz_ids[msg_id];
|
||||
|
||||
if ( notice_type && this.ffz_last_notices && this.ffz_last_notices[notice_type] === msg )
|
||||
delete this.ffz_last_notices[notice_type];
|
||||
}
|
||||
|
||||
messages.removeAt(0, to_remove);
|
||||
}
|
||||
},*/
|
||||
|
||||
// Artificial chat delay
|
||||
ffz_chat_delay: function() {
|
||||
var val = f.settings.chat_delay;
|
||||
|
@ -1682,9 +1676,11 @@ FFZ.prototype._modify_room = function(room) {
|
|||
return;
|
||||
|
||||
var room_messages = this.get("messages"),
|
||||
trimmed = room_messages.length + new_messages.length > this.messageBufferSize ?
|
||||
room_messages.slice(Math.max(0, (room_messages.length - this.messageBufferSize)) + new_messages.length, room_messages.length) :
|
||||
room_messages.slice(0, room_messages.length);
|
||||
raw_remove = room_messages.length + new_messages.length > this.messageBufferSize ?
|
||||
Math.max(0, room_messages.length - this.messageBufferSize) + new_messages.length : 0,
|
||||
|
||||
to_remove = raw_remove - raw_remove % 2,
|
||||
trimmed = room_messages.slice(to_remove, room_messages.length);
|
||||
|
||||
var earliest_message;
|
||||
for(var i=0; i < trimmed.length; i++)
|
||||
|
@ -1726,23 +1722,6 @@ FFZ.prototype._modify_room = function(room) {
|
|||
}
|
||||
},
|
||||
|
||||
/*ffzActualPushMessage: function (msg) {
|
||||
if ( this.shouldShowMessage(msg) && this.ffzShouldShowMessage(msg) ) {
|
||||
this.get("messages").pushObject(msg);
|
||||
this.trimMessages();
|
||||
Ember.propertyDidChange(this, "messages");
|
||||
|
||||
if ( msg.style !== "admin" && msg.style !== "whisper" ) {
|
||||
if ( msg.ffz_has_mention ) {
|
||||
this.ffz_last_mention = Date.now();
|
||||
}
|
||||
|
||||
this.ffz_last_activity = Date.now();
|
||||
this.incrementProperty("unreadCount", 1);
|
||||
}
|
||||
}
|
||||
},*/
|
||||
|
||||
ffzSchedulePendingFlush: function(now) {
|
||||
// Instead of just blindly looping every x seconds, we want to calculate the time until
|
||||
// the next message should be displayed, and then set the timeout for that. We'll
|
||||
|
|
|
@ -228,18 +228,17 @@ FFZ.prototype.setup_sidebar = function() {
|
|||
this.error("Unable to load the Ember games-following controller.", null);
|
||||
|
||||
|
||||
// Navigation Controller
|
||||
var NavController = utils.ember_lookup('controller:navigation');
|
||||
if ( NavController ) {
|
||||
// Navigation Component
|
||||
this.update_views('component:twitch-navigation', this.modify_navigation);
|
||||
|
||||
// Navigation Service
|
||||
var NavService = utils.ember_lookup('service:navigation');
|
||||
if ( NavService ) {
|
||||
// Open Drawer by Default
|
||||
if ( this.settings.sidebar_start_open )
|
||||
NavController.set('isDrawerOpen', true);
|
||||
|
||||
NavService.set('isDrawerOpen', true);
|
||||
} else
|
||||
this.error("Unable to load the Ember navigation controller.", null);
|
||||
|
||||
if ( this._views_to_update )
|
||||
this.update_views('view:navigation', this.modify_navigation, true);
|
||||
this.error("Unable to load the Ember Navigation service.")
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ FFZ.msg_commands = {};
|
|||
|
||||
// Version
|
||||
var VER = FFZ.version_info = {
|
||||
major: 3, minor: 5, revision: 319,
|
||||
major: 3, minor: 5, revision: 320,
|
||||
toString: function() {
|
||||
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
||||
}
|
||||
|
|
|
@ -315,7 +315,7 @@ FFZ.prototype.format_display_name = function(display_name, user_id, disable_alia
|
|||
display_name = utils.sanitize(display_name || (user_id && user_id.capitalize()));
|
||||
|
||||
if ( ! disable_intl && setting === 3 && ! name_matches )
|
||||
display_name += disable_html ? '(' + user_id + ')' : ' <span class="intl-login">(' + user_id + ')</span>';
|
||||
display_name += disable_html ? ' (' + user_id + ')' : ' <span class="intl-login">(' + user_id + ')</span>';
|
||||
|
||||
else if ( ((disable_intl && setting === 3) || setting === 4) && ! name_matches )
|
||||
tooltip = user_id;
|
||||
|
@ -456,6 +456,9 @@ FFZ.prototype.render_tooltip = function(el) {
|
|||
} else if ( emote_set === "--twitch-turbo--" || emote_set === "turbo" || emote_set === "--turbo-faces--" ) {
|
||||
emote_set = "Twitch Turbo";
|
||||
set_type = null;
|
||||
} else if ( emote_set === '--prime--' || emote_set === '--prime-faces--' ) {
|
||||
emote_set = "Twitch Prime";
|
||||
set_type = null;
|
||||
}
|
||||
|
||||
if ( this.classList.contains('ffz-tooltip-no-credit') )
|
||||
|
|
|
@ -593,7 +593,7 @@ FFZ.mod_card_pages.notes = {
|
|||
|
||||
var output = this._build_mod_card_history(message, mod_card, true, false, can_mod);
|
||||
|
||||
/*if ( can_mod ) {
|
||||
if ( can_mod ) {
|
||||
var mod_icons = output.querySelector('.mod-icons');
|
||||
if ( can_delete ) {
|
||||
var btn_delete = utils.createElement('a', 'mod-icon html-tooltip delete-note', 'Delete');
|
||||
|
@ -633,8 +633,8 @@ FFZ.mod_card_pages.notes = {
|
|||
var btn_edit = utils.createElement('a', 'mod-icon html-tooltip edit-note', 'Edit');
|
||||
btn_edit.title = 'Edit Note';
|
||||
mod_icons.appendChild(btn_edit);
|
||||
}*
|
||||
}*/
|
||||
}
|
||||
|
||||
return output;
|
||||
},
|
||||
|
|
53
style.css
53
style.css
|
@ -1525,6 +1525,11 @@ img.channel_background[src="null"] { display: none; }
|
|||
|
||||
/* Chat Rows */
|
||||
|
||||
.conversation-window .conversation-chat-line {
|
||||
margin: 0;
|
||||
padding: 3px 10px;
|
||||
}
|
||||
|
||||
.ember-chat .chat-messages .chat-line {
|
||||
margin: 0;
|
||||
padding: 3px 20px;
|
||||
|
@ -3529,9 +3534,8 @@ body.ffz-bttv #ffz-feed-tabs .tabs { margin-bottom: 0 }
|
|||
padding-top: 80px;
|
||||
}
|
||||
|
||||
.ffz-minimal-channel-title.ffz-channel-title-top #channel {
|
||||
padding-top: 50px;
|
||||
}
|
||||
.ffz-hide-channel-banner .cn-cover { height: 0 !important }
|
||||
.ffz-minimal-channel-title.ffz-channel-title-top #channel { padding-top: 50px }
|
||||
|
||||
.ffz-channel-title-top .cn-metabar__title {
|
||||
position: absolute;
|
||||
|
@ -3542,19 +3546,16 @@ body.ffz-bttv #ffz-feed-tabs .tabs { margin-bottom: 0 }
|
|||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.ffz-channel-title-top .cn-metabar__more > div { order: 999; }
|
||||
.ffz-channel-title-top .cn-metabar__more > span:last-of-type { flex-grow: 1 }
|
||||
.ffz-channel-title-top .cn-metabar__more > span:last-of-type > div { float: left }
|
||||
.ffz-channel-title-top .cn-metabar__more > div:last-of-type { margin-right: 0 !important }
|
||||
.ffz-channel-title-top .cn-metabar__more > div + button:first-of-type,
|
||||
.ffz-channel-title-top .cn-metabar__more > div + span:first-of-type button.mg-l-1 { margin-left: 0 !important }
|
||||
.ffz-channel-title-top .cn-metabar__viewcount { flex-grow: 0 !important; }
|
||||
|
||||
.ffz-minimal-channel-bar .cn-bar-fixed {
|
||||
top: -40px;
|
||||
transition: top ease-in-out 75ms, bottom ease-in-out 75ms;
|
||||
}
|
||||
|
||||
body:not(.ffz-channel-bar-bottom).ffz-small-player #player .dynamic-player { margin-top: 50px }
|
||||
body:not(.ffz-channel-bar-bottom).ffz-small-player.ffz-minimal-channel-bar #player .dynamic-player { margin-top: 10px }
|
||||
|
||||
.cn-bar-fixed { z-index: 100 }
|
||||
|
||||
.ffz-minimal-channel-bar .cn-bar-fixed:hover { top: 0 }
|
||||
.ffz-minimal-channel-bar.ffz-channel-bar-bottom .cn-bar-fixed { top: auto; bottom: -40px }
|
||||
.ffz-minimal-channel-bar.ffz-channel-bar-bottom .cn-bar-fixed:hover { bottom: 0 }
|
||||
|
@ -3566,6 +3567,36 @@ body.ffz-bttv #ffz-feed-tabs .tabs { margin-bottom: 0 }
|
|||
|
||||
.ffz-hide-channel-banner .cn-bar__avatar-wrap { width: 4rem; height: 4rem; }
|
||||
|
||||
/* Channel Metadata Sorting */
|
||||
|
||||
.cn-metabar__more > * {
|
||||
margin: 0 1rem 0 0 !important;
|
||||
order: 49;
|
||||
}
|
||||
|
||||
.cn-metabar__more > span { order: 150 }
|
||||
|
||||
.cn-metabar__more:after {
|
||||
content: '';
|
||||
order: 75;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.ffz-channel-options .qa-channel-options,
|
||||
.ffz-share-box .qa-share-box__button { margin: 0 !important }
|
||||
|
||||
.cn-metabar__more > .cn-metabar__livecount { order: 1 }
|
||||
.cn-metabar__more > #ffz-uptime-display { order: 2 }
|
||||
.cn-metabar__more > #ffz-player-stats { order: 3 }
|
||||
.cn-metabar__more > .cn-metabar__viewcount { order: 50; flex-grow: 0 !important }
|
||||
.cn-metabar__more > #ffz-chatter-display { order: 51 }
|
||||
|
||||
.cn-metabar__more > #ffz-ui-host-button { order: 98 }
|
||||
.cn-metabar__more > .ffz-channel-broadcast-link { order: 100 }
|
||||
.cn-metabar__more > .ffz-share-box { order: 101 }
|
||||
.cn-metabar__more > .ffz-channel-options { order: 999; margin-right: 0 !important }
|
||||
|
||||
|
||||
/* Mod Card Notes */
|
||||
|
||||
.ffz-moderation-card .note-input textarea {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue