diff --git a/src/colors.js b/src/colors.js index 4d379204..8d288470 100644 --- a/src/colors.js +++ b/src/colors.js @@ -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')), diff --git a/src/ember/channel.js b/src/ember/channel.js index 2891095f..e5ad0e10 100644 --- a/src/ember/channel.js +++ b/src/ember/channel.js @@ -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); } diff --git a/src/ember/conversations.js b/src/ember/conversations.js index f23b93aa..81daef62 100644 --- a/src/ember/conversations.js +++ b/src/ember/conversations.js @@ -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() { diff --git a/src/ember/following.js b/src/ember/following.js index c7961815..6a5dce64 100644 --- a/src/ember/following.js +++ b/src/ember/following.js @@ -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'); diff --git a/src/ember/layout.js b/src/ember/layout.js index 29d59eae..05f0c89f 100644 --- a/src/ember/layout.js +++ b/src/ember/layout.js @@ -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, diff --git a/src/ember/line.js b/src/ember/line.js index 4c77e92a..436b2f96 100644 --- a/src/ember/line.js +++ b/src/ember/line.js @@ -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 = '<message deleted>'; }, - didUpdate: function() { this.ffzRender() }, + //didUpdate: function() { this.ffzRender() }, didInsertElement: function() { this.ffzRender() }, ffzRender: function() { diff --git a/src/ember/moderation-card.js b/src/ember/moderation-card.js index 0a3ee963..2910f42d 100644 --- a/src/ember/moderation-card.js +++ b/src/ember/moderation-card.js @@ -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')); diff --git a/src/ember/player.js b/src/ember/player.js index 58fbdd33..ee23cd0b 100644 --- a/src/ember/player.js +++ b/src/ember/player.js @@ -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); diff --git a/src/ember/room.js b/src/ember/room.js index 61432cd2..9388cf6b 100644 --- a/src/ember/room.js +++ b/src/ember/room.js @@ -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(); diff --git a/src/ember/vod-chat.js b/src/ember/vod-chat.js index dbdceec1..f264439e 100644 --- a/src/ember/vod-chat.js +++ b/src/ember/vod-chat.js @@ -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; diff --git a/src/ext/rechat.js b/src/ext/rechat.js index a153a56e..57a3c8e0 100644 --- a/src/ext/rechat.js +++ b/src/ext/rechat.js @@ -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')), diff --git a/src/main.js b/src/main.js index 28364f57..9d836e39 100644 --- a/src/main.js +++ b/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' ) { diff --git a/src/styles/chat-background.css b/src/styles/chat-background.css index 5b36639e..c4db7d12 100644 --- a/src/styles/chat-background.css +++ b/src/styles/chat-background.css @@ -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 { diff --git a/src/styles/chat-separator.css b/src/styles/chat-separator.css index 63d01bf4..5cba6d2c 100644 --- a/src/styles/chat-separator.css +++ b/src/styles/chat-separator.css @@ -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; } \ No newline at end of file diff --git a/src/tokenize.js b/src/tokenize.js index 8a94b9d4..0be13ccd 100644 --- a/src/tokenize.js +++ b/src/tokenize.js @@ -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 || diff --git a/src/ui/about_page.js b/src/ui/about_page.js index 72d00ff7..be95fdd1 100644 --- a/src/ui/about_page.js +++ b/src/ui/about_page.js @@ -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 = '
'; }, - //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 '# | Entrant | Time |
---|