From 0089619ed9ee8e95b82b60b07d2f479bfd83261d Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 20 Mar 2013 21:45:01 -0700 Subject: [PATCH] Eyeline will no fire any events if the window has no focus After posts are rendered a debounced eyeline is fired Dont trigger eyeline from TopicPostsView, its the wrong spot, will only fire on first render --- .../discourse/components/eyeline.js | 12 ++-- .../discourse/controllers/topic_controller.js | 12 +++- .../javascripts/discourse/views/post_view.js | 12 +++- .../discourse/views/topic_posts_view.js | 5 +- .../javascripts/discourse/views/topic_view.js | 67 ++++++++++++++----- 5 files changed, 79 insertions(+), 29 deletions(-) diff --git a/app/assets/javascripts/discourse/components/eyeline.js b/app/assets/javascripts/discourse/components/eyeline.js index a5b0f1cd3b1..393decd7d7d 100644 --- a/app/assets/javascripts/discourse/components/eyeline.js +++ b/app/assets/javascripts/discourse/components/eyeline.js @@ -22,9 +22,12 @@ Discourse.Eyeline = function Eyeline(selector) { @method update **/ Discourse.Eyeline.prototype.update = function() { - var $elements, $results, atBottom, bottomOffset, docViewBottom, docViewTop, documentHeight, foundElement, windowHeight, + var $elements, atBottom, bottomOffset, docViewBottom, docViewTop, documentHeight, foundElement, windowHeight, _this = this; + // before anything ... let us not do anything if we have no focus + if (!Discourse.get('hasFocus')) { return; } + docViewTop = $(window).scrollTop(); windowHeight = $(window).height(); docViewBottom = docViewTop + windowHeight; @@ -38,9 +41,10 @@ Discourse.Eyeline.prototype.update = function() { // Whether we've seen any elements in this search foundElement = false; - $results = $(this.selector); - return $results.each(function(i, elem) { + + return $elements.each(function(i, elem) { var $elem, elemBottom, elemTop, markSeen; + $elem = $(elem); elemTop = $elem.offset().top; elemBottom = elemTop + $elem.height(); @@ -71,7 +75,7 @@ Discourse.Eyeline.prototype.update = function() { if (i === 0) { _this.trigger('sawTop', { detail: $elem }); } - if (i === ($results.length - 1)) { + if (i === ($elements.length - 1)) { return _this.trigger('sawBottom', { detail: $elem }); } }); diff --git a/app/assets/javascripts/discourse/controllers/topic_controller.js b/app/assets/javascripts/discourse/controllers/topic_controller.js index 12dc33c33db..8db9879b765 100644 --- a/app/assets/javascripts/discourse/controllers/topic_controller.js +++ b/app/assets/javascripts/discourse/controllers/topic_controller.js @@ -271,7 +271,8 @@ Discourse.TopicController = Discourse.ObjectController.extend({ // there is a condition where the view never calls unsubscribe, navigate to a topic from a topic bus.unsubscribe('/topic/*'); - return bus.subscribe("/topic/" + (this.get('content.id')), function(data) { + + bus.subscribe("/topic/" + (this.get('content.id')), function(data) { var posts, topic; topic = _this.get('content'); if (data.notification_level_change) { @@ -289,7 +290,7 @@ Discourse.TopicController = Discourse.ObjectController.extend({ topic.set('highest_post_number', data.post_number); topic.set('last_poster', data.user); topic.set('last_posted_at', data.created_at); - return Discourse.notifyTitle(); + Discourse.notifyTitle(); }); }, @@ -411,6 +412,13 @@ Discourse.TopicController = Discourse.ObjectController.extend({ post.set('version', post.get('version') + 1); } return post["delete"](); + }, + + postRendered: function(post) { + var onPostRendered = this.get('onPostRendered'); + if (onPostRendered) { + onPostRendered(post); + } } }); diff --git a/app/assets/javascripts/discourse/views/post_view.js b/app/assets/javascripts/discourse/views/post_view.js index d90d9d5b6de..f3f68d15bd4 100644 --- a/app/assets/javascripts/discourse/views/post_view.js +++ b/app/assets/javascripts/discourse/views/post_view.js @@ -240,8 +240,10 @@ Discourse.PostView = Discourse.View.extend({ $post = this.$(); post = this.get('post'); + postNumber = post.get('scrollToAfterInsert'); + // Do we want to scroll to this post now that we've inserted it? - if (postNumber = post.get('scrollToAfterInsert')) { + if (postNumber) { Discourse.TopicView.scrollTo(this.get('post.topic_id'), postNumber); if (postNumber === post.get('post_number')) { $contents = $('.topic-body .contents', $post); @@ -271,7 +273,13 @@ Discourse.PostView = Discourse.View.extend({ } // Find all the quotes - return this.insertQuoteControls(); + this.insertQuoteControls(); + + // be sure that eyeline tracked it + var controller = this.get('controller'); + if (controller && controller.postRendered) { + controller.postRendered(post); + } } }); diff --git a/app/assets/javascripts/discourse/views/topic_posts_view.js b/app/assets/javascripts/discourse/views/topic_posts_view.js index ff7459b5e0b..af65ced895a 100644 --- a/app/assets/javascripts/discourse/views/topic_posts_view.js +++ b/app/assets/javascripts/discourse/views/topic_posts_view.js @@ -7,10 +7,7 @@ @module Discourse **/ Discourse.TopicPostsView = Em.CollectionView.extend({ - itemViewClass: Discourse.PostView, - didInsertElement: function() { - this.get('topicView').postsRendered(); - } + itemViewClass: Discourse.PostView }); diff --git a/app/assets/javascripts/discourse/views/topic_view.js b/app/assets/javascripts/discourse/views/topic_view.js index 1cccef1c797..ca1c90c39cf 100644 --- a/app/assets/javascripts/discourse/views/topic_view.js +++ b/app/assets/javascripts/discourse/views/topic_view.js @@ -110,22 +110,31 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, { // This view is being removed. Shut down operations willDestroyElement: function() { - var _ref; + var screenTrack, controller; this.unbindScrolling(); - this.get('controller').unsubscribe(); - if (_ref = this.get('screenTrack')) { - _ref.stop(); + + controller = this.get('controller'); + controller.unsubscribe(); + controller.set('onPostRendered', null); + + screenTrack = this.get('screenTrack'); + if (screenTrack) { + screenTrack.stop(); } + this.set('screenTrack', null); + $(window).unbind('scroll.discourse-on-scroll'); $(document).unbind('touchmove.discourse-on-scroll'); $(window).unbind('resize.discourse-on-scroll'); - return this.resetExamineDockCache(); + + this.resetExamineDockCache(); }, didInsertElement: function(e) { - var eyeline, onScroll, screenTrack, + var eyeline, onScroll, screenTrack, controller, _this = this; + onScroll = Discourse.debounce((function() { return _this.onScroll(); }), 10); @@ -133,7 +142,12 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, { $(document).bind('touchmove.discourse-on-scroll', onScroll); $(window).bind('resize.discourse-on-scroll', onScroll); this.bindScrolling(); - this.get('controller').subscribe(); + controller = this.get('controller'); + + controller.subscribe(); + controller.set('onPostRendered', function(){ + _this.postsRendered.apply(_this); + }); // Insert our screen tracker screenTrack = Discourse.ScreenTrack.create({ topic_id: this.get('topic.id') }); @@ -142,19 +156,33 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, { // Track the user's eyeline eyeline = new Discourse.Eyeline('.topic-post'); - eyeline.on('saw', function(e) { return _this.postSeen(e.detail); }); - eyeline.on('sawBottom', function(e) { _this.nextPage(e.detail); }); - eyeline.on('sawTop', function(e) { _this.prevPage(e.detail); }); + + eyeline.on('saw', function(e) { + _this.postSeen(e.detail); + }); + + eyeline.on('sawBottom', function(e) { + _this.postSeen(e.detail); + _this.nextPage(e.detail); + }); + + eyeline.on('sawTop', function(e) { + _this.postSeen(e.detail); + _this.prevPage(e.detail); + }); + this.set('eyeline', eyeline); this.$().on('mouseup.discourse-redirect', '.cooked a, a.track-link', function(e) { return Discourse.ClickTrack.trackClick(e); }); - return this.onScroll(); + this.onScroll(); + }, - // Triggered from the post view all posts are rendered - postsRendered: function(postDiv, post) { + // Triggered whenever any posts are rendered, debounced to save over calling + postsRendered: Discourse.debounce(function() { + var $lastPost, $window, _this = this; $window = $(window); @@ -166,7 +194,7 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, { // last is not in view, so only examine in 2 seconds Em.run.later(function() { _this.examineRead(); }, 2000); } - }, + }, 100), resetRead: function(e) { var _this = this; @@ -179,6 +207,12 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, { }); }, + gotFocus: function(){ + if (Discourse.get('hasFocus')){ + this.examineRead(); + } + }.observes("Discourse.hasFocus"), + // Called for every post seen postSeen: function($post) { var post, postView, _ref; @@ -192,7 +226,8 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, { } if (!post.get('read')) { post.set('read', true); - return (_ref = this.get('screenTrack')) ? _ref.guessedSeen(post.get('post_number')) : void 0; + _ref = this.get('screenTrack'); + if (_ref) { _ref.guessedSeen(post.get('post_number')); } } } }, @@ -277,8 +312,6 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, { postCountChanged: (function() { this.set('seenBottom', false); - var eyeline = this.get('eyeline'); - if (eyeline) eyeline.update() }).observes('topic.highest_post_number'), loadMore: function(post) {