mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-28 15:27:43 +00:00
3.5.194. Rename controller:layout and controller:login to be services. Rewrite styles to better work with the new chat DOM layout. Stop exposing tokens to the built-in chat templates to avoid rendering errors and improve performance. Schedule scrolling events with requestAnimationFrame. Very initial bits support that doesn't actually do anything yet. Fix SRL race information.
This commit is contained in:
parent
57a95986d3
commit
ee21ab28c3
21 changed files with 218 additions and 94 deletions
|
@ -130,7 +130,7 @@ FFZ.prototype.setup_colors = function() {
|
|||
this._update_colors();
|
||||
|
||||
// Events for rebuilding colors.
|
||||
var Layout = utils.ember_lookup('controller:layout'),
|
||||
var Layout = utils.ember_lookup('service:layout'),
|
||||
Settings = utils.ember_lookup('controller:settings');
|
||||
|
||||
if ( Layout )
|
||||
|
@ -654,7 +654,7 @@ FFZ.prototype._rebuild_colors = function() {
|
|||
|
||||
FFZ.prototype._update_colors = function(darkness_only) {
|
||||
// Update the lines. ALL of them.
|
||||
var Layout = utils.ember_lookup('controller:layout'),
|
||||
var Layout = utils.ember_lookup('service:layout'),
|
||||
Settings = utils.ember_lookup('controller:settings'),
|
||||
|
||||
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('settings.darkMode')),
|
||||
|
|
|
@ -233,7 +233,7 @@ FFZ.prototype._modify_cindex = function(view) {
|
|||
f.rebuild_race_ui();
|
||||
|
||||
if ( f.settings.auto_theater ) {
|
||||
var Layout = utils.ember_lookup('controller:layout');
|
||||
var Layout = utils.ember_lookup('service:layout');
|
||||
if ( Layout )
|
||||
Layout.set('isTheatreMode', true);
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ FFZ.prototype._modify_conversation_menu = function(component) {
|
|||
|
||||
FFZ.prototype._modify_conversation_window = function(component) {
|
||||
var f = this,
|
||||
Layout = utils.ember_lookup('controller:layout');
|
||||
Layout = utils.ember_lookup('service:layout');
|
||||
|
||||
component.reopen({
|
||||
headerBadges: Ember.computed("thread.participants", "currentUsername", function() {
|
||||
|
@ -178,7 +178,7 @@ FFZ.prototype._modify_conversation_window = function(component) {
|
|||
|
||||
FFZ.prototype._modify_conversation_line = function(component) {
|
||||
var f = this,
|
||||
Layout = utils.ember_lookup('controller:layout');
|
||||
Layout = utils.ember_lookup('service:layout');
|
||||
|
||||
component.reopen({
|
||||
tokenizedMessage: function() {
|
||||
|
|
|
@ -33,6 +33,59 @@ FFZ.prototype.setup_profile_following = function() {
|
|||
this._following_cache = {};
|
||||
this._follower_cache = {};
|
||||
|
||||
/*try {
|
||||
var ChannelSerializer = window.require("web-client/serializers/new-channel"),
|
||||
BaseSerializer = window.require("web-client/serializers/application"),
|
||||
process_channel = function(chan) {
|
||||
var cid = chan.name;
|
||||
return {
|
||||
type: "new-channel",
|
||||
id: cid,
|
||||
attributes: chan,
|
||||
relationships: {
|
||||
following: {
|
||||
links: {
|
||||
related: "/kraken/users/" + cid + "/follows/channels?offset=0&on_site=1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var ser = ChannelSerializer.default = BaseSerializer.default.extend({
|
||||
normalizeFindRecordResponse: function(e, t, a, r) {
|
||||
var l = process_channel(a);
|
||||
return this._super(e, t, {
|
||||
data: l
|
||||
}, r)
|
||||
},
|
||||
|
||||
normalizeResponse: function(e, t, a, r, l) {
|
||||
if ( ! a.follows )
|
||||
return this._super.apply(this, arguments);
|
||||
|
||||
f.log("Normalizing Response", [e, t, a, r, l]);
|
||||
var i = this.extractMeta(e, t, a),
|
||||
o = a.follows.map(function(e) {
|
||||
return process_channel(e.channel);
|
||||
}),
|
||||
d = {
|
||||
data: o,
|
||||
meta: i
|
||||
};
|
||||
|
||||
return this._super(e, t, d, r, l);
|
||||
}
|
||||
});
|
||||
|
||||
App.registry.unregister('serializer:new-channel');
|
||||
App.registry.register('serializer:new-channel', ser);
|
||||
|
||||
} catch(err) {
|
||||
this.error("Unable to modify the Ember new-channel serializer", err);
|
||||
}*/
|
||||
|
||||
|
||||
// First, we need to hook the model. This is what we'll use to grab the following notification state,
|
||||
// rather than making potentially hundreds of API requests.
|
||||
var Following = utils.ember_resolve('model:kraken-channel-following');
|
||||
|
|
|
@ -39,7 +39,7 @@ FFZ.settings_info.portrait_mode = {
|
|||
if ( this.has_bttv )
|
||||
return;
|
||||
|
||||
var Layout = utils.ember_lookup('controller:layout');
|
||||
var Layout = utils.ember_lookup('service:layout');
|
||||
if ( ! Layout )
|
||||
return;
|
||||
|
||||
|
@ -126,7 +126,7 @@ FFZ.settings_info.right_column_width = {
|
|||
if ( this.has_bttv )
|
||||
return;
|
||||
|
||||
var Layout = utils.ember_lookup('controller:layout');
|
||||
var Layout = utils.ember_lookup('service:layout');
|
||||
if ( ! Layout )
|
||||
return;
|
||||
|
||||
|
@ -151,12 +151,13 @@ FFZ.prototype.setup_layout = function() {
|
|||
s.id = 'ffz-layout-css';
|
||||
document.head.appendChild(s);
|
||||
|
||||
this.log("Hooking the Ember Layout controller.");
|
||||
var Layout = utils.ember_lookup('controller:layout'),
|
||||
var Layout = utils.ember_lookup('service:layout'),
|
||||
f = this;
|
||||
|
||||
if ( ! Layout )
|
||||
return;
|
||||
return this.log("Unable to locate the Ember service:layout");
|
||||
|
||||
this.log("Hooking the Ember service:layout");
|
||||
|
||||
Layout.reopen({
|
||||
rightColumnWidth: 340,
|
||||
|
|
|
@ -637,11 +637,15 @@ FFZ.prototype.save_aliases = function() {
|
|||
|
||||
FFZ.prototype._modify_chat_line = function(component, is_vod) {
|
||||
var f = this,
|
||||
Layout = utils.ember_lookup('controller:layout'),
|
||||
Layout = utils.ember_lookup('service:layout'),
|
||||
Settings = utils.ember_lookup('controller:settings');
|
||||
|
||||
component.reopen({
|
||||
tokenizedMessage: function() {
|
||||
return [];
|
||||
}.property('msgObject.message'),
|
||||
|
||||
ffzTokenizedMessage: function() {
|
||||
try {
|
||||
return f.tokenize_chat_line(this.get('msgObject'));
|
||||
} catch(err) {
|
||||
|
@ -650,7 +654,7 @@ FFZ.prototype._modify_chat_line = function(component, is_vod) {
|
|||
}
|
||||
}.property("msgObject.message", "isChannelLinksDisabled", "currentUserNick", "msgObject.from", "msgObject.tags.emotes"),
|
||||
|
||||
lineChanged: Ember.observer("msgObject.deleted", "isModeratorOrHigher", "msgObject.ffz_old_messages", function() {
|
||||
lineChanged: Ember.observer("msgObject.deleted", "isModeratorOrHigher", "msgObject.ffz_old_messages", "ffzTokenizedMessage", function() {
|
||||
this.$(".mod-icons").replaceWith(this.buildModIconsHTML());
|
||||
if ( this.get("msgObject.deleted") ) {
|
||||
this.$(".message").replaceWith(this.buildDeletedMessageHTML());
|
||||
|
@ -812,7 +816,7 @@ FFZ.prototype._modify_chat_line = function(component, is_vod) {
|
|||
} else
|
||||
output = '<span class="message">';
|
||||
|
||||
output += f.render_tokens(this.get('tokenizedMessage'), true, is_whisper && f.settings.filter_whispered_links && this.get("ffzUserLevel") < 4);
|
||||
output += f.render_tokens(this.get('ffzTokenizedMessage'), true, is_whisper && f.settings.filter_whispered_links && this.get("ffzUserLevel") < 4);
|
||||
|
||||
var old_messages = this.get('msgObject.ffz_old_messages');
|
||||
if ( old_messages && old_messages.length )
|
||||
|
@ -821,15 +825,10 @@ FFZ.prototype._modify_chat_line = function(component, is_vod) {
|
|||
return output + '</span>';
|
||||
},
|
||||
|
||||
//tagName: "li",
|
||||
|
||||
ffzRender: function() {
|
||||
var el = this.get('element'),
|
||||
output = this.buildSenderHTML();
|
||||
|
||||
if ( el.tagName === 'DIV' )
|
||||
return this.rerender();
|
||||
|
||||
if ( this.get('msgObject.deleted') )
|
||||
output += this.buildDeletedMessageHTML()
|
||||
else
|
||||
|
@ -868,7 +867,7 @@ FFZ.prototype._modify_chat_subline = function(component) {
|
|||
this.set('msgObject._line', null);
|
||||
},
|
||||
|
||||
didUpdate: function() { this.ffzRender(); },
|
||||
//didUpdate: function() { this.ffzRender(); },
|
||||
|
||||
click: function(e) {
|
||||
if ( ! e.target )
|
||||
|
@ -966,6 +965,10 @@ FFZ.prototype._modify_vod_line = function(component) {
|
|||
attributeBindings: ["msgObject.room:data-room", "msgObject.from:data-sender", "msgObject.deleted:data-deleted"],
|
||||
|
||||
tokenizedMessage: function() {
|
||||
return [];
|
||||
}.property('msgObject.message'),
|
||||
|
||||
ffzTokenizedMessage: function() {
|
||||
try {
|
||||
return f.tokenize_vod_line(this.get('msgObject'), !(this.get('enableLinkification') || this.get('isModeratorOrHigher')));
|
||||
} catch(err) {
|
||||
|
@ -992,7 +995,7 @@ FFZ.prototype._modify_vod_line = function(component) {
|
|||
return '<span clas="deleted"><message deleted></span>';
|
||||
},
|
||||
|
||||
didUpdate: function() { this.ffzRender() },
|
||||
//didUpdate: function() { this.ffzRender() },
|
||||
didInsertElement: function() { this.ffzRender() },
|
||||
|
||||
ffzRender: function() {
|
||||
|
|
|
@ -1172,7 +1172,7 @@ FFZ.prototype._build_mod_card_history = function(msg, modcard, show_from) {
|
|||
var raw_color = msg.color,
|
||||
colors = raw_color && this._handle_color(raw_color),
|
||||
|
||||
Layout = utils.ember_lookup('controller:layout'),
|
||||
Layout = utils.ember_lookup('service:layout'),
|
||||
Settings = utils.ember_lookup('controller:settings'),
|
||||
|
||||
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('settings.darkMode'));
|
||||
|
|
|
@ -44,7 +44,7 @@ FFZ.settings_info.classic_player = {
|
|||
|
||||
on_update: function(val) {
|
||||
utils.toggle_cls('ffz-classic-player')(val);
|
||||
var Layout = utils.ember_lookup('controller:layout');
|
||||
var Layout = utils.ember_lookup('service:layout');
|
||||
if ( Layout )
|
||||
Layout.set('PLAYER_CONTROLS_HEIGHT', val ? 32 : 0);
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ FFZ.prototype.setup_player = function() {
|
|||
utils.toggle_cls('ffz-player-volume')(this.settings.player_volume_bar);
|
||||
utils.toggle_cls('ffz-classic-player')(this.settings.classic_player);
|
||||
|
||||
var Layout = utils.ember_lookup('controller:layout');
|
||||
var Layout = utils.ember_lookup('service:layout');
|
||||
if ( Layout )
|
||||
Layout.set('PLAYER_CONTROLS_HEIGHT', this.settings.classic_player ? 32 : 0);
|
||||
|
||||
|
|
|
@ -371,7 +371,8 @@ FFZ.prototype._modify_rview = function(view) {
|
|||
s = this._$chatMessagesScroller;
|
||||
|
||||
Ember.run.next(function() {
|
||||
setTimeout(function(){
|
||||
// Trying random performance tweaks for fun and profit!
|
||||
(window.requestAnimationFrame||setTimeout)(function(){
|
||||
if ( e.ffz_frozen || ! s || ! s.length )
|
||||
return;
|
||||
|
||||
|
@ -1104,7 +1105,7 @@ FFZ.prototype._modify_room = function(room) {
|
|||
|
||||
// Now that we've reset the tokens, if there's a line for this,
|
||||
if ( last_ban._line )
|
||||
Ember.propertyDidChange(last_ban._line, 'tokenizedMessage');
|
||||
Ember.propertyDidChange(last_ban._line, 'ffzTokenizedMessage');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1218,7 +1219,8 @@ FFZ.prototype._modify_room = function(room) {
|
|||
// 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.
|
||||
now = now || Date.now();
|
||||
var delay = Math.max(
|
||||
var t = this,
|
||||
delay = Math.max(
|
||||
(f.settings.chat_delay !== 0 ? 50 + Math.max(0, (f.settings.chat_delay + (this.ffzPending[0].time||0)) - now) : 0),
|
||||
(f.settings.chat_batching !== 0 ? Math.max(0, f.settings.chat_batching - (now - (this._ffz_last_batch||0))) : 0));
|
||||
|
||||
|
@ -1316,16 +1318,23 @@ FFZ.prototype._modify_room = function(room) {
|
|||
var room = f.rooms && f.rooms[msg.room];
|
||||
if ( room ) {
|
||||
var chat_history = room.user_history = room.user_history || {},
|
||||
user_history = room.user_history[msg.from] = room.user_history[msg.from] || [];
|
||||
user_history = room.user_history[msg.from] = room.user_history[msg.from] || [],
|
||||
last_history = user_history.length && user_history[user_history.length - 1],
|
||||
|
||||
user_history.push({
|
||||
from: msg.from,
|
||||
tags: {'display-name': msg.tags && msg.tags['display-name']},
|
||||
message: msg.message,
|
||||
cachedTokens: msg.cachedTokens,
|
||||
style: msg.style,
|
||||
date: msg.date
|
||||
});
|
||||
new_msg = {
|
||||
from: msg.from,
|
||||
tags: {'display-name': msg.tags && msg.tags['display-name']},
|
||||
message: msg.message,
|
||||
cachedTokens: msg.cachedTokens,
|
||||
style: msg.style,
|
||||
date: msg.date
|
||||
};
|
||||
|
||||
// Preserve message order if we *just* received a ban.
|
||||
if ( last_history && last_history.is_delete && (msg.date - last_history.date) <= 200 ) {
|
||||
user_history.splice(user_history.length - 1, 0, new_msg);
|
||||
} else
|
||||
user_history.push(new_msg);
|
||||
|
||||
if ( user_history.length > 20 )
|
||||
user_history.shift();
|
||||
|
|
|
@ -277,7 +277,7 @@ FFZ.prototype._modify_vod_chat_display = function(component) {
|
|||
return;
|
||||
|
||||
Ember.run.next(function() {
|
||||
setTimeout(function() {
|
||||
(window.requestAnimationFrame||setTimeout)(function() {
|
||||
if ( e.ffz_frozen )
|
||||
return;
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ FFZ.prototype.process_rechat_line = function(line, reprocess) {
|
|||
user_id = line.getAttribute('data-sender'),
|
||||
room_id = line.getAttribute('data-room'),
|
||||
|
||||
Layout = utils.ember_lookup('controller:layout'),
|
||||
Layout = utils.ember_lookup('service:layout'),
|
||||
Settings = utils.ember_lookup('controller:settings'),
|
||||
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('settings.darkMode')),
|
||||
|
||||
|
|
13
src/main.js
13
src/main.js
|
@ -37,7 +37,7 @@ FFZ.msg_commands = {};
|
|||
|
||||
// Version
|
||||
var VER = FFZ.version_info = {
|
||||
major: 3, minor: 5, revision: 190,
|
||||
major: 3, minor: 5, revision: 194,
|
||||
toString: function() {
|
||||
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ FFZ.prototype.get_user = function(force_reload) {
|
|||
if ( ! force_reload && this.__user )
|
||||
return this.__user;
|
||||
|
||||
var LC = FFZ.utils.ember_lookup('controller:login'),
|
||||
var LC = FFZ.utils.ember_lookup('service:login'),
|
||||
user = LC ? LC.get('userData') : undefined;
|
||||
|
||||
if ( ! user && window.PP && PP.login )
|
||||
|
@ -225,10 +225,11 @@ FFZ.prototype.initialize = function(increment, delay) {
|
|||
// Twitch ember application is ready.
|
||||
|
||||
// Pages we don't want to interact with at all.
|
||||
if ( location.hostname === 'passport.twitch.tv' || /^\/user\/two_factor/.test(location.pathname) ) {
|
||||
this.log("Found authentication sub-page. Not initializing.");
|
||||
return;
|
||||
}
|
||||
if ( location.hostname === 'passport.twitch.tv' || /^\/user\/two_factor/.test(location.pathname) )
|
||||
return this.log("Found authentication sub-page. Not initializing.");
|
||||
|
||||
if ( ['im.twitch.tv', 'api.twitch.tv'].indexOf(location.hostname) !== -1 )
|
||||
return this.log("Found banned sub-domain. Not initializing.");
|
||||
|
||||
// Check for the player
|
||||
if ( location.hostname === 'player.twitch.tv' ) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* Regular Alternating Background */
|
||||
.conversation-chat-lines > div:nth-child(2n+0):before,
|
||||
.chat-lines > div:nth-child(2n+0) > .chat-line:before,
|
||||
.chat-line:nth-child(2n+0):before {
|
||||
background-color: rgba(0,0,0, 0.1);
|
||||
}
|
||||
|
@ -12,10 +11,6 @@
|
|||
|
||||
.theatre .conversation-chat-lines > div:nth-child(2n+0):before,
|
||||
.theatre .chat-line:nth-child(2n+0):before,
|
||||
.theatre .chat-lines > div:nth-child(2n+0) > .chat-line:before,
|
||||
|
||||
.dark .chat-lines > div:nth-child(2n+0) > .chat-line:before,
|
||||
.force-dark .chat-lines > div:nth-child(2n+0) > .chat-line:before,
|
||||
|
||||
.dark .chat-line:nth-child(2n+0):before,
|
||||
.force-dark .chat-line:nth-child(2n+0):before {
|
||||
|
@ -29,7 +24,6 @@
|
|||
}
|
||||
|
||||
|
||||
.chat-lines > div:nth-child(2n+0) > .chat-line.whisper:nth-child(2n+0):before,
|
||||
.chat-line.whisper:nth-child(2n+0):before {
|
||||
background-color: rgba(185, 163, 227, 0.4);
|
||||
}
|
||||
|
@ -40,10 +34,6 @@
|
|||
background-color: rgba(100, 65, 165, 0.2);
|
||||
}
|
||||
|
||||
.theatre .chat-lines > div:nth-child(2n+0) > .chat-line.whisper:before,
|
||||
.dark .chat-lines > div:nth-child(2n+0) > .chat-line.whisper:before,
|
||||
.force-dark .chat-lines > div:nth-child(2n+0) > .chat-line.whisper:before,
|
||||
|
||||
.theatre .chat-line.whisper:nth-child(2n+0):before,
|
||||
.dark .chat-line.whisper:nth-child(2n+0):before,
|
||||
.force-dark .chat-line.whisper:nth-child(2n+0):before {
|
||||
|
|
|
@ -17,14 +17,12 @@
|
|||
|
||||
/* Hide First Line */
|
||||
.conversation-chat-lines > div:first-child:before,
|
||||
.chat-lines > div:first-of-type > .chat-line:before,
|
||||
.chatReplay .chat-line:first-of-type:before {
|
||||
.chat-line:first-of-type:before {
|
||||
border-top-color: transparent !important;
|
||||
}
|
||||
|
||||
/* Hide Last Line */
|
||||
.conversation-chat-lines > div:last-child:nth-child(odd):before,
|
||||
.chat-lines > div:last-of-type:nth-child(odd) > .chat-line:before,
|
||||
.chatReplay .chat-line:last-of-type:nth-child(odd):before {
|
||||
.chat-line:last-of-type:nth-child(odd):before {
|
||||
border-bottom-color: transparent !important;
|
||||
}
|
|
@ -476,7 +476,7 @@ FFZ.prototype.tokenize_vod_line = function(msgObject, delete_links) {
|
|||
}
|
||||
|
||||
|
||||
FFZ.prototype.tokenize_chat_line = function(msgObject, prevent_notification, delete_links) {
|
||||
FFZ.prototype.tokenize_chat_line = function(msgObject, prevent_notification, delete_links, use_bits) {
|
||||
if ( msgObject.cachedTokens )
|
||||
return msgObject.cachedTokens;
|
||||
|
||||
|
@ -489,6 +489,9 @@ FFZ.prototype.tokenize_chat_line = function(msgObject, prevent_notification, del
|
|||
tokens = [msg];
|
||||
|
||||
// Standard tokenization
|
||||
if ( use_bits && helpers && helpers.tokenizeBits )
|
||||
tokens = helpers.tokenizeBits(tokens);
|
||||
|
||||
if ( helpers && helpers.linkifyMessage ) {
|
||||
var labels = msgObject.labels || [],
|
||||
mod_or_higher = labels.indexOf("owner") !== -1 ||
|
||||
|
|
|
@ -52,7 +52,7 @@ FFZ.ws_commands.update_news = function(version) {
|
|||
// About Page
|
||||
// -------------------
|
||||
|
||||
var include_html = function(heading_text, filename) {
|
||||
var include_html = function(heading_text, filename, callback) {
|
||||
return function(view, container) {
|
||||
var heading = createElement('div', 'chat-menu-content center');
|
||||
heading.innerHTML = '<h1>FrankerFaceZ</h1>' + (heading_text ? '<div class="ffz-about-subheading">' + heading_text + '</div>' : '');
|
||||
|
@ -67,6 +67,8 @@ var include_html = function(heading_text, filename) {
|
|||
jQuery('#ffz-old-news', container).css('display', 'block');
|
||||
});
|
||||
|
||||
typeof callback === "function" && callback(view, container);
|
||||
|
||||
}).fail(function(data) {
|
||||
var content = createElement('div', 'chat-menu-content menu-side-padding');
|
||||
content.textContent = 'There was an error loading this page from the server.';
|
||||
|
@ -252,7 +254,7 @@ FFZ.menu_pages.about = {
|
|||
},
|
||||
|
||||
changelog: {
|
||||
name: "Changelog",
|
||||
name: "Changes",
|
||||
wide: true,
|
||||
render: include_html("change log", constants.SERVER + "script/changelog.html")
|
||||
},
|
||||
|
@ -272,11 +274,19 @@ FFZ.menu_pages.about = {
|
|||
},*/
|
||||
|
||||
credits: {
|
||||
name: "Credits",
|
||||
name: "Credit",
|
||||
wide: true,
|
||||
render: include_html("credits", constants.SERVER + "script/credits.html")
|
||||
},
|
||||
|
||||
/*status: {
|
||||
name: "Status",
|
||||
wide: true,
|
||||
render: include_html("server status", constants.SERVER + "script/status.html", function(view, container) {
|
||||
|
||||
})
|
||||
},*/
|
||||
|
||||
debugging: {
|
||||
name: "Debug",
|
||||
wide: true,
|
||||
|
|
|
@ -77,7 +77,7 @@ FFZ.ffz_commands.following = function(room, args) {
|
|||
|
||||
FFZ.ws_on_close.push(function() {
|
||||
var controller = utils.ember_lookup('controller:channel'),
|
||||
current_id = controller && controller.get('id'),
|
||||
current_id = controller && controller.get('content.id'),
|
||||
current_host = controller && controller.get('hostModeTarget.id'),
|
||||
need_update = false;
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ FFZ.prototype.setup_menu = function() {
|
|||
this.log("Hooking the Ember Chat Settings view.");
|
||||
|
||||
var Settings = utils.ember_resolve('view:settings'),
|
||||
Layout = utils.ember_lookup('controller:layout'),
|
||||
Layout = utils.ember_lookup('service:layout'),
|
||||
f = this;
|
||||
|
||||
if ( ! Settings )
|
||||
|
|
|
@ -36,7 +36,7 @@ FFZ.settings_info.srl_races = {
|
|||
|
||||
FFZ.ws_on_close.push(function() {
|
||||
var controller = utils.ember_lookup('controller:channel'),
|
||||
current_id = controller && controller.get('id'),
|
||||
current_id = controller && controller.get('content.id'),
|
||||
current_host = controller && controller.get('hostModeTarget.id'),
|
||||
need_update = false;
|
||||
|
||||
|
@ -56,7 +56,7 @@ FFZ.ws_on_close.push(function() {
|
|||
|
||||
FFZ.ws_commands.srl_race = function(data) {
|
||||
var controller = utils.ember_lookup('controller:channel'),
|
||||
current_id = controller && controller.get('id'),
|
||||
current_id = controller && controller.get('content.id'),
|
||||
current_host = controller && controller.get('hostModeTarget.id'),
|
||||
need_update = false;
|
||||
|
||||
|
@ -92,7 +92,7 @@ FFZ.ws_commands.srl_race = function(data) {
|
|||
|
||||
FFZ.prototype.rebuild_race_ui = function() {
|
||||
var controller = utils.ember_lookup('controller:channel'),
|
||||
channel_id = controller && controller.get('id'),
|
||||
channel_id = controller && controller.get('content.id'),
|
||||
hosted_id = controller && controller.get('hostModeTarget.id');
|
||||
|
||||
if ( ! this._cindex )
|
||||
|
@ -111,7 +111,7 @@ FFZ.prototype.rebuild_race_ui = function() {
|
|||
|
||||
} else {
|
||||
if ( ! race_container ) {
|
||||
race_container = document.createElement('span');
|
||||
race_container = utils.createElement('span', 'balloon-wrapper inline');
|
||||
race_container.id = 'ffz-ui-race';
|
||||
race_container.setAttribute('data-channel', channel_id);
|
||||
|
||||
|
@ -143,7 +143,7 @@ FFZ.prototype.rebuild_race_ui = function() {
|
|||
|
||||
} else {
|
||||
if ( ! race_container ) {
|
||||
race_container = document.createElement('span');
|
||||
race_container = utils.createElement('span', 'balloon-wrapper inline');
|
||||
race_container.id = 'ffz-ui-race';
|
||||
race_container.setAttribute('data-channel', hosted_id);
|
||||
|
||||
|
@ -191,10 +191,10 @@ FFZ.prototype._build_race_popup = function(container, channel_id) {
|
|||
pos = el.offsetLeft + el.offsetWidth,
|
||||
race = this.srl_races[channel_id];
|
||||
|
||||
var popup = document.createElement('div'), out = '';
|
||||
var popup = utils.createElement('div', 'share balloon balloon--md balloon--up balloon--dropmenu'), out = '';
|
||||
popup.id = 'ffz-race-popup';
|
||||
popup.setAttribute('data-channel', channel_id);
|
||||
popup.className = (pos >= 300 ? 'right' : 'left') + ' share dropmenu';
|
||||
//popup.className = (pos >= 300 ? 'right' : 'left') + ' share dropmenu';
|
||||
|
||||
this._popup_kill = this._race_kill.bind(this);
|
||||
this._popup_allow_parent = true;
|
||||
|
@ -212,13 +212,12 @@ FFZ.prototype._build_race_popup = function(container, channel_id) {
|
|||
|
||||
var height = document.querySelector('.app-main.theatre') ? document.body.clientHeight - 300 : container.parentElement.offsetTop - 175,
|
||||
controller = utils.ember_lookup('controller:channel'),
|
||||
display_name = controller ? controller.get('display_name') : FFZ.get_capitalization(channel_id),
|
||||
display_name = controller && controller.get('content.id') === channel_id ? controller.get('content.display_name') : FFZ.get_capitalization(channel_id),
|
||||
tweet = encodeURIComponent("I'm watching " + display_name + " race " + race.goal + " in " + race.game + " on SpeedRunsLive!");
|
||||
|
||||
out = '<div class="heading"><div></div><span></span></div>';
|
||||
out = '<div class="heading"><div></div><span class="html-tooltip"></span></div>';
|
||||
out += '<div class="table" style="max-height:' + height + 'px"><table><thead><tr><th>#</th><th>Entrant</th><th> </th><th>Time</th></tr></thead>';
|
||||
out += '<tbody></tbody></table></div>';
|
||||
out += '<div class="divider"></div>';
|
||||
|
||||
out += '<iframe class="twitter_share_button" style="width:130px; height:25px" src="https://platform.twitter.com/widgets/tweet_button.html?text=' + tweet + '%20Watch%20at&via=Twitch&url=http://www.twitch.tv/' + channel_id + '"></iframe>';
|
||||
|
||||
|
@ -266,7 +265,7 @@ FFZ.prototype._update_race = function(container, not_timer) {
|
|||
|
||||
if ( popup ) {
|
||||
var tbody = popup.querySelector('tbody'),
|
||||
timer = popup.querySelector('.heading span'),
|
||||
timer = popup.querySelector('.heading > span'),
|
||||
info = popup.querySelector('.heading div');
|
||||
|
||||
tbody.innerHTML = '';
|
||||
|
@ -310,7 +309,7 @@ FFZ.prototype._update_race = function(container, not_timer) {
|
|||
place = utils.place_string(ent.place),
|
||||
comment = ent.comment ? utils.sanitize(ent.comment) : "";
|
||||
|
||||
tbody.innerHTML += '<tr' + (comment ? ' title="' + comment + '"' : '') + ' class="' + ent.state + '"><td>' + place + '</td><td>' + name + '</td><td>' + twitch_link + hitbox_link + '</td><td class="time">' + (ent.state == "forfeit" ? "Forfeit" : time) + '</td></tr>';
|
||||
tbody.innerHTML += '<tr' + (comment ? ' title="' + comment + '"' : '') + ' class="' + ent.state + (comment ? ' tooltip' : '') + '"><td>' + place + '</td><td>' + name + '</td><td>' + twitch_link + hitbox_link + '</td><td class="time">' + (ent.state == "forfeit" ? "Forfeit" : time) + '</td></tr>';
|
||||
}
|
||||
|
||||
if ( this._race_game != race.game || this._race_goal != race.goal ) {
|
||||
|
@ -318,9 +317,18 @@ FFZ.prototype._update_race = function(container, not_timer) {
|
|||
this._race_goal = race.goal;
|
||||
|
||||
var game = utils.sanitize(race.game),
|
||||
goal = utils.sanitize(race.goal);
|
||||
goal = utils.unquote_attr(race.goal),
|
||||
old_goal = popup.getAttribute('data-old-goal');
|
||||
|
||||
info.innerHTML = '<h2 title="' + game + '">' + game + "</h2><b>Goal: </b>" + goal;
|
||||
if ( goal !== old_goal ) {
|
||||
popup.setAttribute('data-old-goal', goal);
|
||||
goal = goal ? this.render_tokens(this.tokenize_line("jtv", null, goal, true)) : '';
|
||||
info.innerHTML = '<h2 class="tooltip" title="' + game + '">' + game + '</h2><span class="goal"><b>Goal: </b>' + goal + '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
if ( race.time ) {
|
||||
timer.title = 'Started at: <nobr>' + utils.sanitize(utils.parse_date(1000 * race.time).toLocaleString()) + '</nobr>';
|
||||
}
|
||||
|
||||
if ( ! elapsed )
|
||||
|
|
|
@ -9,6 +9,10 @@ var sanitize_el = document.createElement('span'),
|
|||
return sanitize_el.innerHTML;
|
||||
},
|
||||
|
||||
unquote_attr = function(msg) {
|
||||
return msg.replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, "'").replace(/>/g, '>').replace(/</g, '<');
|
||||
},
|
||||
|
||||
escape_regex = RegExp.escape || function(str) {
|
||||
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
},
|
||||
|
@ -388,6 +392,7 @@ module.exports = FFZ.utils = {
|
|||
},
|
||||
|
||||
sanitize: sanitize,
|
||||
unquote_attr: unquote_attr,
|
||||
quote_attr: quote_attr,
|
||||
|
||||
date_string: function(date) {
|
||||
|
|
77
style.css
77
style.css
|
@ -54,12 +54,12 @@ body:not(.ffz-minimal-chat-input):not(.ffz-menu-replace) .chat-interface .emotic
|
|||
.ember-chat-container.dark .ffz-ui-toggle svg.svg-emoticons path,
|
||||
.chat-container.dark .ffz-ui-toggle svg.svg-emoticons path,
|
||||
.app-main.theatre .ffz-ui-toggle svg.svg-emoticons path,
|
||||
body.ffz-bttv-dark .ffz-ui-toggle svg.svg-emoticons path { fill: #888; }
|
||||
body.ffz-bttv-dark .ffz-ui-toggle svg.svg-emoticons path { fill: #555; }
|
||||
|
||||
.ember-chat-container.dark .ffz-ui-toggle:hover svg.svg-emoticons path,
|
||||
.chat-container.dark .ffz-ui-toggle:hover svg.svg-emoticons path,
|
||||
.app-main.theatre .ffz-ui-toggle:hover svg.svg-emoticons path,
|
||||
body.ffz-bttv-dark .ffz-ui-toggle:hover svg.svg-emoticons path { fill: #777; }
|
||||
body.ffz-bttv-dark .ffz-ui-toggle:hover svg.svg-emoticons path { fill: #999; }
|
||||
|
||||
|
||||
.ffz-ui-toggle.no-emotes svg.svg-emoticons path { fill: rgba(80,0,0,0.2); }
|
||||
|
@ -360,50 +360,79 @@ body.ffz-bttv-dark .ffz-ui-toggle.blue.live:hover svg.svg-emoticons path { fill:
|
|||
|
||||
#ffz-race-popup {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
display: block;
|
||||
background-image: url("//cdn.frankerfacez.com/script/zreknarf-bg.png");
|
||||
background-repeat: no-repeat;
|
||||
padding: 1rem;
|
||||
background-position: 115% 110%;
|
||||
}
|
||||
|
||||
#ffz-race-popup.right { right: 10px; }
|
||||
|
||||
#ffz-race-popup .heading {
|
||||
margin: -20px -20px 20px;
|
||||
width: 340px; height: 65px;
|
||||
margin: -1rem -1rem 1rem;
|
||||
height: 65px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#ffz-race-popup .heading div {
|
||||
padding: 10px 0 0 20px;
|
||||
max-width: 240px;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
#ffz-race-popup .heading h2,
|
||||
#ffz-race-popup .heading .goal {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#ffz-race-popup .heading .goal {
|
||||
display: block;
|
||||
margin: calc(-1rem + 1px);
|
||||
padding: calc(1rem - 1px);
|
||||
}
|
||||
|
||||
#ffz-race-popup .heading .goal:hover {
|
||||
white-space: normal;
|
||||
background-color: rgba(255,255,255,0.9);
|
||||
border-bottom: 1px solid rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.theatre #ffz-race-popup .heading .goal:hover,
|
||||
.ffz-dark #ffz-race-popup .heading .goal:hover {
|
||||
background-color: rgba(16,16,16,0.9);
|
||||
border-color: rgba(255,255,255,0.2);
|
||||
}
|
||||
|
||||
#ffz-race-popup .heading h2 {
|
||||
max-width: 240px;
|
||||
font-size: 1.5em;
|
||||
padding-bottom: 5px;
|
||||
display: block;
|
||||
width: 240px;
|
||||
max-height: 45px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 200px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#ffz-race-popup .heading span {
|
||||
#ffz-race-popup .heading > span {
|
||||
line-height: 30px;
|
||||
position: absolute;
|
||||
top: 17.5px;
|
||||
right: 20px;
|
||||
top: 7.5px;
|
||||
right: 1rem;
|
||||
padding: 0 5px;
|
||||
background: rgba(0,0,0,0.5);
|
||||
color: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#ffz-race-popup .right { text-align: right; }
|
||||
#ffz-race-popup .right {
|
||||
padding-top: 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#ffz-race-popup .table {
|
||||
overflow-y: auto;
|
||||
border-bottom: 1px solid;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
#ffz-race-popup table {
|
||||
|
@ -587,6 +616,16 @@ body.ffz-bttv-dark .ffz-ui-toggle.blue.live:hover svg.svg-emoticons path { fill:
|
|||
|
||||
.list-header span.right { float: right; }
|
||||
|
||||
.ember-chat .chat-menu .list-header.sub-header {
|
||||
border-top: none;
|
||||
margin: 0 20px;
|
||||
padding: 5px 0 0;
|
||||
}
|
||||
|
||||
.ember-chat .chat-menu .list-header.sub-header + .chat-menu-content {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.chat-menu-content.collapsable .heading span.right {
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
@ -635,6 +674,10 @@ body.ffz-bttv-dark .ffz-ui-toggle.blue.live:hover svg.svg-emoticons path { fill:
|
|||
border-bottom: 1px dotted rgba(127,127,127,0.5);
|
||||
}
|
||||
|
||||
.ffz-ui-menu-page .version-list ul {
|
||||
margin-left: 20px
|
||||
}
|
||||
|
||||
.ffz-ui-menu-page pre {
|
||||
box-shadow: none !important;
|
||||
white-space: pre-wrap;
|
||||
|
@ -1255,7 +1298,7 @@ img.channel_background[src="null"] { display: none; }
|
|||
.ffz-moderation-card .mod-controls:last-of-type button:last-of-type { margin-right: 0 }
|
||||
|
||||
.ffz-moderation-card .follow-button a {
|
||||
text-indent: -9999px;
|
||||
font-size: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
|
@ -2795,7 +2838,7 @@ body:not(.ffz-tags-on-channel) .tw-title--tall { height: 60px }
|
|||
/* Banned and Spoiler Games */
|
||||
|
||||
.ffz-game-spoilered .thumb .cap img,
|
||||
body:not([data-current-path^="directory.csgo"]):not([data-current-path^="directory.game-directory"]):not([data-current-path^="directory.creative"]) .ffz-game-banned { display: none }
|
||||
body:not([data-current-path^="directory.csgo"]):not([data-current-path^="directory.game"]):not([data-current-path^="directory.creative"]) .ffz-game-banned { display: none }
|
||||
|
||||
.ffz-game-spoilered .thumb .cap {
|
||||
position: absolute !important; top: 0; left: 0; bottom: 0; right: 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue