mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-02 16:08:31 +00:00
3.5.84 to 3.5.100. Most importantly, started using new Ember stuff. -view-registry instead of Ember.View.views, and such. Finally added UI for managing pinned channels. Use HTTPS for the API and socket servers. Don't immediately unload chat rooms. Smarter chat tab behavior. Added /card command for opening mod cards. Other stuff.
This commit is contained in:
parent
c167a8b626
commit
800553c602
28 changed files with 1016 additions and 525 deletions
12
dark.css
12
dark.css
|
@ -3,7 +3,7 @@
|
|||
background-color:rgb(16,16,16)!important;
|
||||
}
|
||||
|
||||
.ffz-dark div#channel > .target-frame.active{
|
||||
.ffz-dark div#channel > .target-frame {
|
||||
background-color:rgb(16,16,16)!important;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,14 @@
|
|||
border-top: 1px solid rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.ffz-dark .offlineChannelStatus {
|
||||
background-color: rgba(255,255,255, 0.05);
|
||||
}
|
||||
|
||||
.ffz-dark .close-hostmode a:before,
|
||||
.ffz-dark .close-hostmode a:after {
|
||||
border-bottom-color: rgba(255,255,255, 0.05);
|
||||
}
|
||||
|
||||
|
||||
/* hidden chat */
|
||||
|
@ -248,7 +256,7 @@
|
|||
.ffz-dark .manager .videos-grid .video:hover .meta .actions li a,
|
||||
.ffz-dark .ember-chat .chat-room-list .room:not(:hover) p.room-title,
|
||||
.ffz-dark .dropmenu_action:not(:hover) span,
|
||||
.ffz-dark a:not(.filter-item):not(.ui-state-focus):not(.button):not(.switch):not(.follow):not(.fb_button) {
|
||||
.ffz-dark a:not(.filter-item):not(.ui-state-focus):not(.button):not(.switch):not(.follow):not(.fb_button):not(.what) {
|
||||
color: #a68ed2;
|
||||
}
|
||||
|
||||
|
|
|
@ -228,9 +228,9 @@ FFZ.prototype.get_line_badges = function(msg) {
|
|||
}
|
||||
}
|
||||
|
||||
if ( msg.labels.indexOf('subscriber') !== -1 )
|
||||
if ( msg.labels && msg.labels.indexOf('subscriber') !== -1 )
|
||||
badges[10] = {klass: 'subscriber', title: 'Subscriber'}
|
||||
if ( msg.labels.indexOf('turbo') !== -1 )
|
||||
if ( msg.labels && msg.labels.indexOf('turbo') !== -1 )
|
||||
badges[15] = {klass: 'turbo', title: 'Turbo'};
|
||||
|
||||
// FFZ Badges
|
||||
|
@ -338,7 +338,7 @@ FFZ.prototype.bttv_badges = function(data) {
|
|||
if ( b.type === full_badge.replaces_type ) {
|
||||
b.type = "ffz-badge-replacement " + b.type;
|
||||
b.description += ", " + (badge.title || full_badge.title) +
|
||||
'" style="background-image: url("' + utils.quote_attr(badge.image || full_badge.image) + '")';
|
||||
'" style="background-image: url(' + utils.quote_attr('"' + (badge.image || full_badge.image) + '"') + ')';
|
||||
replaced = true;
|
||||
break;
|
||||
}
|
||||
|
@ -349,18 +349,18 @@ FFZ.prototype.bttv_badges = function(data) {
|
|||
}
|
||||
|
||||
if ( alpha && badge.transparent_image )
|
||||
style += 'background-image: url("' + utils.quote_attr(badge.transparent_image) + '");';
|
||||
style += 'background-image: url("' + badge.transparent_image + '");';
|
||||
else if ( badge.image )
|
||||
style += 'background-image: url("' + utils.quote_attr(badge.image) + '");';
|
||||
style += 'background-image: url("' + badge.image + '");';
|
||||
|
||||
if ( badge.color && ! alpha )
|
||||
style += 'background-color: ' + utils.quote_attr(badge.color) + '; ';
|
||||
style += 'background-color: ' + badge.color + '; ';
|
||||
|
||||
if ( badge.extra_css )
|
||||
style += utils.quote_attr(badge.extra_css);
|
||||
style += badge.extra_css;
|
||||
|
||||
if ( style )
|
||||
desc += '" style="' + style;
|
||||
desc += '" style="' + utils.quote_attr(style);
|
||||
|
||||
badges_out.push([(insert_at == -1 ? 1 : -1) * slot, {type: "ffz-badge-" + badge.id + (alpha ? " alpha" : ""), name: "", description: desc}]);
|
||||
}
|
||||
|
@ -451,14 +451,17 @@ FFZ.prototype._legacy_load_donors = function(callback, tries) {
|
|||
|
||||
FFZ.prototype._legacy_parse_badges = function(callback, data, slot, badge_id, title_template) {
|
||||
var title = this.badges[badge_id].title,
|
||||
count = 0;
|
||||
count = 0,
|
||||
ds = null;
|
||||
|
||||
title_template = title_template || '{}';
|
||||
|
||||
if ( data != null ) {
|
||||
var lines = data.trim().split(/\W+/);
|
||||
var lines = data.trim().split(/[ \t\n\r]+/);
|
||||
for(var i=0; i < lines.length; i++) {
|
||||
if ( ! /^\w/.test(lines[i]) )
|
||||
continue;
|
||||
|
||||
var line_data = lines[i].split(";"),
|
||||
user_id = line_data[0],
|
||||
user = this.users[user_id] = this.users[user_id] || {},
|
||||
|
@ -471,7 +474,7 @@ FFZ.prototype._legacy_parse_badges = function(callback, data, slot, badge_id, ti
|
|||
if ( badges[slot] )
|
||||
continue;
|
||||
|
||||
badges[slot] = {id:badge_id};
|
||||
badges[slot] = {id: badge_id};
|
||||
if ( line_data.length > 1 )
|
||||
badges[slot].title = title_template.replace('{}', line_data[1]);
|
||||
count += 1;
|
||||
|
|
|
@ -129,9 +129,9 @@ FFZ.prototype.setup_colors = function() {
|
|||
Layout.addObserver("isTheatreMode", this._update_colors.bind(this, true));
|
||||
|
||||
if ( Settings )
|
||||
Settings.addObserver("model.darkMode", this._update_colors.bind(this, true))
|
||||
Settings.addObserver("settings.darkMode", this._update_colors.bind(this, true))
|
||||
|
||||
this._color_old_darkness = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('model.darkMode'));
|
||||
this._color_old_darkness = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('settings.darkMode'));
|
||||
}
|
||||
|
||||
|
||||
|
@ -602,7 +602,7 @@ FFZ.prototype._update_colors = function(darkness_only) {
|
|||
var Layout = window.App && App.__container__.lookup('controller:layout'),
|
||||
Settings = window.App && App.__container__.lookup('controller:settings'),
|
||||
|
||||
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('model.darkMode'));
|
||||
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('settings.darkMode'));
|
||||
|
||||
if ( darkness_only && this._color_old_darkness === is_dark )
|
||||
return;
|
||||
|
|
|
@ -69,6 +69,47 @@ FFZ.ffz_commands.reload = function(room, args) {
|
|||
}
|
||||
|
||||
|
||||
// -----------------
|
||||
// Moderation Cards
|
||||
// -----------------
|
||||
|
||||
FFZ.chat_commands.card = function(room, args) {
|
||||
if ( ! args || ! args.length || args.length > 1 )
|
||||
return "Usage: /card <username>";
|
||||
|
||||
if ( ! this._roomv )
|
||||
return "An error occured. (We don't have the Room View.)";
|
||||
|
||||
// Get the position of the input box.
|
||||
var el = this._roomv.get('element'),
|
||||
ta = el && el.querySelector('textarea'),
|
||||
bounds = ta && ta.getBoundingClientRect(),
|
||||
|
||||
x = 0, y = 0, bottom, right;
|
||||
|
||||
if ( ! bounds )
|
||||
bounds = el && el.getBoundingClientRect() || document.body.getBoundingClientRect();
|
||||
|
||||
if ( bounds ) {
|
||||
if ( bounds.left > 400 ) {
|
||||
right = bounds.left - 40;
|
||||
bottom = bounds.top + bounds.height;
|
||||
} else {
|
||||
x = bounds.left - 20;
|
||||
bottom = bounds.top - 20;
|
||||
}
|
||||
}
|
||||
|
||||
this._roomv.get('controller').send('showModOverlay', {
|
||||
top: y,
|
||||
left: x,
|
||||
bottom: bottom,
|
||||
right: right,
|
||||
sender: args[0]
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// -----------------
|
||||
// Mass Moderation
|
||||
// -----------------
|
||||
|
|
|
@ -2,21 +2,21 @@ var SVGPATH = '<path d="m120.95 1.74c4.08-0.09 8.33-0.84 12.21 0.82 3.61 1.8 7 4
|
|||
|
||||
DEBUG = localStorage.ffzDebugMode == "true" && document.body.classList.contains('ffz-dev'),
|
||||
SERVER = DEBUG ? "//localhost:8000/" : "//cdn.frankerfacez.com/";
|
||||
DIRECT_SERVER = DEBUG ? "//localhost:8000/" : "//direct-cdn.frankerfacez.com/";
|
||||
//DIRECT_SERVER = DEBUG ? "//localhost:8000/" : "//direct-cdn.frankerfacez.com/";
|
||||
|
||||
module.exports = {
|
||||
DEBUG: DEBUG,
|
||||
SERVER: SERVER,
|
||||
DIRECT_SERVER: DIRECT_SERVER,
|
||||
//DIRECT_SERVER: DIRECT_SERVER,
|
||||
|
||||
API_SERVER: "//api.frankerfacez.com/",
|
||||
API_SERVER_2: "//direct-api.frankerfacez.com/",
|
||||
API_SERVER: "https://api.frankerfacez.com/",
|
||||
//API_SERVER_2: "http://direct-api.frankerfacez.com/",
|
||||
|
||||
WS_SERVER_POOLS: {
|
||||
1: [
|
||||
["ws://catbag.frankerfacez.com/", 0.5],
|
||||
["ws://andknuckles.frankerfacez.com/", 1],
|
||||
["ws://tuturu.frankerfacez.com/", 1]],
|
||||
["wss://catbag.frankerfacez.com/", 0.5],
|
||||
["wss://andknuckles.frankerfacez.com/", 1],
|
||||
["wss://tuturu.frankerfacez.com/", 1]],
|
||||
2: [
|
||||
["ws://localhost:8001/", 1]]
|
||||
},
|
||||
|
|
|
@ -38,11 +38,12 @@ FFZ.prototype.setup_channel = function() {
|
|||
} catch(err) { }
|
||||
|
||||
// Update Existing
|
||||
for(var key in Ember.View.views) {
|
||||
if ( ! Ember.View.views.hasOwnProperty(key) )
|
||||
var views = window.App && App.__container__.lookup('-view-registry:main') || Ember.View.views;
|
||||
for(var key in views) {
|
||||
if ( ! views.hasOwnProperty(key) )
|
||||
continue;
|
||||
|
||||
var view = Ember.View.views[key];
|
||||
var view = views[key];
|
||||
if ( !(view instanceof Channel) )
|
||||
continue;
|
||||
|
||||
|
@ -166,8 +167,8 @@ FFZ.prototype.setup_channel = function() {
|
|||
if ( display_name )
|
||||
FFZ.capitalization[name] = [display_name, Date.now()];
|
||||
|
||||
if ( f.settings.group_tabs && f._chatv )
|
||||
f._chatv.ffzRebuildTabs();
|
||||
if ( f._chatv )
|
||||
f._chatv.ffzUpdateHost(target);
|
||||
|
||||
if ( f.settings.follow_buttons )
|
||||
f.rebuild_following_ui();
|
||||
|
|
|
@ -90,24 +90,24 @@ FFZ.settings_info.input_emoji = {
|
|||
// ---------------------
|
||||
|
||||
FFZ.prototype.setup_chat_input = function() {
|
||||
this.log("Hooking the Ember Chat Input controller.");
|
||||
this.log("Hooking the Ember Chat Input component.");
|
||||
var Input = App.__container__.resolve('component:twitch-chat-input'),
|
||||
f = this;
|
||||
|
||||
if ( ! Input )
|
||||
return;
|
||||
return this.log("Unable to get Chat Input component.");
|
||||
|
||||
this._modify_chat_input(Input);
|
||||
|
||||
if ( this._roomv ) {
|
||||
for(var i=0; i < this._roomv._childViews.length; i++) {
|
||||
var v = this._roomv._childViews[i];
|
||||
var views = this._roomv && this._roomv._viewRegistry || window.App && App.__container__.lookup('-view-registry:main') || Ember.View.views;
|
||||
for(var key in views) {
|
||||
var v = views[key];
|
||||
if ( v instanceof Input ) {
|
||||
this.log("Manually modifying Chat Input component.", v);
|
||||
this._modify_chat_input(v);
|
||||
v.ffzInit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -116,6 +116,7 @@ FFZ.prototype._modify_chat_input = function(component) {
|
|||
|
||||
component.reopen({
|
||||
ffz_mru_index: -1,
|
||||
ffz_chatters: [],
|
||||
|
||||
didInsertElement: function() {
|
||||
this._super();
|
||||
|
@ -149,9 +150,6 @@ FFZ.prototype._modify_chat_input = function(component) {
|
|||
|
||||
this.ffzResizeInput();
|
||||
setTimeout(this.ffzResizeInput.bind(this), 500);
|
||||
|
||||
/*var suggestions = this._parentView.get('context.model.chatSuggestions');
|
||||
this.set('ffz_chatters', suggestions);*/
|
||||
},
|
||||
|
||||
ffzTeardown: function() {
|
||||
|
@ -291,7 +289,7 @@ FFZ.prototype._modify_chat_input = function(component) {
|
|||
return;
|
||||
|
||||
var ind = this.get('ffz_mru_index'),
|
||||
mru = this._parentView.get('context.model.mru_list') || [];
|
||||
mru = this.get('parentView.context.model.mru_list') || [];
|
||||
|
||||
if ( key === KEYCODES.UP )
|
||||
ind = (ind + 1) % (mru.length + 1);
|
||||
|
@ -336,7 +334,7 @@ FFZ.prototype._modify_chat_input = function(component) {
|
|||
/*ffz_emoticons: function() {
|
||||
var output = [],
|
||||
|
||||
room = this._parentView.get('context.model'),
|
||||
room = this.get('parentView.context.model'),
|
||||
room_id = room && room.get('id'),
|
||||
tmi = room && room.tmiSession,
|
||||
|
||||
|
@ -349,7 +347,7 @@ FFZ.prototype._modify_chat_input = function(component) {
|
|||
for(var set_id in es.emoticon_sets) {
|
||||
var emote_set = es.emoticon_sets[set_id];
|
||||
for(var emote_id in emote_set) {
|
||||
if ( emote_set[emote_id] ) {
|
||||
if ( emote_set[emote_id] && emote_set[emote_id].code ) {
|
||||
var code = emote_set[emote_id].code;
|
||||
output.push({id: constants.KNOWN_CODES[code] || code});
|
||||
}
|
||||
|
@ -365,7 +363,7 @@ FFZ.prototype._modify_chat_input = function(component) {
|
|||
|
||||
for(var emote_id in emote_set.emoticons) {
|
||||
var emote = emote_set.emoticons[emote_id];
|
||||
if ( ! emote.hidden )
|
||||
if ( ! emote.hidden && emote.name )
|
||||
output.push({id:emote.name});
|
||||
}
|
||||
}
|
||||
|
@ -373,8 +371,6 @@ FFZ.prototype._modify_chat_input = function(component) {
|
|||
return output;
|
||||
}.property(),
|
||||
|
||||
ffz_chatters: [],
|
||||
|
||||
suggestions: function(key, value, previousValue) {
|
||||
if ( arguments.length > 1 ) {
|
||||
this.set('ffz_chatters', value);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -58,8 +58,7 @@ FFZ.prototype.setup_conversations = function() {
|
|||
FFZ.prototype._modify_conversation_window = function(component) {
|
||||
var f = this,
|
||||
|
||||
Layout = App.__container__.lookup('controller:layout'),
|
||||
Settings = App.__container__.lookup('controller:settings');
|
||||
Layout = App.__container__.lookup('controller:layout');
|
||||
|
||||
component.reopen({
|
||||
headerBadges: Ember.computed("thread.participants", "currentUsername", function() {
|
||||
|
@ -106,8 +105,7 @@ FFZ.prototype._modify_conversation_window = function(component) {
|
|||
FFZ.prototype._modify_conversation_line = function(component) {
|
||||
var f = this,
|
||||
|
||||
Layout = App.__container__.lookup('controller:layout'),
|
||||
Settings = App.__container__.lookup('controller:settings');
|
||||
Layout = App.__container__.lookup('controller:layout');
|
||||
|
||||
component.reopen({
|
||||
tokenizedMessage: function() {
|
||||
|
|
|
@ -149,9 +149,11 @@ FFZ.prototype.setup_directory = function() {
|
|||
document.body.classList.toggle('ffz-creative-tags', this.settings.directory_creative_all_tags);
|
||||
document.body.classList.toggle('ffz-creative-showcase', this.settings.directory_creative_showcase);
|
||||
|
||||
this.log("Hooking the Ember games-following controller.");
|
||||
var GamesFollowing = App.__container__.lookup('controller:games-following');
|
||||
var GamesFollowing = App.__container__.lookup('controller:games-following'),
|
||||
f = this;
|
||||
|
||||
if ( GamesFollowing ) {
|
||||
this.log("Hooking the Ember games-following controller.");
|
||||
GamesFollowing.reopen({
|
||||
ffz_sidebar_games: this.settings.sidebar_followed_games,
|
||||
|
||||
|
@ -164,7 +166,8 @@ FFZ.prototype.setup_directory = function() {
|
|||
});
|
||||
|
||||
Ember.propertyDidChange(GamesFollowing, 'sidePanelFollowing');
|
||||
}
|
||||
} else
|
||||
this.error("Unable to load the Ember games-following controller.");
|
||||
|
||||
|
||||
this.log("Attempting to modify the Following collection.");
|
||||
|
@ -189,8 +192,9 @@ FFZ.prototype.setup_directory = function() {
|
|||
this._modify_directory_host(HostView);
|
||||
|
||||
// Initialize existing views.
|
||||
for(var key in Ember.View.views) {
|
||||
var view = Ember.View.views[key];
|
||||
var views = window.App && App.__container__.lookup('-view-registry:main') || Ember.View.views;
|
||||
for(var key in views) {
|
||||
var view = views[key];
|
||||
try {
|
||||
if ( (ChannelView && view instanceof ChannelView) || (CreativeChannel && view instanceof CreativeChannel) || (CSGOChannel && view instanceof CSGOChannel) || (HostView && view instanceof HostView) )
|
||||
view.ffzInit();
|
||||
|
@ -469,10 +473,20 @@ FFZ.prototype._modify_directory_host = function(dir) {
|
|||
for(var i=0; i < hosts.length; i++)
|
||||
make_link(hosts[i]);
|
||||
|
||||
f.show_popup(menu, [e.clientX - 60, e.clientY - 60], document.querySelector('#main_col > .tse-scroll-content > .tse-content'));
|
||||
var cont = document.querySelector('#main_col > .tse-scroll-content > .tse-content'),
|
||||
bounds = cont && cont.getBoundingClientRect(),
|
||||
|
||||
x = e.clientX - 60,
|
||||
y = e.clientY - 60;
|
||||
|
||||
if ( bounds )
|
||||
x = Math.max(bounds.left, Math.min(x, (bounds.left + bounds.width) - 302));
|
||||
|
||||
f.show_popup(menu, [x, y], document.querySelector('#main_col > .tse-scroll-content > .tse-content'));
|
||||
},
|
||||
|
||||
ffzCleanup: function() {
|
||||
var target = this.get('context.model.target.channel');
|
||||
if ( f._popup && f._popup.classList.contains('ffz-channel-selector') && f._popup.getAttribute('data-channel') === target )
|
||||
f.close_popup();
|
||||
},
|
||||
|
@ -485,7 +499,41 @@ FFZ.prototype._modify_directory_host = function(dir) {
|
|||
title = meta && meta.querySelector('.title a'),
|
||||
|
||||
target = this.get('context.model.target.channel'),
|
||||
hosts = this.get('context.model.ffz_hosts');
|
||||
hosts = this.get('context.model.ffz_hosts'),
|
||||
|
||||
boxart = thumb && thumb.querySelector('.boxart');
|
||||
|
||||
|
||||
// Fix the game not showing
|
||||
if ( ! boxart && thumb && this.get('context.model.game') ) {
|
||||
var img = document.createElement('img'),
|
||||
game = this.get("context.model.game"),
|
||||
c = this.get('controller');
|
||||
|
||||
boxart = document.createElement('a');
|
||||
boxart.className = 'boxart';
|
||||
boxart.href = this.get("context.model.gameUrl");
|
||||
boxart.setAttribute('original-title', game);
|
||||
|
||||
boxart.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
jQuery('.tipsy').remove();
|
||||
|
||||
if ( game === "Counter-Strike: Global Offensive" )
|
||||
c.transitionTo('csgo.channels.index')
|
||||
else if ( game === "Creative" )
|
||||
c.transitionTo('creative.channels.index');
|
||||
else
|
||||
c.transitionTo('gameDirectory.index', encodeURIComponent(game));
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
img.src = this.get("context.model.gameBoxart");
|
||||
boxart.appendChild(img);
|
||||
thumb.appendChild(boxart);
|
||||
}
|
||||
|
||||
|
||||
if ( f.settings.directory_logos ) {
|
||||
el.classList.add('ffz-directory-logo');
|
||||
|
|
|
@ -71,7 +71,7 @@ FFZ.prototype.setup_profile_following = function() {
|
|||
ffzInit: function() {
|
||||
// Only process our own profile following page.
|
||||
var user = f.get_user();
|
||||
if ( ! f.settings.enhance_profile_following || ! user || ! user.login === this.get('context.id') )
|
||||
if ( ! f.settings.enhance_profile_following || ! user || user.login !== this.get('context.id') )
|
||||
return;
|
||||
|
||||
var el = this.get('element'),
|
||||
|
@ -259,8 +259,9 @@ FFZ.prototype.setup_profile_following = function() {
|
|||
ProfileView.create().destroy();
|
||||
} catch(err) { }
|
||||
|
||||
for(var key in Ember.View.views) {
|
||||
var view = Ember.View.views[key];
|
||||
var views = window.App && App.__container__.lookup('-view-registry:main') || Ember.View.views;
|
||||
for(var key in views) {
|
||||
var view = views[key];
|
||||
if ( ! view || !(view instanceof ProfileView) )
|
||||
continue;
|
||||
|
||||
|
|
|
@ -671,7 +671,7 @@ FFZ.prototype._modify_line = function(component) {
|
|||
raw_color = this.get('msgObject.color'),
|
||||
colors = raw_color && f._handle_color(raw_color),
|
||||
|
||||
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('model.darkMode'));
|
||||
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('settings.darkMode'));
|
||||
|
||||
|
||||
e.push('<div class="indicator"></div>');
|
||||
|
|
|
@ -399,7 +399,10 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
Card.reopen({
|
||||
ffzForceRedraw: function() {
|
||||
this.rerender();
|
||||
}.observes("cardInfo.isModeratorOrHigher", "cardInfo.user"),
|
||||
if ( f.settings.mod_card_history )
|
||||
this.ffzRenderHistory();
|
||||
|
||||
}.observes("cardInfo.isModeratorOrHigher", "cardInfo.user.id"),
|
||||
|
||||
ffzRebuildInfo: function() {
|
||||
var el = this.get('element'),
|
||||
|
@ -730,19 +733,68 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
|
||||
|
||||
// Message History
|
||||
if ( f.settings.mod_card_history ) {
|
||||
var Chat = App.__container__.lookup('controller:chat'),
|
||||
if ( f.settings.mod_card_history )
|
||||
this.ffzRenderHistory();
|
||||
|
||||
// Reposition the menu if it's off-screen.
|
||||
var el_bound = el.getBoundingClientRect(),
|
||||
body_bound = document.body.getBoundingClientRect(),
|
||||
|
||||
renderBottom = this.get('cardInfo.renderBottom'),
|
||||
renderRight = this.get('cardInfo.renderRight');
|
||||
|
||||
if ( renderRight ) {
|
||||
var offset = (el_bound.left + el_bound.width) - renderRight;
|
||||
el.style.left = (el_bound.left - offset) + "px";
|
||||
}
|
||||
|
||||
if ( renderBottom ) {
|
||||
var offset = el_bound.bottom - renderBottom;
|
||||
el.style.top = (el_bound.top - offset) + "px";
|
||||
|
||||
} else if ( el_bound.bottom > body_bound.bottom ) {
|
||||
var offset = el_bound.bottom - body_bound.bottom;
|
||||
if ( el_bound.top - offset > body_bound.top )
|
||||
el.style.top = (el_bound.top - offset) + "px";
|
||||
}
|
||||
|
||||
// Focus the Element
|
||||
this.$().draggable({
|
||||
start: function() {
|
||||
el.focus();
|
||||
}});
|
||||
|
||||
el.focus();
|
||||
|
||||
} catch(err) {
|
||||
try {
|
||||
f.error("ModerationCardView didInsertElement: " + err);
|
||||
} catch(err) { }
|
||||
}
|
||||
},
|
||||
|
||||
ffzRenderHistory: function() {
|
||||
var t = this,
|
||||
Chat = App.__container__.lookup('controller:chat'),
|
||||
room = Chat && Chat.get('currentRoom'),
|
||||
delete_links = room && room.get('roomProperties.hide_chat_links'),
|
||||
tmiSession = room.tmiSession || (window.TMI && TMI._sessions && TMI._sessions[0]),
|
||||
room_id = room.get('id'),
|
||||
user_id = controller.get('cardInfo.user.id'),
|
||||
user_id = this.get('cardInfo.user.id'),
|
||||
ffz_room = room && f.rooms && f.rooms[room_id],
|
||||
user_history = ffz_room && ffz_room.user_history && ffz_room.user_history[user_id] || [],
|
||||
el = this.get('element'),
|
||||
|
||||
history = el && el.querySelector('.chat-history');
|
||||
|
||||
if ( ! history ) {
|
||||
history = document.createElement('ul');
|
||||
|
||||
history.className = 'interface clearfix chat-history';
|
||||
el.appendChild(history);
|
||||
} else {
|
||||
history.classList.remove('loading');
|
||||
history.innerHTML = '';
|
||||
}
|
||||
|
||||
if ( user_history.length < 50 ) {
|
||||
var before = (user_history.length > 0 ? user_history[0].date.getTime() : Date.now()) - (f._ws_server_offset || 0);
|
||||
|
@ -787,40 +839,12 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
for(var i=0; i < user_history.length; i++)
|
||||
history.appendChild(f._build_mod_card_history(user_history[i], t));
|
||||
|
||||
el.appendChild(history);
|
||||
|
||||
// Lazy scroll-to-bottom
|
||||
history.scrollTop = history.scrollHeight;
|
||||
}
|
||||
|
||||
// Reposition the menu if it's off-screen.
|
||||
var el_bound = el.getBoundingClientRect(),
|
||||
body_bound = document.body.getBoundingClientRect();
|
||||
|
||||
if ( el_bound.bottom > body_bound.bottom ) {
|
||||
var offset = el_bound.bottom - body_bound.bottom;
|
||||
if ( el_bound.top - offset > body_bound.top )
|
||||
el.style.top = (el_bound.top - offset) + "px";
|
||||
}
|
||||
|
||||
// Focus the Element
|
||||
this.$().draggable({
|
||||
start: function() {
|
||||
el.focus();
|
||||
}});
|
||||
|
||||
el.focus();
|
||||
|
||||
} catch(err) {
|
||||
try {
|
||||
f.error("ModerationCardView didInsertElement: " + err);
|
||||
} catch(err) { }
|
||||
}
|
||||
},
|
||||
|
||||
ffzAdjacentHistory: function(line) {
|
||||
var Chat = App.__container__.lookup('controller:chat'),
|
||||
controller = this.get('controller'),
|
||||
t = this,
|
||||
|
||||
user_id = this.get('cardInfo.user.id'),
|
||||
|
@ -835,23 +859,31 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
history = el && el.querySelector('.chat-history'),
|
||||
logs = el && el.querySelector('.chat-history.adjacent-history'),
|
||||
|
||||
when = line.date.getTime();
|
||||
when = line.date.getTime(),
|
||||
scroll_top = logs && logs.scrollTop || history && history.scrollTop || 0;
|
||||
|
||||
if ( ! history )
|
||||
return;
|
||||
|
||||
if ( logs )
|
||||
if ( logs ) {
|
||||
logs.classList.add('loading');
|
||||
else
|
||||
logs.scrollTop = 0;
|
||||
} else {
|
||||
history.classList.add('loading');
|
||||
history.scrollTop = 0;
|
||||
}
|
||||
|
||||
if ( ! f.ws_send("adjacent_history", [room_id, when, 2], function(success, data) {
|
||||
if ( logs )
|
||||
var was_loading = history.classList.contains('loading');
|
||||
if ( logs ) {
|
||||
logs.classList.remove('loading');
|
||||
else
|
||||
logs.scrollTop = scroll_top;
|
||||
} else {
|
||||
history.classList.remove('loading');
|
||||
history.scrollTop = scroll_top;
|
||||
}
|
||||
|
||||
if ( ! success || ! data || ! data.length )
|
||||
if ( ! success || ! data || ! data.length || ! was_loading )
|
||||
return;
|
||||
|
||||
var had_logs = false,
|
||||
|
@ -908,10 +940,13 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
});
|
||||
|
||||
}) )
|
||||
if ( logs )
|
||||
if ( logs ) {
|
||||
logs.classList.remove('loading');
|
||||
else
|
||||
logs.scrollTop = scroll_top;
|
||||
} else {
|
||||
history.classList.remove('loading');
|
||||
history.scrollTop = scroll_top;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -928,6 +963,9 @@ FFZ.prototype._build_mod_card_history = function(msg, modcard, show_from) {
|
|||
out.push('<span class="timestamp float-left">' + helpers.getTime(msg.date) + '</span>');
|
||||
|
||||
|
||||
var alias = this.aliases[msg.from],
|
||||
name = (msg.tags && msg.tags['display-name']) || (msg.from && msg.from.capitalize()) || "unknown user";
|
||||
|
||||
if ( show_from ) {
|
||||
// Badges
|
||||
out.push('<span class="badges float-left">');
|
||||
|
@ -942,13 +980,11 @@ FFZ.prototype._build_mod_card_history = function(msg, modcard, show_from) {
|
|||
Layout = App.__container__.lookup('controller:layout'),
|
||||
Settings = App.__container__.lookup('controller:settings'),
|
||||
|
||||
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('model.darkMode'));
|
||||
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('settings.darkMode'));
|
||||
|
||||
|
||||
// Aliases and Styling
|
||||
var alias = this.aliases[msg.from],
|
||||
name = (msg.tags && msg.tags['display-name']) || (msg.from && msg.from.capitalize()) || "unknown user",
|
||||
style = colors && 'color:' + (is_dark ? colors[1] : colors[0]),
|
||||
var style = colors && 'color:' + (is_dark ? colors[1] : colors[0]),
|
||||
colored = style ? ' has-color' : '';
|
||||
|
||||
|
||||
|
|
|
@ -72,11 +72,12 @@ FFZ.prototype.setup_player = function() {
|
|||
if ( ! window.Ember )
|
||||
return;
|
||||
|
||||
for(var key in Ember.View.views) {
|
||||
if ( ! Ember.View.views.hasOwnProperty(key) )
|
||||
var views = window.App && App.__container__.lookup('-view-registry:main') || Ember.View.views;
|
||||
for(var key in views) {
|
||||
if ( ! views.hasOwnProperty(key) )
|
||||
continue;
|
||||
|
||||
var view = Ember.View.views[key];
|
||||
var view = views[key];
|
||||
if ( !(view instanceof Player2) )
|
||||
continue;
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
var FFZ = window.FrankerFaceZ,
|
||||
CSS = /\.([\w\-_]+)\s*?\{content:\s*?"([^"]+)";\s*?background-image:\s*?url\("([^"]+)"\);\s*?height:\s*?(\d+)px;\s*?width:\s*?(\d+)px;\s*?margin:([^;}]+);?([^}]*)\}/mg,
|
||||
MOD_CSS = /[^\n}]*\.badges\s+\.moderator\s*{\s*background-image:\s*url\(\s*['"]([^'"]+)['"][^}]+(?:}|$)/,
|
||||
GROUP_CHAT = /^_([^_]+)_\d+$/,
|
||||
HOSTED_SUB = / subscribed to /,
|
||||
constants = require('../constants'),
|
||||
utils = require('../utils'),
|
||||
|
@ -58,6 +55,35 @@ FFZ.prototype.setup_room = function() {
|
|||
this.get("model.tmiRoom").sendMessage("/timeout " + e.user + " 1");
|
||||
this.get("model").clearMessages(e.user);
|
||||
}
|
||||
|
||||
RC._actions.showModOverlay = function(e) {
|
||||
var Channel = App.__container__.resolve('model:channel');
|
||||
if ( ! Channel )
|
||||
return;
|
||||
|
||||
var chan = Channel.find({id: e.sender});
|
||||
|
||||
// Don't try loading the channel if it's already loaded. Don't make mod cards
|
||||
// refresh the channel page when you click the broadcaster, basically.
|
||||
if ( ! chan.get('isLoaded') )
|
||||
chan.load();
|
||||
|
||||
this.set("showModerationCard", true);
|
||||
|
||||
// We pass in renderBottom and renderRight, which we use to reposition the window
|
||||
// after we know how big it actually is.
|
||||
this.set("moderationCardInfo", {
|
||||
user: chan,
|
||||
renderTop: e.top,
|
||||
renderLeft: e.left,
|
||||
renderBottom: e.bottom,
|
||||
renderRight: e.right,
|
||||
isIgnored: this.get("tmiSession").isIgnored(e.sender),
|
||||
isChannelOwner: this.get("controllers.login.userData.login") === e.sender,
|
||||
profileHref: Twitch.uri.profile(e.sender),
|
||||
isModeratorOrHigher: this.get("model.isModeratorOrHigher")
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.log("Hooking the Ember Room model.");
|
||||
|
@ -90,11 +116,12 @@ FFZ.prototype.setup_room = function() {
|
|||
} catch(err) { }
|
||||
|
||||
// Modify all existing Room views.
|
||||
for(var key in Ember.View.views) {
|
||||
if ( ! Ember.View.views.hasOwnProperty(key) )
|
||||
var views = window.App && App.__container__.lookup('-view-registry:main') || Ember.View.views;
|
||||
for(var key in views) {
|
||||
if ( ! views.hasOwnProperty(key) )
|
||||
continue;
|
||||
|
||||
var view = Ember.View.views[key];
|
||||
var view = views[key];
|
||||
if ( !(view instanceof RoomView) )
|
||||
continue;
|
||||
|
||||
|
@ -834,7 +861,7 @@ FFZ.prototype._insert_history = function(room_id, data, from_server) {
|
|||
|
||||
FFZ.prototype.load_room = function(room_id, callback, tries) {
|
||||
var f = this;
|
||||
jQuery.getJSON(((tries||0)%2 === 0 ? constants.API_SERVER : constants.API_SERVER_2) + "v1/room/" + room_id)
|
||||
jQuery.getJSON(constants.API_SERVER + "v1/room/" + room_id)
|
||||
.done(function(data) {
|
||||
if ( data.sets ) {
|
||||
for(var key in data.sets)
|
||||
|
@ -935,6 +962,28 @@ FFZ.prototype._modify_room = function(room) {
|
|||
}
|
||||
},
|
||||
|
||||
ffzScheduleDestroy: function() {
|
||||
if ( this._ffz_destroy_timer )
|
||||
return;
|
||||
|
||||
var t = this;
|
||||
this._ffz_destroy_timer = setTimeout(function() {
|
||||
t._ffz_destroy_timer = null;
|
||||
t.ffzCheckDestroy();
|
||||
}, 5000);
|
||||
},
|
||||
|
||||
ffzCheckDestroy: function() {
|
||||
var Chat = App.__container__.lookup('controller:chat'),
|
||||
user = f.get_user(),
|
||||
room_id = this.get('id');
|
||||
|
||||
if ( (Chat && Chat.get('currentChannelRoom') === this) || (user && user.login === room_id) || (f._chatv && f._chatv._ffz_host === room_id) || (f.settings.pinned_rooms && f.settings.pinned_rooms.indexOf(room_id) !== -1) )
|
||||
return;
|
||||
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
ffzUpdateStatus: function() {
|
||||
if ( f._roomv )
|
||||
f._roomv.ffzUpdateStatus();
|
||||
|
@ -1089,7 +1138,14 @@ FFZ.prototype._modify_room = function(room) {
|
|||
this.get("messages").pushObject(msg);
|
||||
this.trimMessages();
|
||||
|
||||
"admin" === msg.style || ("whisper" === msg.style && ! this.ffz_whisper_room ) || this.incrementProperty("unreadCount", 1);
|
||||
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);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1102,9 +1158,6 @@ FFZ.prototype._modify_room = function(room) {
|
|||
if ( this._ffz_pending_flush )
|
||||
return;
|
||||
|
||||
/*if ( this._ffz_pending_flush )
|
||||
clearTimeout(this._ffz_pending_flush);*/
|
||||
|
||||
if ( this.ffzPending && this.ffzPending.length ) {
|
||||
// We need either the amount of chat delay past the first message, if chat_delay is on, or the
|
||||
// amount of time from the last batch.
|
||||
|
@ -1258,10 +1311,9 @@ FFZ.prototype._modify_room = function(room) {
|
|||
},
|
||||
|
||||
send: function(text, ignore_history) {
|
||||
if ( f.settings.group_tabs && f.settings.whisper_room && this.ffz_whisper_room )
|
||||
return;
|
||||
|
||||
try {
|
||||
this.ffz_last_input = Date.now();
|
||||
|
||||
if ( text && ! ignore_history ) {
|
||||
// Command History
|
||||
var mru = this.get('mru_list'),
|
||||
|
@ -1294,16 +1346,13 @@ FFZ.prototype._modify_room = function(room) {
|
|||
},
|
||||
|
||||
ffzUpdateUnread: function() {
|
||||
if ( f.settings.group_tabs ) {
|
||||
var Chat = App.__container__.lookup('controller:chat');
|
||||
if ( Chat && Chat.get('currentRoom') === this )
|
||||
this.resetUnreadCount();
|
||||
else if ( f._chatv )
|
||||
f._chatv.ffzTabUnread(this.get('id'));
|
||||
}
|
||||
f._chatv.ffzUpdateUnread(this.get('id'));
|
||||
}.observes('unreadCount'),
|
||||
|
||||
|
||||
ffzInitChatterCount: function() {
|
||||
if ( ! this.tmiRoom )
|
||||
return;
|
||||
|
|
|
@ -21,12 +21,28 @@ FFZ.settings_info.sort_viewers = {
|
|||
|
||||
FFZ.prototype.setup_viewers = function() {
|
||||
this.log("Hooking the Ember Viewers controller.");
|
||||
|
||||
var Viewers = App.__container__.resolve('controller:viewers');
|
||||
if ( Viewers )
|
||||
this._modify_viewers(Viewers);
|
||||
|
||||
/* Disable for now because Twitch reverted this change
|
||||
this.log("Hooking the Ember Viewers view.");
|
||||
var ViewerView = App.__container__.resolve('view:viewers');
|
||||
if ( ViewerView )
|
||||
this._modify_viewer_view(ViewerView);*/
|
||||
}
|
||||
|
||||
|
||||
/*FFZ.prototype._modify_viewer_view = function(view) {
|
||||
view.reopen({
|
||||
setListDimensions: function(e) {
|
||||
// Don't set the stupid scroll thing. Don't use the stupid height thing.
|
||||
this.$(".js-chatters-container").width(e.width).height(e.height);
|
||||
}
|
||||
});
|
||||
}*/
|
||||
|
||||
|
||||
FFZ.prototype._modify_viewers = function(controller) {
|
||||
var f = this;
|
||||
|
||||
|
@ -55,7 +71,7 @@ FFZ.prototype._modify_viewers = function(controller) {
|
|||
|
||||
// If the current room isn't the channel's chat, then we shouldn't
|
||||
// display them as the broadcaster.
|
||||
if ( room_id != broadcaster )
|
||||
if ( room_id !== broadcaster )
|
||||
broadcaster = null;
|
||||
|
||||
// Now, break the viewer array down into something we can use.
|
||||
|
|
|
@ -372,7 +372,7 @@ FFZ.prototype.load_emoji_data = function(callback, tries) {
|
|||
|
||||
FFZ.prototype.load_global_sets = function(callback, tries) {
|
||||
var f = this;
|
||||
jQuery.getJSON(((tries||0)%2 === 0 ? constants.API_SERVER : constants.API_SERVER_2) + "v1/set/global")
|
||||
jQuery.getJSON(constants.API_SERVER + "v1/set/global")
|
||||
.done(function(data) {
|
||||
f.default_sets = data.default_sets;
|
||||
var gs = f.global_sets = [],
|
||||
|
@ -409,7 +409,7 @@ FFZ.prototype.load_global_sets = function(callback, tries) {
|
|||
|
||||
FFZ.prototype.load_set = function(set_id, callback, tries) {
|
||||
var f = this;
|
||||
jQuery.getJSON(((tries||0)%2 === 0 ? constants.API_SERVER : constants.API_SERVER_2) + "v1/set/" + set_id)
|
||||
jQuery.getJSON(constants.API_SERVER + "v1/set/" + set_id)
|
||||
.done(function(data) {
|
||||
f._load_set_json(set_id, callback, data && data.set);
|
||||
|
||||
|
|
|
@ -86,14 +86,14 @@ API.prototype.log = function(msg, data, to_json, log_json) {
|
|||
|
||||
API.prototype._load_set = function(real_id, set_id, data) {
|
||||
if ( ! data )
|
||||
return false;
|
||||
return null;
|
||||
|
||||
// Check for an existing set to copy the users.
|
||||
var users = [];
|
||||
if ( this.emote_sets[real_id] && this.emote_sets[real_id].users )
|
||||
users = this.emote_sets[real_id].users;
|
||||
|
||||
var set = {
|
||||
var emote_set = {
|
||||
source: this.name,
|
||||
source_ext: this.id,
|
||||
source_id: set_id,
|
||||
|
@ -108,14 +108,14 @@ API.prototype._load_set = function(real_id, set_id, data) {
|
|||
title: data.title || "Global Emoticons",
|
||||
};
|
||||
|
||||
this.emote_sets[real_id] = set;
|
||||
this.emote_sets[real_id] = emote_set;
|
||||
|
||||
if ( this.ffz.emote_sets )
|
||||
this.ffz.emote_sets[real_id] = set;
|
||||
this.ffz.emote_sets[real_id] = emote_set;
|
||||
|
||||
var output_css = "",
|
||||
ems = data.emoticons,
|
||||
emoticons = set.emoticons;
|
||||
emoticons = emote_set.emoticons;
|
||||
|
||||
for(var i=0; i < ems.length; i++) {
|
||||
var emote = ems[i],
|
||||
|
@ -158,15 +158,17 @@ API.prototype._load_set = function(real_id, set_id, data) {
|
|||
new_emote.regex = emote.regex;
|
||||
else if ( typeof emote.name !== "string" )
|
||||
new_emote.regex = emote.name;
|
||||
else if ( emote_set.require_spaces || emote.require_spaces )
|
||||
new_emote.regex = new RegExp("(^| )(" + utils.escape_regex(emote.name) + ")(?= |$)", "g");
|
||||
else
|
||||
new_emote.regex = new RegExp("(^|\\W|\\b)(" + utils.escape_regex(emote.name) + ")(?=\\W|$)", "g");
|
||||
|
||||
output_css += build_css(new_emote);
|
||||
set.count++;
|
||||
emote_set.count++;
|
||||
emoticons[id] = new_emote;
|
||||
}
|
||||
|
||||
utils.update_css(this.ffz._emote_style, real_id, output_css + (set.css || ""));
|
||||
utils.update_css(this.ffz._emote_style, real_id, output_css + (emote_set.css || ""));
|
||||
|
||||
if ( this.ffz._cindex )
|
||||
this.ffz._cindex.ffzFixTitle();
|
||||
|
@ -175,7 +177,7 @@ API.prototype._load_set = function(real_id, set_id, data) {
|
|||
this.ffz.update_ui_link();
|
||||
} catch(err) { }
|
||||
|
||||
return set;
|
||||
return emote_set;
|
||||
}
|
||||
|
||||
|
||||
|
@ -223,7 +225,7 @@ API.prototype.unload_set = function(id) {
|
|||
if ( ! room )
|
||||
continue;
|
||||
|
||||
ind = room.ext_sets.indexOf(exact_id);
|
||||
var ind = room.ext_sets.indexOf(exact_id);
|
||||
if ( ind !== -1 )
|
||||
room.ext_sets.splice(ind,1);
|
||||
}
|
||||
|
@ -232,7 +234,7 @@ API.prototype.unload_set = function(id) {
|
|||
}
|
||||
|
||||
|
||||
return set;
|
||||
return emote_set;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -43,10 +43,16 @@ FFZ.prototype.setup_bttv = function(delay) {
|
|||
}
|
||||
|
||||
// Disable Chat Tabs
|
||||
if ( this.settings.group_tabs && this._chatv ) {
|
||||
if ( this._chatv ) {
|
||||
if ( this.settings.group_tabs )
|
||||
this._chatv.ffzDisableTabs();
|
||||
|
||||
this._chatv.ffzTeardownMenu();
|
||||
this._chatv.ffzUnloadHost();
|
||||
}
|
||||
|
||||
this.disconnect_extra_chat();
|
||||
|
||||
if ( this._roomv ) {
|
||||
// Disable Chat Pause
|
||||
if ( this.settings.chat_hover_pause )
|
||||
|
|
|
@ -47,6 +47,26 @@ FFZ.prototype.setup_rechat = function() {
|
|||
FFZ.prototype.find_rechat = function() {
|
||||
var el = !this.has_bttv ? document.querySelector('.rechat-chat-line') : null;
|
||||
|
||||
if ( ! this._rechat_listening && ! el ) {
|
||||
// Try darkening a chat container. We don't have chat.
|
||||
var container = document.querySelector('.chat-container'),
|
||||
header = container && container.querySelector('.chat-header');
|
||||
|
||||
if ( header && header.textContent.indexOf('ReChat') !== -1 ) {
|
||||
// Look-up dark mode.
|
||||
var dark_chat = this.settings.dark_twitch;
|
||||
if ( ! dark_chat ) {
|
||||
var model = window.App ? App.__container__.lookup('controller:settings').get('model') : undefined;
|
||||
dark_chat = model && model.get('darkMode');
|
||||
}
|
||||
|
||||
container.classList.toggle('dark', dark_chat);
|
||||
jQuery(container).find('.chat-lines').addClass('ffz-scrollbar');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// If there's no change, don't continue.
|
||||
if ( !!el === this._rechat_listening )
|
||||
return;
|
||||
|
@ -128,7 +148,7 @@ FFZ.prototype.process_rechat_line = function(line, reprocess) {
|
|||
|
||||
Layout = App.__container__.lookup('controller:layout'),
|
||||
Settings = App.__container__.lookup('controller:settings'),
|
||||
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('model.darkMode')),
|
||||
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('settings.darkMode')),
|
||||
|
||||
badges_el = line.querySelector('.badges'),
|
||||
from_el = line.querySelector('.from'),
|
||||
|
@ -196,7 +216,7 @@ FFZ.prototype.process_rechat_line = function(line, reprocess) {
|
|||
if ( ! message_el )
|
||||
return;
|
||||
|
||||
if ( ! reprocess && message_el.style.color ) {
|
||||
if ( ! reprocess && colors && message_el.style.color ) {
|
||||
message_el.classList.add('has-color');
|
||||
message_el.style.color = is_dark ? colors[1] : colors[0];
|
||||
}
|
||||
|
|
10
src/main.js
10
src/main.js
|
@ -22,7 +22,7 @@ FFZ.get = function() { return FFZ.instance; }
|
|||
|
||||
// Version
|
||||
var VER = FFZ.version_info = {
|
||||
major: 3, minor: 5, revision: 83,
|
||||
major: 3, minor: 5, revision: 100,
|
||||
toString: function() {
|
||||
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
||||
}
|
||||
|
@ -333,10 +333,18 @@ FFZ.prototype.init_ember = function(delay) {
|
|||
|
||||
this.users = {};
|
||||
this.is_dashboard = false;
|
||||
|
||||
try {
|
||||
this.embed_in_dash = window.top !== window && /\/[^\/]+\/dashboard/.test(window.top.location.pathname) && !/bookmarks$/.test(window.top.location.pathname);
|
||||
} catch(err) { this.embed_in_dash = false; }
|
||||
|
||||
|
||||
// Make an alias so they STOP RENAMING THIS ON ME
|
||||
var Settings = App.__container__.lookup('controller:settings');
|
||||
if ( Settings && Settings.get('settings') === undefined )
|
||||
Settings.reopen({settings: Ember.computed.alias('model')});
|
||||
|
||||
|
||||
// Initialize all the modules.
|
||||
this.load_settings();
|
||||
|
||||
|
|
|
@ -357,7 +357,7 @@ FFZ.prototype.ws_ping = function() {
|
|||
return;
|
||||
|
||||
this._ws_ping_time = window.performance ? performance.now() : Date.now();
|
||||
if ( ! this.ws_send("ping", null, this._ws_on_pong.bind(this)) )
|
||||
if ( ! this.ws_send("ping", undefined, this._ws_on_pong.bind(this)) )
|
||||
this._ws_ping_time = null;
|
||||
}
|
||||
|
||||
|
|
|
@ -449,11 +449,21 @@ FFZ.prototype.tokenize_chat_line = function(msgObject, prevent_notification, del
|
|||
// We have a mention!
|
||||
msgObject.ffz_has_mention = true;
|
||||
|
||||
// If we have chat tabs, update the status.
|
||||
if ( room_id && ! this.has_bttv && this.settings.group_tabs && this._chatv && this._chatv._ffz_tabs ) {
|
||||
var el = this._chatv._ffz_tabs.querySelector('.ffz-chat-tab[data-room="' + room_id + '"]');
|
||||
if ( el && ! el.classList.contains('active') )
|
||||
el.classList.add('tab-mentioned');
|
||||
// If we have chat tabs/rows, update the status.
|
||||
if ( room_id && ! this.has_bttv && this._chatv ) {
|
||||
var room = this.rooms[room_id] && this.rooms[room_id].room;
|
||||
if ( room._ffz_tab && ! room._ffz_tab.classList.contains('active') ) {
|
||||
room._ffz_tab.classList.add('tab-mentioned');
|
||||
var was_hidden = room._ffz_tab.classList.contains('hidden');
|
||||
|
||||
if ( was_hidden ) {
|
||||
room._ffz_tab.classList.remove('hidden');
|
||||
this._chatv.$('.chat-room').css('top', this._chatv._ffz_tabs.offsetHeight + "px");
|
||||
}
|
||||
}
|
||||
|
||||
if ( room._ffz_row && ! room._ffz_row.classList.contains('active') )
|
||||
room._ffz_row.classList.add('row-mentioned');
|
||||
}
|
||||
|
||||
// Display notifications if that setting is enabled. Also make sure
|
||||
|
@ -601,7 +611,7 @@ FFZ.prototype.render_tokens = function(tokens, render_links) {
|
|||
}
|
||||
|
||||
//var mirror_url = utils.quote_attr(constants.EMOTE_MIRROR_BASE + id + '.png');
|
||||
extra = ' data-emote="' + id + '"'; // onerror="FrankerFaceZ._emote_mirror_swap(this)"'; // Disable error checking for now.
|
||||
extra = ' data-emote="' + id + '" onerror="FrankerFaceZ._emote_mirror_swap(this)"'; // Disable error checking for now.
|
||||
|
||||
if ( ! constants.EMOTE_REPLACEMENTS[id] )
|
||||
srcset = utils.build_srcset(id);
|
||||
|
|
|
@ -136,14 +136,15 @@ FFZ.settings_info.dark_twitch = {
|
|||
|
||||
document.body.classList.toggle("ffz-dark", val);
|
||||
|
||||
var model = window.App ? App.__container__.lookup('controller:settings').get('model') : undefined;
|
||||
var Settings = window.App && App.__container__.lookup('controller:settings'),
|
||||
settings = Settings.get('settings');
|
||||
|
||||
if ( val ) {
|
||||
this._load_dark_css();
|
||||
model && this.settings.set('twitch_chat_dark', model.get('darkMode'));
|
||||
model && model.set('darkMode', true);
|
||||
settings && this.settings.set('twitch_chat_dark', settings.get('darkMode'));
|
||||
settings && settings.set('darkMode', true);
|
||||
} else
|
||||
model && model.set('darkMode', this.settings.twitch_chat_dark);
|
||||
settings && settings.set('darkMode', this.settings.twitch_chat_dark);
|
||||
|
||||
// Try coloring ReChat
|
||||
jQuery('.rechat-chat-line').parents('.chat-container').toggleClass('dark', val || this.settings.twitch_chat_dark);
|
||||
|
@ -199,7 +200,16 @@ FFZ.prototype.setup_dark = function() {
|
|||
if ( ! this.settings.dark_twitch )
|
||||
return;
|
||||
|
||||
window.App && App.__container__.lookup('controller:settings').set('model.darkMode', true);
|
||||
var Settings = window.App && App.__container__.lookup('controller:settings');
|
||||
if ( Settings ) {
|
||||
try {
|
||||
Settings.set('settings.darkMode', true);
|
||||
} catch(err) {
|
||||
this.error("Unable to set the darkMode setting because it isn't named what we expect. WTF?");
|
||||
}
|
||||
} else
|
||||
this.error("Unable to load the Ember settings controller.");
|
||||
|
||||
this._load_dark_css();
|
||||
}
|
||||
|
||||
|
@ -214,6 +224,6 @@ FFZ.prototype._load_dark_css = function() {
|
|||
|
||||
s.id = "ffz-dark-css";
|
||||
s.setAttribute('rel', 'stylesheet');
|
||||
s.setAttribute('href', constants.DIRECT_SERVER + "script/dark" + (constants.DEBUG ? "" : ".min") + ".css?_=" + (constants.DEBUG ? Date.now() : FFZ.version_info));
|
||||
s.setAttribute('href', constants.SERVER + "script/dark" + (constants.DEBUG ? "" : ".min") + ".css?_=" + (constants.DEBUG ? Date.now() : FFZ.version_info));
|
||||
document.head.appendChild(s);
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
var FFZ = window.FrankerFaceZ,
|
||||
constants = require('../constants');
|
||||
|
||||
|
||||
// --------------------
|
||||
// Configuration
|
||||
// --------------------
|
||||
|
||||
FFZ.settings_info.group_tabs = {
|
||||
type: "boolean",
|
||||
value: false,
|
||||
|
||||
no_bttv: true,
|
||||
|
||||
category: "Chat",
|
||||
name: "Chat Room Tabs <span>Beta</span>",
|
||||
help: "Enhanced UI for switching the current chat room and noticing new messages.",
|
||||
|
||||
on_update: function(val) {
|
||||
var enabled = !this.has_bttv && val;
|
||||
if ( ! this._chatv || enabled === this._group_tabs_state )
|
||||
return;
|
||||
|
||||
if ( enabled )
|
||||
this._chatv.ffzEnableTabs();
|
||||
else
|
||||
this._chatv.ffzDisableTabs();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------
|
||||
// Initializer
|
||||
// --------------------
|
||||
|
||||
FFZ.prototype.setup_group_chat = function() {
|
||||
if ( this.has_bttv || ! this.settings.group_tabs )
|
||||
return;
|
||||
|
||||
this.log("Initializing secondary group chat UI.");
|
||||
//this.group_tabs_enable();
|
||||
}
|
||||
|
||||
|
||||
// --------------------
|
||||
//
|
||||
// --------------------
|
|
@ -126,7 +126,7 @@ FFZ.prototype.setup_menu = function() {
|
|||
content.appendChild(p);
|
||||
|
||||
a.addEventListener('click', function(e) {
|
||||
view.set('controller.model.hidden', true);
|
||||
view.set('controller.settings.hidden', true);
|
||||
f._last_page = 'settings';
|
||||
f.build_ui_popup(f._chatv);
|
||||
e.stopPropagation();
|
||||
|
@ -164,11 +164,12 @@ FFZ.prototype.setup_menu = function() {
|
|||
} catch(err) { }
|
||||
|
||||
// Modify all existing Chat Settings views.
|
||||
for(var key in Ember.View.views) {
|
||||
if ( ! Ember.View.views.hasOwnProperty(key) )
|
||||
var views = window.App && App.__container__.lookup('-view-registry:main') || Ember.View.views;
|
||||
for(var key in views) {
|
||||
if ( ! views.hasOwnProperty(key) )
|
||||
continue;
|
||||
|
||||
var view = Ember.View.views[key];
|
||||
var view = views[key];
|
||||
if ( !(view instanceof Settings) )
|
||||
continue;
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ FFZ.prototype.setup_css = function() {
|
|||
var s = this._main_style = document.createElement('link');
|
||||
s.id = "ffz-main-css";
|
||||
s.setAttribute('rel', 'stylesheet');
|
||||
s.setAttribute('href', constants.DIRECT_SERVER + "script/style" + (constants.DEBUG ? "" : ".min") + ".css?_=" + (constants.DEBUG ? Date.now() : FFZ.version_info));
|
||||
s.setAttribute('href', constants.SERVER + "script/style" + (constants.DEBUG ? "" : ".min") + ".css?_=" + (constants.DEBUG ? Date.now() : FFZ.version_info));
|
||||
document.head.appendChild(s);
|
||||
|
||||
this.log("Readying toggleable styles.");
|
||||
|
|
36
style.css
36
style.css
|
@ -955,6 +955,7 @@ body:not(.ffz-bttv) .dropmenu.share { margin-bottom: 0; }
|
|||
|
||||
/* Menu Scrollbar */
|
||||
|
||||
.chatters-container::-webkit-scrollbar,
|
||||
.ffz-scrollbar::-webkit-scrollbar,
|
||||
.ember-chat .chat-settings::-webkit-scrollbar,
|
||||
.conversations-list .conversations-list-inner::-webkit-scrollbar,
|
||||
|
@ -967,6 +968,7 @@ body:not(.ffz-bttv) .dropmenu.share { margin-bottom: 0; }
|
|||
width: 6px;
|
||||
}
|
||||
|
||||
.chatters-container::-webkit-scrollbar-thumb,
|
||||
.ffz-scrollbar::-webkit-scrollbar-thumb,
|
||||
.ember-chat .chat-settings::-webkit-scrollbar-thumb,
|
||||
.conversations-list .conversations-list-inner::-webkit-scrollbar-thumb,
|
||||
|
@ -987,6 +989,7 @@ body:not(.ffz-bttv) .dropmenu.share { margin-bottom: 0; }
|
|||
.ffz-dark .conversations-list .conversations-list-inner::-webkit-scrollbar-thumb,
|
||||
.ffz-dark .conversation-input-bar .emoticon-selector-box .all-emotes::-webkit-scrollbar-thumb,
|
||||
|
||||
.theatre .chatters-container::-webkit-scrollbar-thumb,
|
||||
.theatre .ffz-scrollbar::-webkit-scrollbar-thumb,
|
||||
.theatre .ember-chat .chat-settings::-webkit-scrollbar-thumb,
|
||||
.theatre .conversation-window .conversation-content::-webkit-scrollbar-thumb,
|
||||
|
@ -995,8 +998,9 @@ body:not(.ffz-bttv) .dropmenu.share { margin-bottom: 0; }
|
|||
.theatre .chat-history::-webkit-scrollbar-thumb,
|
||||
.theatre .emoticon-selector-box .all-emotes::-webkit-scrollbar-thumb,
|
||||
.theatre .ffz-ui-menu-page::-webkit-scrollbar-thumb,
|
||||
.theatre .ffz-ui-sub-menu-page::-webkit-scrollbar-thumb
|
||||
.theatre .ffz-ui-sub-menu-page::-webkit-scrollbar-thumb,
|
||||
|
||||
.dark .chatters-container::-webkit-scrollbar-thumb,
|
||||
.dark .ffz-scrollbar::-webkit-scrollbar-thumb,
|
||||
.dark .ember-chat .chat-settings::-webkit-scrollbar-thumb,
|
||||
.dark .chat-history::-webkit-scrollbar-thumb,
|
||||
|
@ -1004,6 +1008,7 @@ body:not(.ffz-bttv) .dropmenu.share { margin-bottom: 0; }
|
|||
.dark .ffz-ui-menu-page::-webkit-scrollbar-thumb,
|
||||
.dark .ffz-ui-sub-menu-page::-webkit-scrollbar-thumb,
|
||||
|
||||
.force-dark .chatters-container::-webkit-scrollbar-thumb,
|
||||
.force-dark .ffz-scrollbar::-webkit-scrollbar-thumb,
|
||||
.force-dark .ember-chat .chat-settings::-webkit-scrollbar-thumb,
|
||||
.force-dark .chat-history::-webkit-scrollbar-thumb,
|
||||
|
@ -1014,6 +1019,12 @@ body:not(.ffz-bttv) .dropmenu.share { margin-bottom: 0; }
|
|||
box-shadow: 0 0 1px 1px rgba(0,0,0,0.25);
|
||||
}
|
||||
|
||||
|
||||
.chatters-container {
|
||||
overflow-x: hidden !important;
|
||||
overflow-y: auto !important;
|
||||
}
|
||||
|
||||
/* Fix Moderation Cards */
|
||||
|
||||
img.channel_background[src="null"] { display: none; }
|
||||
|
@ -1377,7 +1388,7 @@ a.unsafe-link {
|
|||
}
|
||||
|
||||
.ffz-room-list td svg {
|
||||
margin: 5px;
|
||||
margin: 5px 10px 5px 0;
|
||||
float: left;
|
||||
}
|
||||
|
||||
|
@ -1391,9 +1402,9 @@ a.unsafe-link {
|
|||
.ffz-room-row:focus svg path,
|
||||
.ffz-room-row.active svg path { fill: #fff; }
|
||||
|
||||
.ffz-room-row:hover td,
|
||||
.ffz-room-row:focus td,
|
||||
.ffz-room-row.active td {
|
||||
.ffz-room-row:hover,
|
||||
.ffz-room-row:focus,
|
||||
.ffz-room-row.active {
|
||||
background-color: #6441A5;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
@ -1404,7 +1415,7 @@ th.ffz-row-switch {
|
|||
|
||||
.ffz-room-row a.leave-chat {
|
||||
float: right;
|
||||
margin-right: 12px;
|
||||
padding: 0 7px;
|
||||
}
|
||||
|
||||
.ffz-row-switch .switch {
|
||||
|
@ -1419,6 +1430,8 @@ th.ffz-row-switch {
|
|||
|
||||
/* Chat Tabs */
|
||||
|
||||
.ember-chat .chat-room { z-index: 5; }
|
||||
|
||||
#ffz-group-tabs {
|
||||
padding: 10px 10px 6px;
|
||||
box-shadow: inset 0 -1px 0 0 rgba(0,0,0,0.2);
|
||||
|
@ -1525,6 +1538,17 @@ th.ffz-row-switch {
|
|||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.ffz-room-row.row-mentioned {
|
||||
background-color: rgba(128,50,50,0.1);
|
||||
color: red !important;
|
||||
}
|
||||
|
||||
.ffz-room-row.row-mentioned:not(.active):hover,
|
||||
.ffz-room-row.row-mentioned:not(.active):focus {
|
||||
background-color: #a54141;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
#ffz-group-tabs .button .notifications {
|
||||
background-color: #d44949;
|
||||
top: 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue