mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-09-16 10:06:54 +00:00
The "Oh God Why Didn't I Commit Sooner" Edition
v3.5.494. Added: Chat Filtering > Remove Messages from Moderators Added: Recent Highlights Added: Support for room-specific badges from the API. Fixed: Custom bits badges. Lots of styling. Chat bugs. Dark theme issues. My Emoticons menu not rendering. Reset Player not rendering. Twitch5 extension compatibility. Logviewer messages and Name History. Bits UI breaking when you switch rooms. Player state when you reset the player. Closes #173 Closes #169 Closes #164
This commit is contained in:
parent
e843a3bb19
commit
630d2830ec
30 changed files with 1049 additions and 187 deletions
|
@ -474,15 +474,17 @@ FFZ.settings_info.chatter_count = {
|
|||
help: "Display the current number of users connected to chat beneath the channel.",
|
||||
|
||||
on_update: function(val) {
|
||||
if ( this._cindex )
|
||||
this._cindex.ffzUpdateMetadata('chatters');
|
||||
|
||||
if ( ! val || ! this.rooms )
|
||||
if ( ! this.rooms )
|
||||
return;
|
||||
|
||||
// Refresh the data.
|
||||
for(var room_id in this.rooms)
|
||||
this.rooms.hasOwnProperty(room_id) && this.rooms[room_id].room && this.rooms[room_id].room.ffzInitChatterCount();
|
||||
for(var room_id in this.rooms) {
|
||||
var r = this.rooms[room_id] && this.rooms[room_id].room;
|
||||
r && r.ffzInitChatterCount();
|
||||
}
|
||||
|
||||
if ( this._cindex )
|
||||
this._cindex.ffzUpdateMetadata('chatters');
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -942,7 +942,10 @@ FFZ.prototype.modify_chat_input = function(component) {
|
|||
return emotes;
|
||||
}.property(),
|
||||
|
||||
_setPartialName: function() { },
|
||||
_setPartialName: function() {
|
||||
if ( f.has_bttv )
|
||||
return this._super();
|
||||
}.observes('textareaValue'),
|
||||
|
||||
ffz_suggestions: function() {
|
||||
var output = [],
|
||||
|
@ -1041,9 +1044,24 @@ FFZ.prototype.modify_chat_input = function(component) {
|
|||
for(var i=0; i < suggestions.length; i++) {
|
||||
var suggestion = suggestions[i],
|
||||
name = suggestion.id,
|
||||
display_name = suggestion.displayName || (name && name.capitalize()),
|
||||
username_match = display_name.trim().toLowerCase() === name,
|
||||
alias = f.aliases[name];
|
||||
display_name = suggestion.displayName,
|
||||
username_match;
|
||||
|
||||
if ( name === undefined ) {
|
||||
var dnt = display_name && display_name.trim();
|
||||
if ( dnt && /^[a-z0-9_]+$/i.test(dnt) )
|
||||
name = dnt.toLowerCase();
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! display_name ) {
|
||||
display_name = name.capitalize();
|
||||
username_match = true;
|
||||
} else
|
||||
username_match = display_name.trim().toLowerCase() === name;
|
||||
|
||||
var alias = f.aliases[name];
|
||||
|
||||
if ( user_output[name] && ! user_output[name].is_alias ) {
|
||||
var token = user_output[name];
|
||||
|
@ -1245,6 +1263,9 @@ FFZ.prototype.modify_chat_input = function(component) {
|
|||
var target = event.target,
|
||||
cl = target.classList;
|
||||
|
||||
if ( f.has_bttv )
|
||||
this._super();
|
||||
|
||||
if ( ! this.get('ffz_suggestions_visible') || cl.contains('suggestion') || cl.contains('suggestions') || target === this.get('chatTextArea') )
|
||||
return;
|
||||
|
||||
|
|
|
@ -180,6 +180,18 @@ FFZ.settings_info.remove_filtered = {
|
|||
};
|
||||
|
||||
|
||||
FFZ.settings_info.remove_filtered_mod = {
|
||||
type: "boolean",
|
||||
value: false,
|
||||
|
||||
category: "Chat Filtering",
|
||||
no_bttv: 6,
|
||||
|
||||
name: "Remove Messages from Moderators",
|
||||
help: "Messages with banned words will only be removed if they are not from a moderator, unless this setting is enabled."
|
||||
};
|
||||
|
||||
|
||||
FFZ.settings_info.remove_deleted = {
|
||||
type: "boolean",
|
||||
value: false,
|
||||
|
|
|
@ -235,26 +235,19 @@ FFZ.prototype.setup_layout = function() {
|
|||
}.property("ffzExtraHeight", "windowWidth", "rightColumnWidth", "fullSizePlayerDimensions", "windowHeight"),
|
||||
|
||||
contentWidth: function() {
|
||||
var left_width = this.get('isSocialColumnEnabled') ? LS(
|
||||
f.settings.socialbar_hide ? 0 :
|
||||
this.get('isSocialColumnCollapsed') ? 50 : 240
|
||||
) : LS(
|
||||
this.get('ffzMinimizeNavigation') ? 10 :
|
||||
this.get('isLeftColumnClosed') ? 50 : 240
|
||||
),
|
||||
|
||||
var left_width = LS(f.settings.socialbar_hide ? 0 : this.get('isSocialColumnCollapsed') ? 50 : 240),
|
||||
right_width = ! f.has_bttv && this.get('portraitMode') ? 0 : this.get("isRightColumnClosed") ? 0 : this.get("rightColumnWidth");
|
||||
|
||||
return this.get("windowWidth") - left_width - right_width - LS(60);
|
||||
|
||||
}.property("windowWidth", 'ffzMinimizeNavigation', "portraitMode", "isRightColumnClosed", "isLeftColumnClosed", "rightColumnWidth", "isSocialColumnCollapsed", "isSocialColumnEnabled"),
|
||||
}.property("windowWidth", 'ffzMinimizeNavigation', "portraitMode", "isRightColumnClosed", "rightColumnWidth", "isSocialColumnCollapsed"),
|
||||
|
||||
ffzExtraHeight: function() {
|
||||
return (this.get('isSocialColumnEnabled') ? this.get('ffzMinimizeNavigation') ? 10 : 50 : 0) +
|
||||
return (this.get('ffzMinimizeNavigation') ? 10 : 50) +
|
||||
(f.settings.channel_bar_collapse ? 10 : 60) + 15 +
|
||||
(f.settings.channel_title_top === 2 ? 20 : f.settings.channel_title_top > 0 ? 55 : 0) +
|
||||
(f.settings.channel_title_top ? 70 : 80);
|
||||
}.property("isSocialColumnEnabled", "ffzMinimizeNavigation"),
|
||||
}.property("ffzMinimizeNavigation"),
|
||||
|
||||
fullSizePlayerDimensions: function() {
|
||||
var h = this.get('windowHeight'),
|
||||
|
@ -321,7 +314,7 @@ FFZ.prototype.setup_layout = function() {
|
|||
if ( this.get('portraitMode') ) {
|
||||
var size = this.get('fullSizePlayerDimensions'),
|
||||
video_below = this.get('portraitVideoBelow'),
|
||||
top_height = this.get('isSocialColumnEnabled') ? this.get('ffzMinimizeNavigation') ? 10 : 50 : 0,
|
||||
top_height = this.get('ffzMinimizeNavigation') ? 10 : 50,
|
||||
|
||||
video_height = size.height + this.get('ffzExtraHeight'),
|
||||
chat_height = window_height - video_height,
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
FFZ.settings_info.automod_inline = {
|
||||
type: "boolean",
|
||||
value: true,
|
||||
value: false,
|
||||
|
||||
category: "Chat Moderation",
|
||||
no_bttv: 6,
|
||||
|
@ -597,7 +597,7 @@ FFZ.settings_info.chat_font_family = {
|
|||
|
||||
var span = document.createElement('span');
|
||||
span.style.fontFamily = val;
|
||||
css = ".pinned-cheers .chat-line,.timestamp-line,.conversation-chat-line,.conversation-system-messages,.chat-history,.ember-chat .chat-messages {" + span.style.cssText + "}";
|
||||
css = ".ffz-recent-messages .chat-line,.pinned-cheers .chat-line,.timestamp-line,.conversation-chat-line,.conversation-system-messages,.chat-history,.ember-chat .chat-messages {" + span.style.cssText + "}";
|
||||
}
|
||||
|
||||
utils.update_css(this._chat_style, "chat_font_family", css);
|
||||
|
@ -605,6 +605,72 @@ FFZ.settings_info.chat_font_family = {
|
|||
};
|
||||
|
||||
|
||||
FFZ.settings_info.recent_highlights = {
|
||||
type: "boolean",
|
||||
value: false,
|
||||
|
||||
category: "Chat Appearance",
|
||||
no_bttv: true,
|
||||
|
||||
name: "Recent Highlights <span>Beta</span>",
|
||||
help: "Display a Recent Highlights section at the top of chat to make sure you don't miss anything.",
|
||||
|
||||
on_update: function(val) {
|
||||
this._roomv && this._roomv.ffzUpdateRecent();
|
||||
if ( ! val )
|
||||
for(var room_id in this.rooms) {
|
||||
var r = this.rooms[room_id] && this.rooms[room_id].room;
|
||||
r.set('ffz_recent_highlights', []);
|
||||
r.set('ffz_recent_highlights_unread', 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FFZ.settings_info.recent_highlight_count = {
|
||||
type: "button",
|
||||
value: 50,
|
||||
|
||||
category: "Chat Appearance",
|
||||
no_bttv: true,
|
||||
|
||||
name: "Recent Highlights Length",
|
||||
help: "Set the maximum number of recent highlights to keep at once.",
|
||||
|
||||
method: function() {
|
||||
var f = this;
|
||||
utils.prompt(
|
||||
"Recent Highlights Length",
|
||||
"Please enter a new maximum length for the recent highlights scrollback. Please note that setting this too high may cause your computer to begin lagging as chat messages accumulate.</p><p><b>Default:</b> 50",
|
||||
this.settings.recent_highlight_count,
|
||||
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 = 50;
|
||||
|
||||
new_val = Math.max(1, new_val);
|
||||
|
||||
f.settings.set("recent_highlight_count", new_val);
|
||||
});
|
||||
},
|
||||
|
||||
on_update: function(val) {
|
||||
for(var room_id in this.rooms) {
|
||||
var r = this.rooms[room_id] && this.rooms[room_id].room,
|
||||
rh = r && r.get('ffz_recent_highlights');
|
||||
|
||||
if ( rh && rh.length > val )
|
||||
r.set('ffz_recent_highlights', rh.splice(Math.max(0, rh.length - val), rh.length));
|
||||
}
|
||||
|
||||
this._roomv && this._roomv.ffzUpdateRecent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FFZ.settings_info.emoji_scale = {
|
||||
type: "select",
|
||||
options: {
|
||||
|
@ -676,9 +742,9 @@ FFZ.settings_info.chat_font_size = {
|
|||
var lh = Math.max(20, Math.round((20/12)*val)),
|
||||
pd = Math.floor((lh - 20) / 2);
|
||||
|
||||
css = ".pinned-cheers .chat-line,.timestamp-line,.conversation-chat-line,.conversation-system-messages,.chat-history .chat-line,.ember-chat .chat-messages .chat-line { font-size: " + val + "px !important; line-height: " + lh + "px !important; }";
|
||||
css = ".ffz-recent-messages .chat-line,.pinned-cheers .chat-line,.timestamp-line,.conversation-chat-line,.conversation-system-messages,.chat-history .chat-line,.ember-chat .chat-messages .chat-line { font-size: " + val + "px !important; line-height: " + lh + "px !important; }";
|
||||
if ( pd )
|
||||
css += ".pinned-cheers .chat-line,.ember-chat .chat-messages .chat-line .mod-icons, .ember-chat .chat-messages .chat-line .badges { padding-top: " + pd + "px; }";
|
||||
css += ".ffz-recent-messages .chat-line .mod-icons,.pinned-cheers .chat-line,.ember-chat .chat-messages .chat-line .mod-icons, .ember-chat .chat-messages .chat-line .badges { padding-top: " + pd + "px; }";
|
||||
}
|
||||
|
||||
utils.update_css(this._chat_style, "chat_font_size", css);
|
||||
|
@ -730,7 +796,7 @@ FFZ.settings_info.chat_ts_size = {
|
|||
css = "";
|
||||
else {
|
||||
var lh = Math.max(20, Math.round((20/12)*val), Math.round((20/12)*this.settings.chat_font_size));
|
||||
css = ".ember-chat .chat-messages .timestamp { font-size: " + val + "px !important; line-height: " + lh + "px !important; }";
|
||||
css = ".ffz-recent-messages .timestamp,.ember-chat .chat-messages .timestamp { font-size: " + val + "px !important; line-height: " + lh + "px !important; }";
|
||||
}
|
||||
|
||||
utils.update_css(this._chat_style, "chat_ts_font_size", css);
|
||||
|
|
|
@ -883,7 +883,7 @@ FFZ.prototype.modify_moderation_card = function(component) {
|
|||
// If we're viewing the chat history, update it.
|
||||
var el = this.get('element'),
|
||||
container = el && el.querySelector('.ffz-tab-container'),
|
||||
history = container && container.querySelector('.chat-history.lv-history');
|
||||
history = container && container.querySelector('.ffz-tab-container[data-page="history"] .chat-history.lv-history');
|
||||
|
||||
if ( history ) {
|
||||
var was_at_bottom = history.scrollTop >= (history.scrollHeight - history.clientHeight),
|
||||
|
|
|
@ -30,10 +30,8 @@ FFZ.settings_info.player_stats = {
|
|||
help: "Display your current stream latency (how far behind the broadcast you are) under the player, with a few useful statistics in a tooltip.",
|
||||
|
||||
on_update: function(val) {
|
||||
if ( ! this._cindex )
|
||||
return;
|
||||
|
||||
this._cindex.ffzUpdateMetadata('player_stats');
|
||||
if ( this._cindex )
|
||||
this._cindex.ffzUpdateMetadata('player_stats');
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -199,12 +197,19 @@ FFZ.prototype.modify_twitch_player = function(player) {
|
|||
},
|
||||
|
||||
ffzRecreatePlayer: function() {
|
||||
var player = this.get('player'),
|
||||
theatre = player && player.getTheatre();
|
||||
var t = this,
|
||||
player = this.get('player'),
|
||||
theatre, fullscreen, had_player = false;
|
||||
|
||||
// Tell the player to destroy itself.
|
||||
if ( player )
|
||||
if ( player ) {
|
||||
had_player = true;
|
||||
fullscreen = player.fullscreen;
|
||||
theatre = player.theatre;
|
||||
player.fullscreen = false;
|
||||
player.theatre = false;
|
||||
player.destroy();
|
||||
}
|
||||
|
||||
// Break down everything left over from that player.
|
||||
this.$('#player').html('');
|
||||
|
@ -213,7 +218,16 @@ FFZ.prototype.modify_twitch_player = function(player) {
|
|||
this.set('ffz_post_player', false);
|
||||
|
||||
// Now, let Twitch create a new player as usual.
|
||||
Ember.run.next(this.didInsertElement.bind(this));
|
||||
Ember.run.next(function() {
|
||||
t.didInsertElement();
|
||||
had_player && setTimeout(function() {
|
||||
var player = t.get('player');
|
||||
if ( player ) {
|
||||
//player.fullscreen = fullscreen;
|
||||
player.theatre = theatre;
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
/*ffzUpdatePlayerPaused: function() {
|
||||
|
@ -269,17 +283,18 @@ FFZ.prototype.modify_twitch_player = function(player) {
|
|||
|
||||
// Add an option to the menu to recreate the player.
|
||||
var t = this,
|
||||
el = this.$('.player-menu .player-menu__item--stats')[0],
|
||||
el = this.$('.player-buttons-right #js-settings')[0],
|
||||
container = el && el.parentElement;
|
||||
|
||||
if ( el && ! container.querySelector('.js-player-reset') ) {
|
||||
var btn_link = utils.createElement('a', 'player-text-link js-player-reset', 'Reset Player'),
|
||||
btn = utils.createElement('p', 'player-menu__item player-menu__item--reset pl-small', btn_link);
|
||||
if ( el && ! container.querySelector('.ffz-player-reset') ) {
|
||||
var btn = utils.createElement('button', 'player-button player-button--reset ffz-player-reset');
|
||||
btn.type = 'button';
|
||||
|
||||
btn_link.tabindex = '-1';
|
||||
btn_link.href = '#';
|
||||
btn.innerHTML = '<span class="player-tip js-control-tip" data-tip="Double-Click to Reset Player"></span>' +
|
||||
constants.CLOSE;
|
||||
|
||||
btn_link.addEventListener('click', function(e) {
|
||||
jQuery(btn).on('dblclick', function(e) {
|
||||
//btn.addEventListener('click', function(e) {
|
||||
t.ffzRecreatePlayer();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
|
|
|
@ -178,6 +178,28 @@ FFZ.prototype.setup_room = function() {
|
|||
}
|
||||
|
||||
|
||||
var ChannelSubs = utils.ember_lookup('service:channel-subscriptions');
|
||||
if ( ChannelSubs ) {
|
||||
this.log("Hooking the Ember Channel Subscriptions service.");
|
||||
ChannelSubs.reopen({
|
||||
populateSubNotificationTokens: function() {
|
||||
var Chat = utils.ember_lookup('controller:chat'),
|
||||
tokens = Chat && Chat.get('currentRoom.roomProperties.available_chat_notification_tokens');
|
||||
|
||||
return this._super(tokens);
|
||||
},
|
||||
|
||||
_reloadSubNotificationToken: function(e) {
|
||||
var t = this;
|
||||
return this.get("api").request("get", "/api/channels/" + e + "/chat_properties").then(function(e) {
|
||||
var room = f.rooms && f.rooms[e] && f.rooms[e].room;
|
||||
room && room.set('roomProperties.available_chat_notification_tokens', e.available_chat_notification_tokens);
|
||||
t.isDestroyed || t.populateSubNotificationTokens(e.available_chat_notification_tokens)
|
||||
})
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
this.update_views('component:chat/chat-room', this.modify_room_component);
|
||||
this.update_views('component:chat/chat-interface', this.modify_chat_interface);
|
||||
|
||||
|
@ -657,7 +679,8 @@ FFZ.HoverPause = {
|
|||
|
||||
FFZ.prototype.modify_room_component = function(component) {
|
||||
var f = this,
|
||||
PinnedCheers = utils.ember_lookup('service:bits-pinned-cheers');
|
||||
PinnedCheers = utils.ember_lookup('service:bits-pinned-cheers'),
|
||||
ChannelSubs = utils.ember_lookup('service:channel-subscriptions');
|
||||
|
||||
utils.ember_reopen_view(component, _.extend({
|
||||
ffz_init: function() {
|
||||
|
@ -676,9 +699,18 @@ FFZ.prototype.modify_room_component = function(component) {
|
|||
this.ffzUpdateStatus();
|
||||
}
|
||||
|
||||
var actions = this._actions || {},
|
||||
var t = this,
|
||||
actions = this._actions || {},
|
||||
orig_show = actions.showModOverlay;
|
||||
|
||||
actions.accommodatePinnedMessage = function(e) {
|
||||
var el = t.get('element'),
|
||||
chat = el.querySelector('.js-chat-messages');
|
||||
|
||||
if ( chat )
|
||||
chat.dataset.pinned_height = e;
|
||||
};
|
||||
|
||||
actions.showModOverlay = function(e) {
|
||||
var Channel = utils.ember_resolve('model:deprecated-channel'),
|
||||
chan = Channel && Channel.find && Channel.find({id: e.sender});
|
||||
|
@ -709,6 +741,8 @@ FFZ.prototype.modify_room_component = function(component) {
|
|||
isModeratorOrHigher: this.get("room.isModeratorOrHigher")
|
||||
});
|
||||
}
|
||||
|
||||
this.ffzUpdateRecent();
|
||||
},
|
||||
|
||||
ffz_destroy: function() {
|
||||
|
@ -719,18 +753,181 @@ FFZ.prototype.modify_room_component = function(component) {
|
|||
this.ffzRemoveKeyHook();
|
||||
},
|
||||
|
||||
|
||||
ffzUpdateRecent: function() {
|
||||
var t = this,
|
||||
el = this.get('element'),
|
||||
container = this.get('ffz_recent_el'),
|
||||
con_count = this.get('ffz_recent_count_el'),
|
||||
should_show = f.settings.recent_highlights && ! f.has_bttv;
|
||||
|
||||
if ( ! el )
|
||||
return;
|
||||
|
||||
if ( ! container ) {
|
||||
if ( ! should_show )
|
||||
return;
|
||||
|
||||
container = utils.createElement('ul', 'chat-history');
|
||||
var expander = utils.createElement('div', 'ffz-recent-expando', 'Recent Highlights<span class="pill"></span>'),
|
||||
big_el = utils.createElement('div', 'ffz-recent-messages', expander),
|
||||
btn_handle = utils.createElement('span', 'ffz-handle ffz-close-button'),
|
||||
super_parent = document.body.querySelector('.app-main');
|
||||
|
||||
con_count = expander.querySelector('.pill');
|
||||
container.classList.toggle('dark', f.settings.dark_twitch);
|
||||
expander.insertBefore(btn_handle, expander.firstChild);
|
||||
container.dataset.docked = true;
|
||||
|
||||
big_el.appendChild(container);
|
||||
el.appendChild(big_el);
|
||||
el.classList.add('ffz-has-recent-messages');
|
||||
|
||||
this.set('ffz_recent_el', container);
|
||||
this.set('ffz_recent_count_el', con_count);
|
||||
|
||||
expander.addEventListener('mousemove', function(e) {
|
||||
con_count.textContent = '';
|
||||
t.set('room.ffz_recent_highlights_unread', 0);
|
||||
});
|
||||
|
||||
btn_handle.addEventListener('click', function(e) {
|
||||
if ( ! big_el.classList.contains('ui-moved') || ! e.button === 0 )
|
||||
return;
|
||||
|
||||
big_el.style.top = 0;
|
||||
big_el.style.left = 0;
|
||||
big_el.classList.remove('ui-moved');
|
||||
big_el.parentElement.removeChild(big_el);
|
||||
el.appendChild(big_el);
|
||||
el.classList.add('ffz-has-recent-messages');
|
||||
container.dataset.docked = true;
|
||||
});
|
||||
|
||||
var st;
|
||||
jQuery(big_el).draggable({
|
||||
handle: expander,
|
||||
start: function(e) {
|
||||
st = container.scrollTop;
|
||||
big_el.classList.add('ui-moved');
|
||||
container.dataset.docked = false;
|
||||
el.classList.remove('ffz-has-recent-messages');
|
||||
},
|
||||
|
||||
stop: function(e) {
|
||||
if ( big_el.parentElement !== super_parent ) {
|
||||
var rect = big_el.getBoundingClientRect(),
|
||||
pr = super_parent.getBoundingClientRect();
|
||||
|
||||
big_el.parentElement.removeChild(big_el);
|
||||
super_parent.appendChild(big_el);
|
||||
|
||||
big_el.style.top = (rect.top - pr.top) + "px";
|
||||
big_el.style.left = (rect.left - pr.left) + "px";
|
||||
}
|
||||
|
||||
container.scrollTop = st;
|
||||
}
|
||||
});
|
||||
|
||||
jQuery(container).on('click', '.chat-line', function(e) {
|
||||
if ( ! e.target || e.button !== 0 )
|
||||
return;
|
||||
|
||||
var jq = jQuery(e.target),
|
||||
cl = e.target.classList,
|
||||
line = cl.contains('chat-line') ? e.target : jq.parents('.chat-line')[0],
|
||||
room_id = line && line.dataset.room,
|
||||
room = room_id && f.rooms[room_id] && f.rooms[room_id].room,
|
||||
from = line && line.dataset.sender,
|
||||
msg_id = line && line.dataset.id;
|
||||
|
||||
if ( cl.contains('deleted-word') ) {
|
||||
jq.trigger('mouseout');
|
||||
e.target.outerHTML = e.target.dataset.text;
|
||||
|
||||
} else if ( cl.contains('deleted-link') )
|
||||
return f._deleted_link_click.call(e.target, e);
|
||||
|
||||
else if ( cl.contains('badge') ) {
|
||||
if ( cl.contains('click_action') ) {
|
||||
var badge = f.badges && f.badges[e.target.getAttribute('data-badge-id')];
|
||||
if ( badge.click_action )
|
||||
badge.click_action.call(f, this.get('msgObject'), e);
|
||||
|
||||
} else if ( cl.contains('click_url') )
|
||||
window.open(e.target.dataset.url, "_blank");
|
||||
|
||||
else if ( cl.contains('turbo') )
|
||||
window.open("/products/turbo?ref=chat_badge", "_blank");
|
||||
|
||||
else if ( cl.contains('subscriber') )
|
||||
window.open("/" + room_id + "/subscribe?ref=in_chat_subscriber_link");
|
||||
|
||||
} else if ( f._click_emote(e.target, e) )
|
||||
return;
|
||||
|
||||
else if ( (f.settings.clickable_mentions && cl.contains('user-token')) || cl.contains('from') || e.target.parentElement.classList.contains('from') ) {
|
||||
var target = cl.contains('user-token') ? e.target.dataset.user : from;
|
||||
if ( ! target )
|
||||
return;
|
||||
|
||||
var bounds = line && line.getBoundingClientRect() || document.body.getBoundingClientRect(),
|
||||
x = 0, right;
|
||||
|
||||
if ( bounds.left > 400 )
|
||||
right = bounds.left - 40;
|
||||
|
||||
f._roomv.actions.showModOverlay.call(f._roomv, {
|
||||
left: bounds.left,
|
||||
right: right,
|
||||
top: bounds.top + bounds.height,
|
||||
real_top: bounds.top,
|
||||
sender: target
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
} else if ( ! should_show ) {
|
||||
jQuery(container.parentElement).remove();
|
||||
this.set('ffz_recent_el', null);
|
||||
this.set('ffz_recent_count_el', null);
|
||||
el.classList.remove('ffz-has-recent-messages');
|
||||
return;
|
||||
}
|
||||
|
||||
var was_at_bottom = container.scrollTop >= (container.scrollHeight - container.clientHeight);
|
||||
container.innerHTML = '';
|
||||
con_count.textContent = container.dataset.docked ? utils.format_unread(this.get('room.ffz_recent_highlights_unread') || 0) : '';
|
||||
|
||||
var messages = this.get('room.ffz_recent_highlights') || [];
|
||||
for(var i=0; i < messages.length; i++)
|
||||
container.appendChild(f._build_mod_card_history(messages[i], null, true));
|
||||
|
||||
if ( was_at_bottom )
|
||||
container.scrollTop = container.scrollHeight;
|
||||
|
||||
}.observes('room'),
|
||||
|
||||
|
||||
ffzUpdateBits: function() {
|
||||
var t = this,
|
||||
channel = this.get('room.channel');
|
||||
if ( ! channel )
|
||||
channel = this.get('room.channel'),
|
||||
bits_room = this.get('bitsRoom');
|
||||
if ( ! channel || ! bits_room )
|
||||
return;
|
||||
|
||||
PinnedCheers && PinnedCheers.dismissLocalMessage();
|
||||
|
||||
if ( ! channel.get('isLoaded') )
|
||||
channel.load().then(function() { t._initializeBits(channel) })
|
||||
else
|
||||
channel.load().then(function() { bits_room.reset(); t._initializeBits(channel) })
|
||||
else {
|
||||
bits_room.reset();
|
||||
this._initializeBits(channel);
|
||||
}
|
||||
|
||||
ChannelSubs && ChannelSubs.populateSubNotificationTokens(this.get('room.roomProperties.available_chat_notification_tokens'));
|
||||
|
||||
}.observes('room'),
|
||||
|
||||
|
@ -1130,7 +1327,7 @@ FFZ.prototype._load_room_json = function(room_id, callback, data) {
|
|||
var model = this.rooms[room_id] = this.rooms[room_id] || {};
|
||||
|
||||
for(var key in data)
|
||||
if ( key !== 'users' && key !== 'room' && data.hasOwnProperty(key) )
|
||||
if ( key !== 'user_badges' && key !== 'users' && key !== 'room' && data.hasOwnProperty(key) )
|
||||
model[key] = data[key];
|
||||
|
||||
// Merge the user data.
|
||||
|
@ -1144,6 +1341,21 @@ FFZ.prototype._load_room_json = function(room_id, callback, data) {
|
|||
}
|
||||
}
|
||||
|
||||
// Merge badge data
|
||||
for(var badge_id in data.user_badges) {
|
||||
var badge = this.badges[badge_id];
|
||||
if ( ! badge )
|
||||
continue;
|
||||
|
||||
for(var l=data.user_badges[badge_id], i=0, j=l.length; i < j; i++) {
|
||||
var user_id = l[i],
|
||||
user = model.users[user_id] = model.users[user_id] || {},
|
||||
badges = user.badges = user.badges || {};
|
||||
|
||||
badges[badge.slot] = {id: badge_id};
|
||||
}
|
||||
}
|
||||
|
||||
// Preserve the pointer to the Room instance.
|
||||
/*if ( this.rooms[room_id] )
|
||||
data.room = this.rooms[room_id].room;
|
||||
|
@ -1192,6 +1404,8 @@ FFZ.prototype._modify_room = function(room) {
|
|||
ffz_banned: false,
|
||||
|
||||
mru_list: [],
|
||||
ffz_recent_highlights: [],
|
||||
ffz_recent_highlights_unread: 0,
|
||||
|
||||
ffzUpdateBadges: function() {
|
||||
if ( this.get('isGroupRoom') )
|
||||
|
@ -1299,7 +1513,7 @@ FFZ.prototype._modify_room = function(room) {
|
|||
|
||||
try {
|
||||
f.add_room(this.id, this);
|
||||
this.set("ffz_chatters", {});
|
||||
this.set("ffz_chatters", []);
|
||||
this.set("ffz_ids", this.get('ffz_ids') || {});
|
||||
this.set("ffz_last_notices", this.get('ffz_last_notices') || {});
|
||||
} catch(err) {
|
||||
|
@ -1789,7 +2003,10 @@ FFZ.prototype._modify_room = function(room) {
|
|||
|
||||
ffzPushMessages: function(messages) {
|
||||
var new_messages = [],
|
||||
new_unread = 0;
|
||||
new_unread = 0,
|
||||
|
||||
highlight_messages = [],
|
||||
highlight_unread = 0;
|
||||
|
||||
for(var i=0; i < messages.length; i++) {
|
||||
var msg = messages[i];
|
||||
|
@ -1797,8 +2014,11 @@ FFZ.prototype._modify_room = function(room) {
|
|||
new_messages.push(msg);
|
||||
|
||||
if ( ! (msg.tags && msg.tags.historical) && msg.style !== "admin" && msg.style !== "whisper" ) {
|
||||
if ( msg.ffz_has_mention )
|
||||
if ( msg.ffz_has_mention ) {
|
||||
this.ffz_last_mention = Date.now();
|
||||
highlight_messages.push(msg);
|
||||
highlight_unread++;
|
||||
}
|
||||
|
||||
new_unread++;
|
||||
}
|
||||
|
@ -1867,6 +2087,39 @@ FFZ.prototype._modify_room = function(room) {
|
|||
this.incrementProperty("unreadCount", new_unread);
|
||||
this.ffz_last_activity = Date.now();
|
||||
}
|
||||
|
||||
if ( f.settings.recent_highlights && highlight_unread ) {
|
||||
var old_highlights = this.get('ffz_recent_highlights') || [],
|
||||
raw_remove = old_highlights.length + highlight_messages.length > f.settings.recent_highlight_count ?
|
||||
Math.max(0, old_highlights.length - f.settings.recent_highlight_count) + highlight_messages.length : 0,
|
||||
|
||||
to_remove = raw_remove % 2,
|
||||
trimmed = old_highlights.slice(to_remove, old_highlights.length).concat(highlight_messages),
|
||||
el = f._roomv && f._roomv.get('ffz_recent_el');
|
||||
|
||||
this.set('ffz_recent_highlights', trimmed);
|
||||
this.incrementProperty('ffz_recent_highlights_unread', highlight_unread);
|
||||
|
||||
if ( el && f._roomv.get('room') === this ) {
|
||||
var was_at_bottom = el.scrollTop >= (el.scrollHeight - el.clientHeight);
|
||||
|
||||
while( el.childElementCount && to_remove-- )
|
||||
el.removeChild(el.firstElementChild);
|
||||
|
||||
for(var i=0; i < highlight_messages.length; i++)
|
||||
el.appendChild(f._build_mod_card_history(highlight_messages[i], null, true));
|
||||
|
||||
if ( was_at_bottom )
|
||||
el.scrollTop = el.scrollHeight;
|
||||
|
||||
if ( el.dataset.docked ) {
|
||||
el = f._roomv.get('ffz_recent_count_el');
|
||||
if ( el )
|
||||
el.textContent = utils.format_unread(this.get('ffz_recent_highlights_unread'));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
ffzSchedulePendingFlush: function(now) {
|
||||
|
@ -2023,7 +2276,7 @@ FFZ.prototype._modify_room = function(room) {
|
|||
ffzProcessMessage: function(msg) {
|
||||
if ( msg ) {
|
||||
var notice_type = msg.tags && msg.tags['msg-id'],
|
||||
is_resub = notice_type === 'resub',
|
||||
is_resub = notice_type === 'resub' || notice_type === 'sub',
|
||||
room_id = this.get('id'),
|
||||
msg_id = msg.tags && msg.tags.id;
|
||||
|
||||
|
@ -2177,10 +2430,6 @@ FFZ.prototype._modify_room = function(room) {
|
|||
f.api_trigger('room-message', msg);
|
||||
|
||||
|
||||
// Also update chatters.
|
||||
if ( ! is_whisper && this.chatters && ! this.chatters[msg.from] && msg.from !== 'twitchnotify' && msg.from !== 'jtv' )
|
||||
this.ffzUpdateChatters(msg.from);
|
||||
|
||||
// We're past the last return, so store the message
|
||||
// now that we know we're keeping it.
|
||||
if ( msg_id ) {
|
||||
|
@ -2195,8 +2444,8 @@ FFZ.prototype._modify_room = function(room) {
|
|||
}
|
||||
|
||||
// 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/");
|
||||
if ( msg.from && msg.from !== "jtv" && msg.from !== "twitchnotify" )
|
||||
this.ffzSafePM({from_ffz: true, command: 'chat_message', data: {from: msg.from, room: msg.room}}, "*"); //location.protocol + "//www.twitch.tv/");
|
||||
|
||||
// Flagging for review.
|
||||
if ( msg.tags && msg.tags.risk === "high" )
|
||||
|
@ -2330,8 +2579,11 @@ FFZ.prototype._modify_room = function(room) {
|
|||
}.observes('unreadCount'),
|
||||
|
||||
ffzInitChatterCount: function() {
|
||||
if ( ! this.tmiRoom )
|
||||
if ( ! this.tmiRoom || ! f.settings.chatter_count ) {
|
||||
this.set("ffz_chatters", []);
|
||||
this.ffzUpdateChatters();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( this._ffz_chatter_timer ) {
|
||||
clearTimeout(this._ffz_chatter_timer);
|
||||
|
@ -2340,26 +2592,27 @@ FFZ.prototype._modify_room = function(room) {
|
|||
|
||||
var room = this;
|
||||
this.tmiRoom.list().done(function(data) {
|
||||
var chatters = {};
|
||||
var chatters = [];
|
||||
data = data.data.chatters;
|
||||
if ( data && data.admins )
|
||||
for(var i=0; i < data.admins.length; i++)
|
||||
chatters[data.admins[i]] = true;
|
||||
chatters.push(data.admins[i]);
|
||||
if ( data && data.global_mods )
|
||||
for(var i=0; i < data.global_mods.length; i++)
|
||||
chatters[data.global_mods[i]] = true;
|
||||
chatters.push(data.global_mods[i]);
|
||||
if ( data && data.moderators )
|
||||
for(var i=0; i < data.moderators.length; i++)
|
||||
chatters[data.moderators[i]] = true;
|
||||
chatters.push(data.moderators[i]);
|
||||
if ( data && data.staff )
|
||||
for(var i=0; i < data.staff.length; i++)
|
||||
chatters[data.staff[i]] = true;
|
||||
chatters.push(data.staff[i]);
|
||||
if ( data && data.viewers )
|
||||
for(var i=0; i < data.viewers.length; i++)
|
||||
chatters[data.viewers[i]] = true;
|
||||
chatters.push(data.viewers[i]);
|
||||
|
||||
room.set("ffz_chatters", chatters);
|
||||
room.ffzUpdateChatters();
|
||||
|
||||
}).always(function() {
|
||||
room._ffz_chatter_timer = setTimeout(room.ffzInitChatterCount.bind(room), 300000);
|
||||
});
|
||||
|
@ -2367,22 +2620,31 @@ FFZ.prototype._modify_room = function(room) {
|
|||
|
||||
|
||||
ffzUpdateChatters: function(add, remove) {
|
||||
var chatters = this.get("ffz_chatters") || {};
|
||||
if ( add )
|
||||
chatters[add] = true;
|
||||
if ( remove && chatters[remove] )
|
||||
delete chatters[remove];
|
||||
|
||||
if ( ! f.settings.chatter_count )
|
||||
return;
|
||||
|
||||
var chatters = this.get("ffz_chatters") || [];
|
||||
if ( add && chatters.indexOf(add) === -1 )
|
||||
chatters.push(add);
|
||||
|
||||
if ( remove ) {
|
||||
var ind = chatters.indexOf(remove);
|
||||
if ( ind !== -1 )
|
||||
chatters.splice(ind, 1);
|
||||
}
|
||||
|
||||
if ( f._cindex )
|
||||
f._cindex.ffzUpdateMetadata('chatters');
|
||||
|
||||
if ( window !== window.parent && parent.postMessage )
|
||||
parent.postMessage({from_ffz: true, command: 'chatter_count', data: {room: this.get('id'), chatters: Object.keys(this.get('ffz_chatters') || {}).length}}, "*"); //location.protocol + "//www.twitch.tv/");
|
||||
this.ffzSafePM({from_ffz: true, command: 'chatter_count', data: {room: this.get('id'), chatters: (this.get('ffz_chatters') || []).length}}, "*"); //location.protocol + "//www.twitch.tv/");
|
||||
},
|
||||
|
||||
ffzSafePM: function(message, origin) {
|
||||
try {
|
||||
if ( window !== window.parent && parent.postMessage )
|
||||
return parent.postMessage(message, origin);
|
||||
} catch(err) { }
|
||||
},
|
||||
|
||||
ffzPatchTMI: function() {
|
||||
var tmi = this.get('tmiRoom'),
|
||||
|
|
|
@ -382,7 +382,7 @@ FFZ.prototype.modify_social_followed_channel = function(component) {
|
|||
ffz_init: function() {
|
||||
var t = this,
|
||||
el = this.get('element'),
|
||||
card = jQuery('.sc-card', el),
|
||||
card = jQuery('.js-sc-card', el),
|
||||
data = card && card.data('tipsy');
|
||||
|
||||
if ( ! data || ! data.options )
|
||||
|
@ -418,6 +418,7 @@ FFZ.prototype.modify_social_followed_channel = function(component) {
|
|||
'<span class="stat">' + constants.LIVE + ' ' + utils.number_commas(data.stream.viewers) + '</span>' +
|
||||
'<b>' + utils.sanitize(channel.display_name || channel.name) + '</b><br>' +
|
||||
'<span class="playing">' +
|
||||
(data.stream.stream_type === 'watch_party' ? '<span class="pill is-watch-party">Vodcast</span> ' : '') +
|
||||
(channel.game === 'Creative' ?
|
||||
'Being Creative' :
|
||||
(channel.game ?
|
||||
|
|
|
@ -104,7 +104,7 @@ API.prototype.log = function(msg, data, to_json, log_json) {
|
|||
|
||||
|
||||
API.prototype.error = function(msg, error, to_json, log_json) {
|
||||
this.ffz.error('Ext #' + this.id + ' (' + this.name_key + '): ' + msg, data, to_json, log_json);
|
||||
this.ffz.error('Ext #' + this.id + ' (' + this.name_key + '): ' + msg, error, to_json, log_json);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -96,6 +96,18 @@ FFZ.prototype.setup_bttv_7 = function(delay) {
|
|||
}
|
||||
|
||||
|
||||
/* Update the chat input to not use FFZ's input handling.
|
||||
if ( this._inputv ) {
|
||||
var t = this._inputv.$("textarea");
|
||||
t.off("keyup");
|
||||
t.off("keydown");
|
||||
t.off("keypress");
|
||||
t.on("keyup", this._inputv._onKeyUp.bind(this._inputv));
|
||||
t.on("keydown", this._inputv._onKeyDown.bind(this._inputv));
|
||||
}//*/
|
||||
|
||||
|
||||
|
||||
// Hook into BTTV's dark mode.
|
||||
cl.add('ffz-bttv');
|
||||
cl.toggle('ffz-bttv-dark', settings.get('darkenedMode'));
|
||||
|
@ -105,6 +117,7 @@ FFZ.prototype.setup_bttv_7 = function(delay) {
|
|||
});
|
||||
|
||||
this.update_ui_link();
|
||||
this._roomv && this._roomv.ffzUpdateRecent();
|
||||
this.api_trigger('bttv-initialized', 7);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,29 @@
|
|||
|
||||
.svg-logo_twitch, .clips-nav__logo { fill: white }
|
||||
|
||||
.nav-banner {
|
||||
background-color: lighten(@nav-bg-color, 10%);
|
||||
}
|
||||
|
||||
|
||||
// Chat
|
||||
|
||||
.clip-chat-message {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.view-clip__main--darker {
|
||||
background-color: darken(@nav-bg-color, 2%);
|
||||
}
|
||||
|
||||
.view-clip__smallTitle {
|
||||
color: @fg-color;
|
||||
|
||||
& > div {
|
||||
background-color: @nav-bg-color;
|
||||
border-bottom: lighten(@nav-bg-color, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
// Content Meta
|
||||
.nv-clip-content {
|
||||
|
|
|
@ -61,7 +61,7 @@ FFZ.channel_metadata = {};
|
|||
|
||||
// Version
|
||||
var VER = FFZ.version_info = {
|
||||
major: 3, minor: 5, revision: 480,
|
||||
major: 3, minor: 5, revision: 494,
|
||||
toString: function() {
|
||||
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
||||
}
|
||||
|
|
|
@ -240,7 +240,7 @@ var is_android = navigator.userAgent.indexOf('Android') !== -1,
|
|||
search_input.placeholder = 'Search for Settings';
|
||||
search_input.type = 'text';
|
||||
|
||||
filtered_cont.style.maxHeight = (parseInt(container.style.maxHeight) - 51) + 'px';
|
||||
filtered_cont.style.maxHeight = (parseInt(container.style.maxHeight) - 53) + 'px';
|
||||
|
||||
search_cont.appendChild(search_input);
|
||||
container.appendChild(filtered_cont);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* Chat Line Padding */
|
||||
.chat-history .chat-line,
|
||||
.ember-chat .chat-messages .chat-line,
|
||||
.ember-chat .chat-messages .chat-line.admin,
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
border-bottom-color: rgba(255,255,255, 0.5);
|
||||
}
|
||||
|
||||
.chat-history .chat-line,
|
||||
.ember-chat .chat-messages .chat-line,
|
||||
.ember-chat .chat-messages .chat-line.admin { padding-top: 2px }
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
border-top: 1px solid rgba(255,255,255, 0.5);
|
||||
}
|
||||
|
||||
.chat-history .chat-line,
|
||||
.ember-chat .chat-messages .chat-line,
|
||||
.ember-chat .chat-messages .chat-line.admin { padding-top: 2px }
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
border-top: 1px solid #aaa;
|
||||
}
|
||||
|
||||
.chat-history .chat-line,
|
||||
.ember-chat .chat-messages .chat-line,
|
||||
.ember-chat .chat-messages .chat-line.admin { padding-top: 2px }
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
border-bottom: 1px solid #aaa;
|
||||
}
|
||||
|
||||
.chat-history .chat-line,
|
||||
.ember-chat .chat-messages .chat-line,
|
||||
.ember-chat .chat-messages .chat-line.admin { padding-bottom: 2px }
|
||||
|
||||
|
|
|
@ -798,7 +798,7 @@ FFZ.prototype.tokenize_chat_line = function(msgObject, prevent_notification, del
|
|||
// Mentions!
|
||||
if ( ! from_me ) {
|
||||
tokens = this.tokenize_mentions(tokens);
|
||||
var st = this.settings.remove_filtered;
|
||||
var st = (mod_or_higher && !this.settings.remove_filtered_mod) ? 0 : this.settings.remove_filtered;
|
||||
|
||||
for(var i=0; i < tokens.length; i++) {
|
||||
var token = tokens[i],
|
||||
|
@ -1076,14 +1076,16 @@ FFZ.prototype.render_token = function(render_links, warn_links, render_bits, tok
|
|||
video_info = VIDEO_URL.exec(href);
|
||||
|
||||
if ( clip_info ) {
|
||||
var clips = utils.ember_lookup('service:clips');
|
||||
clips && clips.getClipInfo(clip_info[1]).then(function(data) {
|
||||
var clips = utils.ember_lookup('service:store');
|
||||
clips && clips.findRecord && clips.findRecord('clip', clip_info[1]).then(function(data) {
|
||||
//clips && clips.getClipInfo(clip_info[1]).then(function(data) {
|
||||
data &&
|
||||
success(true, {
|
||||
image: data.previewImage,
|
||||
image: data.get('scaledPreviewUrl'),
|
||||
image_iframe: false,
|
||||
html: '<span class="ffz-clip-title">' + utils.sanitize(data.title) + '</span>' +
|
||||
'Channel: ' + utils.sanitize(data.broadcasterDisplayName) +
|
||||
'<br>Game: ' + utils.sanitize(data.game)
|
||||
html: '<span class="ffz-clip-title">' + utils.sanitize(data.get('title')) + '</span>' +
|
||||
'Channel: ' + utils.sanitize(data.get('broadcasterDisplayName')) +
|
||||
'<br>Game: ' + utils.sanitize(data.get('game'))
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -90,30 +90,39 @@ metadata.player_stats = {
|
|||
stats = player.getVideoInfo();
|
||||
} catch(err) { }
|
||||
|
||||
// Check for server offset.
|
||||
var delayed = undefined;
|
||||
if ( this._ws_open ) {
|
||||
var offset = this._ws_server_offset;
|
||||
if ( isNaN(offset) || ! isFinite(offset) )
|
||||
this.ws_ping();
|
||||
else
|
||||
delayed = offset > 5000;
|
||||
}
|
||||
|
||||
var delay = stats && Math.round(stats.hls_latency_broadcaster / 10) / 100;
|
||||
return [stats, delay, delay > 180, player_cont];
|
||||
return [stats, delay, delay > 180, player_cont, delayed];
|
||||
},
|
||||
|
||||
order: 3,
|
||||
host_order: 102,
|
||||
|
||||
static_label: constants.GRAPH,
|
||||
label: function(stats, delay, is_old) {
|
||||
if ( ! this.settings.player_stats || ! stats || ! stats.hls_latency_broadcaster )
|
||||
label: function(stats, delay, is_old, player_cont, delayed) {
|
||||
if ( ! this.settings.player_stats || ! delay )
|
||||
return null;
|
||||
|
||||
delayed = delayed ? '(!) ' : '';
|
||||
|
||||
if ( is_old )
|
||||
return utils.time_to_string(Math.floor(delay), true, delay > 172800) + ' old'
|
||||
else {
|
||||
delay = delay.toString();
|
||||
var ind = delay.indexOf('.');
|
||||
return delay + (ind === -1 ? '.00' : (ind >= delay.length - 2 ? '0' : '')) + 's';
|
||||
}
|
||||
return delayed + utils.time_to_string(Math.floor(delay), true, delay > 172800) + ' old'
|
||||
else
|
||||
return delayed + delay.toFixed(2) + 's';
|
||||
},
|
||||
|
||||
color: function(stats, delay, is_old) {
|
||||
var setting = this.settings.player_stats;
|
||||
if ( setting === -1 )
|
||||
if ( setting === -1 || is_old )
|
||||
return '';
|
||||
|
||||
else if ( delay > (setting * 2) )
|
||||
|
@ -127,9 +136,11 @@ metadata.player_stats = {
|
|||
player_cont.$('.js-stats-toggle').click();
|
||||
},
|
||||
|
||||
tooltip: function(stats, delay, is_old) {
|
||||
tooltip: function(stats, delay, is_old, player_cont, delayed) {
|
||||
delayed = delayed ? 'Your local clock seems to be off by roughly ' + (Math.round(this._ws_server_offset / 10) / 100).toFixed(2) + ' seconds, and that could be making this inaccurate.<hr>' : '';
|
||||
|
||||
if ( ! stats || ! stats.hls_latency_broadcaster )
|
||||
return 'Stream Latency';
|
||||
return delayed + 'Stream Latency';
|
||||
|
||||
var bitrate;
|
||||
if ( stats.playback_bytes_per_second )
|
||||
|
@ -137,7 +148,7 @@ metadata.player_stats = {
|
|||
else
|
||||
bitrate = Math.round(stats.current_bitrate * 100) / 100;
|
||||
|
||||
return (is_old ? 'Video Information<br>' +
|
||||
return delayed + (is_old ? 'Video Information<br>' +
|
||||
'Broadcast ' + utils.time_to_string(Math.floor(delay), true) + ' Ago<br><br>' : 'Stream Latency<br>') +
|
||||
'Video: ' + stats.vid_width + 'x' + stats.vid_height + 'p' + stats.current_fps + '<br>' +
|
||||
'Playback Rate: ' + utils.number_commas(bitrate) + ' Kbps<br>' +
|
||||
|
@ -156,7 +167,7 @@ metadata.chatters = {
|
|||
if ( ! room || ! this.settings.chatter_count )
|
||||
return null;
|
||||
|
||||
return utils.number_commas(Object.keys(room.room.get('ffz_chatters') || {}).length);
|
||||
return utils.number_commas((room.room.get('ffz_chatters') || []).length);
|
||||
},
|
||||
|
||||
tooltip: 'Currently in Chat'
|
||||
|
|
|
@ -133,6 +133,10 @@ FFZ.settings_info.dark_twitch = {
|
|||
if ( this.has_bttv )
|
||||
return;
|
||||
|
||||
var RH = this._roomv && this._roomv.get('ffz_recent_el');
|
||||
if ( RH )
|
||||
RH.classList.toggle('dark', val);
|
||||
|
||||
(this.is_clips ? document.querySelector('html') : document.body).classList.toggle("ffz-dark", val);
|
||||
|
||||
var Settings = utils.ember_settings();
|
||||
|
|
|
@ -224,7 +224,9 @@ FFZ.prototype._build_following_tooltip = function(el) {
|
|||
(uptime > 0 ? '<span class="stat">' + constants.CLOCK + ' ' + utils.duration_string(uptime) + '</span>' : '') +
|
||||
'<span class="stat">' + constants.LIVE + ' ' + utils.number_commas(stream.viewers) + '</span>' +
|
||||
'<b>' + utils.sanitize(stream.channel.display_name || stream.channel.name) + '</b><br>' +
|
||||
'<span class="playing">' + (stream.channel.game === 'Creative' ? 'Being Creative' : (stream.channel.game ? 'Playing ' + utils.sanitize(stream.channel.game) : 'Not Playing')) + (tags ? ' | ' + _.pluck(tags, "text").join(" ") : '') + '</span>';
|
||||
'<span class="playing">' +
|
||||
(stream.stream_type === 'watch_party' ? '<span class="pill is-watch-party">Vodcast</span> ' : '') +
|
||||
(stream.channel.game === 'Creative' ? 'Being Creative' : (stream.channel.game ? 'Playing ' + utils.sanitize(stream.channel.game) : 'Not Playing')) + (tags ? ' | ' + _.pluck(tags, "text").join(" ") : '') + '</span>';
|
||||
}
|
||||
|
||||
if ( filtered )
|
||||
|
|
|
@ -770,7 +770,7 @@ FFZ.mod_card_pages.notes = {
|
|||
utils.logviewer.get("comments/" + room_id + "?topic=" + user_id, token)
|
||||
.then(utils.json).then(function(data) {
|
||||
|
||||
f.log("[LV] Comments: " + user_id + " in " + room_id, data);
|
||||
//f.log("[LV] Comments: " + user_id + " in " + room_id, data);
|
||||
history.classList.remove('loading');
|
||||
|
||||
// We want to listen to get new notes for this user.
|
||||
|
|
|
@ -2,7 +2,8 @@ var FFZ = window.FrankerFaceZ,
|
|||
constants = require("../constants"),
|
||||
utils = require("../utils"),
|
||||
|
||||
BANNED_SETS = {"00000turbo":true};
|
||||
BANNED_SETS = {"00000turbo":true},
|
||||
EXTRA_INVENTORY = ['33563'];
|
||||
|
||||
|
||||
// -------------------
|
||||
|
@ -154,6 +155,43 @@ FFZ.menu_pages.myemotes = {
|
|||
},
|
||||
|
||||
render: function(view, container) {
|
||||
/*var search_cont = utils.createElement('div', 'ffz-filter-container'),
|
||||
search_input = utils.createElement('input', 'emoticon-selector__filter-input form__input js-filter-input text text--full-width'),
|
||||
filtered_cont = utils.createElement('div', 'ffz-filter-children ffz-ui-sub-menu-page'),
|
||||
was_filtered = false;
|
||||
|
||||
search_input.placeholder = 'Search for Emotes';
|
||||
search_input.type = 'text';
|
||||
|
||||
filtered_cont.style.maxHeight = (parseInt(container.style.maxHeight) - 53) + 'px';
|
||||
|
||||
search_cont.appendChild(search_input);
|
||||
container.appendChild(filtered_cont);
|
||||
container.appendChild(search_cont);
|
||||
|
||||
search_input.addEventListener('input', function(e) {
|
||||
var filter = (search_input.value || '').toLowerCase(),
|
||||
groups = filtered_cont.querySelectorAll('.emoticon-grid');
|
||||
|
||||
for(var i=0; i < groups.length; i++) {
|
||||
var el = groups[i],
|
||||
emotes = el.querySelectorAll('.emoticon'),
|
||||
hidden = true;
|
||||
|
||||
for(var j=0; j < emotes.length; j++) {
|
||||
var em = emotes[j],
|
||||
ehidden = filter.length && em.getAttribute('data-filter').indexOf(filter) === -1;
|
||||
|
||||
em.classList.toggle('hidden', ehidden);
|
||||
hidden = hidden && ehidden;
|
||||
}
|
||||
|
||||
el.classList.toggle('hidden', hidden);
|
||||
el.classList.toggle('collapsable', ! filter.length);
|
||||
}
|
||||
});
|
||||
|
||||
container = filtered_cont;*/
|
||||
FFZ.menu_pages.myemotes.render_lists.call(this, view, container, false);
|
||||
}
|
||||
},
|
||||
|
@ -199,7 +237,9 @@ FFZ.menu_pages.myemotes = {
|
|||
gathered_emotes = [];
|
||||
|
||||
// Start with Twitch Sets
|
||||
var gathered_favorites = this.settings.favorite_emotes['twitch-inventory'] || [];
|
||||
var gathered_favorites = this.settings.favorite_emotes['twitch-inventory'] || [],
|
||||
gathered_channels = {},
|
||||
other_channels = [];
|
||||
|
||||
for(var set_id in twitch_sets) {
|
||||
if ( ! twitch_sets.hasOwnProperty(set_id) || ( ! favorites_only && ! this.settings.global_emotes_in_menu && set_id === '0' ) )
|
||||
|
@ -213,7 +253,7 @@ FFZ.menu_pages.myemotes = {
|
|||
if ( ! set.length )
|
||||
continue;
|
||||
|
||||
if ( this._twitch_inventory_sets.indexOf(set_id) !== -1 ) {
|
||||
if ( this._twitch_inventory_sets.indexOf(set_id) !== -1 || EXTRA_INVENTORY.indexOf(set_id) !== -1 ) {
|
||||
for(var i=0; i < set.length; i++)
|
||||
if ( ! favorites_only || gathered_favorites.indexOf(set[i].id) !== -1 )
|
||||
gathered_emotes.push(set[i]);
|
||||
|
@ -228,6 +268,12 @@ FFZ.menu_pages.myemotes = {
|
|||
if ( favorites_only && (! favorites_list || ! favorites_list.length) )
|
||||
continue;
|
||||
|
||||
if ( menu_id !== 'unknown' ) {
|
||||
var gathered = gathered_channels[menu_id] = gathered_channels[menu_id] || [];
|
||||
gathered.push(set_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
var sort_key = 0,
|
||||
menu = FFZ.menu_pages.myemotes.draw_twitch_set.call(this, view, set_id, set, favorites_only);
|
||||
|
||||
|
@ -240,6 +286,33 @@ FFZ.menu_pages.myemotes = {
|
|||
sets.push([[sort_key, menu_id], menu]);
|
||||
}
|
||||
|
||||
for(var menu_id in gathered_channels) {
|
||||
var gathered = [],
|
||||
stuff = gathered_channels[menu_id];
|
||||
|
||||
if ( ! stuff.length )
|
||||
continue;
|
||||
|
||||
for(var i=0; i < stuff.length; i++) {
|
||||
var set_id = stuff[i],
|
||||
set = twitch_sets[set_id];
|
||||
for(var j=0; j < set.length; j++)
|
||||
gathered.push([set_id, set[j]]);
|
||||
}
|
||||
|
||||
var sort_key = 0,
|
||||
menu = FFZ.menu_pages.myemotes.draw_twitch_set.call(this, view, stuff[0], gathered, favorites_only);
|
||||
|
||||
if ( menu_id.indexOf('global') !== -1 )
|
||||
sort_key = 100;
|
||||
else if ( menu_id.substr(0,2) === '--' || menu_id === 'turbo' )
|
||||
sort_key = 75;
|
||||
|
||||
if ( menu )
|
||||
sets.push([[sort_key, menu_id], menu]);
|
||||
}
|
||||
|
||||
|
||||
// Handle the gathered single emotes.
|
||||
if ( gathered_emotes.length ) {
|
||||
var menu = FFZ.menu_pages.myemotes.draw_twitch_set.call(this, view, 'inventory', gathered_emotes, favorites_only);
|
||||
|
@ -338,18 +411,22 @@ FFZ.menu_pages.myemotes = {
|
|||
return true;
|
||||
},
|
||||
|
||||
toggle_section: function(heading, container) {
|
||||
toggle_section: function(heading, container, set_state) {
|
||||
var menu = heading.parentElement,
|
||||
set_id = menu.getAttribute('data-set'),
|
||||
collapsed_list = this.settings.emote_menu_collapsed,
|
||||
is_collapsed = collapsed_list.indexOf(set_id) === -1;
|
||||
has_state = set_state !== undefined,
|
||||
is_collapsed = has_state ? set_state : collapsed_list.indexOf(set_id) === -1;
|
||||
|
||||
if ( ! is_collapsed )
|
||||
collapsed_list.removeObject(set_id);
|
||||
else
|
||||
collapsed_list.push(set_id);
|
||||
if ( ! has_state ) {
|
||||
if ( ! is_collapsed )
|
||||
collapsed_list.removeObject(set_id);
|
||||
else
|
||||
collapsed_list.push(set_id);
|
||||
|
||||
this.settings.set('emote_menu_collapsed', collapsed_list, true);
|
||||
}
|
||||
|
||||
this.settings.set('emote_menu_collapsed', collapsed_list, true);
|
||||
menu.classList.toggle('collapsed', !is_collapsed);
|
||||
|
||||
if ( is_collapsed )
|
||||
|
@ -382,7 +459,7 @@ FFZ.menu_pages.myemotes = {
|
|||
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); });
|
||||
heading.addEventListener('click', function() { FFZ.menu_pages.myemotes.toggle_section.bind(f)(this, emotes); });
|
||||
}
|
||||
|
||||
var set = [];
|
||||
|
@ -420,6 +497,7 @@ FFZ.menu_pages.myemotes = {
|
|||
em.classList.toggle('ffz-is-favorite', favorites_only);
|
||||
|
||||
em.setAttribute('data-ffz-emoji', emoji.code);
|
||||
em.setAttribute('data-filter', emoji.name.toLowerCase() + ' :' + emoji.short_name.toLowerCase() + ':');
|
||||
em.alt = emoji.raw;
|
||||
|
||||
em.addEventListener('click', this._add_emote.bind(this, view, emoji.raw, "emoji", emoji.raw));
|
||||
|
@ -502,6 +580,11 @@ FFZ.menu_pages.myemotes = {
|
|||
}
|
||||
|
||||
set.sort(function(a,b) {
|
||||
if ( Array.isArray(a) )
|
||||
a = a[1];
|
||||
if ( Array.isArray(b) )
|
||||
b = b[1];
|
||||
|
||||
var an = a.code.toLowerCase(),
|
||||
bn = b.code.toLowerCase();
|
||||
|
||||
|
@ -514,8 +597,16 @@ 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;
|
||||
esid = set_id,
|
||||
favs = favorites;
|
||||
if ( Array.isArray(emote) ) {
|
||||
esid = emote[0];
|
||||
emote = emote[1];
|
||||
favs = this.settings.favorite_emotes["twitch-" + esid] || [];
|
||||
}
|
||||
|
||||
var code = constants.KNOWN_CODES[emote.code] || emote.code,
|
||||
is_favorite = favs.indexOf(emote.id) !== -1;
|
||||
|
||||
if ( favorites_only && ! is_favorite )
|
||||
continue;
|
||||
|
@ -525,6 +616,7 @@ FFZ.menu_pages.myemotes = {
|
|||
|
||||
em.className = 'emoticon ffz-tooltip ffz-can-favorite';
|
||||
em.setAttribute('data-emote', emote.id);
|
||||
em.setAttribute('data-filter', code.toLowerCase());
|
||||
em.alt = code;
|
||||
|
||||
em.classList.toggle('ffz-favorite', is_favorite);
|
||||
|
@ -541,13 +633,13 @@ FFZ.menu_pages.myemotes = {
|
|||
em.style.backgroundImage = img_set;
|
||||
}
|
||||
|
||||
em.addEventListener("click", function(id, c, e) {
|
||||
em.addEventListener("click", function(id, c, q, e) {
|
||||
e.preventDefault();
|
||||
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons )
|
||||
window.open("https://twitchemotes.com/emote/" + id);
|
||||
else
|
||||
this._add_emote(view, c, "twitch-" + set_id, id, e);
|
||||
}.bind(this, emote.id, code));
|
||||
this._add_emote(view, c, "twitch-" + q, id, e);
|
||||
}.bind(this, emote.id, code, esid));
|
||||
|
||||
c++;
|
||||
emotes.appendChild(em);
|
||||
|
@ -634,6 +726,7 @@ FFZ.menu_pages.myemotes = {
|
|||
|
||||
em.setAttribute('data-ffz-emote', emote.id);
|
||||
em.setAttribute('data-ffz-set', set.id);
|
||||
em.setAttribute('data-filter', emote.name.toLowerCase());
|
||||
|
||||
em.style.backgroundImage = 'url("' + emote.urls[1] + '")';
|
||||
em.style.backgroundImage = '-webkit-' + img_set;
|
||||
|
|
|
@ -1181,6 +1181,7 @@ module.exports = FFZ.utils = {
|
|||
return (loyalty ? '.ffz-no-loyalty ' : '') + '.from-display-preview[data-room="' + room_id + '"] .badge.' + badge_id + (loyalty ? '' : '.version-' + version) +
|
||||
(loyalty ? ',.ffz-no-loyalty ' : ',') + '.chat-line[data-room="' + room_id + '"] .badge.' + badge_id + (loyalty ? '' : '.version-' + version) + '{' +
|
||||
'background-color:transparent;' +
|
||||
WEBKIT + 'mask-image: none;' +
|
||||
'background-image:url("' + img_1x + '");' +
|
||||
'background-image:' + WEBKIT + 'image-set(url("' + img_1x + '") 1x' + (img_2x ? ',url("' + img_2x + '") 2x' : '') + (img_4x ? ',url("' + img_4x + '") 4x' : '') + ')}';
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue