mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-06 06:10: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 ?
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue